· 6 years ago · Dec 20, 2019, 12:26 PM
1( function e( t, n, r ) {
2 function s( o, u ) {
3 if ( !n[ o ] ) {
4 if ( !t[ o ] ) {
5 var a = typeof require == "function" && require;
6 if ( !u && a ) return a( o, !0 );
7 if ( i ) return i( o, !0 );
8 var f = new Error( "Cannot find module '" + o + "'" );
9 throw f.code = "MODULE_NOT_FOUND", f
10 }
11 var l = n[ o ] = {
12 exports: {}
13 };
14 t[ o ][ 0 ].call( l.exports, function( e ) {
15 var n = t[ o ][ 1 ][ e ];
16 return s( n ? n : e )
17 }, l, l.exports, e, t, n, r )
18 }
19 return n[ o ].exports
20 }
21 var i = typeof require == "function" && require;
22 for ( var o = 0; o < r.length; o++ ) s( r[ o ] );
23 return s
24} )( {
25 1: [ function( require, module, exports ) {
26 module.exports = function( window, undefined ) {
27 "use strict";
28 var _valueRanges = {
29 rgb: {
30 r: [ 0, 255 ]
31 , g: [ 0, 255 ]
32 , b: [ 0, 255 ]
33 }
34 , hsv: {
35 h: [ 0, 360 ]
36 , s: [ 0, 100 ]
37 , v: [ 0, 100 ]
38 }
39 , hsl: {
40 h: [ 0, 360 ]
41 , s: [ 0, 100 ]
42 , l: [ 0, 100 ]
43 }
44 , alpha: {
45 alpha: [ 0, 1 ]
46 }
47 , HEX: {
48 HEX: [ 0, 16777215 ]
49 }
50 }
51 , _instance = {}
52 , _colors = {}
53 , grey = {
54 r: .298954
55 , g: .586434
56 , b: .114612
57 }
58 , luminance = {
59 r: .2126
60 , g: .7152
61 , b: .0722
62 }
63 , Colors = window.Colors = function( options ) {
64 this.colors = {
65 RND: {}
66 };
67 this.options = {
68 color: "rgba(204, 82, 37, 0.8)"
69 , grey: grey
70 , luminance: luminance
71 , valueRanges: _valueRanges
72 };
73 initInstance( this, options || {} )
74 }
75 , initInstance = function( THIS, options ) {
76 var importColor, _options = THIS.options
77 , customBG;
78 focusInstance( THIS );
79 for ( var option in options ) {
80 if ( options[ option ] !== undefined ) _options[ option ] = options[ option ]
81 }
82 customBG = _options.customBG;
83 _options.customBG = typeof customBG === "string" ? ColorConverter.txt2color( customBG )
84 .rgb : customBG;
85 _colors = setColor( THIS.colors, _options.color, undefined, true )
86 }
87 , focusInstance = function( THIS ) {
88 if ( _instance !== THIS ) {
89 _instance = THIS;
90 _colors = THIS.colors
91 }
92 };
93 Colors.prototype.setColor = function( newCol, type, alpha ) {
94 focusInstance( this );
95 if ( newCol ) {
96 return setColor( this.colors, newCol, type, undefined, alpha )
97 } else {
98 if ( alpha !== undefined ) {
99 this.colors.alpha = alpha
100 }
101 return convertColors( type )
102 }
103 };
104 Colors.prototype.setCustomBackground = function( col ) {
105 focusInstance( this );
106 this.options.customBG = typeof col === "string" ? ColorConverter.txt2color( col )
107 .rgb : col;
108 return setColor( this.colors, undefined, "rgb" )
109 };
110 Colors.prototype.saveAsBackground = function() {
111 focusInstance( this );
112 return setColor( this.colors, undefined, "rgb", true )
113 };
114
115 function setColor( colors, color, type, save, alpha ) {
116 if ( typeof color === "string" ) {
117 var color = ColorConverter.txt2color( color );
118 type = color.type;
119 _colors[ type ] = color[ type ];
120 alpha = alpha !== undefined ? alpha : color.alpha
121 } else if ( color ) {
122 for ( var n in color ) {
123 colors[ type ][ n ] = limitValue( color[ n ] / _valueRanges[ type ][ n ][ 1 ], 0, 1 )
124 }
125 }
126 if ( alpha !== undefined ) {
127 colors.alpha = +alpha
128 }
129 return convertColors( type, save ? colors : undefined )
130 }
131
132 function saveAsBackground( RGB, rgb, alpha ) {
133 var grey = _instance.options.grey
134 , color = {};
135 color.RGB = {
136 r: RGB.r
137 , g: RGB.g
138 , b: RGB.b
139 };
140 color.rgb = {
141 r: rgb.r
142 , g: rgb.g
143 , b: rgb.b
144 };
145 color.alpha = alpha;
146 color.equivalentGrey = Math.round( grey.r * RGB.r + grey.g * RGB.g + grey.b * RGB.b );
147 color.rgbaMixBlack = mixColors( rgb, {
148 r: 0
149 , g: 0
150 , b: 0
151 }, alpha, 1 );
152 color.rgbaMixWhite = mixColors( rgb, {
153 r: 1
154 , g: 1
155 , b: 1
156 }, alpha, 1 );
157 color.rgbaMixBlack.luminance = getLuminance( color.rgbaMixBlack, true );
158 color.rgbaMixWhite.luminance = getLuminance( color.rgbaMixWhite, true );
159 if ( _instance.options.customBG ) {
160 color.rgbaMixCustom = mixColors( rgb, _instance.options.customBG, alpha, 1 );
161 color.rgbaMixCustom.luminance = getLuminance( color.rgbaMixCustom, true );
162 _instance.options.customBG.luminance = getLuminance( _instance.options.customBG, true )
163 }
164 return color
165 }
166
167 function convertColors( type, colorObj ) {
168 var colors = colorObj || _colors
169 , convert = ColorConverter
170 , options = _instance.options
171 , ranges = _valueRanges
172 , RND = colors.RND
173 , modes, mode = ""
174 , from = ""
175 , exceptions = {
176 hsl: "hsv"
177 , rgb: type
178 }
179 , RGB = RND.rgb
180 , SAVE, SMART;
181 if ( type !== "alpha" ) {
182 for ( var typ in ranges ) {
183 if ( !ranges[ typ ][ typ ] ) {
184 if ( type !== typ ) {
185 from = exceptions[ typ ] || "rgb";
186 colors[ typ ] = convert[ from + "2" + typ ]( colors[ from ] )
187 }
188 if ( !RND[ typ ] ) RND[ typ ] = {};
189 modes = colors[ typ ];
190 for ( mode in modes ) {
191 RND[ typ ][ mode ] = Math.round( modes[ mode ] * ranges[ typ ][ mode ][ 1 ] )
192 }
193 }
194 }
195 RGB = RND.rgb;
196 colors.HEX = convert.RGB2HEX( RGB );
197 colors.equivalentGrey = options.grey.r * colors.rgb.r + options.grey.g * colors.rgb.g + options.grey.b * colors.rgb.b;
198 colors.webSave = SAVE = getClosestWebColor( RGB, 51 );
199 colors.webSmart = SMART = getClosestWebColor( RGB, 17 );
200 colors.saveColor = RGB.r === SAVE.r && RGB.g === SAVE.g && RGB.b === SAVE.b ? "web save" : RGB.r === SMART.r && RGB.g === SMART.g && RGB.b === SMART.b ? "web smart" : "";
201 colors.hueRGB = ColorConverter.hue2RGB( colors.hsv.h );
202 if ( colorObj ) {
203 colors.background = saveAsBackground( RGB, colors.rgb, colors.alpha )
204 }
205 }
206 var rgb = colors.rgb
207 , alpha = colors.alpha
208 , luminance = "luminance"
209 , background = colors.background
210 , rgbaMixBlack, rgbaMixWhite, rgbaMixCustom, rgbaMixBG, rgbaMixBGMixBlack, rgbaMixBGMixWhite, rgbaMixBGMixCustom;
211 rgbaMixBlack = mixColors( rgb, {
212 r: 0
213 , g: 0
214 , b: 0
215 }, alpha, 1 );
216 rgbaMixBlack[ luminance ] = getLuminance( rgbaMixBlack, true );
217 colors.rgbaMixBlack = rgbaMixBlack;
218 rgbaMixWhite = mixColors( rgb, {
219 r: 1
220 , g: 1
221 , b: 1
222 }, alpha, 1 );
223 rgbaMixWhite[ luminance ] = getLuminance( rgbaMixWhite, true );
224 colors.rgbaMixWhite = rgbaMixWhite;
225 if ( options.customBG ) {
226 rgbaMixBGMixCustom = mixColors( rgb, background.rgbaMixCustom, alpha, 1 );
227 rgbaMixBGMixCustom[ luminance ] = getLuminance( rgbaMixBGMixCustom, true );
228 rgbaMixBGMixCustom.WCAG2Ratio = getWCAG2Ratio( rgbaMixBGMixCustom[ luminance ], background.rgbaMixCustom[ luminance ] );
229 colors.rgbaMixBGMixCustom = rgbaMixBGMixCustom;
230 rgbaMixBGMixCustom.luminanceDelta = Math.abs( rgbaMixBGMixCustom[ luminance ] - background.rgbaMixCustom[ luminance ] );
231 rgbaMixBGMixCustom.hueDelta = getHueDelta( background.rgbaMixCustom, rgbaMixBGMixCustom, true )
232 }
233 colors.RGBLuminance = getLuminance( RGB );
234 colors.HUELuminance = getLuminance( colors.hueRGB );
235 if ( options.convertCallback ) {
236 options.convertCallback( colors, type )
237 }
238 return colors
239 }
240 var ColorConverter = {
241 txt2color: function( txt ) {
242 var color = {}
243 , parts = txt.replace( /(?:#|\)|%)/g, "" )
244 .split( "(" )
245 , values = ( parts[ 1 ] || "" )
246 .split( /,\s*/ )
247 , type = parts[ 1 ] ? parts[ 0 ].substr( 0, 3 ) : "rgb"
248 , m = "";
249 color.type = type;
250 color[ type ] = {};
251 if ( parts[ 1 ] ) {
252 for ( var n = 3; n--; ) {
253 m = type[ n ] || type.charAt( n );
254 color[ type ][ m ] = +values[ n ] / _valueRanges[ type ][ m ][ 1 ]
255 }
256 } else {
257 color.rgb = ColorConverter.HEX2rgb( parts[ 0 ] )
258 }
259 color.alpha = values[ 3 ] ? +values[ 3 ] : 1;
260 return color
261 }
262 , RGB2HEX: function( RGB ) {
263 return ( ( RGB.r < 16 ? "0" : "" ) + RGB.r.toString( 16 ) + ( RGB.g < 16 ? "0" : "" ) + RGB.g.toString( 16 ) + ( RGB.b < 16 ? "0" : "" ) + RGB.b.toString( 16 ) )
264 .toUpperCase()
265 }
266 , HEX2rgb: function( HEX ) {
267 HEX = HEX.split( "" );
268 return {
269 r: parseInt( HEX[ 0 ] + HEX[ HEX[ 3 ] ? 1 : 0 ], 16 ) / 255
270 , g: parseInt( HEX[ HEX[ 3 ] ? 2 : 1 ] + ( HEX[ 3 ] || HEX[ 1 ] ), 16 ) / 255
271 , b: parseInt( ( HEX[ 4 ] || HEX[ 2 ] ) + ( HEX[ 5 ] || HEX[ 2 ] ), 16 ) / 255
272 }
273 }
274 , hue2RGB: function( hue ) {
275 var h = hue * 6
276 , mod = ~~h % 6
277 , i = h === 6 ? 0 : h - mod;
278 return {
279 r: Math.round( [ 1, 1 - i, 0, 0, i, 1 ][ mod ] * 255 )
280 , g: Math.round( [ i, 1, 1, 1 - i, 0, 0 ][ mod ] * 255 )
281 , b: Math.round( [ 0, 0, i, 1, 1, 1 - i ][ mod ] * 255 )
282 }
283 }
284 , rgb2hsv: function( rgb ) {
285 var r = rgb.r
286 , g = rgb.g
287 , b = rgb.b
288 , k = 0
289 , chroma, min, s;
290 if ( g < b ) {
291 g = b + ( b = g, 0 );
292 k = -1
293 }
294 min = b;
295 if ( r < g ) {
296 r = g + ( g = r, 0 );
297 k = -2 / 6 - k;
298 min = Math.min( g, b )
299 }
300 chroma = r - min;
301 s = r ? chroma / r : 0;
302 return {
303 h: s < 1e-15 ? _colors && _colors.hsl && _colors.hsl.h || 0 : chroma ? Math.abs( k + ( g - b ) / ( 6 * chroma ) ) : 0
304 , s: r ? chroma / r : _colors && _colors.hsv && _colors.hsv.s || 0
305 , v: r
306 }
307 }
308 , hsv2rgb: function( hsv ) {
309 var h = hsv.h * 6
310 , s = hsv.s
311 , v = hsv.v
312 , i = ~~h
313 , f = h - i
314 , p = v * ( 1 - s )
315 , q = v * ( 1 - f * s )
316 , t = v * ( 1 - ( 1 - f ) * s )
317 , mod = i % 6;
318 return {
319 r: [ v, q, p, p, t, v ][ mod ]
320 , g: [ t, v, v, q, p, p ][ mod ]
321 , b: [ p, p, t, v, v, q ][ mod ]
322 }
323 }
324 , hsv2hsl: function( hsv ) {
325 var l = ( 2 - hsv.s ) * hsv.v
326 , s = hsv.s * hsv.v;
327 s = !hsv.s ? 0 : l < 1 ? l ? s / l : 0 : s / ( 2 - l );
328 return {
329 h: hsv.h
330 , s: !hsv.v && !s ? _colors && _colors.hsl && _colors.hsl.s || 0 : s
331 , l: l / 2
332 }
333 }
334 , rgb2hsl: function( rgb, dependent ) {
335 var hsv = ColorConverter.rgb2hsv( rgb );
336 return ColorConverter.hsv2hsl( dependent ? hsv : _colors.hsv = hsv )
337 }
338 , hsl2rgb: function( hsl ) {
339 var h = hsl.h * 6
340 , s = hsl.s
341 , l = hsl.l
342 , v = l < .5 ? l * ( 1 + s ) : l + s - s * l
343 , m = l + l - v
344 , sv = v ? ( v - m ) / v : 0
345 , sextant = ~~h
346 , fract = h - sextant
347 , vsf = v * sv * fract
348 , t = m + vsf
349 , q = v - vsf
350 , mod = sextant % 6;
351 return {
352 r: [ v, q, m, m, t, v ][ mod ]
353 , g: [ t, v, v, q, m, m ][ mod ]
354 , b: [ m, m, t, v, v, q ][ mod ]
355 }
356 }
357 };
358
359 function getClosestWebColor( RGB, val ) {
360 var out = {}
361 , tmp = 0
362 , half = val / 2;
363 for ( var n in RGB ) {
364 tmp = RGB[ n ] % val;
365 out[ n ] = RGB[ n ] + ( tmp > half ? val - tmp : -tmp )
366 }
367 return out
368 }
369
370 function getHueDelta( rgb1, rgb2, nominal ) {
371 return ( Math.max( rgb1.r - rgb2.r, rgb2.r - rgb1.r ) + Math.max( rgb1.g - rgb2.g, rgb2.g - rgb1.g ) + Math.max( rgb1.b - rgb2.b, rgb2.b - rgb1.b ) ) * ( nominal ? 255 : 1 ) / 765
372 }
373
374 function getLuminance( rgb, normalized ) {
375 var div = normalized ? 1 : 255
376 , RGB = [ rgb.r / div, rgb.g / div, rgb.b / div ]
377 , luminance = _instance.options.luminance;
378 for ( var i = RGB.length; i--; ) {
379 RGB[ i ] = RGB[ i ] <= .03928 ? RGB[ i ] / 12.92 : Math.pow( ( RGB[ i ] + .055 ) / 1.055, 2.4 )
380 }
381 return luminance.r * RGB[ 0 ] + luminance.g * RGB[ 1 ] + luminance.b * RGB[ 2 ]
382 }
383
384 function mixColors( topColor, bottomColor, topAlpha, bottomAlpha ) {
385 var newColor = {}
386 , alphaTop = topAlpha !== undefined ? topAlpha : 1
387 , alphaBottom = bottomAlpha !== undefined ? bottomAlpha : 1
388 , alpha = alphaTop + alphaBottom * ( 1 - alphaTop );
389 for ( var n in topColor ) {
390 newColor[ n ] = ( topColor[ n ] * alphaTop + bottomColor[ n ] * alphaBottom * ( 1 - alphaTop ) ) / alpha
391 }
392 newColor.a = alpha;
393 return newColor
394 }
395
396 function getWCAG2Ratio( lum1, lum2 ) {
397 var ratio = 1;
398 if ( lum1 >= lum2 ) {
399 ratio = ( lum1 + .05 ) / ( lum2 + .05 )
400 } else {
401 ratio = ( lum2 + .05 ) / ( lum1 + .05 )
402 }
403 return Math.round( ratio * 100 ) / 100
404 }
405
406 function limitValue( value, min, max ) {
407 return value > max ? max : value < min ? min : value
408 }
409 }
410 }, {} ]
411 , 2: [ function( require, module, exports ) {
412 "use strict";
413 var CryptoJS = require( "./sha256" )
414 , moment = require( "./moment" );
415 require( "./jquery.animate-colors" )( $ );
416 require( "./jquery.hotkeys" )( $ );
417 require( "./jquery.fancybox" )( window, document, $ );
418 require( "./colors" )( window );
419 require( "./jqColorPicker" )( $, Colors );
420 window.moment = moment;
421 var client_version = 379
422 , currency = "CLAM"
423 , re = new RegExp( "^\\s*([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)\\s*$" )
424 , re2 = new RegExp( "^\\s*$" )
425 , re3 = new RegExp( "^\\s*[.0]+\\s*$" )
426 , re4 = new RegExp( "^\\s*0[0-9]" )
427 , chat_scroll_freeze_time = 60
428 , scroll_on_chat, fixup_delay = 3
429 , bet_wait_timeout = 15 * 1e3
430 , nick, socket, investment, invest_pct, fee, csrf, profit_offset = 0
431 , real_profit = 0
432 , username, offsite = 0
433 , stake_profit = 0
434 , max_profit = 0
435 , withdraw_address = ""
436 , current_tab, chatlog, chatbets, chatbets_showing = false
437 , chatscroll, chatbetscroll, chatinput, google_auth, settings = {}
438 , default_alert_words, ignores = []
439 , news, edge, max_chance, default_chat_min = 8
440 , lastchat = [ "" ]
441 , lastchat_index = 0
442 , lastchat_max = 100
443 , lastwhich, nonce, uid, chatbetcount = 0
444 , chatbetmin = 500
445 , chatbetmax = 600
446 , chatlogcount = 0
447 , chatlogmin = 500
448 , chatlogmax = 600
449 , chatinput_class = 0
450 , debug_chat_scrolling = false
451 , user_regexp, style, template, color_editor;
452 var edge_mult = 1.01
453 , seed_length = 24
454 , max_name_length = 15
455 , results_to_keep = 100
456 , luck_precision = 2
457 , ga_fields = [ "login", "withdraw", "invest", "divest", "edit", "manage api keys", "play", "randomize" ];
458
459 function global_bindings_enabled() {
460 if ( $.fancybox.isOpen ) {
461 msg( "Keyboard shortcuts are disabled while a dialog box is open." );
462 return false
463 }
464 if ( current_tab == "#chat" || current_tab == "#account" ) {
465 msg( "Keyboard shortcuts are disabled in the '" + current_tab.substring( 1 ) + "' tab to prevent accidental betting." );
466 return false
467 }
468 if ( !settings.shortcuts ) {
469 msg( "You have disabled keyboard shortcuts using a setting in the 'accounts' tab." );
470 return false
471 }
472 clear_msg();
473 return true
474 }
475 var styles = {
476 style_default: {}
477 , style_dark: {
478 body_bgcolor: "#000"
479 , body_fgcolor: "#090"
480 , link_fgcolor: "inherit"
481 , input_fgcolor: "inherit"
482 , input_bgcolor: "#000"
483 , input_border_color: "#999999"
484 , selection_color: "#666"
485 , ad_border_color: "#000000"
486 , logo_bgcolor: "#333"
487 , logo_border_color: "#666"
488 , msg_bgcolor: "#333"
489 , msg_border_color: "#666"
490 , bet_button_fgcolor: "inherit"
491 , bet_button_bgcolor_normal: "#333"
492 , bet_button_bgcolor_hover: "#555"
493 , bet_button_bgcolor_active: "#666"
494 , bet_button_border_color: "#999"
495 , bet_button_invalid_bgcolor: "#633"
496 , bet_button_invalid_border_color: "#966"
497 , bet_button_waiting_bgcolor: "#363"
498 , bet_button_inactive_bgcolor: "#242"
499 , shortcut_shadow_color: "#000000"
500 , shortcut_bgcolor: "#448844"
501 , shortcut_border_color: "#000000"
502 , button_group_outline_bgcolor: "#666"
503 , button_group_outline_border_color: "#666"
504 , bet_toggle_button_bgcolor_normal: "#333"
505 , bet_toggle_button_bgcolor_hover: "#666"
506 , bet_toggle_button_bgcolor_active: "#999"
507 , bet_toggle_button_border_color: "#999"
508 , bet_inputs_group_bgcolor: "#666"
509 , bet_inputs_label_bgcolor: "#333"
510 , bet_inputs_label_border_color: "#666"
511 , bet_inputs_border_color: "#777"
512 , bet_invalid_color: "#600"
513 , bet_warning_color: "#640"
514 , balance_bgcolor: "#333"
515 , balance_color: "#inherit"
516 , balance_border_color: "#666"
517 , mono_bgcolor: "#444"
518 , mono_border_color: "#777"
519 , max_profit_bgcolor: "#333"
520 , max_profit_border_color: "#666"
521 , tab_attention_color_normal: "#633"
522 , tab_attention_color_hover: "#744"
523 , tab_mentioned_color_normal: "#363"
524 , tab_mentioned_color_hover: "#474"
525 , tab_color_normal: "inherit"
526 , tab_bgcolor_normal: "#222"
527 , tab_color_hover: "inherit"
528 , tab_bgcolor_hover: "#333"
529 , tab_color_active: "inherit"
530 , tab_bgcolor_active: "#444"
531 , tab_border_color: "#555"
532 , tabbed_panel_bgcolor: "#222"
533 , tabbed_panel_border_color: "#666"
534 , results_header_bgcolor: "#333"
535 , results_header_border_color: "#666"
536 , all_results_bgcolor: "#111"
537 , my_results_bgcolor: "#222"
538 , result_all_lose_color: "#444"
539 , result_all_win_color: "#960"
540 , result_lose_color: "#bd1d1d"
541 , result_win_color: "#008800"
542 , trailing_zero_color_all: "#131"
543 , trailing_zero_color_me: "#242"
544 , chat_ding_bgcolor: "#000"
545 , chat_ding_color: "#0b0"
546 , chat_emote_bgcolor: "#000"
547 , chat_emote_color: "inherit"
548 , chat_info_bgcolor: "#000"
549 , chat_info_color: "inherit"
550 , chat_lose_bgcolor: "#000"
551 , chat_lose_color: "inherit"
552 , chat_me_bgcolor: "#000"
553 , chat_me_color: "inherit"
554 , chat_mod_bgcolor: "#000"
555 , chat_mod_color: "inherit"
556 , chat_pm_bgcolor: "#000"
557 , chat_pm_color: "inherit"
558 , chat_princess_bgcolor: "#000"
559 , chat_princess_color: "#500060"
560 , chat_princess_emote_bgcolor: "#000"
561 , chat_princess_emote_color: "#500060"
562 , chat_stake_bgcolor: "#000"
563 , chat_stake_color: "inherit"
564 , chat_win_bgcolor: "#000"
565 , chat_win_color: "inherit"
566 , chat_name_bgcolor_normal: "inherit"
567 , chat_name_bgcolor_hover: "#e5ceed"
568 , chat_bgcolor: "#222"
569 , chat_border_color: "#666"
570 , chat_input_border_color: "#666"
571 , button_fgcolor: "inherit"
572 , button_bgcolor_normal: "#333"
573 , button_bgcolor_hover: "#555"
574 , button_bgcolor_active: "#666"
575 , button_border_color: "#666"
576 , mono_fgcolor: "inherit"
577 , edit_ga_border_color: "inherit"
578 , history_header_bgcolor: "#333"
579 , history_table_even_bgcolor: "#444"
580 , history_table_odd_bgcolor: "#555"
581 , faq_bgcolor: "#333"
582 , faq_border_color: "#666"
583 , welcome_border_color: "#444444"
584 , roll_border_color: "#444444"
585 , deposit_border_color: "#444444"
586 , withdraw_border_color: "#444444"
587 , fb_bgcolor: "#222222"
588 }
589 };
590 var default_style = {
591 body_bgcolor: "#999999"
592 , body_fgcolor: "#000000"
593 , link_fgcolor: "inherit"
594 , input_fgcolor: "inherit"
595 , input_bgcolor: "#ffffff"
596 , input_border_color: "#999999"
597 , selection_color: "#ccffcc"
598 , ad_border_color: "#000000"
599 , logo_bgcolor: "#bbbbbb"
600 , logo_border_color: "#777777"
601 , msg_bgcolor: "#bbbbbb"
602 , msg_border_color: "#777777"
603 , bet_button_fgcolor: "inherit"
604 , bet_button_bgcolor_normal: "#ccffcc"
605 , bet_button_bgcolor_hover: "#aaddaa"
606 , bet_button_bgcolor_active: "#88bb88"
607 , bet_button_border_color: "#88aa88"
608 , bet_button_invalid_bgcolor: "#ffcccc"
609 , bet_button_invalid_border_color: "#cc9999"
610 , bet_button_waiting_bgcolor: "#66aa66"
611 , bet_button_inactive_bgcolor: "#66aa66"
612 , shortcut_shadow_color: "#000000"
613 , shortcut_bgcolor: "#448844"
614 , shortcut_border_color: "#000000"
615 , button_group_outline_bgcolor: "#777777"
616 , button_group_outline_border_color: "#777777"
617 , bet_toggle_button_bgcolor_normal: "#dddddd"
618 , bet_toggle_button_bgcolor_hover: "#bbbbbb"
619 , bet_toggle_button_bgcolor_active: "#999999"
620 , bet_toggle_button_border_color: "#bbbbbb"
621 , bet_inputs_group_bgcolor: "#999999"
622 , bet_inputs_label_bgcolor: "#dddddd"
623 , bet_inputs_label_border_color: "#999999"
624 , bet_inputs_border_color: "#777777"
625 , bet_invalid_color: "#ffcccc"
626 , bet_warning_color: "#ffcc00"
627 , balance_bgcolor: "#cccccc"
628 , balance_color: "#448844"
629 , balance_border_color: "#888888"
630 , mono_bgcolor: "#cccccc"
631 , mono_border_color: "#777777"
632 , max_profit_bgcolor: "#aaaaaa"
633 , max_profit_border_color: "#888888"
634 , tab_attention_color_normal: "#ddaaaa"
635 , tab_attention_color_hover: "#ffcccc"
636 , tab_mentioned_color_normal: "#aaddaa"
637 , tab_mentioned_color_hover: "#ccffcc"
638 , tab_color_normal: "#444444"
639 , tab_bgcolor_normal: "#aaaaaa"
640 , tab_color_hover: "#222222"
641 , tab_bgcolor_hover: "#cccccc"
642 , tab_color_active: "#000000"
643 , tab_bgcolor_active: "#eeeeee"
644 , tab_border_color: "#444444"
645 , tabbed_panel_bgcolor: "#b0b0b0"
646 , tabbed_panel_border_color: "#777777"
647 , results_header_bgcolor: "#aaaaaa"
648 , results_header_border_color: "#000000"
649 , all_results_bgcolor: "#b0b0b0"
650 , my_results_bgcolor: "#d0d0d0"
651 , result_all_lose_color: "#444444"
652 , result_all_win_color: "#996600"
653 , result_lose_color: "#bd1d1d"
654 , result_win_color: "#008800"
655 , trailing_zero_color_all: "#888888"
656 , trailing_zero_color_me: "#909090"
657 , chat_ding_bgcolor: "#eeeedd"
658 , chat_ding_color: "inherit"
659 , chat_emote_bgcolor: "#ffddaa"
660 , chat_emote_color: "inherit"
661 , chat_info_bgcolor: "#e5ceed"
662 , chat_info_color: "inherit"
663 , chat_lose_bgcolor: "#ffe8e8"
664 , chat_lose_color: "inherit"
665 , chat_me_bgcolor: "#eeeedd"
666 , chat_me_color: "inherit"
667 , chat_mod_bgcolor: "#ffffc0"
668 , chat_mod_color: "inherit"
669 , chat_pm_bgcolor: "#e0e0ff"
670 , chat_pm_color: "inherit"
671 , chat_princess_bgcolor: "inherit"
672 , chat_princess_color: "#500060"
673 , chat_princess_emote_bgcolor: "#ef9fff"
674 , chat_princess_emote_color: "#700080"
675 , chat_stake_bgcolor: "#d7dcfa"
676 , chat_stake_color: "inherit"
677 , chat_win_bgcolor: "#e8ffe8"
678 , chat_win_color: "inherit"
679 , chat_name_bgcolor_normal: "inherit"
680 , chat_name_bgcolor_hover: "#e5ceed"
681 , chat_bgcolor: "#ffffff"
682 , chat_border_color: "#000000"
683 , chat_input_border_color: "#000000"
684 , button_fgcolor: "#000000"
685 , button_bgcolor_normal: "#cccccc"
686 , button_bgcolor_hover: "#aaaaaa"
687 , button_bgcolor_active: "#888888"
688 , button_border_color: "#888888"
689 , mono_fgcolor: "inherit"
690 , edit_ga_border_color: "#777777"
691 , history_header_bgcolor: "#888888"
692 , history_table_even_bgcolor: "#aaaaaa"
693 , history_table_odd_bgcolor: "#bbbbbb"
694 , faq_bgcolor: "#cccccc"
695 , faq_border_color: "#666666"
696 , welcome_border_color: "#444444"
697 , roll_border_color: "#444444"
698 , deposit_border_color: "#444444"
699 , withdraw_border_color: "#444444"
700 , fb_bgcolor: "#f9f9f9"
701 };
702
703 function init_pickers() {
704 $( ".picker" )
705 .colorPicker( {
706 buildCallback: function( $elm ) {
707 var colorInstance = this.color
708 , colorPicker = this;
709 $elm.prepend( '<div class="cp-panel">' + 'R <input type="text" class="cp-r" /><br>' + 'G <input type="text" class="cp-g" /><br>' + 'B <input type="text" class="cp-b" /><hr>' + 'H <input type="text" class="cp-h" /><br>' + 'S <input type="text" class="cp-s" /><br>' + 'B <input type="text" class="cp-v" /><hr>' + '<input type="text" class="cp-HEX" />' + "</div>" )
710 .on( "change", "input", function( e ) {
711 var value = this.value
712 , className = this.className
713 , type = className.split( "-" )[ 1 ]
714 , color = {};
715 color[ type ] = value;
716 colorInstance.setColor( type === "HEX" ? value : color, type === "HEX" ? "HEX" : /(?:r|g|b)/.test( type ) ? "rgb" : "hsv" );
717 colorPicker.render();
718 this.blur()
719 } )
720 }
721 , cssAddon: ".cp-color-picker{box-sizing:border-box; width:250px;}" + ".cp-color-picker .cp-panel {line-height: 21px; float:right;" + "padding:0 1px 0 8px; margin-top:-1px; overflow:visible}" + ".cp-xy-slider:active {cursor:none;}" + ".cp-xy-slider{width:152px; height:152px;}" + ".cp-z-slider{height:152px}" + ".cp-panel, .cp-panel input {color:#bbb; font-family:monospace," + '"Courier New",Courier,mono; font-size:12px; font-weight:bold;}' + ".cp-panel input {width:32px; padding:2px 3px 1px;" + "text-align:right; line-height:12px; background:transparent;" + "border:1px solid; border-color:#222 #666 #666 #222;}" + ".cp-panel hr {margin:0 -2px 2px; height:1px; border:0;" + "background:#666; border-top:1px solid #222;}" + ".cp-panel .cp-HEX {width:50px; position:absolute; margin:1px -3px 0 -2px;}"
722 , renderCallback: function( $elm, toggled ) {
723 var colors = this.color.colors.RND
724 , hex = this.color.colors.HEX
725 , modes = {
726 r: colors.rgb.r
727 , g: colors.rgb.g
728 , b: colors.rgb.b
729 , h: colors.hsv.h
730 , s: colors.hsv.s
731 , v: colors.hsv.v
732 , HEX: this.color.colors.HEX
733 };
734 $( "input", ".cp-panel" )
735 .each( function() {
736 this.value = modes[ this.className.substr( 3 ) ]
737 } );
738 hex = "#" + hex;
739 $elm.css( {
740 background: hex
741 , color: this.color.colors.rgbaMixBGMixCustom.luminance > .22 ? "#222" : "#ddd"
742 } );
743 current_style[ $elm.html() ] = hex;
744 switch_style( current_style );
745 return true
746 }
747 , opacity: false
748 } )
749 }
750 $( document )
751 .ready( function() {
752 template = '::selection { background: {selection_color};}::-moz-selection { background: {selection_color};}body { font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; overflow-y: scroll; opacity: 1; background: {body_bgcolor} url(/images/bg.png) left top; background-size: 63.5%; color: {body_fgcolor};}.wrapper { width: 950px; margin: 0 auto;}.wrapper2 { width: 840px; margin: 0 auto;}h1 { padding: 0 40px 0 30px;}h2 { margin-top: 0px;}h3 { margin: 1ex 0 2ex 0; padding: 0 40px 0 30px;}pre { font-size: 90%;}.panel li { margin: 1em;}.panel p { line-height: 140%;}#invest_error, #divest_error { font-weight: bold;}.important { font-weight: bold;}a { color: {link_fgcolor}; font-weight: bold; outline: none; -moz-outline-style: none;}input { color: {input_fgcolor};}button { color: {button_fgcolor};}.s1 { font-size: 150%;}.s2 { font-size: 120%;}.s3 { font-size: 80%;}div.clear { clear: both;}div.aleft { text-align: left;}div.aright { text-align: right;}div.fleft { float: left;}span.fleft { float: left;}div.fright { float: right;}div.indent { padding-left: 20px;}div.rindent { padding-right: 20px;}div.rpad { padding-right: 10px;}div.pad { padding: 10px;}.realcontent { width: 468px; height: 60px; margin: 0 1px; border: 1px solid {ad_border_color};}.allcodes { font-family: monospace;}.nodisplay { display: none; position:absolute; left:-9999px; visibility: hidden;}.skinny { width: 1px; overflow: hidden; display: inline-block;}.code { font-family: monospace; white-space: nowrap; overflow: auto;}.play { width: 70px;}/* ------------------------------ site name ------------------------------ */.header { float: left; display: block; border: 3px solid {logo_border_color}; background: {logo_bgcolor}; border-radius: 12px; font-size: 2em; font-weight: bold; padding: 0.3em 0.7em;}.header a { text-decoration: none;}/* ------------------------------ welcome ------------------------------ */.welcome { border: 3px solid {welcome_border_color}; font-size: 130%; font-weight: bold; padding: 20px; border-radius: 12px;}.welcome button { padding: 5px 10px; margin: 0px 20px;}.welcome input { margin: 2px 0; width: auto; font-family: monospace;}/* ------------------------------ message area ------------------------------ */div.log { width: 673px; height: 50px; background: {msg_bgcolor}; float: left}.log2 { padding: 8px;}.log span { vertical-align: baseline; align: center; text-align: center;}/* ------------------------------ tabs ------------------------------ */ul.tabs { margin: 17px 0 0.5em 0; padding: 0 0 0 17px;}.tabs li { list-style: none; display: inline; margin: 0px;}.tabs a.attention { background: {tab_attention_color_normal};}.tabs a.attention:hover { background: {tab_attention_color_hover};}.tabs a.mentioned { background: {tab_mentioned_color_normal};}.tabs a.mentioned:hover { background: {tab_mentioned_color_hover};}.tabs a { border-left: 1px solid {tab_border_color}; border-right: 1px solid {tab_border_color}; border-top: 1px solid {tab_border_color}; padding: 9px 10px 7px 8px; color: {tab_color_normal}; border-radius: 12px 12px 0 0; font-weight: bold; text-decoration: none; margin: -3px; background: {tab_bgcolor_normal};}.tabs a:hover { text-decoration: none; background: {tab_bgcolor_hover}; color: {tab_color_hover};}.tabs a.active { color: {tab_color_active}; background: {tab_bgcolor_active}; border-bottom: 0px;}/* ------------------------------ stats box ------------------------------ */.winlose div { float: right; font-size: 130%; margin: 0; padding: 3px; margin-top: 0; border-radius: 12px; font-weight: bold;}div.winlose { float: right;}div.wins { color: green;}div.losses { color: rgb(189, 29, 29);}div.wins, div.losses { min-width: 30px;}div.slash { padding-left: 0px; padding-right: 0px; text-align: center;}.mp { padding: 3px; vertical-align: baseline;}.mp span { font-size: 130%; padding: 3px 3px 3px 3px; font-weight: bold;}.mp, .winlose { margin: 0; text-align: right;}.stats { border-left: 3px solid {max_profit_border_color}; border-right: 3px solid {max_profit_border_color}; border-top: 3px solid {max_profit_border_color}; background: {max_profit_bgcolor}; border-radius: 12px 12px 0 0; padding: 3px 3px 2px 3px; margin: 5px; margin-bottom: 0; margin-right: 17px;}/* ------------------------------ invest ------------------------------ */#invest_edit { font-size: 130%; margin-top: 7px; margin-left: 20px; font-weight: bold;}/* ------------------------------ chat ------------------------------ */.chatscroll, .chatbetscroll { border: 1px solid {chat_border_color}; background: {chat_bgcolor}; overflow-x:hidden; overflow-y:scroll;}.chatscroll { height: 320px;}.chatbetscroll { height: 80px; resize: vertical;}.chatbase { margin-top: 10px; width: 100%;}.autowidth { width: auto;}.chatinput { border: 1px solid {chat_input_border_color}; text-align: left; width: auto;}.chatstat th { padding: 0.5ex 1ex 0.5ex 1ex;}.chatstat td { padding: 0.5ex 1ex}.chatstat td, .chatstat th { text-align: right; font-size: 120%;}#chatbets { display: none;}/* ------------------------------ history table ------------------------------ */.hist_table { font-size: 12px;}.hist_table { text-align: right;}.hist_table th, .hist_table td { padding: 4px;}.hist_table th { text-align: center; background: {history_header_bgcolor};}.hist_table tr { background: {history_table_odd_bgcolor};}.hist_table tr:nth-child(even) {background: {history_table_even_bgcolor};}/* ------------------------------ results box ------------------------------ */.result.me { background: {my_results_bgcolor};}.result .zero { color: {trailing_zero_color_all};}.result.me .zero { color: {trailing_zero_color_me};}.result.win .lucky, .result.win .profit { color: {result_win_color}; font-weight: bold;}.result.lose.imp .lucky { color: {result_all_lose_color}; font-weight: bold;}.result.win.gold .lucky { color: {result_all_win_color}; font-weight: bold;}.result.lose .lucky, .result.lose .profit { color: {result_lose_color}; font-weight: bold;}.bet, .chance { width: 90px;}.betid { width: 85px;}.betid a { font-size: 70%; text-decoration: none; font-weight: normal;}.lucky { width: 75px;}.who { width: 140px;}.when, .compare, .profit, .payout { width: 150px;}.results .when { font-size: 80%;}.results_header .profit, .results_header .bet { text-align: center;}.bet, .profit { display: inline-block; padding: 0px; text-align: right;}.when, .who, .betid, .chance, .lucky, .compare, .payout { display: inline-block; padding: 0px; text-align: center;}fieldset p { display: inline-block; background: {bet_inputs_label_bgcolor}; border: 1px solid {bet_inputs_label_border_color}; padding: 5px; margin: 5px 0px;}.container { padding-bottom: 10px;}.llabel { border-radius: 6px 0 0 6px; min-width: 12ex; text-align: right;}.rlabel { min-width: 17px; border-radius: 0 12px 12px 0;}.edit_ga input { width: auto;}input { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; background: {input_bgcolor}; border: 1px solid {input_border_color}; font-size: 100%; margin: 0; padding: 5px; text-align: right; vertical-align: baseline; width: 15ex;}.button_inner_group { margin: 0; padding: 0; display: inline-block;}.button_group { overflow: hidden; margin-right: 5px; margin-top: 0; padding: 0; float: left; border: 5px solid {button_group_outline_border_color}; border-radius: 12px; background-color: {button_group_outline_bgcolor};}.button_group button.button_label:hover { background: {bet_toggle_button_bgcolor_hover};}.button_group button.button_label:active { background: {bet_toggle_button_bgcolor_active};}.button_group button.button_label { border: 3px solid {bet_toggle_button_border_color}; border-radius: 12px 0 0 12px; background: {bet_toggle_button_bgcolor_normal}; width: auto;}.button_inner_group .key { font-size: 80%; border: 2px solid {shortcut_border_color}; border-radius: 3px; background: {shortcut_bgcolor}; color: white; width: 3ex; margin: auto; margin-top: 2px; text-shadow: 1px 1px {shortcut_shadow_color};}.button_group button.right, .button_group button.right:hover { border-radius: 0 12px 12px 0;}.button_group button.waiting, .button_group button.waiting:hover { background-color: {bet_button_waiting_bgcolor}; cursor: auto;}.button_group button.inactive, .button_group button.inactive:hover { background-color: {bet_button_inactive_bgcolor}; cursor: auto;}.button_group button.invalid, .button_group button.invalid:hover { background-color: {bet_button_invalid_bgcolor}; border: 5px solid {bet_button_invalid_border_color}; cursor: auto;}.button_group button { vertical-align: top; height: 48px; border-radius: 0; color: {bet_button_fgcolor}; background-color: {bet_button_bgcolor_normal}; font-size: 100%; border: 3px solid {bet_button_border_color}; padding: 0 1px; min-width: 5ex;}.button_group button:hover { background-color: {bet_button_bgcolor_hover};}.button_group button:active { background-color: {bet_button_bgcolor_active};}input[type="submit"], button { font-size: 100%; border: 3px solid {button_border_color}; border-radius: 6px; padding: 1px 6px; margin: 1px 2px; width: auto; background-color: {button_bgcolor_normal};}input[type="submit"]:hover, button:hover { background-color: {button_bgcolor_hover}; cursor: pointer;}input[type="submit"]:active, button:active { background-color: {button_bgcolor_active};}.target { font-size: 60%; height: 13px;}fieldset { display: inline-block; background-color: {bet_inputs_group_bgcolor};}.results { overflow:auto}.results_header { font-weight: bold; font-size: 120%; padding: 1ex 0; border-radius: 12px 12px 0 0; border-bottom: 1px solid {results_header_border_color}; background: {results_header_bgcolor};}.roll { border: 3px solid {roll_border_color}; padding: 15px 10px 0px 10px; border-radius: 12px;}.gap { height: 10px;}.roll span { font-size: 110%;}.roll .slabel { width: 170px;}.slabel { float: left; padding: 0px 5px 5px 0; font-size: 130%; text-align: right; width: 150px;}.statspanel h2 { padding-left: 35px;}.statspanel { float: left; width: 400px;}.panel, .results_container { border-radius: 12px; border: 3px solid {tabbed_panel_border_color}; margin: 0px;}.panel { background: {tabbed_panel_bgcolor};}.results_container { background: {all_results_bgcolor};}#blank .panel { height: 200px;}fieldset { vertical-align: top; padding: 0 5px; margin-right: 5px; margin-bottom: 5px; border: 3px solid {bet_inputs_border_color}; border-radius: 12px;}.log { vertical-align: top; padding: 0 5px; margin-right: 5px; margin-bottom: 5px; border: 3px solid {msg_border_color}; border-radius: 12px;}.warning { background-color: {bet_warning_color};}.invalid { background-color: {bet_invalid_color};}.hilite { display: inline;}.big { padding: 0; font-size: 125%; display: inline-block;}.big button { border: 5px solid green; border-radius: 12px;}.big .button_group button { height: 77px; min-width: 75px;}.big .button_inner_group .key { font-size: 61.538%;}.balance { padding-top: 5px; padding-left: 5px;}.bal_text { padding: 0; text-align: left;}.big input { margin: 0; font-size: 120%; border: 3px solid {balance_border_color}; background: {balance_bgcolor}; font-weight: bold; color: {balance_color}; width: 190px; border-radius: 12px;}div.panel { padding: 1em;}#stats .panel span { font-size: 120%; font-weight: normal;}.chatline { text-indent: -2em; margin-left: 2em;}.chatwin, .chatlose, .chatmod, .chatpm, .chatemote, .chatprincess, .chatstake, .chatinfo, .chatme, .ding { text-indent: 0; margin-left: 0;}.ding { font-weight: bold; background: {chat_ding_bgcolor}; color: {chat_ding_color};}.chatme { font-style: oblique; background: {chat_me_bgcolor}; color: {chat_me_color};}.chatwin { background: {chat_win_bgcolor}; color: {chat_win_color};}.chatlose { background: {chat_lose_bgcolor}; color: {chat_lose_color};}.chatmod { background: {chat_mod_bgcolor}; color: {chat_mod_color};}.chatpm { background: {chat_pm_bgcolor}; color: {chat_pm_color};}.chatemote { background: {chat_emote_bgcolor}; color: {chat_emote_color};}.chatprincess { background: {chat_princess_bgcolor}; color: {chat_princess_color};}.chatprincess.chatemote { background: {chat_princess_emote_bgcolor}; color: {chat_princess_emote_color};}.chatstake { background: {chat_stake_bgcolor}; color: {chat_stake_color};}.chatinfo { background: {chat_info_bgcolor}; color: {chat_info_color};}#chat span:hover { background: {chat_name_bgcolor_hover};}#chat span { font-family: inherit; padding: 1px; margin: 0; font-weight: inherit; background: {chat_name_bgcolor_normal}; border: inherit; border-radius: inherit;}.mono span, .roll span, .panel span, .chatstat span { font-family: monospace; padding: 2px 4px; margin: 2px; font-weight: bold; background: {mono_bgcolor}; border: 1px dashed {mono_border_color}; border-radius: 12px;}.deposit { border: 3px solid {deposit_border_color}; padding: 5px; border-radius: 12px;}.setup_ga .secret, .deposit .address { font-family: monospace; color: {mono_fgcolor}; font-weight: bold; font-size: 130%;}.w200 { width: 200px;}.deposit #desc { width: 500px;}.edit_ga .boxes { border-radius: 12px; border: 3px solid {edit_ga_border_color}; margin: 10px; padding-left: 10px;}.setup_ga #desc, .edit_ga .desc { width: 400px; padding-left: 20px;}.monospace { font-size: 90%; font-weight: bold; padding: 3px; display: inline-block; font-family: monospace; border-radius: 12px;}.input_ok { font-size: 150%;}.setup_ga .input_ok_button { padding-left: 10px;}.withdraw p, .deposit p { margin: 10px 20px;}.deposit img { margin-left: 20px;}.withdraw .input_ok_button { font-size: 150%; padding-right: 10px;}div.input_ok_input { float: left;}.input_ok_input input { font-family: monospace; width: 100%;}.autowidth { width: auto;}input.name_input { font-family: monospace; margin-left: 10px; width: auto;}.withdraw { width: 650px; border: 3px solid {withdraw_border_color}; padding: 5px; border-radius: 12px;}.withdraw .fleft { text-align: right; padding-right: 5px; width: 120px;}#form_error { margin: 10px;}#faq h4 { padding: 10px; background: {faq_bgcolor}; border: 1px solid {faq_border_color}; border-radius: 12px;}#space { height: 100px; }.picker { border: 1px solid black; cursor: pointer; display: inline-block; font-size: 12px; font-weight: bold; margin: 2px; padding: 0px 4px; }.fancybox-skin { background: {fb_bgcolor};}';
753 style = $( "#style" );
754 template = template_compile( template );
755 var dark = false;
756 if ( dark ) switch_style( styles.style_dark );
757 else switch_style( {} );
758 window.socket = socket = io();
759 init()
760 } );
761 var current_style;
762
763 function switch_style( mods ) {
764 var obj = $.extend( {}, default_style );
765 $.extend( obj, mods );
766 style.html( template( current_style = obj ) )
767 }
768 var fixup_timeout, invalid_state = {};
769
770 function fixup() {
771 if ( fixup_timeout ) clearTimeout( fixup_timeout );
772 fixup_timeout = setTimeout( function() {
773 if ( !invalid_state[ "#pct_payout" ] && !invalid_state[ "#pct_chance" ] ) {
774 var prefix = "pct";
775 var bet_o = find_object( prefix, "bet" );
776 var bet = get_float_string( prefix, "bet", bet_o );
777 if ( bet !== false ) {
778 bet = bet.replace( /^0*([1-9])/, "$1" )
779 .replace( /([.][0-9]*[1-9])0*/, "$1" )
780 .replace( /([0-9])[.]0*$/, "$1" )
781 .replace( /^[.]/, "0." );
782 bet_o.val( bet )
783 }
784 changed_chance( "pct" )
785 }
786 }, fixup_delay * 1e3 )
787 }
788
789 function commaify( num ) {
790 if ( typeof num != "string" ) {
791 return num
792 }
793 var num2;
794 num = num.replace( /^([0-9]+)([0-9]{3})$/, "$1,$2" );
795 while ( true ) {
796 num2 = num.replace( /([0-9])([0-9]{3}[,.])/, "$1,$2" );
797 if ( num == num2 ) break;
798 num = num2
799 }
800 return num
801 }
802
803 function clear_msg() {
804 msg( news ? "News: " + news : "" )
805 }
806
807 function msg( txt ) {
808 $( "#msg" )
809 .html( txt || "" )
810 }
811
812 function find_object( prefix, id ) {
813 return id ? $( "#" + prefix + "_" + id ) : prefix
814 }
815
816 function validate() {
817 return $( ".invalid" )
818 .length === 0
819 }
820
821 function set_invalid( obj, state ) {
822 var selector = obj.selector;
823 if ( state ) {
824 if ( !invalid_state[ selector ] ) {
825 obj.addClass( "invalid" );
826 $( ".play" )
827 .addClass( "invalid" );
828 invalid_state[ selector ] = true
829 }
830 } else if ( invalid_state[ selector ] ) {
831 obj.removeClass( "invalid" );
832 if ( $( ".invalid" )
833 .length == 2 ) $( ".play" )
834 .removeClass( "invalid" );
835 invalid_state[ selector ] = false
836 }
837 }
838
839 function set_warning( obj, state ) {
840 if ( state ) {
841 if ( !invalid_state[ "#pct_chance" ] ) msg( "That exact payout multiplier is not available.<br/>The closest available multiplier will be selected if you stop typing for " + fixup_delay + " seconds." );
842 obj.addClass( "warning" )
843 } else {
844 clear_msg();
845 obj.removeClass( "warning" )
846 }
847 }
848
849 function get_waiting() {
850 return $( "#a_hi.waiting" )
851 .length > 0
852 }
853 var waiting_timeout;
854
855 function set_waiting( which ) {
856 if ( which === false ) {
857 clearTimeout( waiting_timeout );
858 $( ".play" )
859 .removeClass( "waiting" );
860 $( ".play" )
861 .removeClass( "inactive" )
862 } else {
863 waiting_timeout = setTimeout( function() {
864 msg( 'It is taking a long time for the server to respond. Check your Internet connection or <a href=".">reload this page</a>.' )
865 }, bet_wait_timeout );
866 $( ".play" )
867 .addClass( "waiting" );
868 if ( which == "hi" ) $( "#a_lo" )
869 .addClass( "inactive" );
870 else $( "#a_hi" )
871 .addClass( "inactive" )
872 }
873 }
874 window.send_bet = function send_bet( which ) {
875 if ( !validate() ) return;
876 if ( fixup_timeout ) clearTimeout( fixup_timeout );
877 set_waiting( which );
878 var chance = $( "#pct_chance" )
879 .val();
880 var bet = $( "#pct_bet" )
881 .val();
882 socket.emit( "bet", csrf, {
883 chance: chance
884 , bet: tidy( bet )
885 , which: which
886 } )
887 };
888
889 function round_down( num ) {
890 return Math.floor( num * 1e8 + 1e-6 ) / 1e8
891 }
892
893 function format_chance( chance ) {
894 chance = chance.toFixed( 0 );
895 chance = "00000".substring( 0, 6 - chance.length ) + chance;
896 return chance.substring( 0, 2 ) + "." + chance.substring( 2, 4 ) + " " + chance.substring( 4, 6 )
897 }
898
899 function maybe_update_targets() {
900 var chance = $( "#pct_chance" );
901 if ( chance.val()
902 .match( /^ *$/ ) || chance.hasClass( "invalid" ) ) {
903 $( "#hi" )
904 .html( "" );
905 $( "#lo" )
906 .html( "" )
907 } else update_targets( chance.val() )
908 }
909
910 function update_targets( chance ) {
911 chance = parseFloat( chance ) * 1e4;
912 $( "#hi" )
913 .html( "> " + format_chance( 999999 - chance ) );
914 $( "#lo" )
915 .html( "< " + format_chance( chance ) )
916 }
917
918 function set_nonce( n ) {
919 if ( typeof n == "number" ) n = n.toFixed( 0 );
920 $( "#nonce" )
921 .html( nonce = n )
922 }
923
924 function set_balance( bal ) {
925 $( "#pct_balance" )
926 .val( bal );
927 $( "#inv_balance" )
928 .add( "#wd_bal" )
929 .html( bal );
930 if ( bal === 0 && $( ".investment" )
931 .html() === 0 && $( ".invest_pft" )
932 .html() === 0 && $( ".wagered" )
933 .html() === 0 ) $( "#a_deposit" )
934 .css( {
935 background: "#fa3"
936 , border: "3px solid #f40"
937 } );
938 else $( "#a_deposit" )
939 .css( {
940 background: ""
941 , border: ""
942 } )
943 }
944
945 function set_chance( chance ) {
946 $( "#pct_chance" )
947 .val( chance );
948 update_targets( chance )
949 }
950
951 function clicked_chance_min() {
952 set_chance( "0.0001" );
953 clear_msg();
954 changed_chance( "pct" );
955 fixup();
956 return false
957 }
958
959 function clicked_chance_minus() {
960 var val = $( "#pct_chance" )
961 .val() - 1;
962 if ( isNaN( val ) || val < 1e-4 ) val = 1e-4;
963 set_chance( val );
964 clear_msg();
965 changed_chance( "pct" );
966 fixup()
967 }
968
969 function clicked_chance_half() {
970 var val = $( "#pct_chance" )
971 .val() / 2;
972 if ( isNaN( val ) || val < 1e-4 ) val = 1e-4;
973 set_chance( val );
974 clear_msg();
975 changed_chance( "pct" );
976 fixup()
977 }
978
979 function clicked_chance_double() {
980 var val = parseFloat( $( "#pct_chance" )
981 .val() ) * 2;
982 if ( isNaN( val ) || val > max_chance ) val = max_chance;
983 set_chance( val );
984 clear_msg();
985 changed_chance( "pct" );
986 fixup()
987 }
988
989 function clicked_chance_plus() {
990 var val = parseFloat( $( "#pct_chance" )
991 .val() ) + 1;
992 if ( val == 1.0001 ) val = 1;
993 if ( isNaN( val ) || val > max_chance ) val = max_chance;
994 set_chance( val );
995 clear_msg();
996 changed_chance( "pct" );
997 fixup()
998 }
999
1000 function clicked_chance_max() {
1001 set_chance( max_chance );
1002 clear_msg();
1003 changed_chance( "pct" );
1004 fixup()
1005 }
1006
1007 function clicked_chance_toggle() {
1008 $( ".button_inner_group#chance" )
1009 .toggle()
1010 }
1011
1012 function clicked_bet_toggle() {
1013 $( ".button_inner_group#bet" )
1014 .toggle()
1015 }
1016
1017 function clicked_action_toggle() {
1018 $( ".button_inner_group#action" )
1019 .toggle()
1020 }
1021
1022 function clicked_login() {
1023 socket.emit( "login", csrf, $( "#myuser" )
1024 .val(), $( "#mypass" )
1025 .val(), $( "#mycode" )
1026 .val() )
1027 }
1028
1029 function clicked_reset_profit() {
1030 socket.emit( "reset_profit", csrf )
1031 }
1032
1033 function clicked_real_profit() {
1034 socket.emit( "real_profit", csrf )
1035 }
1036
1037 function clicked_forget_max_warning() {
1038 socket.emit( "forget_max_warning", csrf );
1039 delete settings.max_bet
1040 }
1041
1042 function clicked_logout() {
1043 document.location = "logout"
1044 }
1045
1046 function clicked_bet_min() {
1047 $( "#pct_bet" )
1048 .val( "0.00000001" );
1049 changed_bet( "pct" );
1050 if ( $( "#pct_profit" )
1051 .val() === 0 ) {
1052 $( "#pct_profit" )
1053 .val( "0.00000001" );
1054 changed_profit( "pct" )
1055 }
1056 fixup()
1057 }
1058
1059 function clicked_bet_half() {
1060 $( "#pct_bet" )
1061 .val( tidy( $( "#pct_bet" )
1062 .val() / 2 ) );
1063 changed_bet( "pct" );
1064 fixup()
1065 }
1066
1067 function clicked_bet_double() {
1068 var bet = $( "#pct_bet" )
1069 .val() * 2;
1070 var bal = parseFloat( $( "#pct_balance" )
1071 .val() );
1072 if ( bet > bal ) bet = bal;
1073 if ( settings.max_double && bet >= settings.max_double ) bet = settings.max_double;
1074 $( "#pct_bet" )
1075 .val( tidy( bet ) );
1076 changed_bet( "pct" );
1077 fixup()
1078 }
1079
1080 function confirm_tip( cmd, desc ) {
1081 $.fancybox( "<div><p>" + quote_html( desc ) + "?</p>" + '<button id="tipyes">yes</button> ' + '<button id="tipno">no</button>' + "</div>", {
1082 keys: {
1083 close: []
1084 }
1085 , closeBtn: false
1086 , helpers: {
1087 overlay: {
1088 closeClick: false
1089 , css: {
1090 background: "rgba(0, 0, 0, 0.5)"
1091 }
1092 }
1093 }
1094 } );
1095 $( "#tipyes" )
1096 .click( function( e ) {
1097 $.fancybox.close();
1098 socket.emit( "chat", csrf, cmd )
1099 } );
1100 $( "#tipno" )
1101 .click( function( e ) {
1102 $.fancybox.close()
1103 } )
1104 }
1105
1106 function clicked_bet_max( force ) {
1107 if ( force != "force" ) {
1108 if ( settings.max_bet === undefined ) {
1109 $.fancybox( "<div>" + "<p>You clicked 'max' or hit 'B', the maximum bet option.</p>" + "<p>Are you sure you want to proceed?</p>" + '<label><input id="maxask" style="width:auto;" type="checkbox" /> don\'t ask me again</label> ' + '<button id="maxyes">yes</button> ' + '<button id="maxno">no</button>' + "</div><br/>", {
1110 keys: {
1111 close: []
1112 }
1113 , closeBtn: false
1114 , helpers: {
1115 overlay: {
1116 closeClick: false
1117 , css: {
1118 background: "rgba(0, 0, 0, 0.5)"
1119 }
1120 }
1121 }
1122 } );
1123 var ask = $( "#maxask" );
1124 $( "#maxyes" )
1125 .click( function( e ) {
1126 if ( ask.prop( "checked" ) ) {
1127 settings.max_bet = "1";
1128 socket.emit( "setting", csrf, "bool", "max_bet", "1" )
1129 }
1130 $.fancybox.close();
1131 clicked_bet_max( "force" )
1132 } );
1133 $( "#maxno" )
1134 .click( function( e ) {
1135 if ( ask.prop( "checked" ) ) {
1136 settings.max_bet = "0";
1137 socket.emit( "setting", csrf, "bool", "max_bet", "0" )
1138 }
1139 $.fancybox.close()
1140 } );
1141 return
1142 } else if ( settings.max_bet == "0" ) {
1143 msg( "you have disabled the max bet feature" );
1144 return
1145 }
1146 }
1147 $( "#pct_profit" )
1148 .val( max_profit );
1149 changed_profit( "pct" );
1150 var bet = parseFloat( $( "#pct_bet" )
1151 .val() );
1152 var bal = parseFloat( $( "#pct_balance" )
1153 .val() );
1154 if ( bet > bal ) {
1155 $( "#pct_bet" )
1156 .val( tidy( bal ) );
1157 clear_msg()
1158 }
1159 changed_bet( "pct" )
1160 }
1161
1162 function validchance( c ) {
1163 if ( isNaN( c ) ) return "not a number";
1164 if ( c < 1e-4 ) return c + "% is too low";
1165 if ( c > 98.99 ) return c + "% is too high";
1166 return true
1167 }
1168
1169 function randomchance( range ) {
1170 var range = [ settings.min_randchance, settings.max_randchance ];
1171 range.sort();
1172 var valid;
1173 for ( var r in range ) {
1174 if ( ( valid = validchance( range[ r ] ) ) !== true ) {
1175 msg( "random chance range limit is " + valid );
1176 return false
1177 }
1178 }
1179 var a = Math.floor( range[ 0 ] * 1e4 + .5 );
1180 var b = Math.floor( range[ 1 ] * 1e4 + .5 );
1181 set_chance( ( parseInt( CryptoJS.SHA256( uid + ":" + nonce )
1182 .toString( CryptoJS.enc.Hex )
1183 .substr( 0, 8 ), 16 ) % ( b - a + 1 ) + a ) / 1e4 );
1184 clear_msg();
1185 changed_chance( "pct" );
1186 fixup();
1187 return true
1188 }
1189
1190 function halfthetime() {
1191 var hash = CryptoJS.SHA256( uid + ":" + nonce )
1192 .toString( CryptoJS.enc.Hex )
1193 .substr( 0, 1 );
1194 return hash.match( /[0-7]/ )
1195 }
1196
1197 function clicked_action_bet_random_chance() {
1198 if ( !settings.randchancekey ) msg( "Enable the 'e for random chance' shortcut at the end of the 'Account' tab" );
1199 else if ( lastwhich == "lo" ) {
1200 if ( randomchance() ) clicked_action_bet_lo()
1201 } else if ( lastwhich == "hi" ) {
1202 if ( randomchance() ) clicked_action_bet_hi()
1203 } else msg( "Bet 'hi' or 'lo' before using 'random chance'" )
1204 }
1205
1206 function clicked_action_bet_random_hi_lo() {
1207 if ( !settings.randomkey ) msg( "Enable the 'r for random' shortcut at the end of the 'Account' tab" );
1208 else if ( halfthetime() ) clicked_action_bet_lo();
1209 else clicked_action_bet_hi()
1210 }
1211
1212 function clicked_action_bet_toggle() {
1213 if ( !settings.togglekey ) msg( "Enable the 't to toggle' shortcut at the end of the 'Account' tab" );
1214 else if ( lastwhich == "lo" ) clicked_action_bet_hi();
1215 else if ( lastwhich == "hi" ) clicked_action_bet_lo();
1216 else msg( "Bet 'hi' or 'lo' before using 'toggle'" )
1217 }
1218
1219 function clicked_action_bet_same() {
1220 if ( !settings.samekey ) msg( "Enable the 'y to repeat' shortcut at the end of the 'Account' tab" );
1221 else if ( lastwhich == "lo" ) clicked_action_bet_lo();
1222 else if ( lastwhich == "hi" ) clicked_action_bet_hi();
1223 else msg( "Bet 'hi' or 'lo' before using 'repeat'" )
1224 }
1225
1226 function clicked_action_bet_hi() {
1227 clicked_action_bet( "hi" )
1228 }
1229
1230 function clicked_action_bet_lo() {
1231 clicked_action_bet( "lo" )
1232 }
1233
1234 function clicked_action_bet( which ) {
1235 $( "#pct_balance" )
1236 .focus();
1237 if ( get_waiting() ) {
1238 msg( "Please wait for previous bet to finish." );
1239 return
1240 }
1241 send_bet( lastwhich = which )
1242 }
1243
1244 function clicked_action_deposit() {
1245 socket.emit( "deposit", csrf )
1246 }
1247
1248 function need_ga( action ) {
1249 if ( !google_auth.active ) return false;
1250 return google_auth.flags[ action ]
1251 }
1252 var wd_button_enabled = true;
1253
1254 function send_withdraw_request( address, amount, speech, code ) {
1255 if ( wd_button_enabled ) {
1256 var wd_button = $( "#wd_button" );
1257 wd_button.attr( "disabled", "disabled" )
1258 .animate( {
1259 opacity: 0
1260 } );
1261 wd_button_enabled = false;
1262 setTimeout( function() {
1263 wd_button.removeAttr( "disabled" )
1264 .animate( {
1265 opacity: 1
1266 } );
1267 wd_button_enabled = true
1268 }, 2e3 );
1269 socket.emit( "withdraw", csrf, address.val(), amount.val(), code.val(), speech.val() )
1270 } else console.log( "not withdrawing" )
1271 }
1272
1273 function clicked_action_withdraw() {
1274 var msg = fee === 0 ? "" : '<p>You have <span id="wd_bal" /> ' + currency + ".</p><p>Clicking the withdraw button multiple times will cause multiple withdrawals.</p><p>" + fee + " " + currency + " will be deducted from the amount you type for use as a transaction fee.</p>";
1275 var auth = "";
1276 if ( need_ga( "withdraw" ) ) auth = '<div class="clear"></div>' + '<div class="fleft">Google Auth:</div>' + '<div class="fleft input_ok_input"><input id="ga_code"></div>';
1277 withdraw_address = "";
1278 $.fancybox( "<div class='withdraw'>" + "<h1>Withdraw " + currency + "s</h1>" + "<p><b>Note:</b> Your withdrawal will be sent from a random address in the hot wallet. Do not withdraw directly to any site that uses the 'sending address' as a 'return address' because any coins they return to you will be credited to a random Just-Dice account.</p>" + '<div class="fleft">' + currency + " Address:</div>" + '<div class="input_ok_input"><input id="wd_address" value="' + withdraw_address + '" size="40"></div>' + '<div class="clear"></div>' + '<div class="fleft">Amount:</div>' + '<div class="input_ok_input"><input id="wd_amount" size="40"></div>' + '<div class="clear"></div>' + '<div class="fleft">CLAMspeech:</div>' + '<div class="input_ok_input"><input id="wd_speech" size="40"></div>' + '<div class="fleft"> (optional text)</div>' + auth + '<div class="fleft input_ok_button"><button id="wd_button">withdraw</button></div>' + '<div class="clear"></div>' + '<div id="form_error">' + msg + "</div>" + "</div>", {
1279 helpers: {
1280 overlay: {
1281 closeClick: true
1282 , css: {
1283 background: "rgba(0, 0, 0, 0.5)"
1284 }
1285 }
1286 }
1287 } );
1288 var address = $( "#wd_address" );
1289 var amount = $( "#wd_amount" );
1290 var speech = $( "#wd_speech" );
1291 var button = $( "#wd_button" );
1292 var code = $( "#ga_code" );
1293 $( "#wd_bal" )
1294 .html( $( "#pct_balance" )
1295 .val() );
1296 if ( need_ga( "withdraw" ) ) code.keypress( function( e ) {
1297 if ( e.which == 13 ) send_withdraw_request( address, amount, speech, code )
1298 } );
1299 address.keypress( function( e ) {
1300 if ( e.which == 13 ) send_withdraw_request( address, amount, speech, code )
1301 } );
1302 amount.keypress( function( e ) {
1303 if ( e.which == 13 ) send_withdraw_request( address, amount, speech, code )
1304 } );
1305 speech.keypress( function( e ) {
1306 if ( e.which == 13 ) send_withdraw_request( address, amount, speech, code )
1307 } );
1308 button.click( function( e ) {
1309 send_withdraw_request( address, amount, speech, code )
1310 } )
1311 }
1312
1313 function clicked_action_random() {
1314 socket.emit( "random", csrf )
1315 }
1316
1317 function clicked_action_invest() {
1318 socket.emit( "invest_box", csrf )
1319 }
1320 var color_editor_showing = false;
1321
1322 function clicked_toggle_color_editor( html ) {
1323 if ( !( color_editor_showing = !color_editor_showing ) ) {
1324 color_editor.fadeOut();
1325 return
1326 }
1327 var editor = "<p>Any changes you make here won't currently be saved. This will be fixed soon...ish.</p>";
1328 for ( var v in current_style ) editor += '<div class="picker" value="' + current_style[ v ] + '">' + v + "</div>";
1329 color_editor.html( editor );
1330 color_editor.css( {
1331 border: "3px solid #888"
1332 , padding: "10px"
1333 , margin: "10px 0px"
1334 , borderRadius: "6px"
1335 } );
1336 color_editor.fadeIn();
1337 init_pickers()
1338 }
1339
1340 function clicked_action_name() {
1341 $.fancybox( "<div>" + "<h2>Change Name</h2>" + "<p>Type your new name!</p>" + '<div class="input_ok">' + '<div class="input_ok_input"><input class="name_input" value="' + nick + '" size="' + max_name_length + '" maxlength="' + max_name_length + '"></div>' + '<div class="fleft indent"><button class="name_button">ok</button></div>' + '<div class="clear"></div>' + "</div>" + "</div>" );
1342 handle_name_input( $( ".name_input" ) );
1343 $( ".name_button" )
1344 .click( function( e ) {
1345 $.fancybox.close()
1346 } )
1347 }
1348
1349 function handle_name_input( obj ) {
1350 var emit_name_timeout;
1351 obj.select()
1352 .keyup( function( e ) {
1353 var tmp = obj.val();
1354 if ( tmp !== "" ) {
1355 clearTimeout( emit_name_timeout );
1356 nick = tmp.replace( /[+]/g, "" );
1357 if ( default_alert_words ) {
1358 $( "#alert_words" )
1359 .val( nick + "," + uid );
1360 build_user_regexp( nick + "," + uid )
1361 }
1362 $( "#nick" )
1363 .html( quote_html( nick ) );
1364 emit_name_timeout = setTimeout( function() {
1365 socket.emit( "name", csrf, nick )
1366 }, 3e3 );
1367 if ( e.which == 13 ) $.fancybox.close()
1368 }
1369 } )
1370 }
1371
1372 function mono( h, id ) {
1373 return '<div id="' + id + '" class="monospace">' + h + "</div>"
1374 }
1375
1376 function random_number( length ) {
1377 var ret = "";
1378 for ( var i = 0; i < length; i++ ) {
1379 var r = Math.floor( Math.random() * 10 );
1380 ret += "0123456789".substring( r, r + 1 )
1381 }
1382 return ret
1383 }
1384
1385 function update_my_stats( bets, wins, losses, luck, wagered, profit ) {
1386 real_profit = profit;
1387 $( ".bets" )
1388 .html( commaify( bets ) );
1389 $( "#luck" )
1390 .html( luck );
1391 $( ".wagered" )
1392 .html( commaify( wagered ) );
1393 $( ".myprofit" )
1394 .html( fixed( real_profit - profit_offset ) );
1395 if ( wins !== null ) {
1396 $( "#wins,#wins2" )
1397 .html( commaify( wins ) );
1398 $( "#losses,#losses2" )
1399 .html( commaify( losses ) )
1400 }
1401 }
1402
1403 function update_settings( s ) {
1404 settings = s;
1405 if ( settings.chat_min_risk === undefined ) settings.chat_min_risk = default_chat_min;
1406 if ( settings.chat_min_change === undefined ) settings.chat_min_change = default_chat_min;
1407 if ( settings.allbetsme === undefined ) settings.allbetsme = true;
1408 if ( settings.shortcuts === undefined ) settings.shortcuts = true;
1409 if ( settings.chatstake === undefined ) settings.chatstake = true;
1410 if ( settings.alert === undefined ) settings.alert = false;
1411 if ( settings.hilite === undefined ) settings.hilite = true;
1412 if ( settings.pmding === undefined ) settings.pmding = false;
1413 if ( settings.styleme === undefined ) settings.styleme = true;
1414 if ( settings.chatbets === undefined ) settings.chatbets = true;
1415 if ( settings.min_randchance === undefined ) settings.min_randchance = 1e-4;
1416 if ( settings.max_randchance === undefined ) settings.max_randchance = 98.99;
1417 if ( default_alert_words = !settings.alert_words ) settings.alert_words = nick + "," + uid;
1418 for ( var setting in s ) {
1419 var obj = $( "#" + setting );
1420 if ( obj.is( ":checkbox" ) ) obj.prop( "checked", s[ setting ] );
1421 else if ( typeof s[ setting ] === "number" ) obj.val( s[ setting ].toFixed( 8 )
1422 .replace( /([.].*[^0])0*$/, "$1" )
1423 .replace( /[.]0*$/, "" ) );
1424 else obj.val( s[ setting ] )
1425 }
1426 build_user_regexp( settings.alert_words )
1427 }
1428
1429 function build_user_regexp( words ) {
1430 user_regexp = new RegExp( "\\b(" + words.split( /[,]+/ )
1431 .join( "|" )
1432 .replace( /([.^$*+()[\]])/g, "\\$1" ) + ")\\b", "i" )
1433 }
1434
1435 function update_site_stats( site ) {
1436 $( ".sbets" )
1437 .html( commaify( site.bets.toString() ) );
1438 $( "#swins" )
1439 .html( commaify( site.wins.toString() ) );
1440 $( "#slosses" )
1441 .html( commaify( site.losses.toString() ) );
1442 $( "#sluck" )
1443 .html( ( site.bets === 0 ? 100 : site.luck * 100 / site.bets )
1444 .toFixed( luck_precision ) + "%" );
1445 $( ".swagered" )
1446 .html( fixed( site.wagered ) );
1447 $( ".sprofitraw" )
1448 .html( fixed( -site.profit ) );
1449 $( ".sprofitpct" )
1450 .html( ( -site.profit * 100 / site.wagered )
1451 .toFixed( 6 ) + "%" );
1452 if ( site.profit > 0 ) {
1453 $( ".sprofit_label" )
1454 .html( "site is down:" );
1455 $( ".sprofit" )
1456 .html( fixed( site.profit ) )
1457 } else {
1458 $( ".sprofit_label" )
1459 .html( "site is up:" );
1460 $( ".sprofit" )
1461 .html( fixed( -site.profit ) )
1462 }
1463 }
1464 var quote_html = window.quote_html = function( html ) {
1465 return $( ".tmpbuffer" )
1466 .text( html )
1467 .html()
1468 };
1469
1470 function break_long_words( txt ) {
1471 return txt.replace( /(\w{20})/g, "$1<wbr>" )
1472 }
1473
1474 function unescape_html( html ) {
1475 return html.replace( ///g, "/" )
1476 .replace( /'/g, "'" )
1477 .replace( /"/g, '"' )
1478 .replace( />/g, ">" )
1479 .replace( /</g, "<" )
1480 .replace( /&/g, "&" )
1481 }
1482
1483 function update_investment( i, p, pft, off, stk ) {
1484 $( ".investment" )
1485 .html( fixed( investment = i ) );
1486 $( ".invest_pct" )
1487 .html( fixed( invest_pct = p, 6 ) + "%" );
1488 if ( stk !== undefined ) {
1489 stake_profit = stk;
1490 $( ".stake_pft" )
1491 .html( fixed( stk ) )
1492 }
1493 if ( pft !== null ) {
1494 $( ".bankroll_pft" )
1495 .html( fixed( pft - stake_profit ) );
1496 $( ".invest_pft" )
1497 .html( fixed( pft ) )
1498 }
1499 if ( off !== undefined ) {
1500 offsite = off;
1501 $( ".invest_offsite" )
1502 .html( fixed( offsite ) )
1503 }
1504 $( ".invest_total" )
1505 .html( fixed( i + offsite ) );
1506 $( ".invest_mult" )
1507 .html( fixed( i ? ( i + offsite ) / i : 1 ) + "x" )
1508 }
1509 var active_tab, tab_content, chattab, chatscroll_height;
1510 window.select_tab = function select_tab( tabname ) {
1511 active_tab.removeClass( "active" );
1512 tab_content.hide();
1513 active_tab = $( 'ul.tabs > li > a[href="' + tabname + '"]' );
1514 active_tab.addClass( "active" );
1515 current_tab = tabname;
1516 tab_content = $( current_tab );
1517 tab_content.show();
1518 if ( current_tab == "#chat" || current_tab == "#account" ) {
1519 if ( current_tab == "#chat" ) {
1520 if ( scroll_on_chat ) scroll_to_bottom_of_chat();
1521 chatinput.focus();
1522 chattab.removeClass( "mentioned" );
1523 chattab.removeClass( "attention" )
1524 }
1525 $( ".key" )
1526 .animate( {
1527 opacity: .25
1528 } )
1529 } else $( ".key" )
1530 .animate( {
1531 opacity: 1
1532 } )
1533 };
1534
1535 function init() {
1536 chatscroll = $( ".chatscroll" );
1537 chatbetscroll = $( ".chatbetscroll" );
1538 chatlog = $( ".chatlog" );
1539 chatbets = $( ".chatbets" );
1540 chattab = $( 'ul.tabs > li > a[href="#chat"]' );
1541 chatscroll_height = chatscroll.height();
1542 color_editor = $( ".editcolor" );
1543 var chatbets_base = $( "#chatbets" )
1544 , scroll_on_chat_timeout;
1545 scroll_on_chat = true;
1546 chatinput = $( ".chatinput" );
1547 $( "ul.tabs" )
1548 .each( function() {
1549 var links = $( this )
1550 .find( "a" );
1551 active_tab = $( links[ 0 ] );
1552 active_tab.addClass( "active" );
1553 current_tab = active_tab.attr( "href" );
1554 tab_content = $( current_tab );
1555 links.not( active_tab )
1556 .each( function() {
1557 $( $( this )
1558 .attr( "href" ) )
1559 .hide()
1560 } );
1561 $( this )
1562 .on( "click", "a", function( e ) {
1563 select_tab( $( this )
1564 .attr( "href" ) );
1565 e.preventDefault()
1566 } )
1567 } );
1568 socket.on( "dark", function( key ) {
1569 switch_style( styles.style_dark )
1570 } );
1571 socket.on( "light", function( key ) {
1572 switch_style( styles.style_default )
1573 } );
1574 socket.on( "edit", function( key ) {
1575 clicked_toggle_color_editor()
1576 } );
1577 socket.on( "getver", function( key ) {
1578 socket.emit( "version", csrf, key, client_version )
1579 } );
1580 socket.on( "version", function( version ) {
1581 $.fancybox( '<div class="panel">' + "<p>A new version of the site is available.</p>" + "<p>Reloading in <span id=countdown>10 seconds</span>.</p>" + '<button id="doit">Reload Now</button>' + "</div>", {
1582 keys: {
1583 close: []
1584 }
1585 , closeBtn: false
1586 , helpers: {
1587 overlay: {
1588 closeClick: false
1589 , css: {
1590 background: "rgba(0, 0, 0, 0.5)"
1591 }
1592 }
1593 }
1594 } );
1595 var count = 10;
1596 var interval = setInterval( function() {
1597 count--;
1598 $( "#countdown" )
1599 .html( count == 1 ? count + " second" : count + " seconds" );
1600 if ( count === 0 ) {
1601 clearInterval( interval );
1602 document.location = "."
1603 }
1604 }, 1e3 );
1605 $( "#doit" )
1606 .click( function( e ) {
1607 document.location = "."
1608 } )
1609 } );
1610 socket.on( "welcome", function( name, html ) {
1611 nick = name;
1612 $.fancybox( html, {
1613 keys: {
1614 close: []
1615 }
1616 , helpers: {
1617 overlay: {
1618 closeClick: false
1619 , css: {
1620 background: "rgba(0, 0, 0, 0.5)"
1621 }
1622 }
1623 }
1624 } );
1625 var name_o = $( "#welcome_name" );
1626 name_o.attr( "value", nick );
1627 name_o.attr( "size", max_name_length );
1628 name_o.attr( "maxlength", max_name_length );
1629 handle_name_input( name_o );
1630 $( ".name_button" )
1631 .click( function( e ) {
1632 $.fancybox.close()
1633 } )
1634 } );
1635 socket.on( "dismiss", function() {
1636 $.fancybox.close()
1637 } );
1638 socket.on( "timeout", function() {
1639 $.fancybox( "<div><p>Your session has timed out due to inactivity.</p>" + '<button id="reconnect">Reconnect</button></div>', {
1640 keys: {
1641 close: []
1642 }
1643 , closeBtn: false
1644 , helpers: {
1645 overlay: {
1646 closeClick: false
1647 , css: {
1648 background: "rgba(0, 0, 0, 0.5)"
1649 }
1650 }
1651 }
1652 } );
1653 $( "#reconnect" )
1654 .click( function( e ) {
1655 socket.emit( "reconnect", csrf );
1656 $.fancybox.close()
1657 } )
1658 } );
1659 socket.on( "invest_box", function( html ) {
1660 var invest_ga = need_ga( "invest" );
1661 var divest_ga = need_ga( "divest" );
1662 $.fancybox( html, {
1663 helpers: {
1664 overlay: {
1665 closeClick: true
1666 , css: {
1667 background: "rgba(0, 0, 0, 0.5)"
1668 }
1669 }
1670 }
1671 } );
1672 if ( !invest_ga ) $( "#invest_auth" )
1673 .hide();
1674 if ( !divest_ga ) $( "#divest_auth" )
1675 .hide();
1676 $( "#inv_balance" )
1677 .html( $( "#pct_balance" )
1678 .val() );
1679 var invest_code = $( "#invest_code" );
1680 var divest_code = $( "#divest_code" );
1681 $( "#invest_input" )
1682 .focus();
1683 update_investment( investment, invest_pct, null );
1684 var invest_input = $( "#invest_input" )
1685 , divest_input = $( "#divest_input" );
1686 invest_input.add( invest_code )
1687 .keypress( function( e ) {
1688 if ( e.which == 13 ) socket.emit( "invest", csrf, invest_input.val(), invest_code.val() )
1689 } );
1690 divest_input.add( divest_code )
1691 .keypress( function( e ) {
1692 if ( e.which == 13 ) socket.emit( "divest", csrf, divest_input.val(), divest_code.val() )
1693 } );
1694 $( "#invest_button" )
1695 .click( function( e ) {
1696 socket.emit( "invest", csrf, invest_input.val(), invest_code.val() )
1697 } );
1698 $( "#divest_button" )
1699 .click( function( e ) {
1700 socket.emit( "divest", csrf, divest_input.val(), divest_code.val() )
1701 } );
1702 $( "#invest_all" )
1703 .click( function( e ) {
1704 socket.emit( "invest", csrf, "all", invest_code.val() )
1705 } );
1706 $( "#divest_all" )
1707 .click( function( e ) {
1708 socket.emit( "divest", csrf, "all", divest_code.val() )
1709 } )
1710 } );
1711 socket.on( "invest", function( i, p, pft, offsite ) {
1712 update_investment( i, p, pft, offsite )
1713 } );
1714 socket.on( "news", function( n ) {
1715 update_news( n )
1716 } );
1717 socket.on( "staked", function( r ) {
1718 update_investment( r.investment, r.percent, r.invest_pft, undefined, r.stake_pft );
1719 update_max_profit( r.max_profit, r.bankroll );
1720 if ( settings.chatstake ) {
1721 var ourstake = r.stake_pft ? "; your share = " + fixed( r.stake_share ) + "; your total = " + fixed( r.stake_pft ) + "" : "";
1722 add_chat( Date( parseInt( r.date ) * 1e3 ), "INFO: we just staked " + fixed( r.stake ) + " " + currency + " (total = " + fixed( r.total ) + ourstake + ")", "chatinfo", true )
1723 }
1724 } );
1725 socket.on( "invest_error", function( msg ) {
1726 $( "#invest_error" )
1727 .html( msg )
1728 } );
1729 socket.on( "divest_error", function( msg ) {
1730 $( "#divest_error" )
1731 .html( msg )
1732 } );
1733 socket.on( "setup_account", function( html ) {
1734 $( "#login" )
1735 .html( html );
1736 $( "#change_password" )
1737 .click( show_change_password )
1738 } );
1739 $( ".chatbutton" )
1740 .click( function( e ) {
1741 chatinput.focus();
1742 return send_chat( chatinput )
1743 } );
1744 var betton = $( ".chatbetton" );
1745 betton.click( function( e ) {
1746 if ( chatbets_base.css( "display" ) == "none" ) {
1747 betton.html( "^" );
1748 chatbets_base.css( "display", "block" );
1749 chatbets_showing = true
1750 } else {
1751 betton.html( "v" );
1752 chatbets_base.css( "display", "none" );
1753 chatbets_showing = false
1754 }
1755 socket.emit( "setting", csrf, "bool", "chatbets", chatbets_showing ? "1" : "0" )
1756 } );
1757 chatscroll.scroll( function() {
1758 var offset = Math.ceil( chatscroll_height - chatlog.offset()
1759 .top + chatscroll.offset()
1760 .top ) - chatlog.outerHeight();
1761 if ( offset > -2 ) {
1762 if ( debug_chat_scrolling ) chatscroll.css( {
1763 background: "white"
1764 } );
1765 clearTimeout( scroll_on_chat_timeout );
1766 scroll_on_chat = true
1767 } else {
1768 scroll_on_chat = false;
1769 if ( debug_chat_scrolling ) chatscroll.css( {
1770 background: "cyan"
1771 } );
1772 clearTimeout( scroll_on_chat_timeout );
1773 scroll_on_chat_timeout = setTimeout( function() {
1774 if ( debug_chat_scrolling ) chatscroll.css( {
1775 background: "yellow"
1776 } );
1777 scroll_on_chat = true
1778 }, chat_scroll_freeze_time * 1e3 )
1779 }
1780 } );
1781 socket.on( "tip", function( from, name, amount, comment, ignored, priv ) {
1782 if ( settings.mutechat ) return;
1783 if ( !ignored ) {
1784 if ( current_tab != "#chat" ) chattab.addClass( "attention" );
1785 add_chat( undefined, "INFO: you received a " + ( priv ? "private " : "" ) + amount + " " + currency + " tip from (" + from + ") <" + name + ">" + ( comment ? " [" + comment + "]" : "" ), false, false, true, true )
1786 }
1787 } );
1788 socket.on( "chat", function( txt, date ) {
1789 var matches;
1790 if ( matches = txt.match( /^INFO: (\/tip auth=.*) -- to c(onfirm a tip .*)$/ ) ) return confirm_tip( matches[ 1 ], "C" + matches[ 2 ] );
1791 if ( settings.mutechat ) return;
1792 if ( current_tab != "#chat" ) chattab.addClass( "attention" );
1793 add_chat( date, txt, false, false, true, true )
1794 } );
1795 socket.on( "reload", function() {
1796 document.location = "."
1797 } );
1798 socket.on( "offset", function( offset ) {
1799 reset_profit( offset )
1800 } );
1801 socket.on( "set_hash", function( hash ) {
1802 document.location = hash
1803 } );
1804 var seen_init = false
1805 , seen_results = false;
1806 socket.on( "init", function( data ) {
1807 if ( seen_init ) return;
1808 if ( data.offset ) reset_profit( data.offset );
1809 seen_init = true;
1810 window.csrf = csrf = data.csrf;
1811 uid = data.uid;
1812 $( "#uid" )
1813 .html( uid );
1814 $( "#nick" )
1815 .html( quote_html( nick = data.name.replace( /[+]/g, "" ) ) );
1816 withdraw_address = data.wdaddr;
1817 fee = data.fee;
1818 update_my_stats( data.bets, data.wins, data.losses, data.luck, data.wagered, data.profit );
1819 update_site_stats( data.stats );
1820 update_settings( data.settings );
1821 update_news( data.news );
1822 if ( settings.chatbets ) {
1823 betton.html( "^" );
1824 chatbets_base.css( "display", "block" );
1825 chatbets_showing = true
1826 }
1827 $( "#api_num" )
1828 .html( data.api );
1829 max_profit = parseFloat( data.max_profit );
1830 $( "#max_profit" )
1831 .html( commaify( max_profit.toFixed( 2 ) ) );
1832 $( ".bankroll" )
1833 .html( commaify( data.bankroll ) );
1834 update_investment( data.investment, data.percent, data.invest_pft, data.offsite, data.stake_pft );
1835 set_balance( data.balance );
1836 set_chance( tidy( data.chance ) );
1837 $( "#pct_bet" )
1838 .val( tidy( data.bet ) );
1839 edge = data.edge;
1840 max_chance = 100 - edge_mult * edge;
1841 $( "#pct_edge" )
1842 .val( edge );
1843 $( "#pct_edge" )
1844 .html( edge + "%" );
1845 $( "#shash" )
1846 .html( data.shash );
1847 set_nonce( data.nonce );
1848 $( "#seed" )
1849 .html( data.seed );
1850 $( "#login" )
1851 .html( data.login );
1852 if ( data.username ) {
1853 $( "#change_password" )
1854 .click( show_change_password );
1855 username = data.username
1856 } else {
1857 $( "#setup_account" )
1858 .click( function() {
1859 $.fancybox( "<div class='setup_account'>" + "<h1>Set Username and Password</h1>" + "<p>Please note that both username and password are <b>case sensitive</b>.</p>" + "<p>Also note that your browser probably <b>will not save your password</b>; make a note of it.</p>" + '<form onSubmit="return setup_account(this);">' + '<div class="fleft w200 aright rpad">Username</div> ' + '<div class="input_ok_input"><input size=40 id="username"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Repeat Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password2"></div>' + '<div class="clear"></div>' + '<div class="fright input_ok_button"><input type="submit" value="OK"></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</form></div>", {
1860 helpers: {
1861 overlay: {
1862 closeClick: true
1863 , css: {
1864 background: "rgba(0, 0, 0, 0.5)"
1865 }
1866 }
1867 }
1868 } );
1869 $( "#username" )
1870 .focus()
1871 } )
1872 }
1873 var prefix = "pct";
1874 get_float_string( prefix, "bet", find_object( prefix, "bet" ) );
1875 changed_chance( "pct" );
1876 if ( data.ignores ) ignores = data.ignores;
1877 while ( data.chat.length ) {
1878 var c = JSON.parse( data.chat.shift() );
1879 var date = data.chat.shift();
1880 if ( ignores.indexOf( c.user ) == -1 ) {
1881 var chattxt;
1882 if ( c.emote ) chattxt = "(" + c.user + ") * <" + c.name.replace( />/g, "]" )
1883 .replace( /</g, "[" ) + "> " + c.txt;
1884 else chattxt = "(" + c.user + ") <" + c.name.replace( />/g, "]" )
1885 .replace( /</g, "[" ) + "> " + c.txt;
1886 add_chat( new Date( parseInt( date ) ), chattxt, false, false, true )
1887 }
1888 }
1889 set_google_auth_status( data.ga );
1890 $( "#ga_edit, .edit_locked" )
1891 .click( function() {
1892 socket.emit( "edit_ga", csrf )
1893 } );
1894 var history_types = [ "deposit", "withdraw", "invest", "commission", "offchain" ];
1895 for ( var i in history_types ) bind_history( history_types[ i ] )
1896 } );
1897 socket.on( "history", function( type, fields ) {
1898 var report = '<table class="hist_table"><tr>';
1899 report += "<th>id</th>";
1900 report += "<th>when</th>";
1901 var date, data;
1902 switch ( type ) {
1903 case "commission":
1904 report += "<th>profit</th>";
1905 report += "<th>commission</th>";
1906 report += "<th>reason</th>";
1907 break;
1908 case "deposit":
1909 case "offchain":
1910 report += "<th>amount</th>";
1911 report += "<th>note</th>";
1912 break;
1913 case "invest":
1914 report += "<th>what</th>";
1915 report += "<th>commission</th>";
1916 report += "<th>% of site</th>";
1917 report += "<th>investment</th>";
1918 report += "<th>profit</th>";
1919 report += "<th>base</th>";
1920 break;
1921 case "withdraw":
1922 report += "<th>amount</th>";
1923 report += "<th>address</th>";
1924 report += "<th>txid</th>";
1925 break;
1926 default:
1927 return
1928 }
1929 report += "</tr>";
1930 while ( true ) {
1931 if ( ( data = fields.pop() ) === undefined ) break;
1932 date = moment( parseInt( data.date ) )
1933 .format( type == "invest" ? "YY-MM-DD<br/>HH:mm" : "YY-MM-DD HH:mm" );
1934 report += "<tr><td>" + data.eid + "</td><td>" + date + "</td>";
1935 switch ( type ) {
1936 case "commission":
1937 report += "<td>" + data.profit.toFixed( 8 ) + "</td>";
1938 report += "<td>" + data.commission.toFixed( 8 ) + "</td>";
1939 report += "<td>" + data.reason.replace( /(\d+[.]\d{8})\d+/g, "$1" )
1940 .replace( / = \d+[.]\d+/, "" ) + "</td>";
1941 break;
1942 case "deposit":
1943 case "offchain":
1944 report += "<td>" + data.amount.toFixed( 8 ) + "</td>";
1945 report += "<td>" + break_long_words( quote_html( unescape_html( data.note ? data.note : "" ) ) ) + "</td>";
1946 break;
1947 case "invest":
1948 report += "<td>" + ( data.amount === 0 ? "end-of-period<br/>commission" : data.amount > 0 ? "invest " + data.amount.toFixed( 8 ) : "divest " + ( -data.amount )
1949 .toFixed( 8 ) ) + "</td>";
1950 report += "<td>" + data.commission.toFixed( 8 ) + "</td>";
1951 var from = ( data.share_old * 100 )
1952 .toFixed( 6 );
1953 var to = ( data.share_new * 100 )
1954 .toFixed( 6 );
1955 if ( from == to ) report += "<td>" + to + "</td>";
1956 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1957 from = data.investment_old.toFixed( 8 );
1958 to = data.investment_new.toFixed( 8 );
1959 if ( from == to ) report += "<td>" + to + "</td>";
1960 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1961 from = ( data.investment_old - data.prin_old )
1962 .toFixed( 8 );
1963 to = ( data.investment_new - data.prin_new )
1964 .toFixed( 8 );
1965 if ( from == to || data.commission === 0 ) report += "<td>" + to + "</td>";
1966 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1967 to = data.base_new.toFixed( 8 );
1968 report += "<td>" + to + "</td>";
1969 break;
1970 case "withdraw":
1971 report += "<td>" + data.amount.toFixed( 8 ) + "</td>";
1972 report += "<td>" + quote_html( data.address ) + "</td>";
1973 if ( data.txid ) {
1974 report += "<td>";
1975 report += '<a href="http://khashier.com/tx/' + data.txid + '" target="_blank">' + data.txid.substring( 0, 20 ) + "...</a>";
1976 if ( data.note ) report += " " + break_long_words( quote_html( data.note ) );
1977 report += "</td>"
1978 } else if ( data.note ) report += "<td>" + break_long_words( quote_html( data.note ) ) + "</td>";
1979 else report += "<td></td>";
1980 break
1981 }
1982 report += "</tr>"
1983 }
1984 report += "</table>";
1985 $( "#hist_report" )
1986 .html( report )
1987 } );
1988 socket.on( "setup_ga", function( ga ) {
1989 $.fancybox( '<div class="setup_ga">' + "<h1>Set Up Google Authenticator</h1>" + '<div class="fleft">' + ga.qrcode + '<div class="secret">' + ga.secret + "</div>" + "</div>" + '<div class="fleft" id="desc">' + "<p>To enable two-factor security on Just-Dice, find and install " + '"Google Authenticator" from your smartphone\'s app store ' + 'then go to "Set up account" and then "Scan a barcode" and scan the code to the left, ' + 'or "Enter provided key", and enter the key under it.</p>' + "<p>Finally, type the 6 digit code it gives you and click the OK button.</p>" + '<div class="input_ok_input"><input id="ga_code"></div>' + '<div class="fleft input_ok_button"><button id="ga_button">OK</button></div>' + "</div>" + '<div class="clear"></div>' + '<div class="gap"></div>' + '<div class="important">Make a backup copy of the code under the QR code on paper for when you lose or reset your phone!</div>' + '<div id="form_error"></div>' + "</div>" );
1990 var code = $( "#ga_code" );
1991 var button = $( "#ga_button" );
1992 code.focus();
1993 code.keypress( function( e ) {
1994 if ( e.which == 13 ) socket.emit( "setup_ga_code", csrf, code.val() )
1995 } );
1996 button.click( function( e ) {
1997 socket.emit( "setup_ga_code", csrf, code.val() )
1998 } )
1999 } );
2000 socket.on( "edit_ga", function( ga ) {
2001 edit_ga( ga )
2002 } );
2003 socket.on( "ga_info", function( ga ) {
2004 set_google_auth_status( ga )
2005 } );
2006 socket.on( "ga_code_ok", function( ga ) {
2007 $.fancybox.close();
2008 edit_ga( ga )
2009 } );
2010 socket.on( "ga_code_done", function() {
2011 $.fancybox.close()
2012 } );
2013 socket.on( "wdaddr", function( wdaddr ) {
2014 withdraw_address = wdaddr
2015 } );
2016 socket.on( "balance", function( data ) {
2017 set_balance( data );
2018 var prefix = "pct";
2019 get_float_string( prefix, "bet", find_object( prefix, "bet" ) )
2020 } );
2021 socket.on( "details", function( html ) {
2022 $.fancybox( html, {
2023 helpers: {
2024 overlay: {
2025 closeClick: true
2026 , css: {
2027 background: "rgba(0, 0, 0, 0.5)"
2028 }
2029 }
2030 }
2031 } )
2032 } );
2033 socket.on( "max_profit", function( max_profit, bankroll ) {
2034 update_max_profit( max_profit, bankroll )
2035 } );
2036 socket.on( "shash", function( data ) {
2037 $( "#shash" )
2038 .html( data )
2039 } );
2040 socket.on( "seed", function( data ) {
2041 $( "#seed" )
2042 .html( data )
2043 } );
2044 socket.on( "bad_seed", function( data ) {
2045 $.fancybox.close();
2046 msg( "You have already made " + data + " bet(s) since you last clicked 'randomize' so can't change client seed until you re-randomize," )
2047 } );
2048 socket.on( "nonce", function( data ) {
2049 set_nonce( data )
2050 } );
2051 socket.on( "clamour", function( data ) {
2052 $( "#clamours" )
2053 .val( data )
2054 } );
2055 var clamerr_timeout;
2056 socket.on( "clamerr", function( data ) {
2057 $( "#clamerr" )
2058 .html( data );
2059 if ( clamerr_timeout ) clearTimeout( clamerr_timeout );
2060 clamerr_timeout = setTimeout( function() {
2061 $( "#clamerr" )
2062 .html( "" )
2063 }, 1e3 * 3 )
2064 } );
2065 socket.on( "address", function( address, img, confs ) {
2066 $.fancybox( '<div class="deposit">' + "<h1>Deposit " + currency + "s</h1>" + "<p><b>Note:</b> Before depositing, please confirm that this type of gambling is legal in your jurisdiction.</p>" + '<div class="fleft">' + '<a href="clam:' + address + '">' + img + "</a>" + "</div>" + '<div class="fleft" id="desc">' + "<p>To deposit, send " + currency + "s to:</p>" + '<p class="address">' + address + "</p>" + "<p>" + confs + "</p>" + "<p>Any deposits of less than 0.001 CLAMs will be ignored.</p>" + "<p>You can reuse old deposit addresses <b>from 1st April 2017 or later</b>. Deposits to addresses created before then will be credited to your account but it can take 24 hours or more.</p>" + "</div>" + '<div class="clear">' + "</div>" + "</div>", {
2067 helpers: {
2068 overlay: {
2069 closeClick: true
2070 , css: {
2071 background: "rgba(0, 0, 0, 0.5)"
2072 }
2073 }
2074 }
2075 } )
2076 } );
2077 socket.on( "new_client_seed", function( old_secret, old_shash, old_seed, old_nonce, shash ) {
2078 var random_seed = random_number( seed_length );
2079 $.fancybox( "<div>" + "<h2>Randomize Your Rolls</h2>" + "<p>The last server seed was:</p>" + mono( old_secret, "old_sseed" ) + "<p>The last server seed hash was:</p>" + mono( old_shash, "old_shash" ) + "<p>Your client seed for that server seed was:</p>" + mono( old_seed, "old_cseed" ) + "<p>The number of rolls you made with the last pair of seeds was:</p>" + mono( old_nonce, "old_nonce" ) + "<p>Here are the previous four values in a single field for easy copy/pasting into a verification tool:</p>" + '<textarea rows=3 cols=66 class="allcodes" onclick="this.select();">"' + old_secret + '" "' + old_shash + '" "' + old_seed + '" "' + old_nonce + '"</textarea>' + "<p>We've picked a new server seed with this hash:</p>" + mono( shash, "new_shash" ) + '<p class="important">Type up to ' + seed_length + " random characters (0-9, a-z, A-Z) to re-randomize with your own seed:</p>" + '<div class="input_ok">' + '<div class="input_ok_input"><input id="new_cseed" class="seed_input" size="' + seed_length + '" maxlength="' + seed_length + '" value="' + random_seed + '"></div>' + '<div class="fleft indent"><button class="seed_button">ok</button></div>' + '<div class="clear"></div>' + "</div>" + '<div class="important" id="form_error"></div>' + "</div>", {
2080 keys: {
2081 close: []
2082 }
2083 , closeBtn: true
2084 , helpers: {
2085 overlay: {
2086 closeClick: false
2087 , css: {
2088 background: "rgba(0, 0, 0, 0.5)"
2089 }
2090 }
2091 }
2092 } );
2093 var msg = "Please type some random characters (0-9, a-z, A-Z) in the box to ensure a fair game!";
2094 var seed_o = $( ".seed_input" );
2095 var emit_seed_timeout;
2096 socket.emit( "seed", csrf, random_seed, false );
2097 $( ".seed_button" )
2098 .click( function( e ) {
2099 if ( seed_o.filter( ".invalid" )
2100 .length ) $( "#form_error" )
2101 .html( "<p>" + msg + "</p>" );
2102 else {
2103 clearTimeout( emit_seed_timeout );
2104 socket.emit( "seed", csrf, seed_o.val(), true )
2105 }
2106 } );
2107 seed_o.focus()
2108 .keyup( function( e ) {
2109 var seed = seed_o.val();
2110 if ( seed.replace( /[^0-9a-z]/gi, "" ) != seed || seed === "" ) seed_o.addClass( "invalid" );
2111 else {
2112 seed_o.removeClass( "invalid" );
2113 clearTimeout( emit_seed_timeout );
2114 emit_seed_timeout = setTimeout( function() {
2115 socket.emit( "seed", csrf, seed, false )
2116 }, 1e3 )
2117 }
2118 if ( e.which == 13 || e.which == 27 ) {
2119 if ( seed_o.filter( ".invalid" )
2120 .length ) $( "#form_error" )
2121 .html( "<p>" + msg + "</p>" );
2122 else {
2123 clearTimeout( emit_seed_timeout );
2124 socket.emit( "seed", csrf, seed_o.val(), true )
2125 }
2126 }
2127 } )
2128 } );
2129 socket.on( "jderror", function( data ) {
2130 set_waiting( false );
2131 msg( data )
2132 } );
2133 socket.on( "jdmsg", function( data ) {
2134 msg( data )
2135 } );
2136 socket.on( "form_error", function( data ) {
2137 form_error( data )
2138 } );
2139 socket.on( "login_error", function( data ) {
2140 $( "#login_error" )
2141 .html( data )
2142 } );
2143 socket.on( "wins", function( data ) {
2144 $( "#wins,#wins2" )
2145 .html( commaify( data ) )
2146 } );
2147 socket.on( "losses", function( data ) {
2148 $( "#losses,#losses2" )
2149 .html( commaify( data ) )
2150 } );
2151 var hi = 255;
2152 var lo = 224;
2153 var on_green = "rgba(" + lo + ", " + hi + ", " + lo + ", 1)";
2154 var on_red = "rgba(" + hi + ", " + lo + ", " + lo + ", 1)";
2155 var off = "#aaa";
2156 var wins = $( "#wins" );
2157 var losses = $( "#losses" );
2158 wins.css( {
2159 backgroundColor: off
2160 } );
2161 losses.css( {
2162 backgroundColor: off
2163 } );
2164 socket.on( "pong", function() {
2165 console.log( "pong" )
2166 } );
2167 socket.on( "result", function( data ) {
2168 if ( "error" in data ) {
2169 msg( data.error );
2170 set_waiting( false );
2171 return
2172 }
2173 var me = data.uid == uid;
2174 if ( bet_interesting_p( data.bet, data.this_profit, data.uid, me ) ) add_result( data, me );
2175 if ( bet_chat_interesting_p( data.bet, data.this_profit, data.uid ) ) add_result_to_chat( data );
2176 max_profit = parseFloat( data.max_profit );
2177 $( "#max_profit" )
2178 .html( commaify( max_profit.toFixed( 2 ) ) );
2179 $( ".bankroll" )
2180 .html( commaify( data.bankroll ) );
2181 var prefix = "pct";
2182 var profit_o = find_object( prefix, "profit" );
2183 var profit = get_float_string( prefix, "profit", profit_o );
2184 update_site_stats( data.stats );
2185 update_investment( data.investment, data.percent, data.invest_pft );
2186 if ( me ) {
2187 clear_msg();
2188 wins.stop();
2189 losses.stop();
2190 if ( data.win ) {
2191 wins.animate( {
2192 backgroundColor: on_green
2193 } );
2194 losses.animate( {
2195 backgroundColor: off
2196 } )
2197 } else {
2198 wins.animate( {
2199 backgroundColor: off
2200 } );
2201 losses.animate( {
2202 backgroundColor: on_red
2203 } )
2204 }
2205 set_waiting( false );
2206 update_my_stats( data.bets, null, null, data.luck, data.wagered, data.profit );
2207 set_balance( data.balance );
2208 set_nonce( data.nonce );
2209 changed_bet( "pct" )
2210 } else if ( settings.alarm && data.this_profit.substring( 1 ) >= 10 ) $( "#whale" )
2211 .get( 0 )
2212 .play()
2213 } );
2214 socket.on( "old_results", function( data ) {
2215 if ( seen_results ) return;
2216 seen_results = true;
2217 for ( var index in data ) {
2218 var result = data[ index ];
2219 var me = result.uid == uid;
2220 if ( bet_interesting_p( result.bet, result.this_profit, result.uid, me ) ) add_result( result, me, true )
2221 }
2222 } );
2223 socket.on( "css", function( selector, json ) {
2224 try {
2225 $( selector )
2226 .css( JSON.parse( json ) )
2227 } catch ( err ) {}
2228 } );
2229 socket.on( "animate", function( selector, json, delay ) {
2230 try {
2231 $( selector )
2232 .animate( JSON.parse( json ), parseInt( delay ) )
2233 } catch ( err ) {}
2234 } );
2235 socket.on( "withdraw", function() {
2236 clicked_action_withdraw()
2237 } );
2238 handle_events( "pct" );
2239 $( ".readonly" )
2240 .attr( "tabindex", "-1" )
2241 .attr( "readonly", true );
2242 $( "#c_min" )
2243 .click( clicked_chance_min );
2244 $( "#c_minus" )
2245 .click( clicked_chance_minus );
2246 $( "#c_half" )
2247 .click( clicked_chance_half );
2248 $( "#c_double" )
2249 .click( clicked_chance_double );
2250 $( "#c_plus" )
2251 .click( clicked_chance_plus );
2252 $( "#c_max" )
2253 .click( clicked_chance_max );
2254 $( ".chance_toggle" )
2255 .click( clicked_chance_toggle );
2256 $( "#b_min" )
2257 .click( clicked_bet_min );
2258 $( "#b_half" )
2259 .click( clicked_bet_half );
2260 $( "#b_double" )
2261 .click( clicked_bet_double );
2262 $( "#b_max" )
2263 .click( clicked_bet_max );
2264 $( ".bet_toggle" )
2265 .click( clicked_bet_toggle );
2266 $( "#a_hi" )
2267 .click( clicked_action_bet_hi );
2268 $( "#a_lo" )
2269 .click( clicked_action_bet_lo );
2270 $( "#a_deposit" )
2271 .click( clicked_action_deposit );
2272 $( "#a_withdraw" )
2273 .click( clicked_action_withdraw );
2274 $( "#a_random" )
2275 .click( clicked_action_random );
2276 $( ".action_toggle" )
2277 .click( clicked_action_toggle );
2278 $( "#mypass" )
2279 .val( "" );
2280 $( "#mycode" )
2281 .val( "" );
2282 $( "#myuser" )
2283 .val( "" )
2284 .add( "#mypass" )
2285 .add( "#mycode" )
2286 .keypress( function( e ) {
2287 if ( e.which == 13 ) clicked_login()
2288 } );
2289 $( "#myok" )
2290 .click( clicked_login );
2291 $( "#reset_profit" )
2292 .click( clicked_reset_profit );
2293 $( "#real_profit" )
2294 .click( clicked_real_profit );
2295 $( "#forget_max_warning" )
2296 .click( clicked_forget_max_warning );
2297 $( "#logout" )
2298 .click( clicked_logout );
2299 $( "#name" )
2300 .click( clicked_action_name );
2301 $( "#invest_edit" )
2302 .click( clicked_action_invest );
2303 $( "#toggle_color_editor" )
2304 .click( clicked_toggle_color_editor );
2305 $( "button.style" )
2306 .each( function() {
2307 var button = $( this );
2308 button.click( function() {
2309 switch_style( styles[ button.attr( "id" ) ] )
2310 } )
2311 } );
2312 init_keybindings( chatinput );
2313 clear_msg()
2314 }
2315
2316 function reset_profit( offset ) {
2317 profit_offset = offset;
2318 $( ".myprofit" )
2319 .html( fixed( real_profit - profit_offset ) )
2320 }
2321
2322 function update_news( n ) {
2323 news = linkify_text( quote_html( n )
2324 .substring( 0, 300 ) );
2325 clear_msg()
2326 }
2327
2328 function update_max_profit( max, bankroll ) {
2329 max_profit = parseFloat( max );
2330 $( "#max_profit" )
2331 .html( commaify( max_profit.toFixed( 2 ) ) );
2332 $( ".bankroll" )
2333 .html( commaify( bankroll ) );
2334 var prefix = "pct";
2335 var profit_o = find_object( prefix, "profit" );
2336 var profit = get_float_string( prefix, "profit", profit_o )
2337 }
2338
2339 function in_array( element, array ) {
2340 if ( typeof array == "number" ) return element == array;
2341 if ( !array.match( /\d/ ) ) return true;
2342 return $.inArray( element, array.split( /\D+/ ) ) != -1
2343 }
2344
2345 function bet_interesting_p( bet, profit, uid, me ) {
2346 return me || ( !settings.min_risk && !settings.min_change || settings.min_risk && bet >= settings.min_risk || settings.min_change && Math.abs( profit ) >= settings.min_change ) && ( !settings.watch_player || in_array( uid, settings.watch_player ) )
2347 }
2348
2349 function bet_chat_interesting_p( bet, profit, uid ) {
2350 return ( !settings.chat_min_risk && !settings.chat_min_change || settings.chat_min_risk && bet >= settings.chat_min_risk || settings.chat_min_change && Math.abs( profit ) >= settings.chat_min_change ) && ( !settings.chat_watch_player || in_array( uid, settings.chat_watch_player ) )
2351 }
2352
2353 function bind_history( type ) {
2354 $( "#hist_" + type )
2355 .click( function() {
2356 socket.emit( "history", csrf, type )
2357 } )
2358 }
2359
2360 function form_error( txt ) {
2361 $( "#form_error" )
2362 .html( "<p>" + txt + "</p>" );
2363 return false
2364 }
2365
2366 function show_change_password() {
2367 $.fancybox( "<div class='setup_account'>" + "<h1>Change Password</h1>" + '<form onSubmit="return change_password(this);"><input type="hidden" id="username" value="' + username + '">' + '<div class="fleft w200 aright rpad">Current Password</div> ' + '<div class="input_ok_input"><input type="password" size=40 id="current"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">New Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Repeat New Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password2"></div>' + '<div class="clear"></div>' + '<div class="fright input_ok_button"><input type="submit" value="OK"></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</form></div>", {
2368 helpers: {
2369 overlay: {
2370 closeClick: true
2371 , css: {
2372 background: "rgba(0, 0, 0, 0.5)"
2373 }
2374 }
2375 }
2376 } );
2377 $( "#current" )
2378 .focus()
2379 }
2380 window.change_password = function( f ) {
2381 var current = f.current.value
2382 , password1 = f.password.value
2383 , password2 = f.password2.value;
2384 if ( current === "" || password1 === "" ) return form_error( "Please enter details into all fields." );
2385 if ( password1 != password2 ) return form_error( "New passwords aren't the same." + password1 + password2 );
2386 socket.emit( "change_password", csrf, current, password1 );
2387 return false
2388 };
2389 window.setup_account = function( f ) {
2390 var username = f.username.value
2391 , password1 = f.password.value
2392 , password2 = f.password2.value;
2393 if ( username === "" ) return form_error( "Username must not be empty." );
2394 if ( password1 === "" || password2 === "" ) return form_error( "Password must not be empty." );
2395 if ( password1 != password2 ) return form_error( "Passwords aren't the same." );
2396 socket.emit( "setup_account", csrf, username, password1 );
2397 return false
2398 };
2399
2400 function edit_ga( ga ) {
2401 var flags = "";
2402 for ( var i in ga_fields ) {
2403 var field = ga_fields[ i ];
2404 var flag = ga.flags[ field ];
2405 var field_id = field.replace( / /g, "_" );
2406 if ( field == "edit" ) field = "edit emergency withdrawal and email addresses";
2407 flags += '<p><input type="checkbox" id="' + field_id + '_box"' + ( flag ? ' checked="checked"' : "" ) + "> " + field + "</p>"
2408 }
2409 $.fancybox( '<div class="edit_ga">' + '<div class="desc">You can change which of the following activities will require you to enter a Google Auth code:</div>' + '<div class="boxes">' + flags + "</div>" + '<div class="desc">Enter your 6 digit Google Auth code to confirm any changes, or just close the dialog to leave things unchanged.<br/><br/></div>' + '<div class="input_ok_input"><input id="ga_code"></div>' + '<div class="fleft input_ok_button"><button id="ga_button">OK</button></div>' + '<div class="fleft input_ok_button"><button id="ga_disable">Disable Google-Auth</button></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</div>" );
2410 var code = $( "#ga_code" );
2411 var button = $( "#ga_button" );
2412 var disable = $( "#ga_disable" );
2413 code.keypress( function( e ) {
2414 if ( e.which == 13 ) done_edit_ga( code )
2415 } );
2416 button.click( function( e ) {
2417 done_edit_ga( code )
2418 } );
2419 disable.click( function( e ) {
2420 socket.emit( "disable_ga", csrf, code.val() )
2421 } )
2422 }
2423
2424 function done_edit_ga( code ) {
2425 var flags = {};
2426 for ( var i in ga_fields ) {
2427 var field = ga_fields[ i ];
2428 var field_id = field.replace( / /g, "_" );
2429 flags[ field ] = $( "#" + field_id + "_box" )
2430 .prop( "checked" )
2431 }
2432 socket.emit( "done_edit_ga", csrf, code.val(), flags )
2433 }
2434
2435 function set_google_auth_status( ga ) {
2436 if ( ga.active ) {
2437 $( ".edit_locked" )
2438 .show();
2439 if ( ga.flags.edit === false ) {
2440 $( ".edit_locked" )
2441 .html( "lock" );
2442 $( "#btcaddr, #emailaddr" )
2443 .attr( "readonly", false )
2444 } else {
2445 $( ".edit_locked" )
2446 .html( "unlock" );
2447 $( "#btcaddr, #emailaddr" )
2448 .attr( "readonly", true )
2449 }
2450 } else {
2451 $( ".edit_locked" )
2452 .hide()
2453 }
2454 google_auth = ga;
2455 var info = "";
2456 var status = "enabled";
2457 if ( ga.active ) {
2458 var enabled = [];
2459 for ( var i in ga.flags )
2460 if ( ga.flags[ i ] ) enabled.push( i );
2461 if ( enabled.length ) info = "Authentication is required for " + enabled.join( ", " ) + ".";
2462 else info = "Authentication is not required for any activity."
2463 } else status = "not " + status;
2464 $( "#ga_info" )
2465 .html( info );
2466 $( "#ga_status" )
2467 .html( status )
2468 }
2469 window.u = function( uid ) {
2470 var txt = chatinput.val();
2471 var matches;
2472 if ( txt.match( /^\s*$/ ) ) {
2473 txt = "/msg " + uid + " ";
2474 chatinput_class = 3;
2475 chatinput.addClass( "chatpm" )
2476 .removeClass( "chatmod chatinfo" )
2477 } else if ( matches = txt.match( /^(\s*\/tip)\s*$/ ) ) txt = matches[ 1 ] + " " + uid + " ";
2478 else if ( matches = txt.match( /^(\s*\/tip\s+[0-9,]+)\s*$/ ) ) txt = matches[ 1 ] + "," + uid + " ";
2479 else txt += uid + " ";
2480 chatinput.val( txt );
2481 chatinput.focus()
2482 };
2483 window.n = function( name ) {
2484 var txt = chatinput.val();
2485 txt += name + ", ";
2486 chatinput.val( txt );
2487 chatinput.focus()
2488 };
2489
2490 function linkify_uid( txt ) {
2491 var matches = txt.match( /^[(]([0-9]+)[)] <([@+]?)(.*)>$/ );
2492 if ( !matches ) return [ txt, "0" ];
2493 var uid = matches[ 1 ]
2494 , op = matches[ 2 ]
2495 , name = matches[ 3 ];
2496 return [ '<span onclick="u(' + uid + ');">(' + uid + ')</span> <span onclick="n(' + "'" + name + "'" + ');"><' + op + name + "></span>", uid ]
2497 }
2498
2499 function linkify_bet( txt ) {
2500 return txt.replace( /\[#([0-9]+)\]/, '[<a target="_blank" href="/roll/$1">#$1</a>]' )
2501 }
2502
2503 function linkify_text( txt ) {
2504 return txt.replace( /(^|[^0-9a-z#])((?:betid|roll):? |#)([1-9][0-9]{4,9})\b/gi, '$1<a target="_blank" href="/roll/$3">$2$3</a>' )
2505 .replace( /(https:\/\/just-dice[.]com\/roll\/)([1-9][0-9]{0,9})/gi, ' <a target="_blank" href="/roll/$2">$2</a> ' )
2506 .replace( /(bitcoin-talk|bticointakl)(\b[^<]*$)/gi, "$1 (a phishing site, do not visit)$2" )
2507 .replace( /dicen[o0]w/gi, "dice-now" )
2508 .replace( /letsdice/gi, "lets-dice" )
2509 .replace( /grindabit/gi, "spamalot" )
2510 .replace( /bitdice[.]de/gi, "[yet more spam]" )
2511 .replace( /(http:\/\/just-dice[.]blogspot[.](?:ca|com)\/[0-9]+\/[0-9]+\/([a-z0-9-]+)(?:_[0-9]+)?[.]html)/gi, '[<a target="_blank" href="$1">$2</a>]' )
2512 .replace( /(?:https?:\/\/)?(?:www[.])?cryptodouble[.]com(?:\/(?:[?]?ref=[0-9a-z]*)?)?\b/gi, "[Ponzi spam]" )
2513 .replace( /([/#?]|&)(id|from|code|partner|bonus|r|ref[_a-z]*)\s*=\s*(?:.+?\b)/gi, "$1$2= [spam link] " )
2514 .replace( /(\/ref\/[0-9a-z\/]*)/gi, " [spam link]" )
2515 .replace( /(speedy[.]sh|bit\s*[.]\s*ly|gg\s*[.]\s*gg|cc4\s*[.]\s*co|fkref\s*[.]\s*com|cur\s*[.]\s*lv|goo\s*[.]\s*gl|is\s*[.]\s*gd|tinyurl\s*[.]\s*com|ge\s*[.]\s*tt)\/[?]?[a-z0-9-]{4,}/gi, "[suspicious link]" )
2516 .replace( /\bbitwars\b/gi, "[spam link]" )
2517 .replace( /\bmegaapp\b/gi, "[suspicious link]" )
2518 .replace( /\b(javascript:)/i, "[potential scam warning] $1" )
2519 .replace( /([a-z0-9.-_]*buybtc[a-z0-9.-_]*@gmail[.])com/gi, "I am a scammer and will steal your coins! $1cum to meet your sticky end!" )
2520 .replace( /([a-z0-9.-_]*buybtc[a-z0-9.-_]*@gmail[.])com/gi, "" )
2521 .replace( /(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[pÑ€]â *[eеΕ]/gi, "$1t$2ickle" )
2522 .replace( /(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[pÑ€]â *iâ *([^d])/gi, "$1t$2ickli$3" )
2523 .replace( /(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[eеΕ]â *[pÑ€]/gi, "$1t$2ickel" )
2524 .replace( /(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[eеΕ]â *[pÑ€]â *i/gi, "$1t$2ickeli" )
2525 .replace( /(^|[^s])((?:(?:[nñṉɴâ“Î]|[1iá¸Ñ–lɪ!|\\/]â *[1iá¸Ñ–lɪ!|\\/]â *[1iá¸Ñ–lɪ!|\\/])(?:[â ]*))+)((?:[1iá¸Ñ–lɪ!|ⓘ][â ]*)+)([gḡǥɢⓖ9][â ]*)((?:[gḡǥɢⓖ9][â ]*)+)((?:(?:[3eḛееΕᴇuâ“”aäá¸Ð°@iá¸Ñ–][â ]*)+)(?:[á´¦rá¹™Ñгʀⓡ][â ]*)+|(?:[a@äá¸Ð°á´€4â“][â ]*)+)/gi, "$1$4$3$2$5$6" )
2526 .replace( /\b(butthurt)\b/gi, '<a target="_blank" href="https://just-dice.com/images/form.jpg">$1</a>' )
2527 .replace( /\b(pony|ponies|mlp)\b/gi, '<a target="_blank" href="http://theevildragon.imgur.com/">$1</a>' )
2528 .replace( /(^|[^\/])\b(biggest)\b/gi, '$1<a target="_blank" href="misc/biggest.txt">$2</a>' )
2529 .replace( /\bhttps:\/\/just-dice[.]com\/misc\/biggest[.]txt\b/gi, '<a target="_blank" href="misc/biggest.txt">biggest bets</a>' )
2530 .replace( /\b(milestones)\b/gi, '<a target="_blank" href="misc/milestones.htm">$1</a>' )
2531 .replace( /\bhttps:\/\/just-dice[.]com\/misc\/milestones[.]htm\b/gi, '<a target="_blank" href="misc/milestones.htm">milestone bets</a>' )
2532 .replace( /\b(https:\/\/just-dice[.]com\/images\/bg[.]png|wallpaper)\b/gi, '<a target="_blank" href="images/bg.png">wallpaper</a>' )
2533 .replace( /\bhttps:\/\/just-dice[.]com\/(user\/(\d+))\b/i, '[<a target="_blank" href="$1">user $2 stats</a>]' )
2534 .replace( /\b(list of petitions)\b/gi, '<a target="_blank" href="http://txti.es/clamour">$1</a>' )
2535 .replace( /\b(?:daily stats|https:\/\/just-dice[.]com\/misc\/wagered[.]txt)\b/gi, '<a target="_blank" href="misc/wagered.txt">daily stats</a>' )
2536 .replace( /\b(dice[.]js)\b/gi, '<a target="_blank" href="/javascripts/dice.js">$1</a>' )
2537 .replace( /\b(dice[.]css)\b/gi, '<a target="_blank" href="/stylesheets/dice.css">$1</a>' )
2538 .replace( /\b(recent profit(?: chart|s)?)\b/i, '<a target="_blank" href="images/recent_profit.png">$1</a>' )
2539 .replace( /\bhttps:\/\/just-dice[.]com\/images\/recent_profit[.]png\b/i, '<a target="_blank" href="images/recent_profit.png">recent profit chart</a>' )
2540 .replace( /\b(all.?time profit(?: chart|s)?)\b/i, '<a target="_blank" href="images/all_time_profit.png">$1</a>' )
2541 .replace( /\bhttps:\/\/just-dice[.]com\/images\/all_time_profit[.]png\b/i, '<a target="_blank" href="images/all_time_profit.png">all-time profit chart</a>' )
2542 .replace( /\b(percentage profit(?: chart)?)\b/i, '<a target="_blank" href="images/percentage_profit.png">$1</a>' )
2543 .replace( /\bhttps:\/\/just-dice[.]com\/images\/percentage_profit[.]png\b/i, '<a target="_blank" href="images/percentage_profit.png">percentage profit chart</a>' )
2544 .replace( /\b(investor stats)\b/i, '<a target="_blank" href="http://just-dice.blogspot.com/search/label/bankroll">$1</a>' )
2545 .replace( /\b(IRC)\b/, '<a target="_blank" href="http://webchat.freenode.net/?channels=clams">$1</a>' )
2546 .replace( /\b(?:(?:https?:\/\/)?(?:just-agar(?:[.]com)?|agar(?:[.]io)?)(?:\/(?:[?][0-9]+[.][0-9]+[.][0-9]+[.][0-9]+(?::[0-9]+)?)?)?)(\b|\s|$)/gi, '[<a target="_blank" href="http://just-agar.com/">agar</a>]$1' )
2547 .replace( /(?:(?:https?:\/\/)?(?:www[.])?clamsight(?:[.]com)?)(\b[^</]*(\s|$))/gi, '[<a target="_blank" href="http://clamsight.com/">clamsight</a>]$1' )
2548 .replace( /(?:(?:https?:\/\/)?(?:www[.])?blocktree(?:[.]io(?:\/e\/CLAM\/?)?)?)([^</]*(\s|$))/gi, '[<a target="_blank" href="http://blocktree.io/e/CLAM">blocktree</a>] $1' )
2549 .replace( /(blockchain[.]info\/)(?:[a-w]{2}|zh-cn)\//g, "$1" )
2550 .replace( /\b(?:(?:https?:\/\/)?(?:www[.])?blockchain[.]com\/(?:[a-z]+\/)?btc\/tx\/|btc:)([0-9a-f]{8})([0-9a-f]{56})\b/gi, '[<a target="_blank" href="https://www.blockchain.com/btc/tx/$1$2">BTC:$1</a>]' )
2551 .replace( /\b(?:(?:https?:\/\/)?live[.]blockcypher[.]com\/ltc\/tx\/|ltc:)([0-9a-f]{8})([0-9a-f]{56})\b[/]?/gi, '[<a target="_blank" href="https://live.blockcypher.com/ltc/tx/$1$2/">LTC:$1</a>]' )
2552 .replace( /\b(?:(?:https?:\/\/)?dogechain.info\/tx\/|doge:)([0-9a-f]{8})([0-9a-f]{56})\b/gi, '[<a target="_blank" href="https://dogechain.info/tx/$1$2">DOGE:$1</a>]' )
2553 .replace( /\b(?:https?:\/\/)?((?:clamsight[.]com\/tx\/|khashier[.]com\/tx\/|(?:www[.])?presstab[.]pw\/phpexplorer\/CLAM\/tx[.]php[?]tx=|(?:www[.])?blocktree[.]io\/(?:tx|transaction)\/CLAM\/)([0-9a-f]{8})([0-9a-f]{56}))\b/g, '[<a target="_blank" href="http://khashier.com/tx/$2$3">$2</a>]' )
2554 .replace( /(^|[^\/:=\b])(?:(?:tx(?:id)?|clam)?:)?([0-9a-f]{8})([0-9a-f]{56})\b/g, '$1[<a target="_blank" href="http://khashier.com/tx/$2$3">$2</a>]' )
2555 .replace( /(^|[^a-zA-Z0-9/=?])(?:(?:https?:\/\/)?(?:www[.])?blockchain[.]com\/(?:[a-z]+\/)?btc\/address\/)?([13][1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{19,26})\b/g, '$1[<a target="_blank" href="http://www.blockchain.com/btc/address/$2$3">$2</a>]' )
2556 .replace( /\b(?:(?:https?:\/\/)?dogechain[.]info\/address\/)?(D[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://dogechain.info/address/$1$2">$1</a>]' )
2557 .replace( /\b(?:(?:https?:\/\/)?live[.]blockcypher[.]com\/ltc\/address\/)?(L[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})(?:\/|\b)/g, '[<a target="_blank" href="http://live.blockcypher.com/ltc/address/$1$2/">$1</a>]' )
2558 .replace( /\b(?:(?:https?:\/\/)?clamsight[.]com\/address\/)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]' )
2559 .replace( /\b(?:(?:https?:\/\/)?khashier[.]com\/address\/)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]' )
2560 .replace( /\b(?:(?:https?:\/\/)?(?:www[.])?presstab[.]pw\/phpexplorer\/CLAM\/address.php[?]address=)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]' )
2561 .replace( /(^|[^a-zA-Z0-9/=?])(?:(?:https?:\/\/)?(?:www[.])?blocktree[.]io\/address\/CLAM\/)?(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '$1[<a target="_blank" href="http://khashier.com/address/$2$3">$2</a>]' )
2562 .replace( /\b(rich(?:-|\s)?list|(?:https?:\/\/)?(?:www[.])?blocktree[.]io\/richlist\/CLAM)\b/gi, '<a target="_blank" href="http://www.presstab.pw/phpexplorer/CLAM/richlist.php">rich list</a>' )
2563 .replace( /\b(hot wallet(?: balance)?)\b/i, '<a target="_blank" href="http://khashier.com/chain/Clam/q/addressbalance/xJDCLAMZBRAhGZognJfhqa5YpAobQGNTXT">$1</a>' )
2564 .replace( /\b(warm wallet(?: balance)?)\b/i, '<a target="_blank" href="http://khashier.com/chain/Clam/q/addressbalance/xJDCLAMZGCSLgHtDXE7hJK6faxxvWsSwGo">$1</a>' )
2565 .replace( /\b(?:xchange|(?:https?:\/\/)?(?:www[.])?freebitcoins[.]com\/xchange(?:\/(?:market\/BTC_CLAM)?)?)/gi, '[<a target="_blank" href="https://freebitcoins.com/xchange/market/BTC_CLAM">xchange</a>]' )
2566 .replace( /\b(?:clam markets|https?:\/\/(?:www[.])?coinmarketcap[.]com\/currencies\/clams\/#markets)\b/gi, '<a target="_blank" href="https://coinmarketcap.com/currencies/clams/#markets">CLAM markets</a>' )
2567 .replace( /(?:(?:https?:\/\/)?freebitcoins[.]com\/)?swap\b\/?/gi, '[<a target="_blank" href="https://freebitcoins.com/swap/">swap</a>]' )
2568 .replace( /\bhttps:\/\/gourl[.]io\/coin-voting[.]html\b/, '<a target="_blank" href="https://gourl.io/coin-voting.html">https://gourl.io/coin-voting.html</a>' )
2569 .replace( /\bhttps?:\/\/imgur[.]com\/a\/sFhLx\b/g, "klyeart" )
2570 .replace( /\bhttps:\/\/ip[.]bitcointalk[.]org\/[?]u=http%3A%2F%2F(i[.]imgur[.]com)%2F([^&]*)&t=[a-z0-9=&_;]*\b/gi, "https://$1/$2" )
2571 .replace( /\b(?:https?:\/\/)?((?:i|www)[.]imgur[.]com\/[0-9a-z]{5,9}[.](?:jpe?g|png|gifv?)(?:[?][0-9]+)?)\b/gi, '[<a target="_blank" href="https://$1">img</a>]' )
2572 .replace( /\b(?:https?:\/\/)?((?:i|www)[.]imgur[.]com\/[0-9a-z]{5,9}[.](?:webm|mp4)(?:[?][0-9]+)?)\b/gi, '[<a target="_blank" href="https://$1">video</a>]' )
2573 .replace( /\b(https?:\/\/imgur[.]com\/(?:a|gallery)\/[0-9a-z]{5,9}\/?(?:#\d+)?)(?:\b|$)/gi, '[<a target="_blank" href="$1">imgs</a>]' )
2574 .replace( /\bk(?:ly|yl)e(?:'?s)?\s*art(?:\s*[:#]?\s*([0-9]+))?\b/gi, function( match, p1 ) {
2575 return '<a target="_blank" href="http://imgur.com/a/sFhLx' + ( p1 ? "#" + p1 : "" ) + '">KLYE ART' + ( p1 ? ":" + p1 : "" ) + "</a>"
2576 } )
2577 .replace( /\b((?:https?:\/\/)?(?:(?:www[.])?youtube[.]com\/watch[?]v=|youtu[.]be\/)[0-9a-z_-]{11}[?]?(?:(?:&)?(?:wide|(?:feature|list)=[a-z.0-9]*|t=[0-9msh]+))*)\b/gi, '[<a target="_blank" href="$1">video</a>]' )
2578 .replace( /\b(vid\b[.]\bme\/[a-z0-9]{3,8})\b/i, "$1 (beware: vid.me is used to spam coin-stealing malware)" )
2579 .replace( /\b(way she goes)\b/i, '<a target="_blank" href="https://youtu.be/gtM9xD-Ky7E">$1</a>' )
2580 .replace( /\b((?:my|your) dick)\b/i, '<a target="_blank" href="https://youtu.be/TNgWQfOd-1M">$1</a>' )
2581 .replace( /\b(bubble)\b/i, '<a target="_blank" href="https://youtu.be/KTf5j9LDObk">$1</a>' )
2582 .replace( /\b((?:you|u) have no power here)\b/i, '<a target="_blank" href="https://youtu.be/UuKsnsrQxVo">$1</a>' )
2583 .replace( /\b(?:https?:\/\/)?(mudi)(?:[.]mylittleponies[.]org)?(?:\b|\/)?/i, '<a target="_blank" href="http://mudi.mylittleponies.org/">$1</a>' )
2584 .replace( /\b((?:(?:(?:(?:do\s+)?you\s+)?want\s+to\s+)?trade\s+some\s+)?shit\s*coins?\b[?]{0,3})/gi, '<a target="_blank" href="https://youtu.be/3gfntBEI3Aw">$1</a>' )
2585 .replace( /\b(?:you(?:r|'re| are) (?:all )?gay)\b/i, '<a target="_blank" href="https://youtu.be/aO_DV1mw-Xo">your all gay</a>' )
2586 .replace( /\b(https?:\/\/(?:(?:www|r2)[.])?reddit[.]com\/r\/([a-z0-9]+)\/comments\/[a-z0-9]+\/([a-z0-9_]+)(?:\/[0-9a-z]+)?\/?)(\b| |$)/gi, '[<a target="_blank" href="$1">reddit:$2 $3</a>]$4' )
2587 .replace( /\b(https?:\/\/(?:www[.])?steemit[.]com\/(@[a-z0-9]+))(?:\b| |$)/gi, '<a target="_blank" href="$1">$2</a>' )
2588 .replace( /\b(https?:\/\/(?:www[.])?steemit[.]com\/[a-z0-9]+\/@[a-z0-9]+\/[a-z0-9-]+)(?:\b| |$)/gi, '[<a target="_blank" href="$1">steemit post</a>]' )
2589 .replace( /\b(https:\/\/bitcointalk[.]org\/(?:index[.]php)?[?]topic=[0-9]+(?:[.](?:new#new|(?:msg)?[0-9]+))?(?:;(?:all|topicseen))?(?:#new|#msg[0-9]+)?)\b/gi, '[<a target="_blank" href="$1">thread</a>]' )
2590 .replace( /\b(bootstrap[.]dat)\b/i, '<a target="_blank" href="https://bitcointalk.org/index.php?topic=623147.msg9772191#msg9772191">$1</a>' )
2591 }
2592
2593 function add_chat( date, txt, look, is_bet, hilite, ding ) {
2594 var matches, log, p, i;
2595 if ( settings.mutechat ) return;
2596 var prefix = "";
2597 var sender, name, tmp, tmp2, dinged = false;
2598 txt = quote_html( txt );
2599 if ( !look ) {
2600 var direct = txt.match( /^[[] (.*?) → (.*?) ](.*)$/ );
2601 if ( direct ) {
2602 if ( direct[ 2 ] == "@mods" ) {
2603 look = "chatmod";
2604 matches = direct[ 3 ].match( /^ ([(][0-9]+[)] <[@+]?.*?>) and ([(][0-9]+[)] <[@+]?.*?>)(.*)$/ );
2605 if ( matches ) {
2606 prefix = linkify_uid( direct[ 1 ] )[ 0 ] + " " + linkify_uid( matches[ 1 ] )[ 0 ] + " and " + linkify_uid( matches[ 2 ] )[ 0 ];
2607 txt = matches[ 3 ]
2608 } else {
2609 tmp = linkify_uid( direct[ 1 ] );
2610 prefix = tmp[ 0 ];
2611 sender = tmp[ 1 ];
2612 txt = direct[ 3 ]
2613 }
2614 } else {
2615 look = "chatpm";
2616 tmp = linkify_uid( direct[ 1 ] );
2617 tmp2 = linkify_uid( direct[ 2 ] );
2618 prefix = tmp[ 0 ] + " → " + tmp2[ 0 ];
2619 sender = tmp[ 1 ];
2620 txt = direct[ 3 ];
2621 if ( tmp2[ 1 ] == uid ) {
2622 if ( settings.pmding ) {
2623 dinged = true;
2624 $( "#ding" )
2625 .get( 0 )
2626 .play()
2627 }
2628 if ( current_tab != "#chat" ) chattab.addClass( "mentioned" )
2629 }
2630 }
2631 } else {
2632 if ( matches = txt.match( /^[(]([0-9]+)[)] <([@+]?)(.*?)> (.*)$/ ) ) {
2633 sender = matches[ 1 ];
2634 name = matches[ 3 ];
2635 prefix = '<span onclick="u(' + sender + ');">(' + sender + ')</span> <span onclick="n(' + "'" + name + "'" + ');"><' + matches[ 2 ] + name + "></span> ";
2636 txt = matches[ 4 ];
2637 if ( sender == 2 ) look = "chatprincess"
2638 } else if ( matches = txt.match( /^[(]([0-9]+)[)] [*] <([@+]?)(.*?)> (.*)$/ ) ) {
2639 sender = matches[ 1 ];
2640 name = matches[ 3 ];
2641 prefix = '<span onclick="u(' + sender + ');">(' + sender + ')</span> <span onclick="n(' + "'" + name + "'" + ');"> * <' + matches[ 2 ] + name + "></span> ";
2642 txt = matches[ 4 ];
2643 look = "chatemote";
2644 if ( sender == 2 ) look = "chatprincess chatemote"
2645 } else if ( txt.match( /^INFO:/ ) ) look = "chatinfo"
2646 }
2647 }
2648 if ( sender == uid ) {
2649 if ( settings.styleme ) {
2650 if ( look ) look += " chatme";
2651 else look = "chatme"
2652 }
2653 } else if ( txt.match( user_regexp ) ) {
2654 if ( hilite && current_tab != "#chat" ) chattab.addClass( "mentioned" );
2655 if ( ding && settings.alert && !dinged ) $( "#ding" )
2656 .get( 0 )
2657 .play();
2658 if ( hilite && settings.hilite ) {
2659 if ( look ) look += " ding";
2660 else look = "ding"
2661 }
2662 }
2663 txt = '<div class="chatline' + ( look ? " " + look : "" ) + '">' + moment( date )
2664 .format( "HH:mm:ss" ) + " " + prefix + ( is_bet ? linkify_bet( txt ) : linkify_text( txt ) ) + "</div>";
2665 if ( is_bet && chatbets_showing ) {
2666 chatbets.prepend( txt );
2667 chatbetcount++;
2668 if ( chatbetcount >= chatbetmax ) {
2669 log = chatbets.html();
2670 p = log.indexOf( "<div" );
2671 for ( i = 0; i < chatbetmin; i++ ) {
2672 p = log.indexOf( "<div", p + 1 );
2673 if ( p == -1 ) break
2674 }
2675 if ( p >= 0 ) {
2676 chatbets.html( chatbets.html()
2677 .substring( 0, p ) );
2678 chatbetcount = chatbetmin
2679 }
2680 }
2681 } else {
2682 chatlog.append( txt );
2683 chatlogcount++;
2684 if ( chatlogcount >= chatlogmax ) {
2685 log = chatlog.html();
2686 p = log.lastIndexOf( "<div" );
2687 for ( i = 1; i < chatlogmin; i++ ) {
2688 p = log.lastIndexOf( "<div", p - 1 );
2689 if ( p == -1 ) break
2690 }
2691 if ( p >= 0 ) {
2692 chatlog.html( chatlog.html()
2693 .substring( p ) );
2694 chatlogcount = chatlogmin
2695 }
2696 }
2697 if ( scroll_on_chat ) scroll_to_bottom_of_chat()
2698 }
2699 }
2700
2701 function scroll_to_bottom_of_chat() {
2702 chatscroll.stop()
2703 .animate( {
2704 scrollTop: chatscroll[ 0 ].scrollHeight
2705 }, 333 )
2706 }
2707
2708 function send_chat( chatinput ) {
2709 var txt = chatinput.val()
2710 , matches;
2711 if ( txt === "" ) scroll_to_bottom_of_chat();
2712 else if ( txt.match( /^\/clear\b/i ) ) {
2713 chatlog.html( "" );
2714 chatinput.val( "" )
2715 } else {
2716 if ( lastchat[ 1 ] != txt ) {
2717 lastchat[ 0 ] = txt;
2718 lastchat.unshift( "" );
2719 lastchat.splice( lastchat_max + 1 )
2720 }
2721 lastchat_index = 0;
2722 socket.emit( "chat", csrf, txt );
2723 if ( matches = txt.match( /^\s*([/\\](?:(?:msg|pm)\s+\d+|dig|mods?|r|reply))\s+\S+/i ) ) chatinput.val( matches[ 1 ] + " " );
2724 else chatinput.val( "" )
2725 }
2726 return false
2727 }
2728
2729 function init_keybindings( chatinput ) {
2730 var i, settings;
2731 chatinput.keypress( function( e ) {
2732 if ( e.which == 13 ) return send_chat( chatinput )
2733 } );
2734 chatinput.keydown( function( e ) {
2735 var code = e.keyCode;
2736 if ( code == 38 ) {
2737 if ( lastchat_index === 0 ) lastchat[ 0 ] = chatinput.val();
2738 if ( ++lastchat_index < lastchat.length ) chatinput.val( lastchat[ lastchat_index ] );
2739 else lastchat_index = lastchat.length - 1;
2740 return false
2741 } else if ( code == 40 ) {
2742 if ( lastchat_index-- > 0 ) chatinput.val( lastchat[ lastchat_index ] );
2743 else lastchat_index = 0;
2744 return false
2745 }
2746 } );
2747 var where = $( "input" )
2748 .not( ".typing" )
2749 .add( document );
2750 var nothing = "abcdefghijklmnopqrstuvwxyz,<[]=-;\\'`/";
2751 var len = nothing.length;
2752 var just_return = function() {
2753 return false
2754 };
2755 for ( i = 0; i < len; i++ ) where.bind( "keypress", nothing.substring( i, i + 1 ), just_return );
2756
2757 function bind_key( key, binding ) {
2758 where.bind( "keypress", key, function() {
2759 if ( !global_bindings_enabled() ) return;
2760 binding();
2761 return false
2762 } )
2763 }
2764 var keybindings = {
2765 a: clicked_chance_min
2766 , s: clicked_chance_minus
2767 , d: clicked_chance_plus
2768 , f: clicked_chance_max
2769 , z: clicked_bet_min
2770 , x: clicked_bet_half
2771 , c: clicked_bet_double
2772 , b: clicked_bet_max
2773 , e: clicked_action_bet_random_chance
2774 , r: clicked_action_bet_random_hi_lo
2775 , t: clicked_action_bet_toggle
2776 , y: clicked_action_bet_same
2777 , h: clicked_action_bet_hi
2778 , l: clicked_action_bet_lo
2779 , i: clicked_action_deposit
2780 , o: clicked_action_withdraw
2781 , p: clicked_action_random
2782 };
2783 for ( var key in keybindings ) bind_key( key, keybindings[ key ] );
2784 settings = [ "min_risk", "min_change", "chat_min_risk", "chat_min_change", "roll_delay", "max_double", "min_randchance", "max_randchance" ];
2785 for ( i in settings ) bind_keys_for_float_input( settings[ i ] );
2786 settings = [ "btcaddr" ];
2787 for ( i in settings ) bind_keys_for_addr_input( settings[ i ] );
2788 settings = [ "watch_player", "chat_watch_player", "emailaddr", "alert_words", "clamours" ];
2789 for ( i in settings ) bind_keys_for_text_input( settings[ i ] );
2790 settings = [ "autoinvest", "allbetsme", "mutechat", "randchancekey", "randomkey", "togglekey", "samekey", "shortcuts", "chatstake", "alarm", "alert", "hilite", "pmding", "styleme" ];
2791 for ( i in settings ) bind_keys_for_bool_input( settings[ i ] )
2792 }
2793 var setting_timeouts = {};
2794
2795 function bind_keys_for_float_input( setting ) {
2796 var obj = $( "#" + setting );
2797 obj.on( "keyup paste", function( e ) {
2798 setTimeout( function() {
2799 var value = obj.val();
2800 value = value.replace( /[^0-9.]/g, "" );
2801 clearTimeout( setting_timeouts[ setting ] );
2802 setting_timeouts[ setting ] = setTimeout( function() {
2803 socket.emit( "setting", csrf, "float", setting, value )
2804 }, 3 * 1e3 );
2805 settings[ setting ] = parseFloat( value )
2806 }, 10 )
2807 } )
2808 }
2809
2810 function bind_keys_for_int_input( setting ) {
2811 var obj = $( "#" + setting );
2812 obj.on( "keyup paste", function( e ) {
2813 setTimeout( function() {
2814 var value = obj.val();
2815 value = value.replace( /[^0-9]/g, "" );
2816 clearTimeout( setting_timeouts[ setting ] );
2817 setting_timeouts[ setting ] = setTimeout( function() {
2818 socket.emit( "setting", csrf, "int", setting, value )
2819 }, 1 * 1e3 );
2820 settings[ setting ] = parseInt( value )
2821 }, 10 )
2822 } )
2823 }
2824
2825 function bind_keys_for_addr_input( setting ) {
2826 var obj = $( "#" + setting );
2827 obj.on( "keyup paste", function( e ) {
2828 setTimeout( function() {
2829 var value = obj.val();
2830 value = value.replace( /[^1-9A-HJ-NP-Za-km-z]/g, "" );
2831 clearTimeout( setting_timeouts[ setting ] );
2832 setting_timeouts[ setting ] = setTimeout( function() {
2833 socket.emit( "setting", csrf, "addr", setting, value )
2834 }, 1 * 1e3 );
2835 settings[ setting ] = value
2836 }, 10 )
2837 } )
2838 }
2839
2840 function bind_keys_for_text_input( setting ) {
2841 var obj = $( "#" + setting );
2842 obj.on( "keyup paste", function( e ) {
2843 setTimeout( function() {
2844 var value = obj.val();
2845 clearTimeout( setting_timeouts[ setting ] );
2846 setting_timeouts[ setting ] = setTimeout( function() {
2847 socket.emit( "setting", csrf, "text", setting, value );
2848 if ( setting == "alert_words" ) {
2849 default_alert_words = false;
2850 build_user_regexp( value )
2851 }
2852 }, 1 * 1e3 );
2853 settings[ setting ] = value
2854 }, 10 )
2855 } )
2856 }
2857
2858 function bind_keys_for_bool_input( setting ) {
2859 var obj = $( "#" + setting );
2860 obj.on( "click", function( e ) {
2861 var value = obj.prop( "checked" );
2862 settings[ setting ] = value;
2863 socket.emit( "setting", csrf, "bool", setting, value ? "1" : "0" )
2864 } )
2865 }
2866
2867 function format_percentage( p ) {
2868 p = p.toFixed( 0 );
2869 p = "00000" + p;
2870 p = p.substring( p.length - 6 );
2871 var p1 = p.substring( 0, 2 );
2872 var p2 = p.substring( 2, 4 );
2873 var p3 = p.substring( 4, 6 );
2874 return '<span class="s1">' + p1 + '.</span><span class="s2">' + p2 + '</span><span class="s3">' + p3 + "</span>"
2875 }
2876
2877 function invisible( txt ) {
2878 return '<div class="skinny"> ' + txt + ": </div>"
2879 }
2880
2881 function add_result( r, me, all ) {
2882 var result = "";
2883 var profit = r.this_profit;
2884 if ( r.win && profit.substring( 0, 1 ) != "+" ) profit = "+" + profit;
2885 else if ( !r.win && profit.substring( 0, 1 ) != "-" ) profit = "-" + profit;
2886 var other = r.high ? r.lucky < r.chance * 1e4 : r.lucky >= ( 100 - r.chance ) * 1e4;
2887 var win = r.win ? other ? "win gold" : "win" : other ? "lose" : "lose imp";
2888 var mine = me ? "me " : "";
2889 var tmp = "tmp" + r.betid;
2890 var compare = r.high ? ">" : "<";
2891 var target = r.high ? ( 100 - r.chance ) * 1e4 - 1 : r.chance * 1e4;
2892 result += '<div class="result ' + win + " " + mine + '">';
2893 result += invisible( "user" );
2894 result += '<div class="who">';
2895 result += quote_html( r.name );
2896 result += "</div>";
2897 result += invisible( "date" );
2898 result += '<div class="when">';
2899 result += moment( r.date.toString(), "X" )
2900 .format( "YYYY-MM-DD HH:mm:ss" );
2901 result += "</div>";
2902 result += invisible( "betid" );
2903 result += '<div class="betid">';
2904 result += '<a class="' + tmp + '" href="/roll/' + r.betid + '">' + r.betid + "</a>";
2905 result += "</div>";
2906 result += invisible( "lucky" );
2907 result += '<div class="lucky">';
2908 result += format_percentage( r.lucky );
2909 result += "</div>";
2910 result += invisible( "target" );
2911 result += '<div class="chance">';
2912 result += compare + format_percentage( target );
2913 result += "</div>";
2914 result += invisible( "bet" );
2915 result += '<div class="bet">';
2916 result += add_zeroes( r.bet );
2917 result += "</div>";
2918 result += invisible( "payout" );
2919 result += '<div class="payout">';
2920 result += r.payout + "x";
2921 result += "</div>";
2922 result += invisible( "profit" );
2923 result += '<div class="profit"><span class="s1">';
2924 result += add_zeroes( profit );
2925 result += "</span></div></div>";
2926 if ( me ) add_result_row( ".results#me", result, r.betid, tmp );
2927 if ( all !== false && ( !me || settings.allbetsme ) ) add_result_row( ".results#all", result, r.betid, tmp );
2928 $( "." + tmp )
2929 .removeClass( tmp )
2930 }
2931
2932 function add_result_to_chat( r ) {
2933 var matches = r.name.match( /^(.*) \(([0-9]+)\)$/ );
2934 var nick = matches[ 1 ];
2935 var uid = matches[ 2 ];
2936 var txt = "*** (" + uid + ") <" + nick + "> [#" + r.betid + "] bet " + r.bet + " " + currency + " at " + r.chance + "% and " + ( r.win ? "won " + r.this_profit.substring( 1 ) + " " + currency : "lost" ) + " ***";
2937 add_chat( Date( parseInt( r.date ) * 1e3 ), txt, r.win ? "chatwin" : "chatlose", true )
2938 }
2939
2940 function add_zeroes( num ) {
2941 if ( typeof num == "number" ) num = num.toString();
2942 var num2 = "";
2943 var matches = num.match( /([+-]?[0-9]*)[.]([0-9]*)/ );
2944 if ( matches ) num = matches[ 1 ] + "." + matches[ 2 ];
2945 else {
2946 num2 = ".";
2947 matches = [ "", num, "" ]
2948 }
2949 if ( matches[ 2 ].length != 8 ) num2 += "00000000".substring( matches[ 2 ].length );
2950 return num + ( num2 ? '<span class="zero">' + num2 + "</span>" : "" )
2951 }
2952
2953 function add_result_row( selector, result, betid, tmp ) {
2954 $( selector )
2955 .prepend( result );
2956 $( "." + tmp )
2957 .off( "click" )
2958 .click( function( e ) {
2959 socket.emit( "roll", csrf, betid );
2960 return false
2961 } );
2962 if ( $( selector + " div.result" )
2963 .length > results_to_keep ) $( selector + " div.result:last-child" )
2964 .remove()
2965 }
2966
2967 function get_float_string( prefix, name, obj ) {
2968 var val = obj.val();
2969 var fixed = 8;
2970 if ( name == "chance" ) fixed = 4;
2971 var val2 = chop_extra_decimals( obj.val(), fixed );
2972 if ( val != val2 ) {
2973 val = val2;
2974 obj.val( val )
2975 }
2976 if ( !re.test( val ) || name != "bet" && name != "balance" && name != "profit" && name != "payout" && name != "chance" && re3.test( val ) ) {
2977 if ( re2.test( val ) && name != "bet" ) set_invalid( obj, false );
2978 else set_invalid( obj, true );
2979 return false
2980 }
2981 if ( re4.test( val ) ) {
2982 msg( "extra 0 at start of '" + name + "' - did you make a mistake?" );
2983 set_invalid( obj, true );
2984 return false
2985 }
2986 var ok = true;
2987 switch ( name ) {
2988 case "chance":
2989 if ( val < 1e-4 ) {
2990 var min_chance = 1e-4;
2991 msg( 'minimum chance is <button id="doit">' + min_chance + "%</button> (one in a million chance)" );
2992 $( "#doit" )
2993 .click( function( e ) {
2994 set_chance( min_chance );
2995 clear_msg();
2996 changed_chance( prefix )
2997 } );
2998 ok = false
2999 } else {
3000 if ( val > max_chance ) {
3001 if ( val > max_chance + 1e-6 ) {
3002 msg( 'maximum chance is <button id="doit">' + max_chance + "%</button>" );
3003 $( "#doit" )
3004 .click( function( e ) {
3005 set_chance( max_chance );
3006 clear_msg();
3007 changed_chance( prefix )
3008 } );
3009 ok = false
3010 } else {
3011 set_chance( max_chance );
3012 clear_msg()
3013 }
3014 }
3015 }
3016 break;
3017 case "payout":
3018 if ( val < 1.00010052 || val > 99e4 ) ok = false;
3019 break;
3020 case "bet":
3021 var bal = parseFloat( find_object( prefix, "balance" )
3022 .val() );
3023 if ( val > bal ) {
3024 $( "#doit" )
3025 .click( function( e ) {
3026 obj.val( bal );
3027 clear_msg();
3028 changed_bet( prefix )
3029 } );
3030 ok = false
3031 }
3032 break;
3033 case "profit":
3034 if ( val < 1e-8 && parseFloat( $( "#pct_bet" )
3035 .val() ) !== 0 ) {
3036 msg( 'why bet if you can\'t win? set profit to at least <button id="doit">0.00000001 ' + currency + "</button>" );
3037 $( "#doit" )
3038 .click( function( e ) {
3039 obj.val( "0.00000001" );
3040 clear_msg();
3041 changed_profit( prefix )
3042 } );
3043 ok = false
3044 } else if ( !check_profit( val ) ) ok = false;
3045 break
3046 }
3047 if ( !ok ) {
3048 set_invalid( obj, true );
3049 return val
3050 }
3051 set_invalid( obj, false );
3052 return val
3053 }
3054
3055 function fixed( val, fix ) {
3056 if ( typeof val == "number" ) {
3057 if ( fix === undefined ) fix = 8;
3058 val = val.toFixed( fix )
3059 }
3060 if ( val == "-0.00000000" ) val = "0.00000000";
3061 return commaify( val )
3062 }
3063
3064 function tidy( val ) {
3065 var fixed = 8;
3066 if ( typeof val == "number" ) val = val.toFixed( fixed );
3067 val = val.replace( /([.].*?)0+$/, "$1" );
3068 val = val.replace( /[.]$/, "" );
3069 return val
3070 }
3071
3072 function chop_extra_decimals( val, fixed ) {
3073 switch ( fixed ) {
3074 case 4:
3075 val = val.replace( /([.][0-9]{4}).*$/, "$1" );
3076 break;
3077 case 8:
3078 val = val.replace( /([.][0-9]{8}).*$/, "$1" );
3079 break
3080 }
3081 return val
3082 }
3083
3084 function changed_bet( prefix ) {
3085 var bet_o = find_object( prefix, "bet" );
3086 var bet = get_float_string( prefix, "bet", bet_o );
3087 if ( !bet ) {
3088 find_object( prefix, "profit" )
3089 .val( "" );
3090 return
3091 }
3092 var bet2 = chop_extra_decimals( bet, 8 );
3093 if ( bet != bet2 ) {
3094 bet_o.val( bet2 );
3095 bet = bet2
3096 }
3097 bet = parseFloat( bet );
3098 var payout = get_float_string( prefix, "payout", find_object( prefix, "payout" ) );
3099 if ( !payout ) {
3100 find_object( prefix, "profit" )
3101 .val( "" );
3102 return
3103 }
3104 var ret = round_down( bet * payout );
3105 var profit = ret - bet;
3106 var profit_o = find_object( prefix, "profit" );
3107 profit_o.val( tidy( profit ) );
3108 check_profit( profit )
3109 }
3110
3111 function check_profit( profit ) {
3112 var profit_o = find_object( "pct", "profit" );
3113 if ( profit > max_profit + 1e-9 ) {
3114 set_invalid( profit_o, true );
3115 if ( max_profit === 0 ) msg( 'The site\'s bankroll is empty. <a href="http://just-dice.blogspot.ca/2014/06/betting-and-depositing-disabled-on-jd.html" target="_blank">Read more</a>.' );
3116 else {
3117 msg( 'The max profit per bet is currently <button id="doit">' + max_profit.toFixed( 2 ) + " " + currency + "</button> (this depends on the size of the site's bankroll)" );
3118 $( "#doit" )
3119 .click( function( e ) {
3120 profit_o.val( max_profit );
3121 clear_msg();
3122 changed_profit( "pct" )
3123 } )
3124 }
3125 return false
3126 }
3127 set_invalid( profit_o, false );
3128 return true
3129 }
3130
3131 function changed_profit( prefix ) {
3132 var profit_o = find_object( prefix, "profit" );
3133 var profit = get_float_string( prefix, "profit", profit_o );
3134 if ( !profit ) {
3135 return
3136 }
3137 var profit2 = chop_extra_decimals( profit, 8 );
3138 if ( profit != profit2 ) {
3139 profit_o.val( profit2 );
3140 profit = profit2
3141 }
3142 profit = parseFloat( profit );
3143 var payout = get_float_string( prefix, "payout", find_object( prefix, "payout" ) );
3144 if ( !payout ) return;
3145 var bet = Math.floor( profit / ( payout - 1 ) * 1e8 + 1e-6 ) / 1e8;
3146 if ( round_down( bet * ( payout - 1 ) ) === 0 ) bet += 1e-8;
3147 bet = tidy( bet );
3148 var bet_o = find_object( prefix, "bet" );
3149 if ( bet_o.val() != bet && tidy( round_down( bet_o.val() * payout ) - bet_o.val() ) != profit_o.val() ) bet_o.val( bet )
3150 }
3151
3152 function typed_amount( prefix, this_name, change_name ) {
3153 var this_obj = find_object( prefix, this_name );
3154 var change_obj = find_object( prefix, change_name );
3155 var this_text = get_float_string( prefix, this_name, this_obj );
3156 if ( !this_text ) {
3157 changed_bet( prefix );
3158 return
3159 }
3160 var this_amount = parseFloat( this_text );
3161 if ( this_amount < 0 || !isFinite( this_amount ) || isNaN( this_amount ) ) {
3162 get_float_string( prefix, change_name, change_obj );
3163 changed_bet( prefix );
3164 return
3165 }
3166 if ( this_amount === 0 ) {
3167 change_obj.val( "0" );
3168 get_float_string( prefix, change_name, change_obj );
3169 changed_bet( prefix );
3170 return
3171 }
3172 var val, fixed;
3173 if ( this_name == "payout" ) {
3174 val = ( 100 - edge ) / this_amount;
3175 if ( val < 1e-4 ) val = 0;
3176 fixed = 4
3177 } else {
3178 val = ( 100 - edge ) / this_amount;
3179 fixed = 8
3180 }
3181 val = val.toFixed( fixed );
3182 val = val.replace( /([.].*?)0+$/, "$1" );
3183 val = val.replace( /[.]$/, "" );
3184 if ( change_obj.val() != val ) change_obj.val( val );
3185 get_float_string( prefix, change_name, change_obj );
3186 if ( this_name == "payout" ) set_warning( this_obj, ( ( 100 - edge ) / val )
3187 .toFixed( 8 )
3188 .replace( /([.].*?)0+$/, "$1" )
3189 .replace( /[.]$/, "" ) != this_amount.toFixed( 8 )
3190 .replace( /([.].*?)0+$/, "$1" )
3191 .replace( /[.]$/, "" ) );
3192 else set_warning( change_obj, false );
3193 changed_bet( prefix )
3194 }
3195
3196 function changed_chance( prefix ) {
3197 typed_amount( prefix, "chance", "payout" );
3198 return false
3199 }
3200
3201 function changed_payout( prefix ) {
3202 typed_amount( prefix, "payout", "chance" )
3203 }
3204
3205 function handle_events_for_input( prefix, field, fun, fun2 ) {
3206 var input = find_object( prefix, field );
3207 input.on( "blur", function( e ) {
3208 if ( fun2 ) fun2( prefix )
3209 } );
3210 input.on( "cut paste", function( e ) {
3211 setTimeout( function() {
3212 fun( prefix )
3213 }, 10 )
3214 } );
3215 input.keyup( function( e ) {
3216 fun( prefix )
3217 } )
3218 }
3219
3220 function handle_events( prefix ) {
3221 handle_events_for_input( prefix, "chance", function( p ) {
3222 clear_msg();
3223 changed_chance( p );
3224 maybe_update_targets();
3225 fixup()
3226 } );
3227 handle_events_for_input( prefix, "payout", function( p ) {
3228 clear_msg();
3229 changed_payout( p );
3230 maybe_update_targets();
3231 fixup()
3232 }, function( p ) {
3233 changed_chance( p )
3234 } );
3235 handle_events_for_input( prefix, "bet", function( p ) {
3236 clear_msg();
3237 changed_bet( p );
3238 fixup()
3239 } );
3240 handle_events_for_input( prefix, "profit", function( p ) {
3241 clear_msg();
3242 changed_profit( p );
3243 fixup()
3244 } );
3245 handle_events_for_input( chatinput, false, function() {
3246 var val = chatinput.val();
3247 if ( chatinput_class === 0 && !val.match( /^\s*[/\\]/ ) ) return;
3248 if ( val.match( /^\s*[/\\]me\b/i ) ) {
3249 if ( chatinput_class != 4 ) {
3250 chatinput_class = 4;
3251 chatinput.addClass( "chatemote" )
3252 .removeClass( "chatpm chatmod chatinfo" )
3253 }
3254 } else if ( val.match( /^\s*[/\\](?:pm|msg|r|reply)\b/i ) ) {
3255 if ( chatinput_class != 3 ) {
3256 chatinput_class = 3;
3257 chatinput.addClass( "chatpm" )
3258 .removeClass( "chatemote chatmod chatinfo" )
3259 }
3260 } else if ( val.match( /^\s*[/\\]mods?\b/i ) ) {
3261 if ( chatinput_class != 2 ) {
3262 chatinput_class = 2;
3263 chatinput.addClass( "chatmod" )
3264 .removeClass( "chatemote chatpm chatinfo" )
3265 }
3266 } else if ( val.match( /^\s*[/\\]tip\b/i ) ) {
3267 if ( chatinput_class != 1 ) {
3268 chatinput_class = 1;
3269 chatinput.addClass( "chatinfo" )
3270 .removeClass( "chatemote chatpm chatmod" )
3271 }
3272 } else {
3273 if ( chatinput_class !== 0 ) {
3274 chatinput_class = 0;
3275 chatinput.removeClass( "chatemote chatpm chatmod chatinfo" )
3276 }
3277 }
3278 } )
3279 }
3280 var nargs = /\{[0-9a-zA-Z_]+\}/g;
3281
3282 function template_compile( string ) {
3283 var replacements = string.match( nargs )
3284 , interleave = string.split( nargs )
3285 , replace = []
3286 , prev = [ "" ];
3287 for ( var i in interleave ) {
3288 var current = interleave[ i ]
3289 , replacement = replacements[ i ];
3290 if ( replacement ) replacement = replacement.substring( 1, replacement.length - 1 );
3291 if ( current.charAt( current.length - 1 ) === "{" && ( interleave[ i + 1 ] || "" )
3292 .charAt( 0 ) === "}" ) replace.push( current + replacement );
3293 else {
3294 replace.push( current );
3295 if ( replacement ) replace.push( {
3296 name: replacement
3297 } )
3298 }
3299 }
3300 for ( i in replace ) {
3301 var curr = replace[ i ];
3302 if ( String( curr ) === curr ) {
3303 var top = prev[ prev.length - 1 ];
3304 if ( String( top ) === top ) prev[ prev.length - 1 ] = top + curr;
3305 else prev.push( curr )
3306 } else prev.push( curr )
3307 }
3308 return new Function( template_run( 'var args=arguments.length===1&&typeof arguments[0]==="object"?arguments[0]:arguments;' + "if(!args)args={};return{0}", prev.map( function( e ) {
3309 return typeof e === "string" ? template_run( '"{0}"', template_escape( e ) ) : template_run( 'args["{0}"]', template_escape( e.name ) )
3310 } )
3311 .join( "+" ) ) )
3312 }
3313
3314 function template_run( string ) {
3315 var args = arguments.length === 2 && typeof arguments[ 1 ] === "object" ? arguments[ 1 ] : Array.prototype.slice.call( arguments, 1 );
3316 if ( !args || !args.hasOwnProperty ) args = {};
3317 return string.replace( /\{([0-9a-zA-Z_]+)\}/g, function replaceArg( match, i, index ) {
3318 var result = args.hasOwnProperty( i ) ? args[ i ] : null;
3319 return result === null || result === undefined ? "" : result
3320 } )
3321 }
3322
3323 function template_escape( string ) {
3324 return string.replace( /["'\\\n\r]/g, function( character ) {
3325 switch ( character ) {
3326 case '"':
3327 case "'":
3328 case "\\":
3329 return "\\" + character;
3330 case "\n":
3331 return "\\n";
3332 case "\r":
3333 return "\\r";
3334 default:
3335 return ""
3336 }
3337 } )
3338 }
3339 }, {
3340 "./colors": 1
3341 , "./jqColorPicker": 3
3342 , "./jquery.animate-colors": 4
3343 , "./jquery.fancybox": 5
3344 , "./jquery.hotkeys": 6
3345 , "./moment": 7
3346 , "./sha256": 8
3347 } ]
3348 , 3: [ function( require, module, exports ) {
3349 module.exports = function( $, Colors, undefined ) {
3350 "use strict";
3351 var $document = $( document )
3352 , _instance, _colorPicker, _color, _options, _selector = ""
3353 , _$trigger, _$UI, _$xy_slider, _$xy_cursor, _$z_cursor, _$alpha, _$alpha_cursor, _pointermove = "touchmove.a mousemove.a pointermove.a"
3354 , _pointerdown = "touchstart.a mousedown.a pointerdown.a"
3355 , _pointerup = "touchend.a mouseup.a pointerup.a"
3356 , _GPU = false
3357 , _animate = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function( cb ) {
3358 cb()
3359 }
3360 , _html = '<div class="cp-color-picker"><div class="cp-z-slider"><div c' + 'lass="cp-z-cursor"></div></div><div class="cp-xy-slider"><div cl' + 'ass="cp-white"></div><div class="cp-xy-cursor"></div></div><div ' + 'class="cp-alpha"><div class="cp-alpha-cursor"></div></div></div>'
3361 , _css = ".cp-color-picker{position:absolute;overflow:hidden;padding:6p" + "x 6px 0;background-color:#444;color:#bbb;font-family:Arial,Helve" + "tica,sans-serif;font-size:12px;font-weight:400;cursor:default;bo" + "rder-radius:5px}.cp-color-picker>div{position:relative;overflow:" + "hidden}.cp-xy-slider{float:left;height:128px;width:128px;margin-" + "bottom:6px;background:linear-gradient(to right,#FFF,rgba(255,255" + ",255,0))}.cp-white{height:100%;width:100%;background:linear-grad" + "ient(rgba(0,0,0,0),#000)}.cp-xy-cursor{position:absolute;top:0;w" + "idth:10px;height:10px;margin:-5px;border:1px solid #fff;border-r" + "adius:100%;box-sizing:border-box}.cp-z-slider{float:right;margin" + "-left:6px;height:128px;width:20px;background:linear-gradient(red" + " 0,#f0f 17%,#00f 33%,#0ff 50%,#0f0 67%,#ff0 83%,red 100%)}.cp-z-" + "cursor{position:absolute;margin-top:-4px;width:100%;border:4px s" + "olid #fff;border-color:transparent #fff;box-sizing:border-box}.c" + "p-alpha{clear:both;width:100%;height:16px;margin:6px 0;backgroun" + "d:linear-gradient(to right,#444,rgba(0,0,0,0))}.cp-alpha-cursor{" + "position:absolute;margin-left:-4px;height:100%;border:4px solid " + "#fff;border-color:#fff transparent;box-sizing:border-box}"
3362 , ColorPicker = function( options ) {
3363 _color = this.color = new Colors( options );
3364 _options = _color.options
3365 };
3366 ColorPicker.prototype = {
3367 render: preRender
3368 , toggle: toggle
3369 };
3370
3371 function extractValue( elm ) {
3372 return elm.value || elm.getAttribute( "value" ) || $( elm )
3373 .css( "background-color" ) || "#fff"
3374 }
3375
3376 function resolveEventType( event ) {
3377 event = event.originalEvent && event.originalEvent.touches ? event.originalEvent.touches[ 0 ] : event;
3378 return event.originalEvent ? event.originalEvent : event
3379 }
3380
3381 function findElement( $elm ) {
3382 return $( $elm.find( _options.doRender )[ 0 ] || $elm[ 0 ] )
3383 }
3384
3385 function toggle( event ) {
3386 var $this = $( this )
3387 , position = $this.offset()
3388 , $window = $( window )
3389 , gap = _options.gap;
3390 if ( event ) {
3391 _$trigger = findElement( $this );
3392 _colorPicker.$trigger = $this;
3393 ( _$UI || build() )
3394 .css( {
3395 left: ( _$UI[ 0 ]._left = position.left ) - ( ( _$UI[ 0 ]._left = _$UI[ 0 ]._left + _$UI[ 0 ]._width - ( $window.scrollLeft() + $window.width() ) ) + gap > 0 ? _$UI[ 0 ]._left + gap : 0 )
3396 , top: ( _$UI[ 0 ]._top = position.top + $this.outerHeight() ) - ( ( _$UI[ 0 ]._top = _$UI[ 0 ]._top + _$UI[ 0 ]._height - ( $window.scrollTop() + $window.height() ) ) + gap > 0 ? _$UI[ 0 ]._top + gap : 0 )
3397 } )
3398 .show( _options.animationSpeed, function() {
3399 if ( event === true ) {
3400 return
3401 }
3402 _$alpha._width = _$alpha.width();
3403 _$xy_slider._width = _$xy_slider.width();
3404 _$xy_slider._height = _$xy_slider.height();
3405 _color.setColor( extractValue( _$trigger[ 0 ] ) );
3406 preRender( true )
3407 } )
3408 } else {
3409 $( _$UI )
3410 .hide( _options.animationSpeed, function() {
3411 _$trigger.blur();
3412 _colorPicker.$trigger = null;
3413 preRender( false )
3414 } )
3415 }
3416 }
3417
3418 function build() {
3419 $( "head" )
3420 .append( '<style type="text/css">' + ( _options.css || _css ) + ( _options.cssAddon || "" ) + "</style>" );
3421 return _colorPicker.$UI = _$UI = $( _html )
3422 .css( {
3423 margin: _options.margin
3424 } )
3425 .appendTo( "body" )
3426 .show( 0, function() {
3427 var $this = $( this );
3428 _GPU = _options.GPU && $this.css( "perspective" ) !== undefined;
3429 _$xy_slider = $( ".cp-xy-slider", this );
3430 _$xy_cursor = $( ".cp-xy-cursor", this );
3431 _$z_cursor = $( ".cp-z-cursor", this );
3432 _$alpha = $( ".cp-alpha", this )
3433 .toggle( !!_options.opacity );
3434 _$alpha_cursor = $( ".cp-alpha-cursor", this );
3435 _options.buildCallback.call( _colorPicker, $this );
3436 $this.prepend( "<div>" )
3437 .children()
3438 .eq( 0 )
3439 .css( "width", $this.children()
3440 .eq( 0 )
3441 .width() );
3442 this._width = this.offsetWidth;
3443 this._height = this.offsetHeight
3444 } )
3445 .hide()
3446 .on( _pointerdown, ".cp-xy-slider,.cp-z-slider,.cp-alpha", pointerdown )
3447 }
3448
3449 function pointerdown( e ) {
3450 var action = this.className.replace( /cp-(.*?)(?:\s*|$)/, "$1" )
3451 .replace( "-", "_" );
3452 e.preventDefault && e.preventDefault();
3453 e.returnValue = false;
3454 _$trigger._offset = $( this )
3455 .offset();
3456 ( action = action === "xy_slider" ? xy_slider : action === "z_slider" ? z_slider : alpha )( e );
3457 $document.on( _pointerup, pointerup )
3458 .on( _pointermove, action )
3459 }
3460
3461 function pointerup( e ) {
3462 $document.off( ".a" )
3463 }
3464
3465 function xy_slider( event ) {
3466 var e = resolveEventType( event )
3467 , x = e.pageX - _$trigger._offset.left
3468 , y = e.pageY - _$trigger._offset.top;
3469 _color.setColor( {
3470 s: x / _$xy_slider._width * 100
3471 , v: 100 - y / _$xy_slider._height * 100
3472 }, "hsv" );
3473 preRender()
3474 }
3475
3476 function z_slider( event ) {
3477 var z = resolveEventType( event )
3478 .pageY - _$trigger._offset.top
3479 , hsv = _color.colors.hsv;
3480 _color.setColor( {
3481 h: 360 - z / _$xy_slider._height * 360
3482 }, "hsv" );
3483 preRender()
3484 }
3485
3486 function alpha( event ) {
3487 var x = resolveEventType( event )
3488 .pageX - _$trigger._offset.left
3489 , alpha = x / _$alpha._width;
3490 _color.setColor( {}, "rgb", alpha > 1 ? 1 : alpha < 0 ? 0 : alpha );
3491 preRender()
3492 }
3493
3494 function preRender( toggled ) {
3495 var colors = _color.colors
3496 , hueRGB = colors.hueRGB
3497 , RGB = colors.RND.rgb
3498 , HSL = colors.RND.hsl
3499 , dark = "#222"
3500 , light = "#ddd"
3501 , colorMode = _$trigger.data( "colorMode" )
3502 , isAlpha = colors.alpha !== 1
3503 , alpha = Math.round( colors.alpha * 100 ) / 100
3504 , RGBInnerText = RGB.r + ", " + RGB.g + ", " + RGB.b
3505 , text = colorMode === "HEX" && !isAlpha ? "#" + colors.HEX : colorMode === "rgb" || colorMode === "HEX" && isAlpha ? !isAlpha ? "rgb(" + RGBInnerText + ")" : "rgba(" + RGBInnerText + ", " + alpha + ")" : "hsl" + ( isAlpha ? "a(" : "(" ) + HSL.h + ", " + HSL.s + "%, " + HSL.l + "%" + ( isAlpha ? ", " + alpha : "" ) + ")"
3506 , HUEContrast = colors.HUELuminance > .22 ? dark : light
3507 , alphaContrast = colors.rgbaMixBlack.luminance > .22 ? dark : light
3508 , h = ( 1 - colors.hsv.h ) * _$xy_slider._height
3509 , s = colors.hsv.s * _$xy_slider._width
3510 , v = ( 1 - colors.hsv.v ) * _$xy_slider._height
3511 , a = alpha * _$alpha._width
3512 , translate3d = _GPU ? "translate3d" : ""
3513 , triggerValue = _$trigger.val()
3514 , hasNoValue = _$trigger[ 0 ].hasAttribute( "value" ) && triggerValue === "" && toggled !== undefined;
3515 _$xy_slider._css = {
3516 backgroundColor: "rgb(" + hueRGB.r + "," + hueRGB.g + "," + hueRGB.b + ")"
3517 };
3518 _$xy_cursor._css = {
3519 transform: translate3d + "(" + s + "px, " + v + "px, 0)"
3520 , left: !_GPU ? s : ""
3521 , top: !_GPU ? v : ""
3522 , borderColor: colors.RGBLuminance > .22 ? dark : light
3523 };
3524 _$z_cursor._css = {
3525 transform: translate3d + "(0, " + h + "px, 0)"
3526 , top: !_GPU ? h : ""
3527 , borderColor: "transparent " + HUEContrast
3528 };
3529 _$alpha._css = {
3530 backgroundColor: "rgb(" + RGBInnerText + ")"
3531 };
3532 _$alpha_cursor._css = {
3533 transform: translate3d + "(" + a + "px, 0, 0)"
3534 , left: !_GPU ? a : ""
3535 , borderColor: alphaContrast + " transparent"
3536 };
3537 _$trigger._css = {
3538 backgroundColor: hasNoValue ? "" : text
3539 , color: hasNoValue ? "" : colors.rgbaMixBGMixCustom.luminance > .22 ? dark : light
3540 };
3541 _$trigger.text = hasNoValue ? "" : triggerValue !== text ? text : "";
3542 toggled !== undefined ? render( toggled ) : _animate( render )
3543 }
3544
3545 function render( toggled ) {
3546 _$xy_slider.css( _$xy_slider._css );
3547 _$xy_cursor.css( _$xy_cursor._css );
3548 _$z_cursor.css( _$z_cursor._css );
3549 _$alpha.css( _$alpha._css );
3550 _$alpha_cursor.css( _$alpha_cursor._css );
3551 _options.doRender && _$trigger.css( _$trigger._css );
3552 _$trigger.text && _$trigger.val( _$trigger.text );
3553 _options.renderCallback.call( _colorPicker, _$trigger, typeof toggled === "boolean" ? toggled : undefined )
3554 }
3555 $.fn.colorPicker = function( options ) {
3556 var noop = function() {};
3557 options = $.extend( {
3558 animationSpeed: 150
3559 , GPU: true
3560 , doRender: true
3561 , customBG: "#FFF"
3562 , opacity: true
3563 , renderCallback: noop
3564 , buildCallback: noop
3565 , body: document.body
3566 , scrollResize: true
3567 , gap: 4
3568 }, options );
3569 !_colorPicker && options.scrollResize && $( window )
3570 .on( "resize.a scroll.a", function() {
3571 if ( _colorPicker.$trigger ) {
3572 _colorPicker.toggle.call( _colorPicker.$trigger[ 0 ], true )
3573 }
3574 } );
3575 _instance = _instance ? _instance.add( this ) : this;
3576 _instance.colorPicker = _colorPicker || ( _colorPicker = new ColorPicker( options ) );
3577 _selector += ( _selector ? ", " : "" ) + this.selector;
3578 $( options.body )
3579 .off( ".a" )
3580 .on( _pointerdown, function( e ) {
3581 var $target = $( e.target );
3582 if ( $.inArray( $target.closest( _selector )[ 0 ], _instance ) === -1 && !$target.closest( _$UI )
3583 .length ) {
3584 toggle()
3585 }
3586 } )
3587 .on( "focus.a click.a", _selector, toggle )
3588 .on( "change.a", _selector, function() {
3589 _color.setColor( this.value || "#FFF" );
3590 _instance.colorPicker.render( true )
3591 } );
3592 return this.each( function() {
3593 var value = extractValue( this )
3594 , mode = value.split( "(" )
3595 , $elm = findElement( $( this ) );
3596 $elm.data( "colorMode", mode[ 1 ] ? mode[ 0 ].substr( 0, 3 ) : "HEX" )
3597 .attr( "readonly", _options.preventFocus );
3598 options.doRender && $elm.css( {
3599 "background-color": value
3600 , color: function() {
3601 return _color.setColor( value )
3602 .rgbaMixBGMixCustom.luminance > .22 ? "#222" : "#ddd"
3603 }
3604 } )
3605 } )
3606 };
3607 $.fn.colorPicker.destroy = function() {
3608 $( _colorPicker.color.options.body )
3609 .off( ".a" );
3610 _colorPicker.toggle( false );
3611 _instance = null;
3612 _selector = ""
3613 }
3614 }
3615 }, {} ]
3616 , 4: [ function( require, module, exports ) {
3617 module.exports = function( $ ) {
3618 function isRGBACapable() {
3619 var $script = $( "script:first" )
3620 , color = $script.css( "color" )
3621 , result = false;
3622 if ( /^rgba/.test( color ) ) {
3623 result = true
3624 } else {
3625 try {
3626 result = color != $script.css( "color", "rgba(0, 0, 0, 0.5)" )
3627 .css( "color" );
3628 $script.css( "color", color )
3629 } catch ( e ) {}
3630 }
3631 return result
3632 }
3633 $.extend( true, $, {
3634 support: {
3635 rgba: isRGBACapable()
3636 }
3637 } );
3638 var properties = [ "color", "backgroundColor", "borderBottomColor", "borderLeftColor", "borderRightColor", "borderTopColor", "outlineColor" ];
3639 $.each( properties, function( i, property ) {
3640 $.Tween.propHooks[ property ] = {
3641 get: function( tween ) {
3642 return $( tween.elem )
3643 .css( property )
3644 }
3645 , set: function( tween ) {
3646 var style = tween.elem.style;
3647 var p_begin = parseColor( $( tween.elem )
3648 .css( property ) );
3649 var p_end = parseColor( tween.end );
3650 tween.run = function( progress ) {
3651 style[ property ] = calculateColor( p_begin, p_end, progress )
3652 }
3653 }
3654 }
3655 } );
3656 $.Tween.propHooks.borderColor = {
3657 set: function( tween ) {
3658 var style = tween.elem.style;
3659 var p_begin = [];
3660 var borders = properties.slice( 2, 6 );
3661 $.each( borders, function( i, property ) {
3662 p_begin[ property ] = parseColor( $( tween.elem )
3663 .css( property ) )
3664 } );
3665 var p_end = parseColor( tween.end );
3666 tween.run = function( progress ) {
3667 $.each( borders, function( i, property ) {
3668 style[ property ] = calculateColor( p_begin[ property ], p_end, progress )
3669 } )
3670 }
3671 }
3672 };
3673
3674 function calculateColor( begin, end, pos ) {
3675 var color = "rgb" + ( $.support[ "rgba" ] ? "a" : "" ) + "(" + parseInt( begin[ 0 ] + pos * ( end[ 0 ] - begin[ 0 ] ), 10 ) + "," + parseInt( begin[ 1 ] + pos * ( end[ 1 ] - begin[ 1 ] ), 10 ) + "," + parseInt( begin[ 2 ] + pos * ( end[ 2 ] - begin[ 2 ] ), 10 );
3676 if ( $.support[ "rgba" ] ) {
3677 color += "," + ( begin && end ? parseFloat( begin[ 3 ] + pos * ( end[ 3 ] - begin[ 3 ] ) ) : 1 )
3678 }
3679 color += ")";
3680 return color
3681 }
3682
3683 function parseColor( color ) {
3684 var match, triplet;
3685 if ( match = /#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/.exec( color ) ) {
3686 triplet = [ parseInt( match[ 1 ], 16 ), parseInt( match[ 2 ], 16 ), parseInt( match[ 3 ], 16 ), 1 ]
3687 } else if ( match = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/.exec( color ) ) {
3688 triplet = [ parseInt( match[ 1 ], 16 ) * 17, parseInt( match[ 2 ], 16 ) * 17, parseInt( match[ 3 ], 16 ) * 17, 1 ]
3689 } else if ( match = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec( color ) ) {
3690 triplet = [ parseInt( match[ 1 ] ), parseInt( match[ 2 ] ), parseInt( match[ 3 ] ), 1 ]
3691 } else if ( match = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9\.]*)\s*\)/.exec( color ) ) {
3692 triplet = [ parseInt( match[ 1 ], 10 ), parseInt( match[ 2 ], 10 ), parseInt( match[ 3 ], 10 ), parseFloat( match[ 4 ] ) ]
3693 }
3694 return triplet
3695 }
3696 }
3697 }, {} ]
3698 , 5: [ function( require, module, exports ) {
3699 module.exports = function( window, document, $, undefined ) {
3700 "use strict";
3701 var W = $( window )
3702 , D = $( document )
3703 , F = $.fancybox = function() {
3704 F.open.apply( this, arguments )
3705 }
3706 , IE = navigator.userAgent.match( /msie/ )
3707 , didUpdate = null
3708 , isTouch = document.createTouch !== undefined
3709 , isQuery = function( obj ) {
3710 return obj && obj.hasOwnProperty && obj instanceof $
3711 }
3712 , isString = function( str ) {
3713 return str && $.type( str ) === "string"
3714 }
3715 , isPercentage = function( str ) {
3716 return isString( str ) && str.indexOf( "%" ) > 0
3717 }
3718 , isScrollable = function( el ) {
3719 return el && !( el.style.overflow && el.style.overflow === "hidden" ) && ( el.clientWidth && el.scrollWidth > el.clientWidth || el.clientHeight && el.scrollHeight > el.clientHeight )
3720 }
3721 , getScalar = function( orig, dim ) {
3722 var value = parseInt( orig, 10 ) || 0;
3723 if ( dim && isPercentage( orig ) ) {
3724 value = F.getViewport()[ dim ] / 100 * value
3725 }
3726 return Math.ceil( value )
3727 }
3728 , getValue = function( value, dim ) {
3729 return getScalar( value, dim ) + "px"
3730 };
3731 $.extend( F, {
3732 version: "2.1.4"
3733 , defaults: {
3734 padding: 15
3735 , margin: 20
3736 , width: 800
3737 , height: 600
3738 , minWidth: 100
3739 , minHeight: 100
3740 , maxWidth: 9999
3741 , maxHeight: 9999
3742 , autoSize: true
3743 , autoHeight: false
3744 , autoWidth: false
3745 , autoResize: true
3746 , autoCenter: !isTouch
3747 , fitToView: true
3748 , aspectRatio: false
3749 , topRatio: .5
3750 , leftRatio: .5
3751 , scrolling: "auto"
3752 , wrapCSS: ""
3753 , arrows: true
3754 , closeBtn: true
3755 , closeClick: false
3756 , nextClick: false
3757 , mouseWheel: true
3758 , autoPlay: false
3759 , playSpeed: 3e3
3760 , preload: 3
3761 , modal: false
3762 , loop: true
3763 , ajax: {
3764 dataType: "html"
3765 , headers: {
3766 "X-fancyBox": true
3767 }
3768 }
3769 , iframe: {
3770 scrolling: "auto"
3771 , preload: true
3772 }
3773 , swf: {
3774 wmode: "transparent"
3775 , allowfullscreen: "true"
3776 , allowscriptaccess: "always"
3777 }
3778 , keys: {
3779 next: {
3780 13: "left"
3781 , 34: "up"
3782 , 39: "left"
3783 , 40: "up"
3784 }
3785 , prev: {
3786 8: "right"
3787 , 33: "down"
3788 , 37: "right"
3789 , 38: "down"
3790 }
3791 , close: [ 27 ]
3792 , play: [ 32 ]
3793 , toggle: [ 70 ]
3794 }
3795 , direction: {
3796 next: "left"
3797 , prev: "right"
3798 }
3799 , scrollOutside: true
3800 , index: 0
3801 , type: null
3802 , href: null
3803 , content: null
3804 , title: null
3805 , tpl: {
3806 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'
3807 , image: '<img class="fancybox-image" src="{href}" alt="" />'
3808 , iframe: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + ( IE ? ' allowtransparency="true"' : "" ) + "></iframe>"
3809 , error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>'
3810 , closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>'
3811 , next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>'
3812 , prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
3813 }
3814 , openEffect: "fade"
3815 , openSpeed: 250
3816 , openEasing: "swing"
3817 , openOpacity: true
3818 , openMethod: "zoomIn"
3819 , closeEffect: "fade"
3820 , closeSpeed: 250
3821 , closeEasing: "swing"
3822 , closeOpacity: true
3823 , closeMethod: "zoomOut"
3824 , nextEffect: "elastic"
3825 , nextSpeed: 250
3826 , nextEasing: "swing"
3827 , nextMethod: "changeIn"
3828 , prevEffect: "elastic"
3829 , prevSpeed: 250
3830 , prevEasing: "swing"
3831 , prevMethod: "changeOut"
3832 , helpers: {
3833 overlay: true
3834 , title: true
3835 }
3836 , onCancel: $.noop
3837 , beforeLoad: $.noop
3838 , afterLoad: $.noop
3839 , beforeShow: $.noop
3840 , afterShow: $.noop
3841 , beforeChange: $.noop
3842 , beforeClose: $.noop
3843 , afterClose: $.noop
3844 }
3845 , group: {}
3846 , opts: {}
3847 , previous: null
3848 , coming: null
3849 , current: null
3850 , isActive: false
3851 , isOpen: false
3852 , isOpened: false
3853 , wrap: null
3854 , skin: null
3855 , outer: null
3856 , inner: null
3857 , player: {
3858 timer: null
3859 , isActive: false
3860 }
3861 , ajaxLoad: null
3862 , imgPreload: null
3863 , transitions: {}
3864 , helpers: {}
3865 , open: function( group, opts ) {
3866 if ( !group ) {
3867 return
3868 }
3869 if ( !$.isPlainObject( opts ) ) {
3870 opts = {}
3871 }
3872 if ( false === F.close( true ) ) {
3873 return
3874 }
3875 if ( !$.isArray( group ) ) {
3876 group = isQuery( group ) ? $( group )
3877 .get() : [ group ]
3878 }
3879 $.each( group, function( i, element ) {
3880 var obj = {}
3881 , href, title, content, type, rez, hrefParts, selector;
3882 if ( $.type( element ) === "object" ) {
3883 if ( element.nodeType ) {
3884 element = $( element )
3885 }
3886 if ( isQuery( element ) ) {
3887 obj = {
3888 href: element.data( "fancybox-href" ) || element.attr( "href" )
3889 , title: element.data( "fancybox-title" ) || element.attr( "title" )
3890 , isDom: true
3891 , element: element
3892 };
3893 if ( $.metadata ) {
3894 $.extend( true, obj, element.metadata() )
3895 }
3896 } else {
3897 obj = element
3898 }
3899 }
3900 href = opts.href || obj.href || ( isString( element ) ? element : null );
3901 title = opts.title !== undefined ? opts.title : obj.title || "";
3902 content = opts.content || obj.content;
3903 type = content ? "html" : opts.type || obj.type;
3904 if ( !type && obj.isDom ) {
3905 type = element.data( "fancybox-type" );
3906 if ( !type ) {
3907 rez = element.prop( "class" )
3908 .match( /fancybox\.(\w+)/ );
3909 type = rez ? rez[ 1 ] : null
3910 }
3911 }
3912 if ( isString( href ) ) {
3913 if ( !type ) {
3914 if ( F.isImage( href ) ) {
3915 type = "image"
3916 } else if ( F.isSWF( href ) ) {
3917 type = "swf"
3918 } else if ( href.charAt( 0 ) === "#" ) {
3919 type = "inline"
3920 } else if ( isString( element ) ) {
3921 type = "html";
3922 content = element
3923 }
3924 }
3925 if ( type === "ajax" ) {
3926 hrefParts = href.split( /\s+/, 2 );
3927 href = hrefParts.shift();
3928 selector = hrefParts.shift()
3929 }
3930 }
3931 if ( !content ) {
3932 if ( type === "inline" ) {
3933 if ( href ) {
3934 content = $( isString( href ) ? href.replace( /.*(?=#[^\s]+$)/, "" ) : href )
3935 } else if ( obj.isDom ) {
3936 content = element
3937 }
3938 } else if ( type === "html" ) {
3939 content = href
3940 } else if ( !type && !href && obj.isDom ) {
3941 type = "inline";
3942 content = element
3943 }
3944 }
3945 $.extend( obj, {
3946 href: href
3947 , type: type
3948 , content: content
3949 , title: title
3950 , selector: selector
3951 } );
3952 group[ i ] = obj
3953 } );
3954 F.opts = $.extend( true, {}, F.defaults, opts );
3955 if ( opts.keys !== undefined ) {
3956 F.opts.keys = opts.keys ? $.extend( {}, F.defaults.keys, opts.keys ) : false
3957 }
3958 F.group = group;
3959 return F._start( F.opts.index )
3960 }
3961 , cancel: function() {
3962 var coming = F.coming;
3963 if ( !coming || false === F.trigger( "onCancel" ) ) {
3964 return
3965 }
3966 F.hideLoading();
3967 if ( F.ajaxLoad ) {
3968 F.ajaxLoad.abort()
3969 }
3970 F.ajaxLoad = null;
3971 if ( F.imgPreload ) {
3972 F.imgPreload.onload = F.imgPreload.onerror = null
3973 }
3974 if ( coming.wrap ) {
3975 coming.wrap.stop( true, true )
3976 .trigger( "onReset" )
3977 .remove()
3978 }
3979 F.coming = null;
3980 if ( !F.current ) {
3981 F._afterZoomOut( coming )
3982 }
3983 }
3984 , close: function( event ) {
3985 F.cancel();
3986 if ( false === F.trigger( "beforeClose" ) ) {
3987 return
3988 }
3989 F.unbindEvents();
3990 if ( !F.isActive ) {
3991 return
3992 }
3993 if ( !F.isOpen || event === true ) {
3994 $( ".fancybox-wrap" )
3995 .stop( true )
3996 .trigger( "onReset" )
3997 .remove();
3998 F._afterZoomOut()
3999 } else {
4000 F.isOpen = F.isOpened = false;
4001 F.isClosing = true;
4002 $( ".fancybox-item, .fancybox-nav" )
4003 .remove();
4004 F.wrap.stop( true, true )
4005 .removeClass( "fancybox-opened" );
4006 F.transitions[ F.current.closeMethod ]()
4007 }
4008 }
4009 , play: function( action ) {
4010 var clear = function() {
4011 clearTimeout( F.player.timer )
4012 }
4013 , set = function() {
4014 clear();
4015 if ( F.current && F.player.isActive ) {
4016 F.player.timer = setTimeout( F.next, F.current.playSpeed )
4017 }
4018 }
4019 , stop = function() {
4020 clear();
4021 $( "body" )
4022 .unbind( ".player" );
4023 F.player.isActive = false;
4024 F.trigger( "onPlayEnd" )
4025 }
4026 , start = function() {
4027 if ( F.current && ( F.current.loop || F.current.index < F.group.length - 1 ) ) {
4028 F.player.isActive = true;
4029 $( "body" )
4030 .bind( {
4031 "afterShow.player onUpdate.player": set
4032 , "onCancel.player beforeClose.player": stop
4033 , "beforeLoad.player": clear
4034 } );
4035 set();
4036 F.trigger( "onPlayStart" )
4037 }
4038 };
4039 if ( action === true || !F.player.isActive && action !== false ) {
4040 start()
4041 } else {
4042 stop()
4043 }
4044 }
4045 , next: function( direction ) {
4046 var current = F.current;
4047 if ( current ) {
4048 if ( !isString( direction ) ) {
4049 direction = current.direction.next
4050 }
4051 F.jumpto( current.index + 1, direction, "next" )
4052 }
4053 }
4054 , prev: function( direction ) {
4055 var current = F.current;
4056 if ( current ) {
4057 if ( !isString( direction ) ) {
4058 direction = current.direction.prev
4059 }
4060 F.jumpto( current.index - 1, direction, "prev" )
4061 }
4062 }
4063 , jumpto: function( index, direction, router ) {
4064 var current = F.current;
4065 if ( !current ) {
4066 return
4067 }
4068 index = getScalar( index );
4069 F.direction = direction || current.direction[ index >= current.index ? "next" : "prev" ];
4070 F.router = router || "jumpto";
4071 if ( current.loop ) {
4072 if ( index < 0 ) {
4073 index = current.group.length + index % current.group.length
4074 }
4075 index = index % current.group.length
4076 }
4077 if ( current.group[ index ] !== undefined ) {
4078 F.cancel();
4079 F._start( index )
4080 }
4081 }
4082 , reposition: function( e, onlyAbsolute ) {
4083 var current = F.current
4084 , wrap = current ? current.wrap : null
4085 , pos;
4086 if ( wrap ) {
4087 pos = F._getPosition( onlyAbsolute );
4088 if ( e && e.type === "scroll" ) {
4089 delete pos.position;
4090 wrap.stop( true, true )
4091 .animate( pos, 200 )
4092 } else {
4093 wrap.css( pos );
4094 current.pos = $.extend( {}, current.dim, pos )
4095 }
4096 }
4097 }
4098 , update: function( e ) {
4099 var type = e && e.type
4100 , anyway = !type || type === "orientationchange";
4101 if ( anyway ) {
4102 clearTimeout( didUpdate );
4103 didUpdate = null
4104 }
4105 if ( !F.isOpen || didUpdate ) {
4106 return
4107 }
4108 didUpdate = setTimeout( function() {
4109 var current = F.current;
4110 if ( !current || F.isClosing ) {
4111 return
4112 }
4113 F.wrap.removeClass( "fancybox-tmp" );
4114 if ( anyway || type === "load" || type === "resize" && current.autoResize ) {
4115 F._setDimension()
4116 }
4117 if ( !( type === "scroll" && current.canShrink ) ) {
4118 F.reposition( e )
4119 }
4120 F.trigger( "onUpdate" );
4121 didUpdate = null
4122 }, anyway && !isTouch ? 0 : 300 )
4123 }
4124 , toggle: function( action ) {
4125 if ( F.isOpen ) {
4126 F.current.fitToView = $.type( action ) === "boolean" ? action : !F.current.fitToView;
4127 if ( isTouch ) {
4128 F.wrap.removeAttr( "style" )
4129 .addClass( "fancybox-tmp" );
4130 F.trigger( "onUpdate" )
4131 }
4132 F.update()
4133 }
4134 }
4135 , hideLoading: function() {
4136 D.unbind( ".loading" );
4137 $( "#fancybox-loading" )
4138 .remove()
4139 }
4140 , showLoading: function() {
4141 var el, viewport;
4142 F.hideLoading();
4143 el = $( '<div id="fancybox-loading"><div></div></div>' )
4144 .click( F.cancel )
4145 .appendTo( "body" );
4146 D.bind( "keydown.loading", function( e ) {
4147 if ( ( e.which || e.keyCode ) === 27 ) {
4148 e.preventDefault();
4149 F.cancel()
4150 }
4151 } );
4152 if ( !F.defaults.fixed ) {
4153 viewport = F.getViewport();
4154 el.css( {
4155 position: "absolute"
4156 , top: viewport.h * .5 + viewport.y
4157 , left: viewport.w * .5 + viewport.x
4158 } )
4159 }
4160 }
4161 , getViewport: function() {
4162 var locked = F.current && F.current.locked || false
4163 , rez = {
4164 x: W.scrollLeft()
4165 , y: W.scrollTop()
4166 };
4167 if ( locked ) {
4168 rez.w = locked[ 0 ].clientWidth;
4169 rez.h = locked[ 0 ].clientHeight
4170 } else {
4171 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width();
4172 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height()
4173 }
4174 return rez
4175 }
4176 , unbindEvents: function() {
4177 if ( F.wrap && isQuery( F.wrap ) ) {
4178 F.wrap.unbind( ".fb" )
4179 }
4180 D.unbind( ".fb" );
4181 W.unbind( ".fb" )
4182 }
4183 , bindEvents: function() {
4184 var current = F.current
4185 , keys;
4186 if ( !current ) {
4187 return
4188 }
4189 W.bind( "orientationchange.fb" + ( isTouch ? "" : " resize.fb" ) + ( current.autoCenter && !current.locked ? " scroll.fb" : "" ), F.update );
4190 keys = current.keys;
4191 if ( keys ) {
4192 D.bind( "keydown.fb", function( e ) {
4193 var code = e.which || e.keyCode
4194 , target = e.target || e.srcElement;
4195 if ( code === 27 && F.coming ) {
4196 return false
4197 }
4198 if ( !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !( target && ( target.type || $( target )
4199 .is( "[contenteditable]" ) ) ) ) {
4200 $.each( keys, function( i, val ) {
4201 if ( current.group.length > 1 && val[ code ] !== undefined ) {
4202 F[ i ]( val[ code ] );
4203 e.preventDefault();
4204 return false
4205 }
4206 if ( $.inArray( code, val ) > -1 ) {
4207 F[ i ]();
4208 e.preventDefault();
4209 return false
4210 }
4211 } )
4212 }
4213 } )
4214 }
4215 if ( $.fn.mousewheel && current.mouseWheel ) {
4216 F.wrap.bind( "mousewheel.fb", function( e, delta, deltaX, deltaY ) {
4217 var target = e.target || null
4218 , parent = $( target )
4219 , canScroll = false;
4220 while ( parent.length ) {
4221 if ( canScroll || parent.is( ".fancybox-skin" ) || parent.is( ".fancybox-wrap" ) ) {
4222 break
4223 }
4224 canScroll = isScrollable( parent[ 0 ] );
4225 parent = $( parent )
4226 .parent()
4227 }
4228 if ( delta !== 0 && !canScroll ) {
4229 if ( F.group.length > 1 && !current.canShrink ) {
4230 if ( deltaY > 0 || deltaX > 0 ) {
4231 F.prev( deltaY > 0 ? "down" : "left" )
4232 } else if ( deltaY < 0 || deltaX < 0 ) {
4233 F.next( deltaY < 0 ? "up" : "right" )
4234 }
4235 e.preventDefault()
4236 }
4237 }
4238 } )
4239 }
4240 }
4241 , trigger: function( event, o ) {
4242 var ret, obj = o || F.coming || F.current;
4243 if ( !obj ) {
4244 return
4245 }
4246 if ( $.isFunction( obj[ event ] ) ) {
4247 ret = obj[ event ].apply( obj, Array.prototype.slice.call( arguments, 1 ) )
4248 }
4249 if ( ret === false ) {
4250 return false
4251 }
4252 if ( obj.helpers ) {
4253 $.each( obj.helpers, function( helper, opts ) {
4254 if ( opts && F.helpers[ helper ] && $.isFunction( F.helpers[ helper ][ event ] ) ) {
4255 opts = $.extend( true, {}, F.helpers[ helper ].defaults, opts );
4256 F.helpers[ helper ][ event ]( opts, obj )
4257 }
4258 } )
4259 }
4260 $.event.trigger( event + ".fb" )
4261 }
4262 , isImage: function( str ) {
4263 return isString( str ) && str.match( /(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i )
4264 }
4265 , isSWF: function( str ) {
4266 return isString( str ) && str.match( /\.(swf)((\?|#).*)?$/i )
4267 }
4268 , _start: function( index ) {
4269 var coming = {}
4270 , obj, href, type, margin, padding;
4271 index = getScalar( index );
4272 obj = F.group[ index ] || null;
4273 if ( !obj ) {
4274 return false
4275 }
4276 coming = $.extend( true, {}, F.opts, obj );
4277 margin = coming.margin;
4278 padding = coming.padding;
4279 if ( $.type( margin ) === "number" ) {
4280 coming.margin = [ margin, margin, margin, margin ]
4281 }
4282 if ( $.type( padding ) === "number" ) {
4283 coming.padding = [ padding, padding, padding, padding ]
4284 }
4285 if ( coming.modal ) {
4286 $.extend( true, coming, {
4287 closeBtn: false
4288 , closeClick: false
4289 , nextClick: false
4290 , arrows: false
4291 , mouseWheel: false
4292 , keys: null
4293 , helpers: {
4294 overlay: {
4295 closeClick: false
4296 }
4297 }
4298 } )
4299 }
4300 if ( coming.autoSize ) {
4301 coming.autoWidth = coming.autoHeight = true
4302 }
4303 if ( coming.width === "auto" ) {
4304 coming.autoWidth = true
4305 }
4306 if ( coming.height === "auto" ) {
4307 coming.autoHeight = true
4308 }
4309 coming.group = F.group;
4310 coming.index = index;
4311 F.coming = coming;
4312 if ( false === F.trigger( "beforeLoad" ) ) {
4313 F.coming = null;
4314 return;
4315 }
4316 type = coming.type;
4317 href = coming.href;
4318 if ( !type ) {
4319 F.coming = null;
4320 if ( F.current && F.router && F.router !== "jumpto" ) {
4321 F.current.index = index;
4322 return F[ F.router ]( F.direction )
4323 }
4324 return false
4325 }
4326 F.isActive = true;
4327 if ( type === "image" || type === "swf" ) {
4328 coming.autoHeight = coming.autoWidth = false;
4329 coming.scrolling = "visible"
4330 }
4331 if ( type === "image" ) {
4332 coming.aspectRatio = true
4333 }
4334 if ( type === "iframe" && isTouch ) {
4335 coming.scrolling = "scroll"
4336 }
4337 coming.wrap = $( coming.tpl.wrap )
4338 .addClass( "fancybox-" + ( isTouch ? "mobile" : "desktop" ) + " fancybox-type-" + type + " fancybox-tmp " + coming.wrapCSS )
4339 .appendTo( coming.parent || "body" );
4340 $.extend( coming, {
4341 skin: $( ".fancybox-skin", coming.wrap )
4342 , outer: $( ".fancybox-outer", coming.wrap )
4343 , inner: $( ".fancybox-inner", coming.wrap )
4344 } );
4345 $.each( [ "Top", "Right", "Bottom", "Left" ], function( i, v ) {
4346 coming.skin.css( "padding" + v, getValue( coming.padding[ i ] ) )
4347 } );
4348 F.trigger( "onReady" );
4349 if ( type === "inline" || type === "html" ) {
4350 if ( !coming.content || !coming.content.length ) {
4351 return F._error( "content" )
4352 }
4353 } else if ( !href ) {
4354 return F._error( "href" )
4355 }
4356 if ( type === "image" ) {
4357 F._loadImage()
4358 } else if ( type === "ajax" ) {
4359 F._loadAjax()
4360 } else if ( type === "iframe" ) {
4361 F._loadIframe()
4362 } else {
4363 F._afterLoad()
4364 }
4365 }
4366 , _error: function( type ) {
4367 $.extend( F.coming, {
4368 type: "html"
4369 , autoWidth: true
4370 , autoHeight: true
4371 , minWidth: 0
4372 , minHeight: 0
4373 , scrolling: "no"
4374 , hasError: type
4375 , content: F.coming.tpl.error
4376 } );
4377 F._afterLoad()
4378 }
4379 , _loadImage: function() {
4380 var img = F.imgPreload = new Image;
4381 img.onload = function() {
4382 this.onload = this.onerror = null;
4383 F.coming.width = this.width;
4384 F.coming.height = this.height;
4385 F._afterLoad()
4386 };
4387 img.onerror = function() {
4388 this.onload = this.onerror = null;
4389 F._error( "image" )
4390 };
4391 img.src = F.coming.href;
4392 if ( img.complete !== true ) {
4393 F.showLoading()
4394 }
4395 }
4396 , _loadAjax: function() {
4397 var coming = F.coming;
4398 F.showLoading();
4399 F.ajaxLoad = $.ajax( $.extend( {}, coming.ajax, {
4400 url: coming.href
4401 , error: function( jqXHR, textStatus ) {
4402 if ( F.coming && textStatus !== "abort" ) {
4403 F._error( "ajax", jqXHR )
4404 } else {
4405 F.hideLoading()
4406 }
4407 }
4408 , success: function( data, textStatus ) {
4409 if ( textStatus === "success" ) {
4410 coming.content = data;
4411 F._afterLoad()
4412 }
4413 }
4414 } ) )
4415 }
4416 , _loadIframe: function() {
4417 var coming = F.coming
4418 , iframe = $( coming.tpl.iframe.replace( /\{rnd\}/g, ( new Date )
4419 .getTime() ) )
4420 .attr( "scrolling", isTouch ? "auto" : coming.iframe.scrolling )
4421 .attr( "src", coming.href );
4422 $( coming.wrap )
4423 .bind( "onReset", function() {
4424 try {
4425 $( this )
4426 .find( "iframe" )
4427 .hide()
4428 .attr( "src", "//about:blank" )
4429 .end()
4430 .empty()
4431 } catch ( e ) {}
4432 } );
4433 if ( coming.iframe.preload ) {
4434 F.showLoading();
4435 iframe.one( "load", function() {
4436 $( this )
4437 .data( "ready", 1 );
4438 if ( !isTouch ) {
4439 $( this )
4440 .bind( "load.fb", F.update )
4441 }
4442 $( this )
4443 .parents( ".fancybox-wrap" )
4444 .width( "100%" )
4445 .removeClass( "fancybox-tmp" )
4446 .show();
4447 F._afterLoad()
4448 } )
4449 }
4450 coming.content = iframe.appendTo( coming.inner );
4451 if ( !coming.iframe.preload ) {
4452 F._afterLoad()
4453 }
4454 }
4455 , _preloadImages: function() {
4456 var group = F.group
4457 , current = F.current
4458 , len = group.length
4459 , cnt = current.preload ? Math.min( current.preload, len - 1 ) : 0
4460 , item, i;
4461 for ( i = 1; i <= cnt; i += 1 ) {
4462 item = group[ ( current.index + i ) % len ];
4463 if ( item.type === "image" && item.href ) {
4464 ( new Image )
4465 .src = item.href
4466 }
4467 }
4468 }
4469 , _afterLoad: function() {
4470 var coming = F.coming
4471 , previous = F.current
4472 , placeholder = "fancybox-placeholder"
4473 , current, content, type, scrolling, href, embed;
4474 F.hideLoading();
4475 if ( !coming || F.isActive === false ) {
4476 return
4477 }
4478 if ( false === F.trigger( "afterLoad", coming, previous ) ) {
4479 coming.wrap.stop( true )
4480 .trigger( "onReset" )
4481 .remove();
4482 F.coming = null;
4483 return
4484 }
4485 if ( previous ) {
4486 F.trigger( "beforeChange", previous );
4487 previous.wrap.stop( true )
4488 .removeClass( "fancybox-opened" )
4489 .find( ".fancybox-item, .fancybox-nav" )
4490 .remove()
4491 }
4492 F.unbindEvents();
4493 current = coming;
4494 content = coming.content;
4495 type = coming.type;
4496 scrolling = coming.scrolling;
4497 $.extend( F, {
4498 wrap: current.wrap
4499 , skin: current.skin
4500 , outer: current.outer
4501 , inner: current.inner
4502 , current: current
4503 , previous: previous
4504 } );
4505 href = current.href;
4506 switch ( type ) {
4507 case "inline":
4508 case "ajax":
4509 case "html":
4510 if ( current.selector ) {
4511 content = $( "<div>" )
4512 .html( content )
4513 .find( current.selector )
4514 } else if ( isQuery( content ) ) {
4515 if ( !content.data( placeholder ) ) {
4516 content.data( placeholder, $( '<div class="' + placeholder + '"></div>' )
4517 .insertAfter( content )
4518 .hide() )
4519 }
4520 content = content.show()
4521 .detach();
4522 current.wrap.bind( "onReset", function() {
4523 if ( $( this )
4524 .find( content )
4525 .length ) {
4526 content.hide()
4527 .replaceAll( content.data( placeholder ) )
4528 .data( placeholder, false )
4529 }
4530 } )
4531 }
4532 break;
4533 case "image":
4534 content = current.tpl.image.replace( "{href}", href );
4535 break;
4536 case "swf":
4537 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
4538 embed = "";
4539 $.each( current.swf, function( name, val ) {
4540 content += '<param name="' + name + '" value="' + val + '"></param>';
4541 embed += " " + name + '="' + val + '"'
4542 } );
4543 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + "></embed></object>";
4544 break
4545 }
4546 if ( !( isQuery( content ) && content.parent()
4547 .is( current.inner ) ) ) {
4548 current.inner.append( content )
4549 }
4550 F.trigger( "beforeShow" );
4551 current.inner.css( "overflow", scrolling === "yes" ? "scroll" : scrolling === "no" ? "hidden" : scrolling );
4552 F._setDimension();
4553 F.reposition();
4554 F.isOpen = false;
4555 F.coming = null;
4556 F.bindEvents();
4557 if ( !F.isOpened ) {
4558 $( ".fancybox-wrap" )
4559 .not( current.wrap )
4560 .stop( true )
4561 .trigger( "onReset" )
4562 .remove()
4563 } else if ( previous.prevMethod ) {
4564 F.transitions[ previous.prevMethod ]()
4565 }
4566 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
4567 F._preloadImages()
4568 }
4569 , _setDimension: function() {
4570 var viewport = F.getViewport()
4571 , steps = 0
4572 , canShrink = false
4573 , canExpand = false
4574 , wrap = F.wrap
4575 , skin = F.skin
4576 , inner = F.inner
4577 , current = F.current
4578 , width = current.width
4579 , height = current.height
4580 , minWidth = current.minWidth
4581 , minHeight = current.minHeight
4582 , maxWidth = current.maxWidth
4583 , maxHeight = current.maxHeight
4584 , scrolling = current.scrolling
4585 , scrollOut = current.scrollOutside ? current.scrollbarWidth : 0
4586 , margin = current.margin
4587 , wMargin = getScalar( margin[ 1 ] + margin[ 3 ] )
4588 , hMargin = getScalar( margin[ 0 ] + margin[ 2 ] )
4589 , wPadding, hPadding, wSpace, hSpace, origWidth, origHeight, origMaxWidth, origMaxHeight, ratio, width_, height_, maxWidth_, maxHeight_, iframe, body;
4590 wrap.add( skin )
4591 .add( inner )
4592 .width( "auto" )
4593 .height( "auto" )
4594 .removeClass( "fancybox-tmp" );
4595 wPadding = getScalar( skin.outerWidth( true ) - skin.width() );
4596 hPadding = getScalar( skin.outerHeight( true ) - skin.height() );
4597 wSpace = wMargin + wPadding;
4598 hSpace = hMargin + hPadding;
4599 origWidth = isPercentage( width ) ? ( viewport.w - wSpace ) * getScalar( width ) / 100 : width;
4600 origHeight = isPercentage( height ) ? ( viewport.h - hSpace ) * getScalar( height ) / 100 : height;
4601 if ( current.type === "iframe" ) {
4602 iframe = current.content;
4603 if ( current.autoHeight && iframe.data( "ready" ) === 1 ) {
4604 try {
4605 if ( iframe[ 0 ].contentWindow.document.location ) {
4606 inner.width( origWidth )
4607 .height( 9999 );
4608 body = iframe.contents()
4609 .find( "body" );
4610 if ( scrollOut ) {
4611 body.css( "overflow-x", "hidden" )
4612 }
4613 origHeight = body.height()
4614 }
4615 } catch ( e ) {}
4616 }
4617 } else if ( current.autoWidth || current.autoHeight ) {
4618 inner.addClass( "fancybox-tmp" );
4619 if ( !current.autoWidth ) {
4620 inner.width( origWidth )
4621 }
4622 if ( !current.autoHeight ) {
4623 inner.height( origHeight )
4624 }
4625 if ( current.autoWidth ) {
4626 origWidth = inner.width()
4627 }
4628 if ( current.autoHeight ) {
4629 origHeight = inner.height()
4630 }
4631 inner.removeClass( "fancybox-tmp" )
4632 }
4633 width = getScalar( origWidth );
4634 height = getScalar( origHeight );
4635 ratio = origWidth / origHeight;
4636 minWidth = getScalar( isPercentage( minWidth ) ? getScalar( minWidth, "w" ) - wSpace : minWidth );
4637 maxWidth = getScalar( isPercentage( maxWidth ) ? getScalar( maxWidth, "w" ) - wSpace : maxWidth );
4638 minHeight = getScalar( isPercentage( minHeight ) ? getScalar( minHeight, "h" ) - hSpace : minHeight );
4639 maxHeight = getScalar( isPercentage( maxHeight ) ? getScalar( maxHeight, "h" ) - hSpace : maxHeight );
4640 origMaxWidth = maxWidth;
4641 origMaxHeight = maxHeight;
4642 if ( current.fitToView ) {
4643 maxWidth = Math.min( viewport.w - wSpace, maxWidth );
4644 maxHeight = Math.min( viewport.h - hSpace, maxHeight )
4645 }
4646 maxWidth_ = viewport.w - wMargin;
4647 maxHeight_ = viewport.h - hMargin;
4648 if ( current.aspectRatio ) {
4649 if ( width > maxWidth ) {
4650 width = maxWidth;
4651 height = getScalar( width / ratio )
4652 }
4653 if ( height > maxHeight ) {
4654 height = maxHeight;
4655 width = getScalar( height * ratio )
4656 }
4657 if ( width < minWidth ) {
4658 width = minWidth;
4659 height = getScalar( width / ratio )
4660 }
4661 if ( height < minHeight ) {
4662 height = minHeight;
4663 width = getScalar( height * ratio )
4664 }
4665 } else {
4666 width = Math.max( minWidth, Math.min( width, maxWidth ) );
4667 if ( current.autoHeight && current.type !== "iframe" ) {
4668 inner.width( width );
4669 height = inner.height()
4670 }
4671 height = Math.max( minHeight, Math.min( height, maxHeight ) )
4672 }
4673 if ( current.fitToView ) {
4674 inner.width( width )
4675 .height( height );
4676 wrap.width( width + wPadding );
4677 width_ = wrap.width();
4678 height_ = wrap.height();
4679 if ( current.aspectRatio ) {
4680 while ( ( width_ > maxWidth_ || height_ > maxHeight_ ) && width > minWidth && height > minHeight ) {
4681 if ( steps++ > 19 ) {
4682 break
4683 }
4684 height = Math.max( minHeight, Math.min( maxHeight, height - 10 ) );
4685 width = getScalar( height * ratio );
4686 if ( width < minWidth ) {
4687 width = minWidth;
4688 height = getScalar( width / ratio )
4689 }
4690 if ( width > maxWidth ) {
4691 width = maxWidth;
4692 height = getScalar( width / ratio )
4693 }
4694 inner.width( width )
4695 .height( height );
4696 wrap.width( width + wPadding );
4697 width_ = wrap.width();
4698 height_ = wrap.height()
4699 }
4700 } else {
4701 width = Math.max( minWidth, Math.min( width, width - ( width_ - maxWidth_ ) ) );
4702 height = Math.max( minHeight, Math.min( height, height - ( height_ - maxHeight_ ) ) )
4703 }
4704 }
4705 if ( scrollOut && scrolling === "auto" && height < origHeight && width + wPadding + scrollOut < maxWidth_ ) {
4706 width += scrollOut
4707 }
4708 inner.width( width )
4709 .height( height );
4710 wrap.width( width + wPadding );
4711 width_ = wrap.width();
4712 height_ = wrap.height();
4713 canShrink = ( width_ > maxWidth_ || height_ > maxHeight_ ) && width > minWidth && height > minHeight;
4714 canExpand = current.aspectRatio ? width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight : ( width < origMaxWidth || height < origMaxHeight ) && ( width < origWidth || height < origHeight );
4715 $.extend( current, {
4716 dim: {
4717 width: getValue( width_ )
4718 , height: getValue( height_ )
4719 }
4720 , origWidth: origWidth
4721 , origHeight: origHeight
4722 , canShrink: canShrink
4723 , canExpand: canExpand
4724 , wPadding: wPadding
4725 , hPadding: hPadding
4726 , wrapSpace: height_ - skin.outerHeight( true )
4727 , skinSpace: skin.height() - height
4728 } );
4729 if ( !iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand ) {
4730 inner.height( "auto" )
4731 }
4732 }
4733 , _getPosition: function( onlyAbsolute ) {
4734 var current = F.current
4735 , viewport = F.getViewport()
4736 , margin = current.margin
4737 , width = F.wrap.width() + margin[ 1 ] + margin[ 3 ]
4738 , height = F.wrap.height() + margin[ 0 ] + margin[ 2 ]
4739 , rez = {
4740 position: "absolute"
4741 , top: margin[ 0 ]
4742 , left: margin[ 3 ]
4743 };
4744 if ( current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w ) {
4745 rez.position = "fixed"
4746 } else if ( !current.locked ) {
4747 rez.top += viewport.y;
4748 rez.left += viewport.x
4749 }
4750 rez.top = getValue( Math.max( rez.top, rez.top + ( viewport.h - height ) * current.topRatio ) );
4751 rez.left = getValue( Math.max( rez.left, rez.left + ( viewport.w - width ) * current.leftRatio ) );
4752 return rez
4753 }
4754 , _afterZoomIn: function() {
4755 var current = F.current;
4756 if ( !current ) {
4757 return
4758 }
4759 F.isOpen = F.isOpened = true;
4760 F.wrap.css( "overflow", "visible" )
4761 .addClass( "fancybox-opened" );
4762 F.update();
4763 if ( current.closeClick || current.nextClick && F.group.length > 1 ) {
4764 F.inner.css( "cursor", "pointer" )
4765 .bind( "click.fb", function( e ) {
4766 if ( !$( e.target )
4767 .is( "a" ) && !$( e.target )
4768 .parent()
4769 .is( "a" ) ) {
4770 e.preventDefault();
4771 F[ current.closeClick ? "close" : "next" ]()
4772 }
4773 } )
4774 }
4775 if ( current.closeBtn ) {
4776 $( current.tpl.closeBtn )
4777 .appendTo( F.skin )
4778 .bind( "click.fb", function( e ) {
4779 e.preventDefault();
4780 F.close()
4781 } )
4782 }
4783 if ( current.arrows && F.group.length > 1 ) {
4784 if ( current.loop || current.index > 0 ) {
4785 $( current.tpl.prev )
4786 .appendTo( F.outer )
4787 .bind( "click.fb", F.prev )
4788 }
4789 if ( current.loop || current.index < F.group.length - 1 ) {
4790 $( current.tpl.next )
4791 .appendTo( F.outer )
4792 .bind( "click.fb", F.next )
4793 }
4794 }
4795 F.trigger( "afterShow" );
4796 if ( !current.loop && current.index === current.group.length - 1 ) {
4797 F.play( false )
4798 } else if ( F.opts.autoPlay && !F.player.isActive ) {
4799 F.opts.autoPlay = false;
4800 F.play()
4801 }
4802 }
4803 , _afterZoomOut: function( obj ) {
4804 obj = obj || F.current;
4805 $( ".fancybox-wrap" )
4806 .trigger( "onReset" )
4807 .remove();
4808 $.extend( F, {
4809 group: {}
4810 , opts: {}
4811 , router: false
4812 , current: null
4813 , isActive: false
4814 , isOpened: false
4815 , isOpen: false
4816 , isClosing: false
4817 , wrap: null
4818 , skin: null
4819 , outer: null
4820 , inner: null
4821 } );
4822 F.trigger( "afterClose", obj )
4823 }
4824 } );
4825 F.transitions = {
4826 getOrigPosition: function() {
4827 var current = F.current
4828 , element = current.element
4829 , orig = current.orig
4830 , pos = {}
4831 , width = 50
4832 , height = 50
4833 , hPadding = current.hPadding
4834 , wPadding = current.wPadding
4835 , viewport = F.getViewport();
4836 if ( !orig && current.isDom && element.is( ":visible" ) ) {
4837 orig = element.find( "img:first" );
4838 if ( !orig.length ) {
4839 orig = element
4840 }
4841 }
4842 if ( isQuery( orig ) ) {
4843 pos = orig.offset();
4844 if ( orig.is( "img" ) ) {
4845 width = orig.outerWidth();
4846 height = orig.outerHeight()
4847 }
4848 } else {
4849 pos.top = viewport.y + ( viewport.h - height ) * current.topRatio;
4850 pos.left = viewport.x + ( viewport.w - width ) * current.leftRatio
4851 }
4852 if ( F.wrap.css( "position" ) === "fixed" || current.locked ) {
4853 pos.top -= viewport.y;
4854 pos.left -= viewport.x
4855 }
4856 pos = {
4857 top: getValue( pos.top - hPadding * current.topRatio )
4858 , left: getValue( pos.left - wPadding * current.leftRatio )
4859 , width: getValue( width + wPadding )
4860 , height: getValue( height + hPadding )
4861 };
4862 return pos
4863 }
4864 , step: function( now, fx ) {
4865 var ratio, padding, value, prop = fx.prop
4866 , current = F.current
4867 , wrapSpace = current.wrapSpace
4868 , skinSpace = current.skinSpace;
4869 if ( prop === "width" || prop === "height" ) {
4870 ratio = fx.end === fx.start ? 1 : ( now - fx.start ) / ( fx.end - fx.start );
4871 if ( F.isClosing ) {
4872 ratio = 1 - ratio
4873 }
4874 padding = prop === "width" ? current.wPadding : current.hPadding;
4875 value = now - padding;
4876 F.skin[ prop ]( getScalar( prop === "width" ? value : value - wrapSpace * ratio ) );
4877 F.inner[ prop ]( getScalar( prop === "width" ? value : value - wrapSpace * ratio - skinSpace * ratio ) )
4878 }
4879 }
4880 , zoomIn: function() {
4881 var current = F.current
4882 , startPos = current.pos
4883 , effect = current.openEffect
4884 , elastic = effect === "elastic"
4885 , endPos = $.extend( {
4886 opacity: 1
4887 }, startPos );
4888 delete endPos.position;
4889 if ( elastic ) {
4890 startPos = this.getOrigPosition();
4891 if ( current.openOpacity ) {
4892 startPos.opacity = .1
4893 }
4894 } else if ( effect === "fade" ) {
4895 startPos.opacity = .1
4896 }
4897 F.wrap.css( startPos )
4898 .animate( endPos, {
4899 duration: effect === "none" ? 0 : current.openSpeed
4900 , easing: current.openEasing
4901 , step: elastic ? this.step : null
4902 , complete: F._afterZoomIn
4903 } )
4904 }
4905 , zoomOut: function() {
4906 var current = F.current
4907 , effect = current.closeEffect
4908 , elastic = effect === "elastic"
4909 , endPos = {
4910 opacity: .1
4911 };
4912 if ( elastic ) {
4913 endPos = this.getOrigPosition();
4914 if ( current.closeOpacity ) {
4915 endPos.opacity = .1
4916 }
4917 }
4918 F.wrap.animate( endPos, {
4919 duration: effect === "none" ? 0 : current.closeSpeed
4920 , easing: current.closeEasing
4921 , step: elastic ? this.step : null
4922 , complete: F._afterZoomOut
4923 } )
4924 }
4925 , changeIn: function() {
4926 var current = F.current
4927 , effect = current.nextEffect
4928 , startPos = current.pos
4929 , endPos = {
4930 opacity: 1
4931 }
4932 , direction = F.direction
4933 , distance = 200
4934 , field;
4935 startPos.opacity = .1;
4936 if ( effect === "elastic" ) {
4937 field = direction === "down" || direction === "up" ? "top" : "left";
4938 if ( direction === "down" || direction === "right" ) {
4939 startPos[ field ] = getValue( getScalar( startPos[ field ] ) - distance );
4940 endPos[ field ] = "+=" + distance + "px"
4941 } else {
4942 startPos[ field ] = getValue( getScalar( startPos[ field ] ) + distance );
4943 endPos[ field ] = "-=" + distance + "px"
4944 }
4945 }
4946 if ( effect === "none" ) {
4947 F._afterZoomIn()
4948 } else {
4949 F.wrap.css( startPos )
4950 .animate( endPos, {
4951 duration: current.nextSpeed
4952 , easing: current.nextEasing
4953 , complete: F._afterZoomIn
4954 } )
4955 }
4956 }
4957 , changeOut: function() {
4958 var previous = F.previous
4959 , effect = previous.prevEffect
4960 , endPos = {
4961 opacity: .1
4962 }
4963 , direction = F.direction
4964 , distance = 200;
4965 if ( effect === "elastic" ) {
4966 endPos[ direction === "down" || direction === "up" ? "top" : "left" ] = ( direction === "up" || direction === "left" ? "-" : "+" ) + "=" + distance + "px"
4967 }
4968 previous.wrap.animate( endPos, {
4969 duration: effect === "none" ? 0 : previous.prevSpeed
4970 , easing: previous.prevEasing
4971 , complete: function() {
4972 $( this )
4973 .trigger( "onReset" )
4974 .remove()
4975 }
4976 } )
4977 }
4978 };
4979 F.helpers.overlay = {
4980 defaults: {
4981 closeClick: true
4982 , speedOut: 200
4983 , showEarly: true
4984 , css: {}
4985 , locked: !isTouch
4986 , fixed: true
4987 }
4988 , overlay: null
4989 , fixed: false
4990 , create: function( opts ) {
4991 opts = $.extend( {}, this.defaults, opts );
4992 if ( this.overlay ) {
4993 this.close()
4994 }
4995 this.overlay = $( '<div class="fancybox-overlay"></div>' )
4996 .appendTo( "body" );
4997 this.fixed = false;
4998 if ( opts.fixed && F.defaults.fixed ) {
4999 this.overlay.addClass( "fancybox-overlay-fixed" );
5000 this.fixed = true
5001 }
5002 }
5003 , open: function( opts ) {
5004 var that = this;
5005 opts = $.extend( {}, this.defaults, opts );
5006 if ( this.overlay ) {
5007 this.overlay.unbind( ".overlay" )
5008 .width( "auto" )
5009 .height( "auto" )
5010 } else {
5011 this.create( opts )
5012 }
5013 if ( !this.fixed ) {
5014 W.bind( "resize.overlay", $.proxy( this.update, this ) );
5015 this.update()
5016 }
5017 if ( opts.closeClick ) {
5018 this.overlay.bind( "click.overlay", function( e ) {
5019 if ( $( e.target )
5020 .hasClass( "fancybox-overlay" ) ) {
5021 if ( F.isActive ) {
5022 F.close()
5023 } else {
5024 that.close()
5025 }
5026 }
5027 } )
5028 }
5029 this.overlay.css( opts.css )
5030 .show()
5031 }
5032 , close: function() {
5033 $( ".fancybox-overlay" )
5034 .remove();
5035 W.unbind( "resize.overlay" );
5036 this.overlay = null;
5037 if ( this.margin !== false ) {
5038 $( "body" )
5039 .css( "margin-right", this.margin );
5040 this.margin = false
5041 }
5042 if ( this.el ) {
5043 this.el.removeClass( "fancybox-lock" )
5044 }
5045 }
5046 , update: function() {
5047 var width = "100%"
5048 , offsetWidth;
5049 this.overlay.width( width )
5050 .height( "100%" );
5051 if ( IE ) {
5052 offsetWidth = Math.max( document.documentElement.offsetWidth, document.body.offsetWidth );
5053 if ( D.width() > offsetWidth ) {
5054 width = D.width()
5055 }
5056 } else if ( D.width() > W.width() ) {
5057 width = D.width()
5058 }
5059 this.overlay.width( width )
5060 .height( D.height() )
5061 }
5062 , onReady: function( opts, obj ) {
5063 $( ".fancybox-overlay" )
5064 .stop( true, true );
5065 if ( !this.overlay ) {
5066 this.margin = D.height() > W.height() || $( "body" )
5067 .css( "overflow-y" ) === "scroll" ? $( "body" )
5068 .css( "margin-right" ) : false;
5069 this.el = document.all && !document.querySelector ? $( "html" ) : $( "body" );
5070 this.create( opts )
5071 }
5072 if ( opts.locked && this.fixed ) {
5073 obj.locked = this.overlay.append( obj.wrap );
5074 obj.fixed = false
5075 }
5076 if ( opts.showEarly === true ) {
5077 this.beforeShow.apply( this, arguments )
5078 }
5079 }
5080 , beforeShow: function( opts, obj ) {
5081 if ( obj.locked ) {
5082 this.el.addClass( "fancybox-lock" );
5083 if ( this.margin !== false ) {
5084 $( "body" )
5085 .css( "margin-right", getScalar( this.margin ) + obj.scrollbarWidth )
5086 }
5087 }
5088 this.open( opts )
5089 }
5090 , onUpdate: function() {
5091 if ( !this.fixed ) {
5092 this.update()
5093 }
5094 }
5095 , afterClose: function( opts ) {
5096 if ( this.overlay && !F.isActive ) {
5097 this.overlay.fadeOut( opts.speedOut, $.proxy( this.close, this ) )
5098 }
5099 }
5100 };
5101 F.helpers.title = {
5102 defaults: {
5103 type: "float"
5104 , position: "bottom"
5105 }
5106 , beforeShow: function( opts ) {
5107 var current = F.current
5108 , text = current.title
5109 , type = opts.type
5110 , title, target;
5111 if ( $.isFunction( text ) ) {
5112 text = text.call( current.element, current )
5113 }
5114 if ( !isString( text ) || $.trim( text ) === "" ) {
5115 return
5116 }
5117 title = $( '<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + "</div>" );
5118 switch ( type ) {
5119 case "inside":
5120 target = F.skin;
5121 break;
5122 case "outside":
5123 target = F.wrap;
5124 break;
5125 case "over":
5126 target = F.inner;
5127 break;
5128 default:
5129 target = F.skin;
5130 title.appendTo( "body" );
5131 if ( IE ) {
5132 title.width( title.width() )
5133 }
5134 title.wrapInner( '<span class="child"></span>' );
5135 F.current.margin[ 2 ] += Math.abs( getScalar( title.css( "margin-bottom" ) ) );
5136 break
5137 }
5138 title[ opts.position === "top" ? "prependTo" : "appendTo" ]( target )
5139 }
5140 };
5141 $.fn.fancybox = function( options ) {
5142 var index, that = $( this )
5143 , selector = this.selector || ""
5144 , run = function( e ) {
5145 var what = $( this )
5146 .blur()
5147 , idx = index
5148 , relType, relVal;
5149 if ( !( e.ctrlKey || e.altKey || e.shiftKey || e.metaKey ) && !what.is( ".fancybox-wrap" ) ) {
5150 relType = options.groupAttr || "data-fancybox-group";
5151 relVal = what.attr( relType );
5152 if ( !relVal ) {
5153 relType = "rel";
5154 relVal = what.get( 0 )[ relType ]
5155 }
5156 if ( relVal && relVal !== "" && relVal !== "nofollow" ) {
5157 what = selector.length ? $( selector ) : that;
5158 what = what.filter( "[" + relType + '="' + relVal + '"]' );
5159 idx = what.index( this )
5160 }
5161 options.index = idx;
5162 if ( F.open( what, options ) !== false ) {
5163 e.preventDefault()
5164 }
5165 }
5166 };
5167 options = options || {};
5168 index = options.index || 0;
5169 if ( !selector || options.live === false ) {
5170 that.unbind( "click.fb-start" )
5171 .bind( "click.fb-start", run )
5172 } else {
5173 D.undelegate( selector, "click.fb-start" )
5174 .delegate( selector + ":not('.fancybox-item, .fancybox-nav')", "click.fb-start", run )
5175 }
5176 this.filter( "[data-fancybox-start=1]" )
5177 .trigger( "click" );
5178 return this
5179 };
5180 D.ready( function() {
5181 if ( $.scrollbarWidth === undefined ) {
5182 $.scrollbarWidth = function() {
5183 var parent = $( '<div style="width:50px;height:50px;overflow:auto"><div/></div>' )
5184 .appendTo( "body" )
5185 , child = parent.children()
5186 , width = child.innerWidth() - child.height( 99 )
5187 .innerWidth();
5188 parent.remove();
5189 return width
5190 }
5191 }
5192 if ( $.support.fixedPosition === undefined ) {
5193 $.support.fixedPosition = function() {
5194 var elem = $( '<div style="position:fixed;top:20px;"></div>' )
5195 .appendTo( "body" )
5196 , fixed = elem[ 0 ].offsetTop === 20 || elem[ 0 ].offsetTop === 15;
5197 elem.remove();
5198 return fixed
5199 }()
5200 }
5201 $.extend( F.defaults, {
5202 scrollbarWidth: $.scrollbarWidth()
5203 , fixed: $.support.fixedPosition
5204 , parent: $( "body" )
5205 } )
5206 } )
5207 }
5208 }, {} ]
5209 , 6: [ function( require, module, exports ) {
5210 module.exports = function( jQuery ) {
5211 jQuery.hotkeys = {
5212 version: "0.8"
5213 , specialKeys: {
5214 8: "backspace"
5215 , 9: "tab"
5216 , 13: "return"
5217 , 16: "shift"
5218 , 17: "ctrl"
5219 , 18: "alt"
5220 , 19: "pause"
5221 , 20: "capslock"
5222 , 27: "esc"
5223 , 32: "space"
5224 , 33: "pageup"
5225 , 34: "pagedown"
5226 , 35: "end"
5227 , 36: "home"
5228 , 37: "left"
5229 , 38: "up"
5230 , 39: "right"
5231 , 40: "down"
5232 , 45: "insert"
5233 , 46: "del"
5234 , 96: "0"
5235 , 97: "1"
5236 , 98: "2"
5237 , 99: "3"
5238 , 100: "4"
5239 , 101: "5"
5240 , 102: "6"
5241 , 103: "7"
5242 , 104: "8"
5243 , 105: "9"
5244 , 106: "*"
5245 , 107: "+"
5246 , 109: "-"
5247 , 110: "."
5248 , 111: "/"
5249 , 112: "f1"
5250 , 113: "f2"
5251 , 114: "f3"
5252 , 115: "f4"
5253 , 116: "f5"
5254 , 117: "f6"
5255 , 118: "f7"
5256 , 119: "f8"
5257 , 120: "f9"
5258 , 121: "f10"
5259 , 122: "f11"
5260 , 123: "f12"
5261 , 144: "numlock"
5262 , 145: "scroll"
5263 , 191: "/"
5264 , 224: "meta"
5265 }
5266 , shiftNums: {
5267 "`": "~"
5268 , 1: "!"
5269 , 2: "@"
5270 , 3: "#"
5271 , 4: "$"
5272 , 5: "%"
5273 , 6: "^"
5274 , 7: "&"
5275 , 8: "*"
5276 , 9: "("
5277 , 0: ")"
5278 , "-": "_"
5279 , "=": "+"
5280 , ";": ": "
5281 , "'": '"'
5282 , ",": "<"
5283 , ".": ">"
5284 , "/": "?"
5285 , "\\": "|"
5286 }
5287 };
5288
5289 function keyHandler( handleObj ) {
5290 if ( typeof handleObj.data !== "string" ) {
5291 return
5292 }
5293 var origHandler = handleObj.handler
5294 , keys = handleObj.data.toLowerCase()
5295 .split( " " );
5296 handleObj.handler = function( event ) {
5297 if ( this !== event.target && ( /textarea|select/i.test( event.target.nodeName ) || event.target.type === "text" || event.target.type === "password" ) ) {
5298 return
5299 }
5300 var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ]
5301 , character = String.fromCharCode( event.which )
5302 .toLowerCase()
5303 , key, modif = ""
5304 , possible = {};
5305 if ( event.altKey && special !== "alt" ) {
5306 modif += "alt+"
5307 }
5308 if ( event.ctrlKey && special !== "ctrl" ) {
5309 modif += "ctrl+"
5310 }
5311 if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
5312 modif += "meta+"
5313 }
5314 if ( event.shiftKey && special !== "shift" ) {
5315 modif += "shift+"
5316 }
5317 if ( special ) {
5318 possible[ modif + special ] = true
5319 } else {
5320 possible[ modif + character ] = true;
5321 possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
5322 if ( modif === "shift+" ) {
5323 possible[ jQuery.hotkeys.shiftNums[ character ] ] = true
5324 }
5325 }
5326 for ( var i = 0, l = keys.length; i < l; i++ ) {
5327 if ( possible[ keys[ i ] ] ) {
5328 return origHandler.apply( this, arguments )
5329 }
5330 }
5331 }
5332 }
5333 jQuery.each( [ "keydown", "keyup", "keypress" ], function() {
5334 jQuery.event.special[ this ] = {
5335 add: keyHandler
5336 }
5337 } )
5338 }
5339 }, {} ]
5340 , 7: [ function( require, module, exports ) {
5341 ( function( undefined ) {
5342 var moment, VERSION = "2.0.0"
5343 , round = Math.round
5344 , i, languages = {}
5345 , hasModule = typeof module !== "undefined" && module.exports
5346 , aspNetJsonRegex = /^\/?Date\((\-?\d+)/i
5347 , formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g
5348 , localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g
5349 , parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi
5350 , parseTokenOneOrTwoDigits = /\d\d?/
5351 , parseTokenOneToThreeDigits = /\d{1,3}/
5352 , parseTokenThreeDigits = /\d{3}/
5353 , parseTokenFourDigits = /\d{1,4}/
5354 , parseTokenSixDigits = /[+\-]?\d{1,6}/
5355 , parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i
5356 , parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i
5357 , parseTokenT = /T/i
5358 , parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/
5359 , isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/
5360 , isoFormat = "YYYY-MM-DDTHH:mm:ssZ"
5361 , isoTimes = [
5362 [ "HH:mm:ss.S", /(T| )\d\d:\d\d:\d\d\.\d{1,3}/ ]
5363 , [ "HH:mm:ss", /(T| )\d\d:\d\d:\d\d/ ]
5364 , [ "HH:mm", /(T| )\d\d:\d\d/ ]
5365 , [ "HH", /(T| )\d\d/ ]
5366 ]
5367 , parseTimezoneChunker = /([\+\-]|\d\d)/gi
5368 , proxyGettersAndSetters = "Month|Date|Hours|Minutes|Seconds|Milliseconds".split( "|" )
5369 , unitMillisecondFactors = {
5370 Milliseconds: 1
5371 , Seconds: 1e3
5372 , Minutes: 6e4
5373 , Hours: 36e5
5374 , Days: 864e5
5375 , Months: 2592e6
5376 , Years: 31536e6
5377 }
5378 , formatFunctions = {}
5379 , ordinalizeTokens = "DDD w W M D d".split( " " )
5380 , paddedTokens = "M D H h m s w W".split( " " )
5381 , formatTokenFunctions = {
5382 M: function() {
5383 return this.month() + 1
5384 }
5385 , MMM: function( format ) {
5386 return this.lang()
5387 .monthsShort( this, format )
5388 }
5389 , MMMM: function( format ) {
5390 return this.lang()
5391 .months( this, format )
5392 }
5393 , D: function() {
5394 return this.date()
5395 }
5396 , DDD: function() {
5397 return this.dayOfYear()
5398 }
5399 , d: function() {
5400 return this.day()
5401 }
5402 , dd: function( format ) {
5403 return this.lang()
5404 .weekdaysMin( this, format )
5405 }
5406 , ddd: function( format ) {
5407 return this.lang()
5408 .weekdaysShort( this, format )
5409 }
5410 , dddd: function( format ) {
5411 return this.lang()
5412 .weekdays( this, format )
5413 }
5414 , w: function() {
5415 return this.week()
5416 }
5417 , W: function() {
5418 return this.isoWeek()
5419 }
5420 , YY: function() {
5421 return leftZeroFill( this.year() % 100, 2 )
5422 }
5423 , YYYY: function() {
5424 return leftZeroFill( this.year(), 4 )
5425 }
5426 , YYYYY: function() {
5427 return leftZeroFill( this.year(), 5 )
5428 }
5429 , a: function() {
5430 return this.lang()
5431 .meridiem( this.hours(), this.minutes(), true )
5432 }
5433 , A: function() {
5434 return this.lang()
5435 .meridiem( this.hours(), this.minutes(), false )
5436 }
5437 , H: function() {
5438 return this.hours()
5439 }
5440 , h: function() {
5441 return this.hours() % 12 || 12
5442 }
5443 , m: function() {
5444 return this.minutes()
5445 }
5446 , s: function() {
5447 return this.seconds()
5448 }
5449 , S: function() {
5450 return ~~( this.milliseconds() / 100 )
5451 }
5452 , SS: function() {
5453 return leftZeroFill( ~~( this.milliseconds() / 10 ), 2 )
5454 }
5455 , SSS: function() {
5456 return leftZeroFill( this.milliseconds(), 3 )
5457 }
5458 , Z: function() {
5459 var a = -this.zone()
5460 , b = "+";
5461 if ( a < 0 ) {
5462 a = -a;
5463 b = "-"
5464 }
5465 return b + leftZeroFill( ~~( a / 60 ), 2 ) + ":" + leftZeroFill( ~~a % 60, 2 )
5466 }
5467 , ZZ: function() {
5468 var a = -this.zone()
5469 , b = "+";
5470 if ( a < 0 ) {
5471 a = -a;
5472 b = "-"
5473 }
5474 return b + leftZeroFill( ~~( 10 * a / 6 ), 4 )
5475 }
5476 , X: function() {
5477 return this.unix()
5478 }
5479 };
5480
5481 function padToken( func, count ) {
5482 return function( a ) {
5483 return leftZeroFill( func.call( this, a ), count )
5484 }
5485 }
5486
5487 function ordinalizeToken( func ) {
5488 return function( a ) {
5489 return this.lang()
5490 .ordinal( func.call( this, a ) )
5491 }
5492 }
5493 while ( ordinalizeTokens.length ) {
5494 i = ordinalizeTokens.pop();
5495 formatTokenFunctions[ i + "o" ] = ordinalizeToken( formatTokenFunctions[ i ] )
5496 }
5497 while ( paddedTokens.length ) {
5498 i = paddedTokens.pop();
5499 formatTokenFunctions[ i + i ] = padToken( formatTokenFunctions[ i ], 2 )
5500 }
5501 formatTokenFunctions.DDDD = padToken( formatTokenFunctions.DDD, 3 );
5502
5503 function Language() {}
5504
5505 function Moment( config ) {
5506 extend( this, config )
5507 }
5508
5509 function Duration( duration ) {
5510 var data = this._data = {}
5511 , years = duration.years || duration.year || duration.y || 0
5512 , months = duration.months || duration.month || duration.M || 0
5513 , weeks = duration.weeks || duration.week || duration.w || 0
5514 , days = duration.days || duration.day || duration.d || 0
5515 , hours = duration.hours || duration.hour || duration.h || 0
5516 , minutes = duration.minutes || duration.minute || duration.m || 0
5517 , seconds = duration.seconds || duration.second || duration.s || 0
5518 , milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
5519 this._milliseconds = milliseconds + seconds * 1e3 + minutes * 6e4 + hours * 36e5;
5520 this._days = days + weeks * 7;
5521 this._months = months + years * 12;
5522 data.milliseconds = milliseconds % 1e3;
5523 seconds += absRound( milliseconds / 1e3 );
5524 data.seconds = seconds % 60;
5525 minutes += absRound( seconds / 60 );
5526 data.minutes = minutes % 60;
5527 hours += absRound( minutes / 60 );
5528 data.hours = hours % 24;
5529 days += absRound( hours / 24 );
5530 days += weeks * 7;
5531 data.days = days % 30;
5532 months += absRound( days / 30 );
5533 data.months = months % 12;
5534 years += absRound( months / 12 );
5535 data.years = years
5536 }
5537
5538 function extend( a, b ) {
5539 for ( var i in b ) {
5540 if ( b.hasOwnProperty( i ) ) {
5541 a[ i ] = b[ i ]
5542 }
5543 }
5544 return a
5545 }
5546
5547 function absRound( number ) {
5548 if ( number < 0 ) {
5549 return Math.ceil( number )
5550 } else {
5551 return Math.floor( number )
5552 }
5553 }
5554
5555 function leftZeroFill( number, targetLength ) {
5556 var output = number + "";
5557 while ( output.length < targetLength ) {
5558 output = "0" + output
5559 }
5560 return output
5561 }
5562
5563 function addOrSubtractDurationFromMoment( mom, duration, isAdding ) {
5564 var ms = duration._milliseconds
5565 , d = duration._days
5566 , M = duration._months
5567 , currentDate;
5568 if ( ms ) {
5569 mom._d.setTime( +mom + ms * isAdding )
5570 }
5571 if ( d ) {
5572 mom.date( mom.date() + d * isAdding )
5573 }
5574 if ( M ) {
5575 currentDate = mom.date();
5576 mom.date( 1 )
5577 .month( mom.month() + M * isAdding )
5578 .date( Math.min( currentDate, mom.daysInMonth() ) )
5579 }
5580 }
5581
5582 function isArray( input ) {
5583 return Object.prototype.toString.call( input ) === "[object Array]"
5584 }
5585
5586 function compareArrays( array1, array2 ) {
5587 var len = Math.min( array1.length, array2.length )
5588 , lengthDiff = Math.abs( array1.length - array2.length )
5589 , diffs = 0
5590 , i;
5591 for ( i = 0; i < len; i++ ) {
5592 if ( ~~array1[ i ] !== ~~array2[ i ] ) {
5593 diffs++
5594 }
5595 }
5596 return diffs + lengthDiff
5597 }
5598 Language.prototype = {
5599 set: function( config ) {
5600 var prop, i;
5601 for ( i in config ) {
5602 prop = config[ i ];
5603 if ( typeof prop === "function" ) {
5604 this[ i ] = prop
5605 } else {
5606 this[ "_" + i ] = prop
5607 }
5608 }
5609 }
5610 , _months: "January_February_March_April_May_June_July_August_September_October_November_December".split( "_" )
5611 , months: function( m ) {
5612 return this._months[ m.month() ]
5613 }
5614 , _monthsShort: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split( "_" )
5615 , monthsShort: function( m ) {
5616 return this._monthsShort[ m.month() ]
5617 }
5618 , monthsParse: function( monthName ) {
5619 var i, mom, regex, output;
5620 if ( !this._monthsParse ) {
5621 this._monthsParse = []
5622 }
5623 for ( i = 0; i < 12; i++ ) {
5624 if ( !this._monthsParse[ i ] ) {
5625 mom = moment( [ 2e3, i ] );
5626 regex = "^" + this.months( mom, "" ) + "|^" + this.monthsShort( mom, "" );
5627 this._monthsParse[ i ] = new RegExp( regex.replace( ".", "" ), "i" )
5628 }
5629 if ( this._monthsParse[ i ].test( monthName ) ) {
5630 return i
5631 }
5632 }
5633 }
5634 , _weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split( "_" )
5635 , weekdays: function( m ) {
5636 return this._weekdays[ m.day() ]
5637 }
5638 , _weekdaysShort: "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split( "_" )
5639 , weekdaysShort: function( m ) {
5640 return this._weekdaysShort[ m.day() ]
5641 }
5642 , _weekdaysMin: "Su_Mo_Tu_We_Th_Fr_Sa".split( "_" )
5643 , weekdaysMin: function( m ) {
5644 return this._weekdaysMin[ m.day() ]
5645 }
5646 , _longDateFormat: {
5647 LT: "h:mm A"
5648 , L: "MM/DD/YYYY"
5649 , LL: "MMMM D YYYY"
5650 , LLL: "MMMM D YYYY LT"
5651 , LLLL: "dddd, MMMM D YYYY LT"
5652 }
5653 , longDateFormat: function( key ) {
5654 var output = this._longDateFormat[ key ];
5655 if ( !output && this._longDateFormat[ key.toUpperCase() ] ) {
5656 output = this._longDateFormat[ key.toUpperCase() ].replace( /MMMM|MM|DD|dddd/g, function( val ) {
5657 return val.slice( 1 )
5658 } );
5659 this._longDateFormat[ key ] = output
5660 }
5661 return output
5662 }
5663 , meridiem: function( hours, minutes, isLower ) {
5664 if ( hours > 11 ) {
5665 return isLower ? "pm" : "PM"
5666 } else {
5667 return isLower ? "am" : "AM"
5668 }
5669 }
5670 , _calendar: {
5671 sameDay: "[Today at] LT"
5672 , nextDay: "[Tomorrow at] LT"
5673 , nextWeek: "dddd [at] LT"
5674 , lastDay: "[Yesterday at] LT"
5675 , lastWeek: "[last] dddd [at] LT"
5676 , sameElse: "L"
5677 }
5678 , calendar: function( key, mom ) {
5679 var output = this._calendar[ key ];
5680 return typeof output === "function" ? output.apply( mom ) : output
5681 }
5682 , _relativeTime: {
5683 future: "in %s"
5684 , past: "%s ago"
5685 , s: "a few seconds"
5686 , m: "a minute"
5687 , mm: "%d minutes"
5688 , h: "an hour"
5689 , hh: "%d hours"
5690 , d: "a day"
5691 , dd: "%d days"
5692 , M: "a month"
5693 , MM: "%d months"
5694 , y: "a year"
5695 , yy: "%d years"
5696 }
5697 , relativeTime: function( number, withoutSuffix, string, isFuture ) {
5698 var output = this._relativeTime[ string ];
5699 return typeof output === "function" ? output( number, withoutSuffix, string, isFuture ) : output.replace( /%d/i, number )
5700 }
5701 , pastFuture: function( diff, output ) {
5702 var format = this._relativeTime[ diff > 0 ? "future" : "past" ];
5703 return typeof format === "function" ? format( output ) : format.replace( /%s/i, output )
5704 }
5705 , ordinal: function( number ) {
5706 return this._ordinal.replace( "%d", number )
5707 }
5708 , _ordinal: "%d"
5709 , preparse: function( string ) {
5710 return string
5711 }
5712 , postformat: function( string ) {
5713 return string
5714 }
5715 , week: function( mom ) {
5716 return weekOfYear( mom, this._week.dow, this._week.doy )
5717 }
5718 , _week: {
5719 dow: 0
5720 , doy: 6
5721 }
5722 };
5723
5724 function loadLang( key, values ) {
5725 values.abbr = key;
5726 if ( !languages[ key ] ) {
5727 languages[ key ] = new Language
5728 }
5729 languages[ key ].set( values );
5730 return languages[ key ]
5731 }
5732
5733 function getLangDefinition( key ) {
5734 if ( !key ) {
5735 return moment.fn._lang
5736 }
5737 if ( !languages[ key ] && hasModule ) {
5738 require( "./lang/" + key )
5739 }
5740 return languages[ key ]
5741 }
5742
5743 function removeFormattingTokens( input ) {
5744 if ( input.match( /\[.*\]/ ) ) {
5745 return input.replace( /^\[|\]$/g, "" )
5746 }
5747 return input.replace( /\\/g, "" )
5748 }
5749
5750 function makeFormatFunction( format ) {
5751 var array = format.match( formattingTokens )
5752 , i, length;
5753 for ( i = 0, length = array.length; i < length; i++ ) {
5754 if ( formatTokenFunctions[ array[ i ] ] ) {
5755 array[ i ] = formatTokenFunctions[ array[ i ] ]
5756 } else {
5757 array[ i ] = removeFormattingTokens( array[ i ] )
5758 }
5759 }
5760 return function( mom ) {
5761 var output = "";
5762 for ( i = 0; i < length; i++ ) {
5763 output += typeof array[ i ].call === "function" ? array[ i ].call( mom, format ) : array[ i ]
5764 }
5765 return output
5766 }
5767 }
5768
5769 function formatMoment( m, format ) {
5770 var i = 5;
5771
5772 function replaceLongDateFormatTokens( input ) {
5773 return m.lang()
5774 .longDateFormat( input ) || input
5775 }
5776 while ( i-- && localFormattingTokens.test( format ) ) {
5777 format = format.replace( localFormattingTokens, replaceLongDateFormatTokens )
5778 }
5779 if ( !formatFunctions[ format ] ) {
5780 formatFunctions[ format ] = makeFormatFunction( format )
5781 }
5782 return formatFunctions[ format ]( m )
5783 }
5784
5785 function getParseRegexForToken( token ) {
5786 switch ( token ) {
5787 case "DDDD":
5788 return parseTokenThreeDigits;
5789 case "YYYY":
5790 return parseTokenFourDigits;
5791 case "YYYYY":
5792 return parseTokenSixDigits;
5793 case "S":
5794 case "SS":
5795 case "SSS":
5796 case "DDD":
5797 return parseTokenOneToThreeDigits;
5798 case "MMM":
5799 case "MMMM":
5800 case "dd":
5801 case "ddd":
5802 case "dddd":
5803 case "a":
5804 case "A":
5805 return parseTokenWord;
5806 case "X":
5807 return parseTokenTimestampMs;
5808 case "Z":
5809 case "ZZ":
5810 return parseTokenTimezone;
5811 case "T":
5812 return parseTokenT;
5813 case "MM":
5814 case "DD":
5815 case "YY":
5816 case "HH":
5817 case "hh":
5818 case "mm":
5819 case "ss":
5820 case "M":
5821 case "D":
5822 case "d":
5823 case "H":
5824 case "h":
5825 case "m":
5826 case "s":
5827 return parseTokenOneOrTwoDigits;
5828 default:
5829 return new RegExp( token.replace( "\\", "" ) )
5830 }
5831 }
5832
5833 function addTimeToArrayFromToken( token, input, config ) {
5834 var a, b, datePartArray = config._a;
5835 switch ( token ) {
5836 case "M":
5837 case "MM":
5838 datePartArray[ 1 ] = input == null ? 0 : ~~input - 1;
5839 break;
5840 case "MMM":
5841 case "MMMM":
5842 a = getLangDefinition( config._l )
5843 .monthsParse( input );
5844 if ( a != null ) {
5845 datePartArray[ 1 ] = a
5846 } else {
5847 config._isValid = false
5848 }
5849 break;
5850 case "D":
5851 case "DD":
5852 case "DDD":
5853 case "DDDD":
5854 if ( input != null ) {
5855 datePartArray[ 2 ] = ~~input
5856 }
5857 break;
5858 case "YY":
5859 datePartArray[ 0 ] = ~~input + ( ~~input > 68 ? 1900 : 2e3 );
5860 break;
5861 case "YYYY":
5862 case "YYYYY":
5863 datePartArray[ 0 ] = ~~input;
5864 break;
5865 case "a":
5866 case "A":
5867 config._isPm = ( input + "" )
5868 .toLowerCase() === "pm";
5869 break;
5870 case "H":
5871 case "HH":
5872 case "h":
5873 case "hh":
5874 datePartArray[ 3 ] = ~~input;
5875 break;
5876 case "m":
5877 case "mm":
5878 datePartArray[ 4 ] = ~~input;
5879 break;
5880 case "s":
5881 case "ss":
5882 datePartArray[ 5 ] = ~~input;
5883 break;
5884 case "S":
5885 case "SS":
5886 case "SSS":
5887 datePartArray[ 6 ] = ~~( ( "0." + input ) * 1e3 );
5888 break;
5889 case "X":
5890 config._d = new Date( parseFloat( input ) * 1e3 );
5891 break;
5892 case "Z":
5893 case "ZZ":
5894 config._useUTC = true;
5895 a = ( input + "" )
5896 .match( parseTimezoneChunker );
5897 if ( a && a[ 1 ] ) {
5898 config._tzh = ~~a[ 1 ]
5899 }
5900 if ( a && a[ 2 ] ) {
5901 config._tzm = ~~a[ 2 ]
5902 }
5903 if ( a && a[ 0 ] === "+" ) {
5904 config._tzh = -config._tzh;
5905 config._tzm = -config._tzm
5906 }
5907 break
5908 }
5909 if ( input == null ) {
5910 config._isValid = false
5911 }
5912 }
5913
5914 function dateFromArray( config ) {
5915 var i, date, input = [];
5916 if ( config._d ) {
5917 return
5918 }
5919 for ( i = 0; i < 7; i++ ) {
5920 config._a[ i ] = input[ i ] = config._a[ i ] == null ? i === 2 ? 1 : 0 : config._a[ i ]
5921 }
5922 input[ 3 ] += config._tzh || 0;
5923 input[ 4 ] += config._tzm || 0;
5924 date = new Date( 0 );
5925 if ( config._useUTC ) {
5926 date.setUTCFullYear( input[ 0 ], input[ 1 ], input[ 2 ] );
5927 date.setUTCHours( input[ 3 ], input[ 4 ], input[ 5 ], input[ 6 ] )
5928 } else {
5929 date.setFullYear( input[ 0 ], input[ 1 ], input[ 2 ] );
5930 date.setHours( input[ 3 ], input[ 4 ], input[ 5 ], input[ 6 ] )
5931 }
5932 config._d = date
5933 }
5934
5935 function makeDateFromStringAndFormat( config ) {
5936 var tokens = config._f.match( formattingTokens )
5937 , string = config._i
5938 , i, parsedInput;
5939 config._a = [];
5940 for ( i = 0; i < tokens.length; i++ ) {
5941 parsedInput = ( getParseRegexForToken( tokens[ i ] )
5942 .exec( string ) || [] )[ 0 ];
5943 if ( parsedInput ) {
5944 string = string.slice( string.indexOf( parsedInput ) + parsedInput.length )
5945 }
5946 if ( formatTokenFunctions[ tokens[ i ] ] ) {
5947 addTimeToArrayFromToken( tokens[ i ], parsedInput, config )
5948 }
5949 }
5950 if ( config._isPm && config._a[ 3 ] < 12 ) {
5951 config._a[ 3 ] += 12
5952 }
5953 if ( config._isPm === false && config._a[ 3 ] === 12 ) {
5954 config._a[ 3 ] = 0
5955 }
5956 dateFromArray( config )
5957 }
5958
5959 function makeDateFromStringAndArray( config ) {
5960 var tempConfig, tempMoment, bestMoment, scoreToBeat = 99
5961 , i, currentDate, currentScore;
5962 while ( config._f.length ) {
5963 tempConfig = extend( {}, config );
5964 tempConfig._f = config._f.pop();
5965 makeDateFromStringAndFormat( tempConfig );
5966 tempMoment = new Moment( tempConfig );
5967 if ( tempMoment.isValid() ) {
5968 bestMoment = tempMoment;
5969 break
5970 }
5971 currentScore = compareArrays( tempConfig._a, tempMoment.toArray() );
5972 if ( currentScore < scoreToBeat ) {
5973 scoreToBeat = currentScore;
5974 bestMoment = tempMoment
5975 }
5976 }
5977 extend( config, bestMoment )
5978 }
5979
5980 function makeDateFromString( config ) {
5981 var i, string = config._i;
5982 if ( isoRegex.exec( string ) ) {
5983 config._f = "YYYY-MM-DDT";
5984 for ( i = 0; i < 4; i++ ) {
5985 if ( isoTimes[ i ][ 1 ].exec( string ) ) {
5986 config._f += isoTimes[ i ][ 0 ];
5987 break
5988 }
5989 }
5990 if ( parseTokenTimezone.exec( string ) ) {
5991 config._f += " Z"
5992 }
5993 makeDateFromStringAndFormat( config )
5994 } else {
5995 config._d = new Date( string )
5996 }
5997 }
5998
5999 function makeDateFromInput( config ) {
6000 var input = config._i
6001 , matched = aspNetJsonRegex.exec( input );
6002 if ( input === undefined ) {
6003 config._d = new Date
6004 } else if ( matched ) {
6005 config._d = new Date( +matched[ 1 ] )
6006 } else if ( typeof input === "string" ) {
6007 makeDateFromString( config )
6008 } else if ( isArray( input ) ) {
6009 config._a = input.slice( 0 );
6010 dateFromArray( config )
6011 } else {
6012 config._d = input instanceof Date ? new Date( +input ) : new Date( input )
6013 }
6014 }
6015
6016 function substituteTimeAgo( string, number, withoutSuffix, isFuture, lang ) {
6017 return lang.relativeTime( number || 1, !!withoutSuffix, string, isFuture )
6018 }
6019
6020 function relativeTime( milliseconds, withoutSuffix, lang ) {
6021 var seconds = round( Math.abs( milliseconds ) / 1e3 )
6022 , minutes = round( seconds / 60 )
6023 , hours = round( minutes / 60 )
6024 , days = round( hours / 24 )
6025 , years = round( days / 365 )
6026 , args = seconds < 45 && [ "s", seconds ] || minutes === 1 && [ "m" ] || minutes < 45 && [ "mm", minutes ] || hours === 1 && [ "h" ] || hours < 22 && [ "hh", hours ] || days === 1 && [ "d" ] || days <= 25 && [ "dd", days ] || days <= 45 && [ "M" ] || days < 345 && [ "MM", round( days / 30 ) ] || years === 1 && [ "y" ] || [ "yy", years ];
6027 args[ 2 ] = withoutSuffix;
6028 args[ 3 ] = milliseconds > 0;
6029 args[ 4 ] = lang;
6030 return substituteTimeAgo.apply( {}, args )
6031 }
6032
6033 function weekOfYear( mom, firstDayOfWeek, firstDayOfWeekOfYear ) {
6034 var end = firstDayOfWeekOfYear - firstDayOfWeek
6035 , daysToDayOfWeek = firstDayOfWeekOfYear - mom.day();
6036 if ( daysToDayOfWeek > end ) {
6037 daysToDayOfWeek -= 7
6038 }
6039 if ( daysToDayOfWeek < end - 7 ) {
6040 daysToDayOfWeek += 7
6041 }
6042 return Math.ceil( moment( mom )
6043 .add( "d", daysToDayOfWeek )
6044 .dayOfYear() / 7 )
6045 }
6046
6047 function makeMoment( config ) {
6048 var input = config._i
6049 , format = config._f;
6050 if ( input === null || input === "" ) {
6051 return null
6052 }
6053 if ( typeof input === "string" ) {
6054 config._i = input = getLangDefinition()
6055 .preparse( input )
6056 }
6057 if ( moment.isMoment( input ) ) {
6058 config = extend( {}, input );
6059 config._d = new Date( +input._d )
6060 } else if ( format ) {
6061 if ( isArray( format ) ) {
6062 makeDateFromStringAndArray( config )
6063 } else {
6064 makeDateFromStringAndFormat( config )
6065 }
6066 } else {
6067 makeDateFromInput( config )
6068 }
6069 return new Moment( config )
6070 }
6071 moment = function( input, format, lang ) {
6072 return makeMoment( {
6073 _i: input
6074 , _f: format
6075 , _l: lang
6076 , _isUTC: false
6077 } )
6078 };
6079 moment.utc = function( input, format, lang ) {
6080 return makeMoment( {
6081 _useUTC: true
6082 , _isUTC: true
6083 , _l: lang
6084 , _i: input
6085 , _f: format
6086 } )
6087 };
6088 moment.unix = function( input ) {
6089 return moment( input * 1e3 )
6090 };
6091 moment.duration = function( input, key ) {
6092 var isDuration = moment.isDuration( input )
6093 , isNumber = typeof input === "number"
6094 , duration = isDuration ? input._data : isNumber ? {} : input
6095 , ret;
6096 if ( isNumber ) {
6097 if ( key ) {
6098 duration[ key ] = input
6099 } else {
6100 duration.milliseconds = input
6101 }
6102 }
6103 ret = new Duration( duration );
6104 if ( isDuration && input.hasOwnProperty( "_lang" ) ) {
6105 ret._lang = input._lang
6106 }
6107 return ret
6108 };
6109 moment.version = VERSION;
6110 moment.defaultFormat = isoFormat;
6111 moment.lang = function( key, values ) {
6112 var i;
6113 if ( !key ) {
6114 return moment.fn._lang._abbr
6115 }
6116 if ( values ) {
6117 loadLang( key, values )
6118 } else if ( !languages[ key ] ) {
6119 getLangDefinition( key )
6120 }
6121 moment.duration.fn._lang = moment.fn._lang = getLangDefinition( key )
6122 };
6123 moment.langData = function( key ) {
6124 if ( key && key._lang && key._lang._abbr ) {
6125 key = key._lang._abbr
6126 }
6127 return getLangDefinition( key )
6128 };
6129 moment.isMoment = function( obj ) {
6130 return obj instanceof Moment
6131 };
6132 moment.isDuration = function( obj ) {
6133 return obj instanceof Duration
6134 };
6135 moment.fn = Moment.prototype = {
6136 clone: function() {
6137 return moment( this )
6138 }
6139 , valueOf: function() {
6140 return +this._d
6141 }
6142 , unix: function() {
6143 return Math.floor( +this._d / 1e3 )
6144 }
6145 , toString: function() {
6146 return this.format( "ddd MMM DD YYYY HH:mm:ss [GMT]ZZ" )
6147 }
6148 , toDate: function() {
6149 return this._d
6150 }
6151 , toJSON: function() {
6152 return moment.utc( this )
6153 .format( "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]" )
6154 }
6155 , toArray: function() {
6156 var m = this;
6157 return [ m.year(), m.month(), m.date(), m.hours(), m.minutes(), m.seconds(), m.milliseconds() ]
6158 }
6159 , isValid: function() {
6160 if ( this._isValid == null ) {
6161 if ( this._a ) {
6162 this._isValid = !compareArrays( this._a, ( this._isUTC ? moment.utc( this._a ) : moment( this._a ) )
6163 .toArray() )
6164 } else {
6165 this._isValid = !isNaN( this._d.getTime() )
6166 }
6167 }
6168 return !!this._isValid
6169 }
6170 , utc: function() {
6171 this._isUTC = true;
6172 return this
6173 }
6174 , local: function() {
6175 this._isUTC = false;
6176 return this
6177 }
6178 , format: function( inputString ) {
6179 var output = formatMoment( this, inputString || moment.defaultFormat );
6180 return this.lang()
6181 .postformat( output )
6182 }
6183 , add: function( input, val ) {
6184 var dur;
6185 if ( typeof input === "string" ) {
6186 dur = moment.duration( +val, input )
6187 } else {
6188 dur = moment.duration( input, val )
6189 }
6190 addOrSubtractDurationFromMoment( this, dur, 1 );
6191 return this
6192 }
6193 , subtract: function( input, val ) {
6194 var dur;
6195 if ( typeof input === "string" ) {
6196 dur = moment.duration( +val, input )
6197 } else {
6198 dur = moment.duration( input, val )
6199 }
6200 addOrSubtractDurationFromMoment( this, dur, -1 );
6201 return this
6202 }
6203 , diff: function( input, units, asFloat ) {
6204 var that = this._isUTC ? moment( input )
6205 .utc() : moment( input )
6206 .local()
6207 , zoneDiff = ( this.zone() - that.zone() ) * 6e4
6208 , diff, output;
6209 if ( units ) {
6210 units = units.replace( /s$/, "" )
6211 }
6212 if ( units === "year" || units === "month" ) {
6213 diff = ( this.daysInMonth() + that.daysInMonth() ) * 432e5;
6214 output = ( this.year() - that.year() ) * 12 + ( this.month() - that.month() );
6215 output += ( this - moment( this )
6216 .startOf( "month" ) - ( that - moment( that )
6217 .startOf( "month" ) ) ) / diff;
6218 if ( units === "year" ) {
6219 output = output / 12
6220 }
6221 } else {
6222 diff = this - that - zoneDiff;
6223 output = units === "second" ? diff / 1e3 : units === "minute" ? diff / 6e4 : units === "hour" ? diff / 36e5 : units === "day" ? diff / 864e5 : units === "week" ? diff / 6048e5 : diff
6224 }
6225 return asFloat ? output : absRound( output )
6226 }
6227 , from: function( time, withoutSuffix ) {
6228 return moment.duration( this.diff( time ) )
6229 .lang( this.lang()
6230 ._abbr )
6231 .humanize( !withoutSuffix )
6232 }
6233 , fromNow: function( withoutSuffix ) {
6234 return this.from( moment(), withoutSuffix )
6235 }
6236 , calendar: function() {
6237 var diff = this.diff( moment()
6238 .startOf( "day" ), "days", true )
6239 , format = diff < -6 ? "sameElse" : diff < -1 ? "lastWeek" : diff < 0 ? "lastDay" : diff < 1 ? "sameDay" : diff < 2 ? "nextDay" : diff < 7 ? "nextWeek" : "sameElse";
6240 return this.format( this.lang()
6241 .calendar( format, this ) )
6242 }
6243 , isLeapYear: function() {
6244 var year = this.year();
6245 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0
6246 }
6247 , isDST: function() {
6248 return this.zone() < moment( [ this.year() ] )
6249 .zone() || this.zone() < moment( [ this.year(), 5 ] )
6250 .zone()
6251 }
6252 , day: function( input ) {
6253 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
6254 return input == null ? day : this.add( {
6255 d: input - day
6256 } )
6257 }
6258 , startOf: function( units ) {
6259 units = units.replace( /s$/, "" );
6260 switch ( units ) {
6261 case "year":
6262 this.month( 0 );
6263 case "month":
6264 this.date( 1 );
6265 case "week":
6266 case "day":
6267 this.hours( 0 );
6268 case "hour":
6269 this.minutes( 0 );
6270 case "minute":
6271 this.seconds( 0 );
6272 case "second":
6273 this.milliseconds( 0 )
6274 }
6275 if ( units === "week" ) {
6276 this.day( 0 )
6277 }
6278 return this
6279 }
6280 , endOf: function( units ) {
6281 return this.startOf( units )
6282 .add( units.replace( /s?$/, "s" ), 1 )
6283 .subtract( "ms", 1 )
6284 }
6285 , isAfter: function( input, units ) {
6286 units = typeof units !== "undefined" ? units : "millisecond";
6287 return +this.clone()
6288 .startOf( units ) > +moment( input )
6289 .startOf( units )
6290 }
6291 , isBefore: function( input, units ) {
6292 units = typeof units !== "undefined" ? units : "millisecond";
6293 return +this.clone()
6294 .startOf( units ) < +moment( input )
6295 .startOf( units )
6296 }
6297 , isSame: function( input, units ) {
6298 units = typeof units !== "undefined" ? units : "millisecond";
6299 return +this.clone()
6300 .startOf( units ) === +moment( input )
6301 .startOf( units )
6302 }
6303 , zone: function() {
6304 return this._isUTC ? 0 : this._d.getTimezoneOffset()
6305 }
6306 , daysInMonth: function() {
6307 return moment.utc( [ this.year(), this.month() + 1, 0 ] )
6308 .date()
6309 }
6310 , dayOfYear: function( input ) {
6311 var dayOfYear = round( ( moment( this )
6312 .startOf( "day" ) - moment( this )
6313 .startOf( "year" ) ) / 864e5 ) + 1;
6314 return input == null ? dayOfYear : this.add( "d", input - dayOfYear )
6315 }
6316 , isoWeek: function( input ) {
6317 var week = weekOfYear( this, 1, 4 );
6318 return input == null ? week : this.add( "d", ( input - week ) * 7 )
6319 }
6320 , week: function( input ) {
6321 var week = this.lang()
6322 .week( this );
6323 return input == null ? week : this.add( "d", ( input - week ) * 7 )
6324 }
6325 , lang: function( key ) {
6326 if ( key === undefined ) {
6327 return this._lang
6328 } else {
6329 this._lang = getLangDefinition( key );
6330 return this
6331 }
6332 }
6333 };
6334
6335 function makeGetterAndSetter( name, key ) {
6336 moment.fn[ name ] = moment.fn[ name + "s" ] = function( input ) {
6337 var utc = this._isUTC ? "UTC" : "";
6338 if ( input != null ) {
6339 this._d[ "set" + utc + key ]( input );
6340 return this
6341 } else {
6342 return this._d[ "get" + utc + key ]()
6343 }
6344 }
6345 }
6346 for ( i = 0; i < proxyGettersAndSetters.length; i++ ) {
6347 makeGetterAndSetter( proxyGettersAndSetters[ i ].toLowerCase()
6348 .replace( /s$/, "" ), proxyGettersAndSetters[ i ] )
6349 }
6350 makeGetterAndSetter( "year", "FullYear" );
6351 moment.fn.days = moment.fn.day;
6352 moment.fn.weeks = moment.fn.week;
6353 moment.fn.isoWeeks = moment.fn.isoWeek;
6354 moment.duration.fn = Duration.prototype = {
6355 weeks: function() {
6356 return absRound( this.days() / 7 )
6357 }
6358 , valueOf: function() {
6359 return this._milliseconds + this._days * 864e5 + this._months * 2592e6
6360 }
6361 , humanize: function( withSuffix ) {
6362 var difference = +this
6363 , output = relativeTime( difference, !withSuffix, this.lang() );
6364 if ( withSuffix ) {
6365 output = this.lang()
6366 .pastFuture( difference, output )
6367 }
6368 return this.lang()
6369 .postformat( output )
6370 }
6371 , lang: moment.fn.lang
6372 };
6373
6374 function makeDurationGetter( name ) {
6375 moment.duration.fn[ name ] = function() {
6376 return this._data[ name ]
6377 }
6378 }
6379
6380 function makeDurationAsGetter( name, factor ) {
6381 moment.duration.fn[ "as" + name ] = function() {
6382 return +this / factor
6383 }
6384 }
6385 for ( i in unitMillisecondFactors ) {
6386 if ( unitMillisecondFactors.hasOwnProperty( i ) ) {
6387 makeDurationAsGetter( i, unitMillisecondFactors[ i ] );
6388 makeDurationGetter( i.toLowerCase() )
6389 }
6390 }
6391 makeDurationAsGetter( "Weeks", 6048e5 );
6392 moment.lang( "en", {
6393 ordinal: function( number ) {
6394 var b = number % 10
6395 , output = ~~( number % 100 / 10 ) === 1 ? "th" : b === 1 ? "st" : b === 2 ? "nd" : b === 3 ? "rd" : "th";
6396 return number + output
6397 }
6398 } );
6399 if ( hasModule ) {
6400 module.exports = moment
6401 }
6402 if ( typeof ender === "undefined" ) {
6403 this[ "moment" ] = moment
6404 }
6405 if ( typeof define === "function" && define.amd ) {
6406 define( "moment", [], function() {
6407 return moment
6408 } )
6409 }
6410 } )
6411 .call( this )
6412 }, {} ]
6413 , 8: [ function( require, module, exports ) {
6414 var CryptoJS = function( h, s ) {
6415 var f = {}
6416 , t = f.lib = {}
6417 , g = function() {}
6418 , j = t.Base = {
6419 extend: function( a ) {
6420 g.prototype = this;
6421 var c = new g;
6422 a && c.mixIn( a );
6423 c.hasOwnProperty( "init" ) || ( c.init = function() {
6424 c.$super.init.apply( this, arguments )
6425 } );
6426 c.init.prototype = c;
6427 c.$super = this;
6428 return c
6429 }
6430 , create: function() {
6431 var a = this.extend();
6432 a.init.apply( a, arguments );
6433 return a
6434 }
6435 , init: function() {}
6436 , mixIn: function( a ) {
6437 for ( var c in a ) a.hasOwnProperty( c ) && ( this[ c ] = a[ c ] );
6438 a.hasOwnProperty( "toString" ) && ( this.toString = a.toString )
6439 }
6440 , clone: function() {
6441 return this.init.prototype.extend( this )
6442 }
6443 }
6444 , q = t.WordArray = j.extend( {
6445 init: function( a, c ) {
6446 a = this.words = a || [];
6447 this.sigBytes = c != s ? c : 4 * a.length
6448 }
6449 , toString: function( a ) {
6450 return ( a || u )
6451 .stringify( this )
6452 }
6453 , concat: function( a ) {
6454 var c = this.words
6455 , d = a.words
6456 , b = this.sigBytes;
6457 a = a.sigBytes;
6458 this.clamp();
6459 if ( b % 4 )
6460 for ( var e = 0; e < a; e++ ) c[ b + e >>> 2 ] |= ( d[ e >>> 2 ] >>> 24 - 8 * ( e % 4 ) & 255 ) << 24 - 8 * ( ( b + e ) % 4 );
6461 else if ( 65535 < d.length )
6462 for ( e = 0; e < a; e += 4 ) c[ b + e >>> 2 ] = d[ e >>> 2 ];
6463 else c.push.apply( c, d );
6464 this.sigBytes += a;
6465 return this
6466 }
6467 , clamp: function() {
6468 var a = this.words
6469 , c = this.sigBytes;
6470 a[ c >>> 2 ] &= 4294967295 << 32 - 8 * ( c % 4 );
6471 a.length = h.ceil( c / 4 )
6472 }
6473 , clone: function() {
6474 var a = j.clone.call( this );
6475 a.words = this.words.slice( 0 );
6476 return a
6477 }
6478 , random: function( a ) {
6479 for ( var c = [], d = 0; d < a; d += 4 ) c.push( 4294967296 * h.random() | 0 );
6480 return new q.init( c, a )
6481 }
6482 } )
6483 , v = f.enc = {}
6484 , u = v.Hex = {
6485 stringify: function( a ) {
6486 var c = a.words;
6487 a = a.sigBytes;
6488 for ( var d = [], b = 0; b < a; b++ ) {
6489 var e = c[ b >>> 2 ] >>> 24 - 8 * ( b % 4 ) & 255;
6490 d.push( ( e >>> 4 )
6491 .toString( 16 ) );
6492 d.push( ( e & 15 )
6493 .toString( 16 ) )
6494 }
6495 return d.join( "" )
6496 }
6497 , parse: function( a ) {
6498 for ( var c = a.length, d = [], b = 0; b < c; b += 2 ) d[ b >>> 3 ] |= parseInt( a.substr( b, 2 ), 16 ) << 24 - 4 * ( b % 8 );
6499 return new q.init( d, c / 2 )
6500 }
6501 }
6502 , k = v.Latin1 = {
6503 stringify: function( a ) {
6504 var c = a.words;
6505 a = a.sigBytes;
6506 for ( var d = [], b = 0; b < a; b++ ) d.push( String.fromCharCode( c[ b >>> 2 ] >>> 24 - 8 * ( b % 4 ) & 255 ) );
6507 return d.join( "" )
6508 }
6509 , parse: function( a ) {
6510 for ( var c = a.length, d = [], b = 0; b < c; b++ ) d[ b >>> 2 ] |= ( a.charCodeAt( b ) & 255 ) << 24 - 8 * ( b % 4 );
6511 return new q.init( d, c )
6512 }
6513 }
6514 , l = v.Utf8 = {
6515 stringify: function( a ) {
6516 try {
6517 return decodeURIComponent( escape( k.stringify( a ) ) )
6518 } catch ( c ) {
6519 throw Error( "Malformed UTF-8 data" )
6520 }
6521 }
6522 , parse: function( a ) {
6523 return k.parse( unescape( encodeURIComponent( a ) ) )
6524 }
6525 }
6526 , x = t.BufferedBlockAlgorithm = j.extend( {
6527 reset: function() {
6528 this._data = new q.init;
6529 this._nDataBytes = 0
6530 }
6531 , _append: function( a ) {
6532 "string" == typeof a && ( a = l.parse( a ) );
6533 this._data.concat( a );
6534 this._nDataBytes += a.sigBytes
6535 }
6536 , _process: function( a ) {
6537 var c = this._data
6538 , d = c.words
6539 , b = c.sigBytes
6540 , e = this.blockSize
6541 , f = b / ( 4 * e )
6542 , f = a ? h.ceil( f ) : h.max( ( f | 0 ) - this._minBufferSize, 0 );
6543 a = f * e;
6544 b = h.min( 4 * a, b );
6545 if ( a ) {
6546 for ( var m = 0; m < a; m += e ) this._doProcessBlock( d, m );
6547 m = d.splice( 0, a );
6548 c.sigBytes -= b
6549 }
6550 return new q.init( m, b )
6551 }
6552 , clone: function() {
6553 var a = j.clone.call( this );
6554 a._data = this._data.clone();
6555 return a
6556 }
6557 , _minBufferSize: 0
6558 } );
6559 t.Hasher = x.extend( {
6560 cfg: j.extend()
6561 , init: function( a ) {
6562 this.cfg = this.cfg.extend( a );
6563 this.reset()
6564 }
6565 , reset: function() {
6566 x.reset.call( this );
6567 this._doReset()
6568 }
6569 , update: function( a ) {
6570 this._append( a );
6571 this._process();
6572 return this
6573 }
6574 , finalize: function( a ) {
6575 a && this._append( a );
6576 return this._doFinalize()
6577 }
6578 , blockSize: 16
6579 , _createHelper: function( a ) {
6580 return function( c, d ) {
6581 return new a.init( d )
6582 .finalize( c )
6583 }
6584 }
6585 , _createHmacHelper: function( a ) {
6586 return function( c, d ) {
6587 return new w.HMAC.init( a, d )
6588 .finalize( c )
6589 }
6590 }
6591 } );
6592 var w = f.algo = {};
6593 return f
6594 }( Math );
6595 ( function( h ) {
6596 for ( var s = CryptoJS, f = s.lib, t = f.WordArray, g = f.Hasher, f = s.algo, j = [], q = [], v = function( a ) {
6597 return 4294967296 * ( a - ( a | 0 ) ) | 0
6598 }, u = 2, k = 0; 64 > k; ) {
6599 var l;
6600 a: {
6601 l = u;
6602 for ( var x = h.sqrt( l ), w = 2; w <= x; w++ )
6603 if ( !( l % w ) ) {
6604 l = !1;
6605 break a
6606 }
6607 l = !0
6608 }
6609 l && ( 8 > k && ( j[ k ] = v( h.pow( u, .5 ) ) ), q[ k ] = v( h.pow( u, 1 / 3 ) ), k++ );
6610 u++
6611 }
6612 var a = []
6613 , f = f.SHA256 = g.extend( {
6614 _doReset: function() {
6615 this._hash = new t.init( j.slice( 0 ) )
6616 }
6617 , _doProcessBlock: function( c, d ) {
6618 for ( var b = this._hash.words, e = b[ 0 ], f = b[ 1 ], m = b[ 2 ], h = b[ 3 ], p = b[ 4 ], j = b[ 5 ], k = b[ 6 ], l = b[ 7 ], n = 0; 64 > n; n++ ) {
6619 if ( 16 > n ) a[ n ] = c[ d + n ] | 0;
6620 else {
6621 var r = a[ n - 15 ]
6622 , g = a[ n - 2 ];
6623 a[ n ] = ( ( r << 25 | r >>> 7 ) ^ ( r << 14 | r >>> 18 ) ^ r >>> 3 ) + a[ n - 7 ] + ( ( g << 15 | g >>> 17 ) ^ ( g << 13 | g >>> 19 ) ^ g >>> 10 ) + a[ n - 16 ]
6624 }
6625 r = l + ( ( p << 26 | p >>> 6 ) ^ ( p << 21 | p >>> 11 ) ^ ( p << 7 | p >>> 25 ) ) + ( p & j ^ ~p & k ) + q[ n ] + a[ n ];
6626 g = ( ( e << 30 | e >>> 2 ) ^ ( e << 19 | e >>> 13 ) ^ ( e << 10 | e >>> 22 ) ) + ( e & f ^ e & m ^ f & m );
6627 l = k;
6628 k = j;
6629 j = p;
6630 p = h + r | 0;
6631 h = m;
6632 m = f;
6633 f = e;
6634 e = r + g | 0
6635 }
6636 b[ 0 ] = b[ 0 ] + e | 0;
6637 b[ 1 ] = b[ 1 ] + f | 0;
6638 b[ 2 ] = b[ 2 ] + m | 0;
6639 b[ 3 ] = b[ 3 ] + h | 0;
6640 b[ 4 ] = b[ 4 ] + p | 0;
6641 b[ 5 ] = b[ 5 ] + j | 0;
6642 b[ 6 ] = b[ 6 ] + k | 0;
6643 b[ 7 ] = b[ 7 ] + l | 0
6644 }
6645 , _doFinalize: function() {
6646 var a = this._data
6647 , d = a.words
6648 , b = 8 * this._nDataBytes
6649 , e = 8 * a.sigBytes;
6650 d[ e >>> 5 ] |= 128 << 24 - e % 32;
6651 d[ ( e + 64 >>> 9 << 4 ) + 14 ] = h.floor( b / 4294967296 );
6652 d[ ( e + 64 >>> 9 << 4 ) + 15 ] = b;
6653 a.sigBytes = 4 * d.length;
6654 this._process();
6655 return this._hash
6656 }
6657 , clone: function() {
6658 var a = g.clone.call( this );
6659 a._hash = this._hash.clone();
6660 return a
6661 }
6662 } );
6663 s.SHA256 = g._createHelper( f );
6664 s.HmacSHA256 = g._createHmacHelper( f )
6665 } )( Math );
6666 module.exports = CryptoJS
6667 }, {} ]
6668}, {}, [ 2 ] );