3 // @namespace http://www.facebook.com/ponyhoof
4 // @run-at document-start
6 // @installURL https://hoof.little.my/files/ponyhoof.user.js
7 // @updateURL https://hoof.little.my/files/ponyhoof.meta.js
8 // @icon https://hoof.little.my/files/app32.png
9 // @icon64 https://hoof.little.my/files/icon64.png
10 // @description Ponify Facebook and make it 20% cooler!
11 // @author The Ponyhoof Team <pony@little.my> http://ponyhoof.little.my
12 // @developer Ng Yik Phang
14 // @contributor http://ponyhoof.little.my/credits
15 // @homepage http://ponyhoof.little.my
16 // @supportURL https://www.facebook.com/Ponyhoof
17 // @contributionURL http://ponyhoof.little.my/donate
18 // @include http://*.facebook.com/*
19 // @include https://*.facebook.com/*
20 // @include http://*.little.my/*
21 // @include https://*.little.my/*
22 // @match http://*.facebook.com/*
23 // @match https://*.facebook.com/*
24 // @match http://*.little.my/*
25 // @match https://*.little.my/*
26 // @exclude http://*.facebook.com/ai.php*
27 // @exclude http://*.facebook.com/l.php*
28 // @exclude http://*.facebook.com/ajax/*
29 // @exclude http://*.channel.facebook.com/*
30 // @exclude http://static.*.facebook.com/*
31 // @exclude http://graph.facebook.com/*
32 // @exclude http://0.facebook.com/*
33 // @exclude https://*.facebook.com/ai.php*
34 // @exclude https://*.facebook.com/l.php*
35 // @exclude https://*.facebook.com/ajax/*
36 // @exclude https://*.channel.facebook.com/*
37 // @exclude https://s-static.*.facebook.com/*
38 // @exclude https://graph.facebook.com/*
39 // @exclude https://0.facebook.com/*
40 // @exclude https://paste.little.my/*
43 /*******************************************************************************
44 * Please visit http://jointheherd.lttle.my for the official install!
45 *******************************************************************************/
49 if (typeof WScript
!== 'undefined' && typeof window
=== 'undefined') {
50 WScript
.echo("Ponyhoof is not run by double-clicking a file in Windows.\n\nPlease visit http://jointheherd.little.my for proper installation.");
54 if (window
.location
.hostname
.indexOf('facebook.com') == -1 && window
.location
.hostname
.indexOf('little.my') == -1) {
61 * @author ngyikp (http://www.facebook.com/ngyikp)
63 var d
= document
, w
= window
;
67 var SIG
= '[Hoof Framework]';
68 var FRIENDLYNAME
= 'Hoof Framework';
71 var userSettings
= {};
73 var USERAGENT
= w
.navigator
.userAgent
.toLowerCase();
74 var ISOPERABLINK
= /OPR\//.test(w
.navigator
.userAgent
);
75 var ISOPERA
= !ISOPERABLINK
&& (typeof opera
!== 'undefined' || /opera/.test(USERAGENT
));
76 var ISMAXTHON
= /maxthon/i.test(USERAGENT
);
77 var ISMSIE
= !ISMAXTHON
&& !ISOPERA
&& typeof opera
=== 'undefined' && /trident/.test(USERAGENT
);
78 var ISMOBILE
= /iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(USERAGENT
);
79 var ISCHROME
= !ISMAXTHON
&& !ISOPERABLINK
&& /chrome/i.test(USERAGENT
) && typeof chrome
!== 'undefined' && typeof chrome
.webstore
!== 'undefined' && typeof chrome
.webstore
.install
!== 'undefined' && chrome
.webstore
.install
;
80 var ISFIREFOX
= /firefox/i.test(USERAGENT
);
81 var ISSAFARI
= !ISOPERABLINK
&& !ISCHROME
&& !/chrome/i.test(USERAGENT
) && /safari/i.test(USERAGENT
);
82 var ISAVANT
= /avant/i.test(USERAGENT
);
84 // R.I.P. unsafeWindow in Chrome 27+ http://crbug.com/222652
85 if (typeof unsafeWindow
== 'undefined') {
88 var USW
= unsafeWindow
;
93 if (typeof console
!== 'undefined' && console
.log
) {
94 console
.log(SIG
+ ' ' + msg
);
101 if (typeof console
!== 'undefined' && console
.log
&& console
.dir
) {
108 function debug(msg
) {
110 if (typeof console
!== 'undefined') {
112 console
.debug(SIG
+ ' ' + msg
);
113 } else if (console
.log
) {
114 console
.log(SIG
+ ' ' + msg
);
122 if (typeof console
!== 'undefined') {
124 console
.info(SIG
+ ' ' + msg
);
125 } else if (console
.log
) {
126 console
.log(SIG
+ ' ' + msg
);
134 if (typeof console
!== 'undefined') {
136 console
.warn(SIG
+ ' ' + msg
);
137 } else if (console
.log
) {
138 console
.log(SIG
+ ' ' + msg
);
144 function error(msg
) {
146 if (typeof console
!== 'undefined') {
148 console
.error(SIG
+ ' ' + msg
);
149 } else if (console
.log
) {
150 console
.log(SIG
+ ' ' + msg
);
158 if (typeof console
!== 'undefined' && console
.trace
) {
165 return d
.getElementById(id
);
168 function randNum(min
, max
) {
169 return min
+ Math
.floor(Math
.random() * (max
- min
+ 1));
172 function hasClass(ele
, c
) {
177 return ele
.classList
.contains(c
);
180 var regex
= new RegExp("(^|\\s)"+c
+"(\\s|$)");
181 if (ele
.className
) { // element node
182 return (ele
.className
&& regex
.test(ele
.className
));
184 return (ele
&& regex
.test(ele
));
188 function addClass(ele
, c
) {
190 ele
.classList
.add(c
);
191 } else if (!hasClass(ele
, c
)) {
192 ele
.className
+= ' '+c
;
196 function removeClass(ele
, c
) {
198 ele
.classList
.remove(c
);
200 ele
.className
= ele
.className
.replace(new RegExp('(^|\\s)'+c
+'(?:\\s|$)','g'),'$1').replace(/\s+/g,' ').replace(/^\s*|\s*$/g,'');
204 function toggleClass(ele
, c
) {
205 if (hasClass(ele
, c
)) {
208 ele
.className
+= ' ' + c
;
212 function clickLink(el
) {
217 var evt
= d
.createEvent('MouseEvents');
218 evt
.initMouseEvent('click', true, true, USW
, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
219 el
.dispatchEvent(evt
);
225 return unescape(d
.cookie
.match('(^|;)?'+n
+'=([^;]*)(;|$)')[2]);
231 function injectManualStyle(css
, id
) {
232 if ($('ponyhoof_style_'+id
)) {
233 return $('ponyhoof_style_'+id
);
236 var n
= d
.createElement('style');
239 n
.id
= 'ponyhoof_style_'+id
;
241 n
.textContent
= '/* '+SIG
+' */'+css
;
244 d
.head
.appendChild(n
);
246 d
.body
.appendChild(n
);
248 d
.documentElement
.appendChild(n
);
254 function fadeOut(ele
, callback
) {
255 addClass(ele
, 'ponyhoof_fadeout');
257 w
.setTimeout(function() {
258 ele
.style
.display
= 'none';
266 function getFbDomain() {
267 if (w
.location
.hostname
== 'beta.facebook.com') {
268 return w
.location
.hostname
;
270 return 'www.facebook.com';
273 function onPageReady(callback
) {
274 var _loop = function() {
275 if (/loaded|complete/.test(d
.readyState
)) {
278 w
.setTimeout(_loop
, 100);
284 var loopClassName = function(name
, func
) {
285 var l
= d
.getElementsByClassName(name
);
287 for (var i
= 0, len
= l
.length
; i
< len
; i
++) {
293 function $$(parent
, query
, func
) {
297 var l
= parent
.querySelectorAll(query
);
299 for (var i
= 0, len
= l
.length
; i
< len
; i
++) {
305 // Hacky code adapted from http://www.javascripter.net/faq/browsern.htm
306 function getBrowserVersion() {
307 var ua
= w
.navigator
.userAgent
;
308 var fullVersion
= ''+parseFloat(w
.navigator
.appVersion
);
309 var majorVersion
= parseInt(w
.navigator
.appVersion
, 10);
310 var nameOffset
, offset
, ix
;
312 if (ua
.indexOf('Opera') != -1) {
313 // In Opera, the true version is after 'Opera' or after 'Version'
314 offset
= ua
.indexOf('Opera');
315 fullVersion
= ua
.substring(offset
+ 6);
317 if (ua
.indexOf('Version') != -1) {
318 offset
= ua
.indexOf('Version');
319 fullVersion
= ua
.substring(offset
+ 8);
321 } else if (ua
.indexOf('OPR/') != -1) {
322 offset
= ua
.indexOf('OPR/');
323 fullVersion
= ua
.substring(offset
+ 4);
324 } else if (ua
.indexOf('MSIE') != -1) {
325 // In MSIE, the true version is after 'MSIE' in userAgent
326 offset
= ua
.indexOf('MSIE');
327 fullVersion
= ua
.substring(offset
+ 5);
328 } else if (ua
.indexOf('Chrome') != -1) {
329 // In Chrome, the true version is after 'Chrome'
330 offset
= ua
.indexOf('Chrome');
331 fullVersion
= ua
.substring(offset
+ 7);
332 } else if (ua
.indexOf('Safari') != -1) {
333 // In Safari, the true version is after 'Safari' or after 'Version'
334 offset
= ua
.indexOf('Safari');
335 fullVersion
= ua
.substring(offset
+ 7);
337 if (ua
.indexOf('Version') != -1) {
338 offset
= ua
.indexOf('Version');
339 fullVersion
= ua
.substring(offset
+ 8);
341 } else if (ua
.indexOf('Firefox') != -1) {
342 // In Firefox, the true version is after 'Firefox'
343 offset
= ua
.indexOf('Firefox');
344 fullVersion
= ua
.substring(offset
+ 8);
346 throw "Unsupported browser";
349 if ((ix
= fullVersion
.indexOf(';')) != -1) {
350 fullVersion
= fullVersion
.substring(0, ix
);
352 if ((ix
= fullVersion
.indexOf(' ')) != -1) {
353 fullVersion
= fullVersion
.substring(0, ix
);
356 majorVersion
= parseInt(''+fullVersion
,10);
357 if (isNaN(majorVersion
)) {
358 fullVersion
= ''+parseFloat(w
.navigator
.appVersion
);
359 majorVersion
= parseInt(w
.navigator
.appVersion
,10);
368 // http://wiki.greasespot.net/Content_Script_Injection
369 var contentEval = function(source
, arg
) {
371 if (typeof source
=== 'function') {
372 source
= '(' + source
+ ')(' + JSON
.stringify(arg
) + ');'
375 var script
= d
.createElement('script');
376 script
.textContent
= source
;
377 d
.documentElement
.appendChild(script
);
378 d
.documentElement
.removeChild(script
);
381 var supportsRange = function() {
382 var i
= d
.createElement('input');
383 i
.setAttribute('type', 'range');
384 return i
.type
!== 'text';
387 var supportsCssTransition = function() {
388 var s
= d
.createElement('div').style
;
389 return ('transition' in s
|| 'WebkitTransition' in s
|| 'MozTransition' in s
|| 'msTransition' in s
|| 'OTransition' in s
);
394 var Menu = function(id
, p
) {
398 MENUS
['ponyhoof_menu_'+k
.id
] = k
;
399 k
.menu
= null; // outer wrap
400 k
.selectorMenu
= null; // .uiMenu.uiSelectorMenu
401 k
.menuInner
= null; // .uiMenuInner
402 k
.content
= null; // .uiScrollableAreaContent
404 k
.wrap
= null; // ponyhoof_menu_wrap, used to separate button and menu
405 k
._scrollTop
= 0; // fix a bug on old safari where menu jumps back to top
407 k
.menuSearch
= null; // .ponyhoof_menu_search
408 k
.menuSearchInput
= null;
409 k
.menuSearchNoResults
= null;
410 k
.focusStealer
= null;
412 k
.hasScrollableArea
= false;
413 k
.scrollableAreaDiv
= null; // .uiScrollableArea
414 k
.scrollableArea
= null; // FB ScrollableArea class
417 k
.afterClose = function() {};
420 k
.alwaysOverflow
= false;
421 k
.rightFaced
= false;
422 k
.buttonTextClipped
= 0;
423 k
.searchNoResultsMessage
= "No results";
425 k
.createButton = function(startText
) {
430 var buttonText
= d
.createElement('span');
431 buttonText
.className
= 'uiButtonText';
432 buttonText
.innerHTML
= startText
;
434 k
.button
= d
.createElement('a');
436 k
.button
.className
= 'uiButton ponyhoof_button_menu';
437 k
.button
.setAttribute('role', 'button');
438 k
.button
.setAttribute('aria-haspopup', 'true');
439 if (k
.buttonTextClipped
) {
440 k
.button
.className
+= ' ponyhoof_button_clipped';
441 buttonText
.style
.maxWidth
= k
.buttonTextClipped
+'px';
443 k
.button
.appendChild(buttonText
);
445 k
.wrap
= d
.createElement('div');
446 k
.wrap
.className
= 'ponyhoof_menu_wrap';
448 k
.wrap
.className
+= ' uiSelectorRight';
450 k
.wrap
.appendChild(k
.button
);
451 k
.p
.appendChild(k
.wrap
);
456 k
.createMenu = function() {
457 if ($('ponyhoof_menu_'+k
.id
)) {
458 k
.menu
= $('ponyhoof_menu_'+k
.id
);
459 k
.menuInner
= k
.menu
.getElementsByClassName('uiMenuInner')[0];
465 k
.menu
= d
.createElement('div');
466 k
.menu
.className
= 'ponyhoof_menu uiSelectorMenuWrapper';
467 k
.menu
.id
= 'ponyhoof_menu_'+k
.id
;
468 k
.menu
.setAttribute('role', 'menu');
469 //k.menu.style.display = 'none';
470 k
.menu
.addEventListener('click', function(e
) {
474 k
.wrap
.appendChild(k
.menu
);
476 k
.selectorMenu
= d
.createElement('div');
477 k
.selectorMenu
.className
= 'uiMenu uiSelectorMenu';
478 k
.menu
.appendChild(k
.selectorMenu
);
480 k
.menuInner
= d
.createElement('div');
481 k
.menuInner
.className
= 'uiMenuInner';
482 k
.selectorMenu
.appendChild(k
.menuInner
);
484 k
.content
= d
.createElement('div');
485 k
.content
.className
= 'uiScrollableAreaContent';
486 k
.menuInner
.appendChild(k
.content
);
489 k
.menuSearch
= d
.createElement('div');
490 k
.menuSearch
.className
= 'ponyhoof_menu_search';
491 k
.content
.appendChild(k
.menuSearch
);
493 k
.menuSearchInput
= d
.createElement('input');
494 k
.menuSearchInput
.type
= 'text';
495 k
.menuSearchInput
.className
= 'inputtext';
496 k
.menuSearchInput
.placeholder
= "Search";
497 k
.menuSearch
.appendChild(k
.menuSearchInput
);
499 k
.menuSearchNoResults
= d
.createElement('div');
500 k
.menuSearchNoResults
.className
= 'ponyhoof_menu_search_noResults';
501 k
.menuSearchNoResults
.textContent
= k
.searchNoResultsMessage
;
502 k
.menuSearch
.appendChild(k
.menuSearchNoResults
);
504 k
.menuSearchInput
.addEventListener('keydown', k
.searchEscapeKey
, false);
505 k
.menuSearchInput
.addEventListener('input', k
.performSearch
, false);
507 k
.focusStealer
= d
.createElement('input');
508 k
.focusStealer
.type
= 'text';
509 k
.focusStealer
.setAttribute('aria-hidden', 'true');
510 k
.focusStealer
.style
.position
= 'absolute';
511 k
.focusStealer
.style
.top
= '-9999px';
512 k
.focusStealer
.style
.left
= '-9999px';
513 k
.focusStealer
.addEventListener('focus', k
.focusStealerFocused
, false);
514 k
.selectorMenu
.appendChild(k
.focusStealer
);
520 k
.attachButton = function() {
521 k
.button
.addEventListener('click', function(e
) {
528 k
.changeButtonText = function(text
) {
529 k
.button
.getElementsByClassName('uiButtonText')[0].innerHTML
= text
;
530 k
.button
.setAttribute('data-ponyhoof-button-orig', text
);
531 k
.button
.setAttribute('data-ponyhoof-button-text', text
);
533 if (k
.buttonTextClipped
) {
534 k
.button
.title
= text
;
538 k
.createSeperator = function() {
539 var sep
= d
.createElement('div');
540 sep
.className
= 'uiMenuSeparator';
541 k
.content
.appendChild(sep
);
544 k
.createMenuItem = function(param
) {
545 var menuItem
= new MenuItem(k
);
546 menuItem
._create(param
);
548 k
.content
.appendChild(menuItem
.menuItem
);
553 k
.injectStyle = function() {
555 css
+= 'html .ponyhoof_dialog .ponyhoof_button_menu, .ponyhoof_menuitem_checked {background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAADdCAMAAAB63HDyAAAAaVBMVEUAAABnfapKZJtjeahofqtsbGxwhK97jrXb29vc3Nze3d3f3t/g4N/h4ODi4uLk5OPk5eXm5ubn5+fo6Ojq6enr6+rs6+zs7Ozu7u3v7+/w8PDw8fDx8vHz8vPz8/T09PT19PX19vb////xKBXBAAAAAnRSTlMA70YmMtEAAAFWSURBVHja7d05UsNQFETRNjIS8zzPeP+LxK7CmA04UZ8T6aV968fKijr5pk6+qJNP6uSDOnmnTt6ok1fq5IXZO9j6vfPM/A3TxrA980SB5br58u/KIw3GadwdeaDC+O8799TJHXVyS53cUCfX1MkVdXJJnVxQJ+fUyRl1ckqdnFAnx9TJEXVEFx3RER3RER3RER3RER3RER3RER3RER3REV10REd05hMdAAAAANij3V/4qKtuiL7qZuirboS+6iYAAAAAAAAAAAAAAAAAAAAAAAAAAACA/TrYMkWRYdoYDFFlsW6+MEOZcRqN0FfdBAAAAAAAAAAAAAAAAAAAAAAAAABzcWiCvuaiFzYXvaq35o2PXPPC6JpXVjdCX3UTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBnZYK+5qIXNhe9qrfmjY9c88LomldWN0JfdRMAzMcPe9ehQpH/3pgAAAAASUVORK5CYII=") !important;background-repeat:no-repeat;-webkit-background-size:500px 221px;-moz-background-size:500px 221px;background-size:500px 221px;}';
557 css
+= 'html .ponyhoof_dialog .ponyhoof_button_menu {background-position:right 0;padding-right:23px;}';
558 css
+= 'html .ponyhoof_button_menu:active {background-position:right -98px;}';
559 css
+= 'html .openToggler .ponyhoof_button_menu {background-color:#6D84B4;background-position:right -49px;border-color:#3B5998;border-bottom-color:#6D84B4;box-shadow:none;}';
560 css
+= 'html .openToggler .ponyhoof_button_menu .uiButtonText {color:#fff;}';
562 css
+= '.ponyhoof_menu_label {padding:7px 4px 0 0;}';
563 css
+= '.ponyhoof_menu_label, .ponyhoof_menu_withlabel .ponyhoof_menu_wrap {display:inline-block;}';
564 css
+= '.ponyhoof_menu_withlabel {margin-bottom:8px;}';
565 css
+= '.ponyhoof_menu_withlabel + .ponyhoof_menu_withlabel {margin-top:-8px;}';
566 css
+= '.ponyhoof_menu_withlabel .ponyhoof_button_menu {margin-top:-3px;}';
567 css
+= '.ponyhoof_menu_labelbreak .ponyhoof_menu_label {display:block;padding-bottom:7px;}';
569 css
+= '.ponyhoof_menu_wrap {position:relative;}';
570 css
+= 'html .ponyhoof_menu {z-index:1999;display:none;min-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
571 css
+= '.ponyhoof_menu_wrap.openToggler .ponyhoof_menu {display:block;}';
572 css
+= '.ponyhoof_menu_wrap + .uiButton {margin:4px 0 0 4px;}';
573 css
+= '.ponyhoof_menu .uiMenu {background:#fff;border:1px solid #777;border-bottom:2px solid #293E6A;color:#000;position:absolute;overflow:auto;overflow-x:hidden;text-align:left;}';
574 css
+= '.ponyhoof_menu .uiMenu.overflow {resize:vertical;height:200px;min-height:200px;}';
575 css
+= '.ponyhoof_menu_wrap.uiSelectorRight .uiMenu {left:auto;right:0;}';
576 css
+= '.ponyhoof_menu .ponyhoof_menu_search {padding:0 3px;margin-bottom:4px;}';
577 css
+= '.ponyhoof_menu .ponyhoof_menu_search input {width:100%;resize:none;}';
578 css
+= '.ponyhoof_menu .ponyhoof_menu_search_noResults {display:none;color:#999;text-align:center;margin-top:7px;width:100px;}';
579 css
+= '.ponyhoof_menuitem {border:solid #fff;border-width:1px 0;color:#111;display:block;font-weight:normal;line-height:16px;padding:1px 22px;text-decoration:none;outline:none;-webkit-user-drag:none;resize:none;}';
580 css
+= '.ponyhoof_menu .ponyhoof_menuitem {color:#111;}';
581 css
+= '.ponyhoof_menuitem:hover, .ponyhoof_menuitem:active, .ponyhoof_menuitem:focus {background-color:#6d84b4;border-color:#3b5998;color:#fff;text-decoration:none;}';
582 css
+= '.ponyhoof_menuitem_checked {background-position:0 -146px;font-weight:bold;}';
583 css
+= '.ponyhoof_menuitem_checked:hover, .ponyhoof_menuitem_checked:active, .ponyhoof_menuitem_checked:focus {background-position:0 -206px;}';
584 css
+= '.ponyhoof_menuitem_span {white-space:nowrap;text-overflow:ellipsis;display:inline-block;overflow:hidden;padding-right:16px;max-width:400px;vertical-align:top;}';
586 css
+= '.ponyhoof_button_clipped > .uiButtonText {text-overflow:ellipsis;overflow:hidden;vertical-align:top;}';
589 css
+= '.ponyhoof_menu .uiMenu.overflow {resize:none !important;height:auto !important;}';
592 injectManualStyle(css
, 'menu');
595 k
.open = function() {
598 addClass(k
.wrap
, 'openToggler');
600 if (!hasClass(k
.menuInner
.parentNode
, 'overflow') && (k
.menuInner
.parentNode
.offsetHeight
>= 224 || k
.alwaysOverflow
)) {
601 addClass(k
.menuInner
.parentNode
, 'overflow');
604 if (k
.canSearch
&& !ISMOBILE
) {
605 k
.menuSearchInput
.focus();
606 k
.menuSearchInput
.select();
609 // Poke the menu to show the scroll visual cue on Mac OS
611 k
.selectorMenu
.scrollTop
= 0;
613 k
.selectorMenu
.scrollTop
= 1;
615 k
.selectorMenu
.scrollTop
= k
._scrollTop
;
617 d
.body
.addEventListener('keydown', k
.documentEscapeKey
, false);
618 d
.body
.addEventListener('click', k
.documentClick
, false);
621 k
.close = function() {
622 if (hasClass(k
.wrap
, 'openToggler')) {
623 k
._scrollTop
= k
.selectorMenu
.scrollTop
;
625 removeClass(k
.wrap
, 'openToggler');
626 d
.body
.removeEventListener('keydown', k
.documentEscapeKey
, false);
627 d
.body
.removeEventListener('click', k
.documentClick
, false);
633 k
.closeAllMenus = function() {
634 for (var menu
in MENUS
) {
635 if (MENUS
.hasOwnProperty(menu
)) {
641 k
.toggle = function() {
642 if (hasClass(k
.wrap
, 'openToggler')) {
649 k
.changeChecked = function(menuItem
) {
650 var already
= k
.menu
.getElementsByClassName('ponyhoof_menuitem_checked');
651 if (already
.length
) {
652 removeClass(already
[0], 'ponyhoof_menuitem_checked');
654 addClass(menuItem
.menuItem
, 'ponyhoof_menuitem_checked');
657 k
.performSearch = function() {
658 var val
= k
.menuSearchInput
.value
;
659 var regex
= new RegExp(val
, 'i');
662 $$(k
.menu
, '.ponyhoof_menuitem', function(menuitem
) {
664 menuitem
.style
.display
= '';
668 if (!hasClass(menuitem
, 'unsearchable')) {
669 menuitem
.style
.display
= 'none';
671 var compare
= menuitem
.textContent
;
672 if (menuitem
.getAttribute('data-ponyhoof-menu-searchAlternate')) {
673 compare
= menuitem
.getAttribute('data-ponyhoof-menu-searchAlternate');
676 if (regex
.test(compare
)) {
677 menuitem
.style
.display
= 'block';
681 menuitem
.style
.display
= 'none';
685 $$(k
.menu
, '.ponyhoof_menu_search_noResults', function(ele
) {
688 ele
.style
.display
= 'block';
690 ele
.style
.display
= 'none';
693 ele
.style
.display
= 'none';
697 $$(k
.menu
, '.uiMenuSeparator', function(menuitem
) {
699 menuitem
.style
.display
= '';
703 menuitem
.style
.display
= 'none';
706 if (k
.hasScrollableArea
) {
707 k
.scrollableArea
.poke();
711 k
.searchEscapeKey = function(e
) {
713 if (k
.menuSearchInput
.value
!= '') {
714 k
.menuSearchInput
.value
= '';
723 e
.cancelBubble
= true;
727 k
.documentEscapeKey = function(e
) {
728 if (e
.which
== 27 && hasClass(k
.wrap
, 'openToggler')) { // esc
731 e
.cancelBubble
= true;
739 k
.documentClick = function(e
) {
745 k
.focusStealerFocused = function(e
) {
747 k
.menuSearchInput
.focus();
752 var MenuItem = function(menu
) {
759 k
._create = function(param
) {
760 k
.menuItem
= d
.createElement('a');
761 k
.menuItem
.href
= '#';
762 k
.menuItem
.className
= 'ponyhoof_menuitem';
763 k
.menuItem
.setAttribute('role', 'menuitem');
766 k
.menuItem
.className
+= ' ponyhoof_menuitem_checked';
770 k
.menuItem
.setAttribute('data-ponyhoof-menu-data', param
.data
);
774 k
.menuItem
.setAttribute('aria-label', param
.title
);
775 k
.menuItem
.setAttribute('data-hover', 'tooltip');
778 if (param
.unsearchable
) {
779 k
.menuItem
.className
+= ' unsearchable';
782 if (param
.searchAlternate
) {
783 k
.menuItem
.setAttribute('data-ponyhoof-menu-searchAlternate', param
.searchAlternate
);
786 if (param
.extraClass
) {
787 k
.menuItem
.className
+= param
.extraClass
;
790 k
.menuItem
.innerHTML
= '<span class="ponyhoof_menuitem_span">'+param
.html
+'</span>';
793 k
.onclick
= param
.onclick
;
795 k
.menuItem
.addEventListener('click', function(e
) {
798 k
.onclick(k
, k
.menu
);
803 k
.menuItem
.addEventListener('dragstart', function() {
810 k
.getText = function() {
811 return k
.menuItem
.getElementsByClassName('ponyhoof_menuitem_span')[0].innerHTML
;
817 var DIALOGCOUNT
= 2000;
818 var Dialog = function(id
) {
822 k
.generic_dialogDiv
= null;
823 k
.popup_dialogDiv
= null;
827 k
.alwaysModal
= false;
831 k
.canCardspace
= true;
832 k
.cardSpaceTimer
= null;
833 k
.cardspaced
= false;
835 k
.onclose = function() {};
836 k
.onclosefinish = function() {};
837 k
.canCloseByEscapeKey
= true;
841 k
.create = function() {
842 //if (DIALOGS[k.id]) {
843 // log("Attempting to recreate dialog ID \""+k.id+"\"");
844 // return DIALOGS[k.id].dialog;
849 log("Creating "+k
.id
+" dialog...");
854 k
.skeleton
= '<!-- '+SIG
+' Dialog -->';
855 k
.skeleton
+= '<div class="generic_dialog pop_dialog" role="dialog" style="z-index:'+(DIALOGCOUNT
)+';">';
856 k
.skeleton
+= ' <div class="generic_dialog_popup">';
857 k
.skeleton
+= ' <div class="popup">';
858 k
.skeleton
+= ' <div class="wrap">';
859 k
.skeleton
+= ' <h3 title="This dialog is sent from '+FRIENDLYNAME
+'"></h3>';
860 k
.skeleton
+= ' <div class="body">';
861 k
.skeleton
+= ' <div class="content clearfix"></div>';
862 k
.skeleton
+= ' <div class="bottom"></div>';
863 k
.skeleton
+= ' </div>'; // body
864 k
.skeleton
+= ' </div>'; // wrap
865 k
.skeleton
+= ' </div>'; // popup
866 k
.skeleton
+= ' </div>'; // generic_dialog_popup
867 k
.skeleton
+= '</div>';
869 INTERNALUPDATE
= true;
871 k
.dialog
= d
.createElement('div');
872 k
.dialog
.className
= 'ponyhoof_dialog';
873 k
.dialog
.id
= 'ponyhoof_dialog_'+k
.id
;
874 k
.dialog
.innerHTML
= k
.skeleton
;
875 d
.body
.appendChild(k
.dialog
);
877 INTERNALUPDATE
= false;
879 k
.generic_dialogDiv
= k
.dialog
.getElementsByClassName('pop_dialog')[0];
880 k
.popup_dialogDiv
= k
.dialog
.getElementsByClassName('popup')[0];
883 addClass(k
.generic_dialogDiv
, 'generic_dialog_modal');
886 addClass(k
.dialog
.getElementsByTagName('h3')[0], 'hidden_elem');
889 addClass(k
.dialog
.getElementsByClassName('bottom')[0], 'hidden_elem');
897 k
.injectStyle = function() {
899 if (d
.getElementsByClassName('-cx-PUBLIC-hasLitestand__body').length
) {
900 cx
= '.-cx-PUBLIC-hasLitestand__body';
904 css
+= '.ponyhoof_message .wrap {margin-top:3px;background:transparent !important;display:block;}';
905 css
+= '.ponyhoof_message .uiButton.rfloat {margin-left:10px;}';
907 css
+= '.ponyhoof_dialog, .ponyhoof_dialog .body {font-size:11px;}';
908 css
+= cx
+' .ponyhoof_dialog, '+cx
+' .ponyhoof_dialog .body {font-size:12px;}';
909 css
+= '.ponyhoof_dialog iframe {-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
910 css
+= '.ponyhoof_dialog textarea, .ponyhoof_dialog input[type="text"] {cursor:text;-moz-box-sizing:border-box;box-sizing:border-box;}';
911 css
+= '.ponyhoof_dialog .generic_dialog_modal, .ponyhoof_dialog .generic_dialog_fixed_overflow {background-color:rgba(0,0,0,.4) !important;}';
912 css
+= '.ponyhoof_dialog .generic_dialog {z-index:250;}';
913 css
+= '.ponyhoof_dialog .generic_dialog_popup {margin-top:80px;}';
914 css
+= '.ponyhoof_dialog .popup {width:465px;margin:0 auto;cursor:default;box-shadow:0 2px 26px rgba(0, 0, 0, .3), 0 0 0 1px rgba(0, 0, 0, .1);}';
915 css
+= cx
+' .ponyhoof_dialog .popup {font-family:"Helvetica Neue", Helvetica, Arial, "lucida grande",tahoma,verdana,arial,sans-serif;}';
916 css
+= '.ponyhoof_dialog .wrap {background:#fff;color:#000;}';
917 css
+= '.ponyhoof_dialog h3 {background-color:#6D84B4;border:1px solid #3B5998;border-bottom:0;color:#fff;font-size:14px !important;font-weight:bold !important;padding:5px 5px 5px 10px;cursor:help;min-height:17px;font-family:\'lucida grande\',tahoma,verdana,arial,sans-serif !important;line-height:1.28 !important;}';
918 css
+= cx
+' .ponyhoof_dialog h3 {background:#f5f6f7;border:0;border-bottom:1px solid #e5e5e5;border-radius:3px 3px 0 0;color:#4e5665;line-height:19px !important;padding:10px 12px;text-shadow:0 1px 0 #fff;font-family:\'Helvetica Neue\', Helvetica, Arial, \'lucida grande\',tahoma,verdana,arial,sans-serif !important;}';
919 css
+= '.ponyhoof_dialog h3:before {background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA90lEQVQYGQXBP0oWAADA0ff9NURBRAVDMBcHl9SpIbCamsOhcOsMObiEICJ2gJYQWhqkscmWTlFeoJbASacIfr4ngaZtAZAGJBLoRV+hDdKjdpJIoJl2oGPopEsSCdAA+tksLfWEREIakcb963ljGpJIoNe9a7eX1beGLbdOIoF01m231U2/um6RRELzpI9V1V2bkEja7qi55npfVf3pbRMSSQddN2ml31XV//YgkTTpWZM+d9xh9aMPfWq3QSKhcQ8a01p/O+hxC522n0gAWqWrnjag750nEqCHXTTbeWs07U3biQRosS9Ne9UIWm6YSABap3kAkntUReU7PxfnpgAAAABJRU5ErkJggg==");background-repeat: no-repeat;display:inline-block;float:right;content:" ";width:16px;height:16px;opacity:.713;}';
920 css
+= cx
+' .ponyhoof_dialog h3:before {display:none;}';
921 css
+= '.ponyhoof_dialog .body {border:1px solid #555;border-top-width:0;}';
922 css
+= '.ponyhoof_dialog h3.hidden_elem + .body {border-top-width:1px;}';
923 css
+= cx
+' .ponyhoof_dialog .body {border:0;}';
924 css
+= '.ponyhoof_dialog .content {padding:10px;}';
925 css
+= '.ponyhoof_dialog .bottom {background:#F2F2F2;border-top:1px solid #ccc;padding:8px 10px 8px 10px;text-align:right;}';
926 css
+= cx
+' .ponyhoof_dialog .bottom {border-radius:0 0 3px 3px;}';
927 css
+= '.ponyhoof_dialog .bottom .lfloat {line-height:17px;margin-top:4px;}';
929 css
+= '.ponyhoof_dialog_header {background:#F2F2F2;border:solid #E2E2E2;border-width:1px 0;padding:4px 10px 5px;color:#333;font-size:11px;margin:0 -10px 8px;display:block;font-weight:bold;}';
930 css
+= '.ponyhoof_tabs {padding:4px 10px 0;background:#F2F2F2;border-bottom:1px solid #ccc;margin:-10px -10px 10px;}';
931 css
+= '.ponyhoof_tabs a {margin:3px 10px 0 0;padding:5px 8px;float:left;}';
932 css
+= '.ponyhoof_tabs a.active {color:#333;padding:4px 7px 5px;background:#fff;border:1px solid #ccc;border-bottom:1px solid #fff;margin-bottom:-1px;text-decoration:none;}';
933 css
+= '.ponyhoof_tabs_section {display:none;}';
936 css
+= '.ponyhoof_dialog .generic_dialog {position:absolute;}';
939 injectManualStyle(css
, 'dialog');
942 k
.show = function() {
943 removeClass(k
.dialog
, 'ponyhoof_fadeout');
944 removeClass(k
.generic_dialogDiv
, 'ponyhoof_fadeout');
947 k
.dialog
.style
.display
= 'block';
948 k
.generic_dialogDiv
.style
.display
= 'block';
951 k
.canCardspace
= false;
954 if (k
.canCardspace
) {
955 w
.addEventListener('resize', k
.onBodyResize
, false);
959 if (k
.canCloseByEscapeKey
) {
960 d
.body
.addEventListener('keydown', k
.documentEscapeKey
, false);
964 k
.close = function(callback
) {
967 if (!userSettings
.disable_animation
) {
968 fadeOut(k
.dialog
, function() {
975 log("Legacy dialog close code found [Dialog.close()]");
979 fadeOut(k
.generic_dialogDiv
);
982 k
.dialog
.style
.display
= 'none';
992 k
.hide = function() {
995 k
.dialog
.style
.display
= 'none';
1000 k
._close = function() {
1003 w
.removeEventListener('resize', k
.onBodyResize
, false);
1004 w
.clearTimeout(k
.cardSpaceTimer
);
1007 removeClass(d
.documentElement
, 'generic_dialog_overflow_mode');
1008 if (!k
.alwaysModal
) {
1009 removeClass(k
.generic_dialogDiv
, 'generic_dialog_modal');
1012 removeClass(k
.generic_dialogDiv
, 'generic_dialog_fixed_overflow');
1013 k
.cardspaced
= false;
1015 d
.body
.removeEventListener('keydown', k
.documentEscapeKey
, false);
1018 k
.changeTitle = function(c
) {
1019 INTERNALUPDATE
= true;
1020 var title
= k
.dialog
.getElementsByTagName('h3');
1023 title
.innerHTML
= c
;
1025 INTERNALUPDATE
= false;
1028 k
.changeContent = function(c
) {
1029 INTERNALUPDATE
= true;
1030 var content
= k
.dialog
.getElementsByClassName('content');
1031 if (content
.length
) {
1032 content
= content
[0];
1033 content
.innerHTML
= c
;
1035 INTERNALUPDATE
= false;
1038 k
.changeBottom = function(c
) {
1039 INTERNALUPDATE
= true;
1040 var bottom
= k
.dialog
.getElementsByClassName('bottom');
1041 if (bottom
.length
) {
1043 bottom
.innerHTML
= c
;
1045 INTERNALUPDATE
= false;
1048 k
.addCloseButton = function(callback
) {
1050 if (CURRENTLANG
&& CURRENTLANG
.close
) {
1051 text
= CURRENTLANG
.close
;
1054 var close
= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button"><span class="uiButtonText">'+text
+'</span></a>';
1055 k
.changeBottom(close
);
1057 k
.dialog
.querySelector('.bottom .uiButton').addEventListener('click', function(e
) {
1058 k
.close(function() {
1060 log("Legacy dialog close code found [Dialog.addCloseButton()]");
1068 k
.onBodyResize = function() {
1069 if (k
.canCardspace
) {
1070 var dialogHeight
= k
.popup_dialogDiv
.clientHeight
+ 80 + 40;
1071 var windowHeight
= w
.innerHeight
;
1073 if (dialogHeight
> windowHeight
) {
1074 if (!k
.cardspaced
) {
1075 addClass(d
.documentElement
, 'generic_dialog_overflow_mode');
1076 if (!k
.alwaysModal
) {
1077 addClass(k
.generic_dialogDiv
, 'generic_dialog_modal');
1079 addClass(k
.generic_dialogDiv
, 'generic_dialog_fixed_overflow');
1081 k
.cardspaced
= true;
1085 removeClass(d
.documentElement
, 'generic_dialog_overflow_mode');
1086 if (!k
.alwaysModal
) {
1087 removeClass(k
.generic_dialogDiv
, 'generic_dialog_modal');
1089 removeClass(k
.generic_dialogDiv
, 'generic_dialog_fixed_overflow');
1091 k
.cardspaced
= false;
1097 k
.cardSpaceTick = function() {
1098 if (k
.canCardspace
&& k
.visible
) {
1100 k
.cardSpaceTimer
= w
.setTimeout(k
.cardSpaceTick
, 500);
1102 w
.clearTimeout(k
.cardSpaceTimer
);
1106 k
.documentEscapeKey = function(e
) {
1107 if (k
.canCloseByEscapeKey
) {
1108 if (e
.which
== 27 && k
.visible
) { // esc
1110 e
.stopPropagation();
1111 e
.cancelBubble
= true;
1116 if (DIALOGS
[k
.id
]) {
1117 log("Attempting to recreate dialog ID \""+k
.id
+"\"");
1118 return DIALOGS
[k
.id
];
1123 function createSimpleDialog(id
, title
, message
) {
1125 DIALOGS
[id
].changeTitle(title
);
1126 DIALOGS
[id
].changeContent(message
);
1131 var di
= new Dialog(id
);
1133 di
.changeTitle(title
);
1134 di
.changeContent(message
);
1135 di
.addCloseButton();
1140 function injectSystemStyle() {
1142 css
+= '.ponyhoof_show_if_injected {display:none;}';
1143 css
+= '.ponyhoof_hide_if_injected {display:block;}';
1144 css
+= '.ponyhoof_hide_if_injected.inline {display:inline;}';
1145 css
+= 'html.ponyhoof_injected .ponyhoof_show_if_injected {display:block;}';
1146 css
+= 'html.ponyhoof_injected .ponyhoof_hide_if_injected {display:none;}';
1147 css
+= '.ponyhoof_show_if_loaded {display:none;}';
1148 css
+= '.ponyhoof_updater_latest, .ponyhoof_updater_newVersion, .ponyhoof_updater_error {display:none;}';
1150 css
+= '.ponyhoof_fadeout {opacity:0;-webkit-transition:opacity .25s linear;-moz-transition:opacity .25s linear;-o-transition:opacity .25s linear;transition:opacity .25s linear;}';
1151 css
+= '.ponyhoof_message {padding:10px;color:#000;font-weight:bold;overflow:hidden;}';
1153 css
+= '.ponyhoof_loading {background:url("//fbstatic-a.akamaihd.net/rsrc.php/v2/y4/x/GsNJNwuI-UM.gif") no-repeat;display:inline-block;width:16px;height:11px;margin:6px 0 0 6px;}';
1154 css
+= '.ponyhoof_loading.ponyhoof_show_if_injected {display:none;}';
1155 css
+= 'html.ponyhoof_injected .ponyhoof_loading_pony {display:inline-block;}';
1157 css
+= '.uiHelpLink {background:url("data:image/gif;base64,R0lGODlhDAALAJEAANvb26enp////wAAACH5BAEAAAIALAAAAAAMAAsAAAIblI8WkbcswAtAwWVzwoIbSWliBzWjR5abagoFADs=") no-repeat 0 center;display:inline-block;height:9px;width:12px;}';
1159 css
+= '.uiInputLabel + .uiInputLabel {margin-top:3px;}';
1160 css
+= '.uiInputLabelCheckbox {float:left;margin:0;padding:0;}';
1161 css
+= '.uiInputLabel label {color:#333;display:block;font-weight:normal;margin-left:17px;vertical-align:baseline;}';
1162 css
+= '.webkit.mac .uiInputLabel label {margin-left:16px;}';
1163 css
+= '.webkit.mac .uiInputLabelCheckbox {margin-top:2px;}';
1165 injectManualStyle(css
, 'system');
1168 // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
1169 var _hiddenPropCached
= '';
1170 var getHiddenProp = function() {
1171 if (_hiddenPropCached
) {
1172 return _hiddenPropCached
;
1175 var prefixes
= ['webkit', 'moz', 'ms', 'o'];
1177 if ('hidden' in document
) {
1178 _hiddenPropCached
= 'hidden';
1179 return _hiddenPropCached
;
1182 for (var i
= 0, len
= prefixes
.length
; i
< len
; i
++){
1183 if ((prefixes
[i
] + 'Hidden') in document
) {
1184 _hiddenPropCached
= prefixes
[i
] + 'Hidden';
1185 return _hiddenPropCached
;
1191 var isPageHidden = function() {
1192 var prop
= getHiddenProp();
1197 return document
[prop
];
1200 // http://stackoverflow.com/a/2745459
1201 var isCanvasSupported = function() {
1202 return !!w
.CanvasRenderingContext2D
;
1205 // http://stackoverflow.com/a/10930441
1206 var isWebPSupported = function(callback
) {
1207 var webp
= new w
.Image();
1209 webp
.onload
= webp
.onerror = function() {
1210 callback(webp
.height
=== 2);
1212 webp
.src
= 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
1218 // http://www.myersdaily.org/joseph/javascript/md5.js
1219 function md5cycle(f
,c
){var b
=f
[0],a
=f
[1],d
=f
[2],e
=f
[3],b
=ff(b
,a
,d
,e
,c
[0],7,-680876936),e
=ff(e
,b
,a
,d
,c
[1],12,-389564586),d
=ff(d
,e
,b
,a
,c
[2],17,606105819),a
=ff(a
,d
,e
,b
,c
[3],22,-1044525330),b
=ff(b
,a
,d
,e
,c
[4],7,-176418897),e
=ff(e
,b
,a
,d
,c
[5],12,1200080426),d
=ff(d
,e
,b
,a
,c
[6],17,-1473231341),a
=ff(a
,d
,e
,b
,c
[7],22,-45705983),b
=ff(b
,a
,d
,e
,c
[8],7,1770035416),e
=ff(e
,b
,a
,d
,c
[9],12,-1958414417),d
=ff(d
,e
,b
,a
,c
[10],17,-42063),a
=ff(a
,d
,e
,b
,c
[11],22,-1990404162),b
=ff(b
,a
,d
,e
,c
[12],7,1804603682),e
=ff(e
,b
,a
,d
,c
[13],12,-40341101),d
=ff(d
,e
,b
,a
,c
[14],17,-1502002290),a
=ff(a
,d
,e
,b
,c
[15],22,1236535329),b
=gg(b
,a
,d
,e
,c
[1],5,-165796510),e
=gg(e
,b
,a
,d
,c
[6],9,-1069501632),d
=gg(d
,e
,b
,a
,c
[11],14,643717713),a
=gg(a
,d
,e
,b
,c
[0],20,-373897302),b
=gg(b
,a
,d
,e
,c
[5],5,-701558691),e
=gg(e
,b
,a
,d
,c
[10],9,38016083),d
=gg(d
,e
,b
,a
,c
[15],14,-660478335),a
=gg(a
,d
,e
,b
,c
[4],20,-405537848),b
=gg(b
,a
,d
,e
,c
[9],5,568446438),e
=gg(e
,b
,a
,d
,c
[14],9,-1019803690),d
=gg(d
,e
,b
,a
,c
[3],14,-187363961),a
=gg(a
,d
,e
,b
,c
[8],20,1163531501),b
=gg(b
,a
,d
,e
,c
[13],5,-1444681467),e
=gg(e
,b
,a
,d
,c
[2],9,-51403784),d
=gg(d
,e
,b
,a
,c
[7],14,1735328473),a
=gg(a
,d
,e
,b
,c
[12],20,-1926607734),b
=hh(b
,a
,d
,e
,c
[5],4,-378558),e
=hh(e
,b
,a
,d
,c
[8],11,-2022574463),d
=hh(d
,e
,b
,a
,c
[11],16,1839030562),a
=hh(a
,d
,e
,b
,c
[14],23,-35309556),b
=hh(b
,a
,d
,e
,c
[1],4,-1530992060),e
=hh(e
,b
,a
,d
,c
[4],11,1272893353),d
=hh(d
,e
,b
,a
,c
[7],16,-155497632),a
=hh(a
,d
,e
,b
,c
[10],23,-1094730640),b
=hh(b
,a
,d
,e
,c
[13],4,681279174),e
=hh(e
,b
,a
,d
,c
[0],11,-358537222),d
=hh(d
,e
,b
,a
,c
[3],16,-722521979),a
=hh(a
,d
,e
,b
,c
[6],23,76029189),b
=hh(b
,a
,d
,e
,c
[9],4,-640364487),e
=hh(e
,b
,a
,d
,c
[12],11,-421815835),d
=hh(d
,e
,b
,a
,c
[15],16,530742520),a
=hh(a
,d
,e
,b
,c
[2],23,-995338651),b
=ii(b
,a
,d
,e
,c
[0],6,-198630844),e
=ii(e
,b
,a
,d
,c
[7],10,1126891415),d
=ii(d
,e
,b
,a
,c
[14],15,-1416354905),a
=ii(a
,d
,e
,b
,c
[5],21,-57434055),b
=ii(b
,a
,d
,e
,c
[12],6,1700485571),e
=ii(e
,b
,a
,d
,c
[3],10,-1894986606),d
=ii(d
,e
,b
,a
,c
[10],15,-1051523),a
=ii(a
,d
,e
,b
,c
[1],21,-2054922799),b
=ii(b
,a
,d
,e
,c
[8],6,1873313359),e
=ii(e
,b
,a
,d
,c
[15],10,-30611744),d
=ii(d
,e
,b
,a
,c
[6],15,-1560198380),a
=ii(a
,d
,e
,b
,c
[13],21,1309151649),b
=ii(b
,a
,d
,e
,c
[4],6,-145523070),e
=ii(e
,b
,a
,d
,c
[11],10,-1120210379),d
=ii(d
,e
,b
,a
,c
[2],15,718787259),a
=ii(a
,d
,e
,b
,c
[9],21,-343485551);f
[0]=add32(b
,f
[0]);f
[1]=add32(a
,f
[1]);f
[2]=add32(d
,f
[2]);f
[3]=add32(e
,f
[3])}function cmn(f
,c
,b
,a
,d
,e
){c
=add32(add32(c
,f
),add32(a
,e
));return add32(c
<<d
|c
>>>32-d
,b
)}function ff(f
,c
,b
,a
,d
,e
,g
){return cmn(c
&b
|~c
&a
,f
,c
,d
,e
,g
)}function gg(f
,c
,b
,a
,d
,e
,g
){return cmn(c
&a
|b
&~a
,f
,c
,d
,e
,g
)}function hh(f
,c
,b
,a
,d
,e
,g
){return cmn(c
^b
^a
,f
,c
,d
,e
,g
)}function ii(f
,c
,b
,a
,d
,e
,g
){return cmn(b
^(c
|~a
),f
,c
,d
,e
,g
)}function md51(f
){var txt
="";var c
=f
.length
,b
=[1732584193,-271733879,-1732584194,271733878],a
;for(a
=64;a
<=f
.length
;a
+=64)md5cycle(b
,md5blk(f
.substring(a
-64,a
)));f
=f
.substring(a
-64);var d
=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(a
=0;a
<f
.length
;a
++)d
[a
>>2]|=f
.charCodeAt(a
)<<(a
%4<<3);d
[a
>>2]|=128<<(a
%4<<3);if(55<a
){md5cycle(b
,d
);for(a
=0;16>a
;a
++)d
[a
]=0}d
[14]=8*c
;md5cycle(b
,d
);return b
}function md5blk(f
){var c
=[],b
;for(b
=0;64>b
;b
+=4)c
[b
>>2]=f
.charCodeAt(b
)+(f
.charCodeAt(b
+1)<<8)+(f
.charCodeAt(b
+2)<<16)+(f
.charCodeAt(b
+3)<<24);return c
}var hex_chr
="0123456789abcdef".split("");function rhex(f
){for(var c
="",b
=0;4>b
;b
++)c
+=hex_chr
[f
>>8*b
+4&15]+hex_chr
[f
>>8*b
&15];return c
}function hex(f
){for(var c
=0;c
<f
.length
;c
++)f
[c
]=rhex(f
[c
]);return f
.join("")}function md5(f
){return hex(md51(f
))}function add32(f
,c
){return f
+c
&4294967295}"5d41402abc4b2a76b9719d911017c592"!=md5("hello")&&(add32=function(f
,c
){var b
=(f
&65535)+(c
&65535);return(f
>>16)+(c
>>16)+(b
>>16)<<16|b
&65535});
1220 var VERSION
= 1.711;
1221 var FRIENDLYNAME
= 'P'+'onyh'+'oof';
1222 var SIG
= '['+FRIENDLYNAME
+' v'+VERSION
+']';
1223 var DISTRIBUTION
= 'userjs';
1226 var STORAGEMETHOD
= 'none';
1227 var INTERNALUPDATE
= false;
1228 var USINGMUTATION
= false;
1230 var CURRENTPONY
= null;
1231 var REALPONY
= CURRENTPONY
;
1234 var UILANG
= 'en_US';
1235 var CURRENTLANG
= {};
1236 var ISUSINGPAGE
= false;
1237 var ISUSINGBUSINESS
= false;
1238 var ONPLUGINPAGE
= false;
1240 var SETTINGSPREFIX
= '';
1241 var globalSettings
= {};
1242 var GLOBALDEFAULTSETTINGS
= {
1243 'allowLoginScreen':true,
1244 'runForNewUsers':true,
1245 'globalSettingsMigrated':false, 'lastUserId':0, 'lastVersion':''
1248 var PONIES
= [{"code":"trixie","name":"Trixie","users":["trixie"],"menu_title":"The Great and Powerful Trixie demands your attention!","color":["6e98b4","3a7196"],"icon16":"trixie\/icon16_2.png","soundNotif":"trixie\/notif","loadingText":"Performing magic..."},{"code":"twilight","name":"Twilight Sparkle","users":["twilight","spark","tw\u0131l\u0131ght","twilite","twi light","\u0162wilight"],"search":"twilight sparkle|twilightsparkle|princess twilight","menu_title":"To switch to Princess Twilight, go to Misc > Appearance","color":["9f6eb4","7a3a96"],"icon16":"twilight\/icon32.png","mane6":true,"loadingText":"Studying friendship..."},{"code":"dash","name":"Rainbow Dash","users":["rainbow","dash"],"search":"rainbow dash|rainbowdash|dashie","color":["6e9db4","3a7796"],"soundNotif":"dash\/notif","mane6":true,"loadingText":"Loading... in ten seconds flat!","successText":"Aww yeah!"},{"code":"pinkie","name":"Pinkie Pie","users":["pink"],"search":"pinkie pie|pinkiepie|pinkamena diane pie","color":["b46e8a","963a5f"],"icon16":"pinkie\/favicon2.png","soundNotif":"pinkie\/notif2","mane6":true,"loadingText":"Come on everypony!"},{"code":"applej","name":"Applejack","users":["apple j","applej"],"search":"applejack|apple jack","color":["b4976e","96703a"],"soundNotif":"applej\/notif2","icon16":"applej\/favicon2.png","mane6":true,"loadingText":"Hold on there sugarcube!","successText":"Yeehaw!"},{"code":"flutter","name":"Fluttershy","users":["flutter","flut ter"],"search":"fluttershy|flutter shy","color":["b4ae6e","968e3a"],"icon16":"flutter\/favicon2.png","soundNotif":"flutter\/notif2","mane6":true,"loadingText":"Screaming...","successText":"Yay!"},{"code":"rarity","name":"Rarity","users":["rarity"],"color":["9b6eb4","763a96"],"soundNotif":"rarity\/notif","icon16":"rarity\/favicon2.png","mane6":true,"loadingText":"Whining...","seperator":true},{"code":"aloe","name":"Aloe","users":["aloe"],"search":"aloe|spa pony|spa ponies","color":["b46e91","963a68"],"icon16":"aloe\/favicon2.png"},{"code":"applebloom","name":"Apple Bloom","users":["appleb","apple b"],"search":"apple bloom|applebloom|cmc|cutie mark crusaders","color":["b46e8d","963a63"],"icon16":"_common\/cmc_favicon.png","soundNotif":"applebloom\/notif","loadingText":"Getting her cutie mark...","nocutie":true},{"code":"babsseed","name":"Babs Seed","users":["babs","seed"],"search":"babs seed|babsseed|cmc|cutie mark crusaders","color":["b4976e","96703a"],"icon16":"_common\/cmc_favicon.png","nocutie":true},{"code":"berry","name":"Berry Punch","users":["berry"],"search":"berry punch|berrypunch","color":["a56eb4","823a96"],"icon16":"berry\/favicon2.png"},{"code":"bigmac","name":"Big Macintosh","users":["bigmac","big mac"],"search":"bigmacintosh|big macintosh|big mcintosh|bigmcintosh","color":["b46e75","963a43"],"icon16":"bigmac\/favicon2.png","soundNotif":"bigmac\/notif","loadingText":"Saying eeyup..."},{"code":"bonbon","name":"Bon Bon","users":["bon bon","bonbon","bon-bon"],"search":"bon bon|bonbon","color":["6e89b4","3a5d96"]},{"code":"braeburn","name":"Braeburn","users":["braeburn","breaburn"],"search":"braeburn|breaburn","color":["b4a86e","96873a"],"icon16":"braeburn\/favicon2.png"},{"code":"cadance","name":"Cadance","users":["cadance","cadence"],"search":"cadance|cadence|princess cadance|princess cadence","color":["b46e96","963a6e"]},{"code":"carrot","name":"Carrot Top","users":["golden","carrot"],"search":"carrot top|carrottop|golden harvest","menu_title":"Also known as Golden Harvest","color":["b2b46e","93963a"]},{"code":"celestia","name":"Celestia","users":["celestia","trollestia","molestia"],"search":"celestia|princess celestia","color":["b46e98","963a71"],"icon16":"celestia\/favicon2.png","loadingText":"Raising the sun..."},{"code":"cheerilee","name":"Cheerilee","users":["cheerilee"],"color":["b46e96","963a6e"]},{"code":"colgate","name":"Colgate","users":["colgate","minuette"],"search":"colgate|minuette|minette","menu_title":"Also known as Minuette","color":["6e99b4","3a7396"],"icon16":"colgate\/favicon2.png","soundNotif":"colgate\/notif","loadingText":"Brushing..."},{"code":"cloudchaser","name":"Cloudchaser","users":["cloudch","cloud ch"],"search":"cloudchaser|cloud chaser|stormwalker|storm walker","menu_title":"Also known as Stormwalker","color":["856eb4","593a96"],"icon16":"cloudchaser\/favicon2.png"},{"code":"daring","name":"Daring Do","users":["daring"],"search":"daring do|daringdo","color":["b4a76e","96853a"]},{"code":"derpy","name":"Derpy Hooves","users":["derpy"],"color":["b4b46e","96963a"],"fbIndex_swf":"derpy\/fbIndex.swf","soundNotif":"derpy\/notif","icon16":"derpy\/icon16_2.png","loadingText":"Wondering what went wrong..."},{"code":"diamondtiara","name":"Diamond Tiara","users":["tiara"],"search":"diamond tiara|diamondtiara","color":["926eb4","6a3a96"],"stack":"villian"},{"code":"discord","name":"Discord","users":["discord"],"color":["b46f6e","963c3a"],"stack":"villian","loadingText":"CHOCOLATE RAIN","nocutie":true},{"code":"whooves","name":"Doctor Whooves","users":["whooves","time turn"],"search":"doctor whooves|doctor hooves|time turner","menu_title":"Also known as Time Turner","color":["b4a06e","967c3a"],"icon16":"whooves\/favicon2.png"},{"code":"fleur","name":"Fleur De Lis","users":["fleur","fluer"],"search":"fleur de lis|fluer de lis|fleur dis lee|fluer dis lee","color":["b46eb4","963a96"]},{"code":"flimflam","name":"Flim and Flam","users":["flim","flam"],"color":["b0b46e","91963a"],"loadingText":"Giving opportunities..."},{"code":"flitter","name":"Flitter","users":["Flitter"],"color":["846eb4","573a96"],"icon16":"flitter\/favicon2.png"},{"code":"gilda","name":"Gilda","users":["gilda"],"color":["b49a6e","96743a"],"stack":"villian","nocutie":true},{"code":"ironwill","name":"Iron Will","users":["iron will","ironwill"],"search":"ironwill|iron will","color":["6e84b4","3a5796"],"stack":"villian","nocutie":true},{"code":"sombra","name":"King Sombra","users":["sombra"],"color":["6eb46e","3a963a"],"stack":"villian","nocutie":true},{"code":"lightningdust","name":"Lightning Dust","users":["lightning"],"color":["6eb4ad","3a968d"],"icon16":"lightningdust\/favicon2.png"},{"code":"lotus","name":"Lotus","users":["lotus"],"search":"lotus|spa pony|spa ponies","color":["6ea0b4","3a7c96"],"icon16":"lotus\/favicon2.png"},{"code":"luna","name":"Luna","users":["luna"],"search":"luna|princess luna|nightmare moon|nightmaremoon","color":["6e7eb4","3a5096"],"icon16":"luna\/favicon2.png","soundNotif":"luna\/notif","loadingText":"Doubling the fun...","successText":"Huzzah!"},{"code":"lyra","name":"Lyra","users":["lyra"],"search":"lyra heartstrings","color":["6eb49d","3a9677"],"icon16":"lyra\/favicon2.png"},{"code":"nightmaremoon","name":"Nightmare Moon","users":["nightmare"],"search":"nightmare moon|nightmaremoon|luna|princess luna","color":["6e7fb4","3a5196"],"stack":"villian"},{"code":"nurseredheart","name":"Nurse Redheart","users":["nurse","redheart"],"color":["b46e76","963a45"],"icon16":"nurseredheart\/favicon2.png"},{"code":"octavia","name":"Octavia","users":["octavia"],"color":["b4a76e","96853a"]},{"code":"pinkamena","name":"Pinkamena","users":["pinkamena"],"search":"pinkamena diane pie","color":["b46e8c","963a62"],"stack":"villian"},{"code":"chrysalis","name":"Queen Chrysalis","users":["chrysalis"],"search":"queen chrysalis|changeling","color":["6ea2b4","3a7f96"],"stack":"chrysalis","loadingText":"Feeding...","nocutie":true},{"code":"roidrage","name":"Roid Rage","users":["snowflake","roid","rage"],"search":"snowflake|roidrage|roid rage","menu_title":"Also known as Snowflake","color":["b4ae6e","968e3a"],"soundNotif":"_sound\/roidrage_yeah","successText":"YEAH!"},{"code":"rose","name":"Rose","users":["rose"],"search":"roseluck","menu_title":"Also known as Roseluck","color":["b46e8c","963a62"],"icon16":"rose\/favicon2.png"},{"code":"scootaloo","name":"Scootaloo","users":["scootaloo"],"search":"scootaloo|cmc|cutie mark crusaders|chicken","color":["b4996e","96733a"],"icon16":"_common\/cmc_favicon.png","loadingText":"Getting her cutie mark...","nocutie":true},{"code":"shiningarmor","name":"Shining Armor","users":["shining armor"],"search":"shining armor|shiningarmor","color":["6e7bb4","3a4b96"],"icon16":"shiningarmor\/favicon2.png"},{"code":"silverspoon","name":"Silver Spoon","users":["spoon"],"search":"silver spoon|silverspoon","color":["6e97b4","3a7096"],"stack":"villian"},{"code":"soarin","name":"Soarin'","users":["soarin"],"search":"soarin'|wonderbolts","color":["6e9db4","3a7796"]},{"code":"spike","name":"Spike","users":["spike"],"color":["a26eb4","7f3a96"],"nocutie":true},{"code":"spitfire","name":"Spitfire","users":["spitfire"],"search":"spitfire|wonderbolts","color":["b4ae6e","968e3a"],"icon16":"spitfire\/favicon2.png"},{"code":"sweetieb","name":"Sweetie Belle","users":["sweetieb","sweetie b"],"search":"sweetiebelle|sweetie belle|cmc|cutie mark crusaders","color":["a06eb4","7c3a96"],"icon16":"_common\/cmc_favicon.png","soundNotif":"sweetieb\/notif","loadingText":"Getting her cutie mark...","nocutie":true},{"code":"thunderlane","name":"Thunderlane","users":["thunder"],"search":"thunderlane|thunder lane","color":["6eb4b4","3a9696"]},{"code":"vinyl","name":"Vinyl Scratch","users":["vinyl","vinyx","dj p"],"search":"vinyl scratch|dj pon3|dj-pon3|dj pon 3|dj pon-3","menu_title":"Also known as DJ Pon-3","color":["6ea9b4","3a8896"],"icon16":"vinyl\/favicon2.png","soundNotif":"vinyl\/notif","loadingText":"Wubbing..."},{"code":"zecora","name":"Zecora","users":["zecora"],"color":["b4af6e","96903a"]},{"code":"blank","name":"(Blank)","color":["b46e6e","963a3a"],"hidden":true,"nocutie":true},{"code":"bloomberg","name":"Bloomberg","color":["9fb46e","7a963a"],"hidden":true,"nocutie":true},{"code":"mono","name":"Mono","color":["b46e6e","963a3a"],"stack":"mono","hidden":true},{"code":"taugeh","name":"Taugeh","color":["b4b46e","96963a"],"icon16":"twilight\/icon32.png","hidden":true,"nocutie":true}];
1249 var LANG
= {"af_ZA":{"sniff_comment_tooltip_like":"Hou van hierdie opmerking","sniff_comment_tooltip_unlike":"Hou nie meer van hierdie opmerking nie"},"ar_AR":{"sniff_comment_tooltip_like":"\u0627\u0644\u0625\u0639\u062c\u0627\u0628 \u0628\u0627\u0644\u062a\u0639\u0644\u064a\u0642","sniff_comment_tooltip_unlike":"\u0625\u0644\u063a\u0627\u0621 \u0625\u0639\u062c\u0627\u0628\u064a \u0628\u0647\u0630\u0627 \u0627\u0644\u062a\u0639\u0644\u064a\u0642"},"az_AZ":{"sniff_comment_tooltip_like":"Bu r\u0259yi b\u0259y\u0259n","sniff_comment_tooltip_unlike":"Bu \u015f\u0259rhi b\u0259y\u0259nm\u0259"},"be_BY":{"sniff_comment_tooltip_like":"\u041f\u0430\u0434\u0430\u0431\u0430\u0435\u0446\u0446\u0430","sniff_comment_tooltip_unlike":"\u041c\u043d\u0435 \u0431\u043e\u043b\u044c\u0448 \u043d\u0435 \u043f\u0430\u0434\u0430\u0431\u0430\u0435\u0446\u0446\u0430 \u0433\u044d\u0442\u044b \u043a\u0430\u043c\u044d\u043d\u0442\u0430\u0440"},"bg_BG":{"sniff_comment_tooltip_like":"\u0425\u0430\u0440\u0435\u0441\u0432\u0430\u043c \u0442\u043e\u0437\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440","sniff_comment_tooltip_unlike":"\u0412\u0435\u0447\u0435 \u043d\u0435 \u0445\u0430\u0440\u0435\u0441\u0432\u0430\u043c"},"bn_IN":{"sniff_comment_tooltip_like":"\u09ae\u09a8\u09cd\u09a4\u09ac\u09cd\u09af\u099f\u09bf \u09ad\u09be\u09b2\u09cb \u09b2\u09c7\u0997\u09c7\u099b\u09c7","sniff_comment_tooltip_unlike":"\u09ad\u09be\u09b2\u09cb \u09b2\u09be\u0997\u09c7\u09a8\u09bf"},"bs_BA":{"sniff_comment_tooltip_like":"Svi\u0111a mi se ovaj komentar","sniff_comment_tooltip_unlike":"Ne svi\u0111a mi se komentar"},"ca_ES":{"sniff_comment_tooltip_like":"M'agrada aquest comentari","sniff_comment_tooltip_unlike":"Ja no m'agrada aquest comentari."},"cs_CZ":{"sniff_comment_tooltip_like":"Tento koment\u00e1\u0159 se mi l\u00edb\u00ed.","sniff_comment_tooltip_unlike":"Koment\u00e1\u0159 se mi u\u017e nel\u00edb\u00ed","close":"Zav\u0159\u00edt"},"cy_GB":{"sniff_comment_tooltip_like":"Hoffi'r sylw hwn","sniff_comment_tooltip_unlike":"Peidio hoffi'r sylw hwn"},"da_DK":{"fb_composer_lessons":"Hvilke lektioner i venskab har du l\u00e6rt idag?","sniff_comment_tooltip_like":"Tilkendegiv, at du synes godt om denne kommentar","sniff_comment_tooltip_unlike":"Synes ikke godt om denne kommentar l\u00e6ngere","close":"Luk"},"de_DE":{"fb_composer_lessons":"Welche Lektionen \u00fcber Freundschaft hast Du heute gelernt?","sniff_comment_tooltip_like":"Dieser Kommentar gef\u00e4llt mir","sniff_comment_tooltip_unlike":"Dieser Kommentar gef\u00e4llt mir nicht mehr","close":"Schlie\u00dfen"},"el_GR":{"sniff_comment_tooltip_like":"\u039c\u03bf\u03c5 \u03b1\u03c1\u03ad\u03c3\u03b5\u03b9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c3\u03c7\u03cc\u03bb\u03b9\u03bf","sniff_comment_tooltip_unlike":"\"\u0394\u03b5\u03bd \u03bc\u03bf\u03c5 \u03b1\u03c1\u03ad\u03c3\u03b5\u03b9!\" \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c3\u03c7\u03cc\u03bb\u03b9\u03bf"},"en_PI":{"sniff_comment_tooltip_like":"This comment be pleasin","sniff_comment_tooltip_unlike":"Care not fer such trifles"},"en_US":{"fb_composer_lessons":"What lessons in friendship have you learned today?","fb_comment_box":"Write a friendship letter...","fb_search_box":"Search for ponies, places and things","fb_search_boxAlt":"Type to search for ponies, places and things","fb_composer_coolstory":"Write a cool story...","fb_composer_ponies":"Ponies!","fb_composer_ponies_caps":"PONIES!!!","fb_share_tooltip":"Remember! You gotta share... You gotta care...","sniff_comment_tooltip_like":"Like this comment","sniff_comment_tooltip_unlike":"Unlike this comment","sniff_fb_search_boxAlt":"Type to search","close":"Close","reloadNow":"Reload now","notNow":"Not now","invertSelection":"Invert selection","finish":"Finish","done":"Eeyup","options_title":"Ponyhoof Options","options_tabs_main":"General","options_tabs_background":"Background","options_tabs_sounds":"Sounds","options_tabs_extras":"Misc","options_tabs_advanced":"Debug","options_tabs_about":"About","settings_disable_runForNewUsers_explain":"If you enable this, Ponyhoof will not automatically run for other Facebook accounts that did not activate Ponyhoof yet. They can still open Ponyhoof Options to re-enable Ponyhoof if they wish to.","settings_extras_login_bg":"Use alternate background","settings_sounds":"Play sounds (e.g. notifications and dialogs)","settings_sounds_noNotification":"Play sounds (e.g. dialogs)","settings_extras_runForNewUsers_explain":"If you disable this, Ponyhoof will not automatically run for other Facebook accounts that did not activate Ponyhoof yet. They can still open Ponyhoof Options to re-enable Ponyhoof if they wish to.","settings_main_visitPage":"Visit the Ponyhoof page for news or contact us","settings_main_visitPageBusiness":"Visit the Ponyhoof page for news","settings_sounds_unavailable":"Notification sounds are not available on your browser. Please update your browser if possible.","updater_title":"Update Ponyhoof","costume_tooltip":"Limited to certain characters only"},"eo_EO":{"sniff_comment_tooltip_like":"\u015cati \u0109i tiun komenton","sniff_comment_tooltip_unlike":"Ne plu \u015dati \u0109i tiun komenton"},"es_ES":{"sniff_comment_tooltip_like":"Me gusta este comentario","sniff_comment_tooltip_unlike":"Ya no me gusta este comentario","close":"Cerrar"},"es_LA":{"fb_composer_lessons":"\u00bfQue has aprendido hoy sobre la amistad?","fb_comment_box":"Escribe un reporte de amistad...","sniff_comment_tooltip_like":"Me gusta este comentario","sniff_comment_tooltip_unlike":"Ya no me gusta este comentario","close":"Cerrar"},"et_EE":{"sniff_comment_tooltip_like":"Meeldib see kommentaar","sniff_comment_tooltip_unlike":"Ei meeldi enam"},"eu_ES":{"sniff_comment_tooltip_like":"Iruzkin hau atsegin dut","sniff_comment_tooltip_unlike":"Iruzkin hau desatsegin"},"fa_IR":{"sniff_comment_tooltip_like":"\u0627\u06cc\u0646 \u062f\u06cc\u062f\u06af\u0627\u0647 \u0631\u0627 \u0645\u06cc\u200c\u067e\u0633\u0646\u062f\u0645","sniff_comment_tooltip_unlike":"\u0627\u06cc\u0646 \u062f\u06cc\u062f\u06af\u0627\u0647 \u0631\u0627 \u0646\u067e\u0633\u0646\u062f\u06cc\u062f\u0645"},"fb_LT":{"fb_composer_lessons":"W|-|47 \u00a33550|\\|5 !|\\| |=|2!3|\\||)5|-|!|* |-|4\\\/3 '\/0|_| \u00a334|2|\\|3|) 70|)4'\/?","fb_comment_box":"W|2!73 4 |=|2!3|\\||)5|-|!|* \u00a33773|2...","fb_search_box":"S34|2(|-| |=0|2 |*0|\\|!35, |*\u00a34(35 4|\\||) 7|-|!|\\|95","fb_search_boxAlt":"T'\/|*3 70 534|2(|-| |=0|2 |*0|\\|!35, |*\u00a34(35 4|\\||) 7|-|!|\\|95","fb_composer_coolstory":"W|2!73 4 (00\u00a3 570|2'\/...","fb_composer_ponies":"P0|\\|!35!","fb_composer_ponies_caps":"PONIES!!!","fb_share_tooltip":"R3|\\\/|3|\\\/|83|2! Y0|_| 90774 5|-|4|23... Y0|_| 90774 (4|23...","close":"Alt+F4","reloadNow":"R3\u00a304|) |\\|0vv","notNow":"N07 |\\|0vv","invertSelection":"I|\\|\\\/3|27 53\u00a33(7!0|\\|","finish":"F!|\\|!5|-|","done":"E3'\/|_||*","options_title":"P0|\\|'\/|-|00|= O|*7!0|\\|5","options_tabs_main":"G3|\\|3|24\u00a3","options_tabs_background":"B4(k9|20|_||\\||)","options_tabs_sounds":"S0|_||\\||)5","options_tabs_extras":"M!5(","options_tabs_advanced":"D38|_|9","options_tabs_about":"A80|_|7","settings_disable_runForNewUsers_explain":"I|= '\/0|_| 3|\\|48\u00a33 7|-|!5, P0|\\|'\/|-|00|= vv!\u00a3\u00a3 |\\|07 4|_|70|\\\/|47!(4\u00a3\u00a3'\/ |2|_||\\| |=0|2 07|-|3|2 F4(3800k 4((0|_||\\|75 7|-|47 |)!|) |\\|07 4(7!\\\/473 P0|\\|'\/|-|00|= '\/37. T|-|3'\/ (4|\\| 57!\u00a3\u00a3 0|*3|\\| P0|\\|'\/|-|00|= O|*7!0|\\|5 70 |23-3|\\|48\u00a33 P0|\\|'\/|-|00|= !|= 7|-|3'\/ vv!5|-| 70.","settings_extras_login_bg":"U53 4\u00a373|2|\\|473 84(k9|20|_||\\||)","settings_sounds":"P\u00a34'\/ 50|_||\\||)5 (3.9. |\\|07!|=!(47!0|\\|5 4|\\||) |)!4\u00a3095)","settings_sounds_noNotification":"P\u00a34'\/ 50|_||\\||)5 (3.9. |)!4\u00a3095)","settings_extras_runForNewUsers_explain":"I|= '\/0|_| |)!548\u00a33 7|-|!5, P0|\\|'\/|-|00|= vv!\u00a3\u00a3 |\\|07 4|_|70|\\\/|47!(4\u00a3\u00a3'\/ |2|_||\\| |=0|2 07|-|3|2 F4(3800k 4((0|_||\\|75 7|-|47 |)!|) |\\|07 4(7!\\\/473 P0|\\|'\/|-|00|= '\/37. T|-|3'\/ (4|\\| 57!\u00a3\u00a3 0|*3|\\| P0|\\|'\/|-|00|= O|*7!0|\\|5 70 |23-3|\\|48\u00a33 P0|\\|'\/|-|00|= !|= 7|-|3'\/ vv!5|-| 70.","settings_main_visitPage":"V!5!7 7|-|3 P0|\\|'\/|-|00|= |*493 |=0|2 |\\|3vv5 0|2 (0|\\|74(7 |_|5","settings_main_visitPageBusiness":"V!5!7 7|-|3 P0|\\|'\/|-|00|= |*493 |=0|2 |\\|3vv5","settings_sounds_unavailable":"N07!|=!(47!0|\\| 50|_||\\||)5 4|23 |\\|07 4\\\/4!\u00a348\u00a33 0|\\| '\/0|_||2 8|20vv53|2. P\u00a33453 |_||*|)473 '\/0|_||2 8|20vv53|2 !|= |*055!8\u00a33.","updater_title":"U|*|)473 P0|\\|'\/|-|00|=","costume_tooltip":"L!|\\\/|!73|) 70 (3|274!|\\| (|-|4|24(73|25 0|\\|\u00a3'\/","sniff_comment_tooltip_like":"<3"},"fi_FI":{"fb_composer_lessons":"Mit\u00e4 oppeja yst\u00e4vyydest\u00e4 olet oppinut t\u00e4n\u00e4\u00e4n?","sniff_comment_tooltip_like":"Tykk\u00e4\u00e4 t\u00e4st\u00e4 kommentista","sniff_comment_tooltip_unlike":"En tykk\u00e4\u00e4k\u00e4\u00e4n","close":"Sulje"},"fo_FO":{"sniff_comment_tooltip_like":"M\u00e6r d\u00e1mar vi\u00f0merkingina"},"fr_CA":{"fb_composer_lessons":"Quelles le\u00e7ons sur l'amiti\u00e9 avez-vous appris aujourd'hui ?","sniff_comment_tooltip_like":"J\u2019aime ce commentaire","sniff_comment_tooltip_unlike":"Je n\u2019aime plus ce commentaire","close":"Fermer"},"fr_FR":{"fb_composer_lessons":"Quelles le\u00e7ons sur l'amiti\u00e9 avez-vous appris aujourd'hui ?","sniff_comment_tooltip_like":"J\u2019aime ce commentaire","sniff_comment_tooltip_unlike":"Je n\u2019aime plus ce commentaire","close":"Fermer"},"fy_NL":{"sniff_comment_tooltip_like":"Leuke reaksje","sniff_comment_tooltip_unlike":"Ik mei net mear oer dit berjocht"},"ga_IE":{"fb_composer_lessons":"cad ceachtanna i cairdeas ad'fhoghlaim t\u00fa inniu?","sniff_comment_tooltip_like":"L\u00e9irigh gur maith leat an tr\u00e1cht seo","sniff_comment_tooltip_unlike":"N\u00ed maith liom an tr\u00e1cht seo","close":"D\u00fan"},"gl_ES":{"sniff_comment_tooltip_like":"G\u00fastame este comentario","sniff_comment_tooltip_unlike":"Xa non me gusta"},"he_IL":{"fb_composer_lessons":"\u05d0\u05d9\u05dc\u05d5 \u05dc\u05e7\u05d7\u05d9\u05dd \u05d1\u05d9\u05d3\u05d9\u05d3\u05d5\u05ea \u05dc\u05de\u05d3\u05ea \u05d4\u05d9\u05d5\u05dd?","sniff_comment_tooltip_like":"\u05d0\u05d5\u05d4\u05d1 \u05d0\u05ea \u05d4\u05ea\u05d2\u05d5\u05d1\u05d4","sniff_comment_tooltip_unlike":"\u05dc\u05d0 \u05d0\u05d4\u05d1\/\u05d4 \u05d0\u05ea \u05ea\u05d2\u05d5\u05d1\u05d4 \u05d6\u05d5","close":"\u05e1\u05d2\u05d5\u05e8"},"hi_IN":{"sniff_comment_tooltip_like":"\u091f\u093f\u092a\u094d\u092a\u0923\u0940 \u092a\u0938\u0902\u0926 \u0915\u0930\u0947\u0902","sniff_comment_tooltip_unlike":"\u0907\u0938 \u091f\u093f\u092a\u094d\u092a\u0923\u0940 \u0915\u094b \u0928\u093e\u092a\u0938\u0902\u0926 \u0915\u0930\u0947\u0902"},"hr_HR":{"sniff_comment_tooltip_like":"Svi\u0111a mi se ovaj komentar","sniff_comment_tooltip_unlike":"Ne svi\u0111a mi se"},"hu_HU":{"fb_composer_lessons":"Mit tanult\u00e1l ma a bar\u00e1ts\u00e1gr\u00f3l?","sniff_comment_tooltip_like":"Tetszik a bejegyz\u00e9s.","sniff_comment_tooltip_unlike":"M\u00e9gsem tetszik","close":"Bez\u00e1r\u00e1s"},"hy_AM":{"sniff_comment_tooltip_like":"\u0540\u0561\u057e\u0561\u0576\u0565\u056c \u0561\u0575\u057d \u0574\u0565\u056f\u0576\u0561\u0562\u0561\u0576\u0578\u0582\u0569\u0575\u0578\u0582\u0576\u0568","sniff_comment_tooltip_unlike":"\u0549\u0570\u0561\u057e\u0561\u0576\u0565\u056c \u0561\u0575\u057d \u0574\u0565\u056f\u0576\u0561\u0562\u0561\u0576\u0578\u0582\u0569\u0575\u0578\u0582\u0576\u0568"},"id_ID":{"fb_composer_lessons":"Apa pelajaran yang kalian dapat tentang persahabatan hari ini?","sniff_comment_tooltip_like":"Suka komentar ini","sniff_comment_tooltip_unlike":"Tidak suka komentar ini","close":"Tutup"},"is_IS":{"sniff_comment_tooltip_like":"L\u00edkar vi\u00f0 \u00feessi umm\u00e6li","sniff_comment_tooltip_unlike":"L\u00edka ekki vi\u00f0 \u00feessi umm\u00e6li"},"it_IT":{"fb_composer_lessons":"Che cosa hai imparato oggi sull'amicizia?","sniff_comment_tooltip_like":"Di' che ti piace questo commento","sniff_comment_tooltip_unlike":"Di' che non ti piace pi\u00f9 questo commento","close":"Chiudi"},"ja_JP":{"fb_composer_lessons":"\u4eca\u65e5\u306f\u53cb\u60c5\u306b\u3069\u306e\u3088\u3046\u306a\u6559\u8a13\u3092\u5b66\u3073\u307e\u3057\u305f\u304b\uff1f","sniff_comment_tooltip_like":"\u3053\u306e\u30b3\u30e1\u30f3\u30c8\u306f\u3044\u3044\u306d\uff01","sniff_comment_tooltip_unlike":"\u3044\u3044\u306d\uff01\u3092\u53d6\u308a\u6d88\u3059","close":"\u9589\u3058\u308b"},"ka_GE":{"sniff_comment_tooltip_like":"\u10db\u10dd\u10d8\u10ec\u10dd\u10dc\u10d4 \u10d4\u10e1 \u10d9\u10dd\u10db\u10d4\u10dc\u10e2\u10d0\u10e0\u10d8","sniff_comment_tooltip_unlike":"\u10d0\u10e6\u10d0\u10e0 \u10db\u10dd\u10db\u10ec\u10dd\u10dc\u10e1 \u10d4\u10e1 \u10d9\u10dd\u10db\u10d4\u10dc\u10e2\u10d0\u10e0\u10d8"},"km_KH":{"sniff_comment_tooltip_like":"\u1785\u17bc\u179b\u1785\u17b7\u178f\u17d2\u178f \u179c\u17b7\u1785\u17b6\u179a \u1793\u17c1\u17c7","sniff_comment_tooltip_unlike":"\u179b\u17c2\u1784\u1785\u17bc\u179b\u1785\u17b7\u178f\u17d2\u178f\u1798\u178f\u17b7\u1793\u17c1\u17c7"},"ko_KR":{"fb_composer_lessons":"\uc6b0\uc815\uc5d0 \uad00\ud574\uc11c \uc624\ub298 \ubb34\uc5c7\uc744 \ubc30\uc6e0\ub098\uc694?","sniff_comment_tooltip_like":"\uc88b\uc544\uc694","sniff_comment_tooltip_unlike":"\uc88b\uc544\uc694 \ucde8\uc18c","close":"\ub2eb\uae30"},"ku_TR":{"sniff_comment_tooltip_like":"V\u00ea \u015f\u00eerovey\u00ea biecib\u00eene","sniff_comment_tooltip_unlike":"V\u00ea \u015firovey\u00ea neecib\u00eene"},"la_VA":[],"lt_LT":{"fb_composer_lessons":"Kokias \u017einias apie draugyst\u0119 i\u0161mokote \u0161iandien?","sniff_comment_tooltip_like":"Patinka \u0161is komentaras","sniff_comment_tooltip_unlike":"Nepatinka \u0161is komentaras","close":"U\u017edaryti"},"lv_LV":{"sniff_comment_tooltip_unlike":"Koment\u0101rs vairs nepat\u012bk"},"mk_MK":{"fb_composer_lessons":"\u041a\u043e\u0438 \u043b\u0435\u043a\u0446\u0438\u0438 \u0437\u0430 \u043f\u0440\u0438\u0458\u0430\u0442\u0435\u043b\u0441\u0442\u0432\u043e\u0442\u043e \u0434\u043e\u0437\u043d\u0430\u0432\u0442\u0435 \u0434\u0435\u043d\u0435\u0441?","sniff_comment_tooltip_like":"\u041c\u0438 \u0441\u0435 \u0434\u043e\u043f\u0430\u0453\u0430 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u043e\u0432","sniff_comment_tooltip_unlike":"\u041d\u0435 \u043c\u0438 \u0441\u0435 \u0434\u043e\u043f\u0430\u0453\u0430","close":"\u0417\u0430\u0442\u0432\u043e\u0440\u0438"},"ml_IN":{"sniff_comment_tooltip_like":"\u0d08 \u0d05\u0d2d\u0d3f\u0d2a\u0d4d\u0d30\u0d3e\u0d2f\u0d02 \u0d07\u0d37\u0d4d\u0d1f\u0d2e\u0d3e\u0d2f\u0d3f"},"ms_MY":{"fb_composer_lessons":"Apakah pelajaran tentang persahabatan yang telah anda pelajari hari ini?","fb_comment_box":"Tuliskan surat persahabatan...","fb_composer_ponies":"Kuda!","fb_composer_ponies_caps":"KUDA!!!","sniff_comment_tooltip_like":"Suka komen ini","sniff_comment_tooltip_unlike":"Tidak suka komen ini","close":"Tutup","options_title":"Opsyen Ponyhoof"},"nb_NO":{"sniff_comment_tooltip_like":"Lik denne kommentaren"},"ne_NP":[],"nl_NL":{"fb_composer_lessons":"Wat heb je vandaag geleerd over vriendschap?","sniff_comment_tooltip_like":"Leuke reactie","sniff_comment_tooltip_unlike":"Reactie niet meer leuk","close":"Sluiten"},"pa_IN":{"sniff_comment_tooltip_like":"\u0a07\u0a39 \u0a1f\u0a3f\u0a71\u0a2a\u0a23\u0a40 \u0a2a\u0a38\u0a70\u0a26 \u0a15\u0a30\u0a4b","sniff_comment_tooltip_unlike":"\u0a07\u0a39 \u0a1f\u0a3f\u0a71\u0a2a\u0a23\u0a40 \u0a28\u0a3e\u0a2a\u0a38\u0a70\u0a26 \u0a15\u0a30\u0a4b|"},"pl_PL":{"fb_composer_lessons":"Czego si\u0119 dzisiaj nauczy\u0142e\u015b o przyja\u017ani?","sniff_comment_tooltip_like":"Polub komentarz","sniff_comment_tooltip_unlike":"Nie lubi\u0119 tego komentarza","close":"Zamknij"},"ps_AF":[],"pt_BR":{"fb_composer_lessons":"Quais li\u00e7\u00f5es sobre amizade voc\u00ea aprendeu hoje?","sniff_comment_tooltip_like":"Curtir este coment\u00e1rio","sniff_comment_tooltip_unlike":"Curtir (desfazer) este coment\u00e1rio","close":"Fechar"},"pt_PT":{"fb_composer_lessons":"Que li\u00e7\u00f5es de amizade voc\u00ea aprendeu hoje?","sniff_comment_tooltip_like":"Gosto deste coment\u00e1rio","sniff_comment_tooltip_unlike":"N\u00e3o gosto deste coment\u00e1rio","close":"Fechar"},"ro_RO":{"fb_composer_lessons":"Ce lec\u0163ii despre prietenie ai \u00eenv\u0103\u0163at ast\u0103zi?","sniff_comment_tooltip_like":"\u00cemi place acest comentariu","sniff_comment_tooltip_unlike":"Nu-mi mai place acest comentariu","close":"\u00cenchide"},"ru_RU":{"fb_composer_lessons":"\u041a\u0430\u043a\u0438\u0435 \u0443\u0440\u043e\u043a\u0438 \u0434\u0440\u0443\u0436\u0431\u044b \u0432\u044b \u0432\u044b\u0443\u0447\u0438\u043b\u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f?","sniff_comment_tooltip_like":"\u041c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439","sniff_comment_tooltip_unlike":"\u041d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f","close":"\u0417\u0430\u043a\u0440\u044b\u0442\u044c"},"sk_SK":{"fb_composer_lessons":"Ak\u00e9 lekcie priate\u013estva si sa nau\u010dil dnes?","sniff_comment_tooltip_like":"P\u00e1\u010di sa mi tento koment\u00e1r","sniff_comment_tooltip_unlike":"Tento koment\u00e1r sa mi u\u017e nep\u00e1\u010di","close":"Zavrie\u0165"},"sl_SI":{"fb_composer_lessons":"Kaj si se o prijateljstvu nau\u010dil\/-a danes?","sniff_comment_tooltip_like":"V\u0161e\u010d mi je","sniff_comment_tooltip_unlike":"Ta komentar mi ni v\u0161e\u010d","close":"Zapri"},"sq_AL":{"sniff_comment_tooltip_like":"P\u00eblqeje k\u00ebt\u00eb koment","sniff_comment_tooltip_unlike":"Mos p\u00eblqe k\u00ebt\u00eb koment"},"sr_RS":{"sniff_comment_tooltip_like":"\u0421\u0432\u0438\u0452\u0430 \u043c\u0438 \u0441\u0435 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440.","sniff_comment_tooltip_unlike":"\u041d\u0435 \u0441\u0432\u0438\u0452\u0430 \u043c\u0438 \u0441\u0435 \u043e\u0432\u0430\u0458 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440","close":"\u0417\u0430\u0442\u0432\u043e\u0440\u0438"},"sv_SE":{"fb_composer_lessons":"Vilka l\u00e4rdomar i v\u00e4nskap har du l\u00e4rt dig idag?","sniff_comment_tooltip_like":"Gilla den h\u00e4r kommentaren","sniff_comment_tooltip_unlike":"Sluta gilla den h\u00e4r kommentaren","close":"St\u00e4ng"},"sw_KE":[],"ta_IN":{"sniff_comment_tooltip_like":"\u0b87\u0b95\u0bcd\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bbf\u0ba9\u0bc8 \u0bb5\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bc1\u0b95\u0bbf\u0bb1\u0bc7\u0ba9\u0bcd","sniff_comment_tooltip_unlike":"\u0b87\u0b95\u0bcd\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bbf\u0ba9\u0bc8 \u0bb5\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bb5\u0bbf\u0bb2\u0bcd\u0bb2\u0bc8","close":"\u0e1b\u0e34\u0e14"},"te_IN":{"sniff_comment_tooltip_unlike":"\u0c35\u0c4d\u0c2f\u0c3e\u0c16\u0c4d\u0c2f \u0c28\u0c1a\u0c4d\u0c1a\u0c32\u0c47\u0c26\u0c41"},"th_TH":{"sniff_comment_tooltip_like":"\u0e16\u0e39\u0e01\u0e43\u0e08\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e19\u0e35\u0e49","sniff_comment_tooltip_unlike":"\u0e40\u0e25\u0e34\u0e01\u0e16\u0e39\u0e01\u0e43\u0e08\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e19\u0e35\u0e49"},"tl_PH":{"fb_composer_lessons":"Anong mga aralin sa pagkakaibigan ang natutunan mo ngayon?","sniff_comment_tooltip_like":"Gustuhin ang komentong ito","sniff_comment_tooltip_unlike":"Ayawan ang komentong ito","close":"Isara"},"tr_TR":{"fb_composer_lessons":"Bug\u00fcn arkada\u015fl\u0131kla ilgili neler \u00f6\u011frendin?","sniff_comment_tooltip_like":"Bu yorumu be\u011fen","sniff_comment_tooltip_unlike":"Bu yorumu be\u011fenmekten vazge\u00e7","close":"Kapat"},"uk_UA":{"fb_composer_lessons":"\u042f\u043a\u0456 \u0443\u0440\u043e\u043a\u0438 \u0432 \u0434\u0440\u0443\u0436\u0431\u0456 \u0432\u0438 \u0434\u0456\u0437\u043d\u0430\u043b\u0438\u0441\u044f \u0441\u044c\u043e\u0433\u043e\u0434\u043d\u0456?","sniff_comment_tooltip_like":"\u0412\u043f\u043e\u0434\u043e\u0431\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440","sniff_comment_tooltip_unlike":"\u041d\u0435 \u043f\u043e\u0434\u043e\u0431\u0430\u0454\u0442\u044c\u0441\u044f \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440","close":"\u0417\u0430\u043a\u0440\u0438\u0442\u0438"},"vi_VN":{"sniff_comment_tooltip_like":"Th\u00edch b\u00ecnh lu\u1eadn n\u00e0y","sniff_comment_tooltip_unlike":"B\u1ecf th\u00edch b\u00ecnh lu\u1eadn n\u00e0y n\u1eefa"},"zh_CN":{"sniff_comment_tooltip_like":"\u559c\u6b22\u6b64\u8bc4\u8bba","sniff_comment_tooltip_unlike":"\u4e0d\u559c\u6b22\u6b64\u8bc4\u8bba","close":"\u5173\u95ed"},"zh_HK":{"sniff_comment_tooltip_like":"\u5c0d\u9019\u5247\u7559\u8a00\u8b9a\u597d","sniff_comment_tooltip_unlike":"\u53d6\u6d88\u8b9a\u597d"},"zh_TW":{"fb_composer_lessons":"\u4f60\u4eca\u5929\u5f9e\u53cb\u60c5\u88e1\u9762\u5b78\u5230\u4e86\u4ec0\u9ebc\uff1f","sniff_comment_tooltip_like":"\u8aaa\u9019\u5247\u7559\u8a00\u8b9a","sniff_comment_tooltip_unlike":"\u6536\u56de\u8b9a","close":"\u95dc\u9589"}};
1250 var SOUNDS
= {"AUTO":{"name":"(Auto-select)","seperator":true},"_sound\/defaultNotification":{"name":"Casting magic","title":"This will also be used for characters that do not have their own notification sound"},"trixie\/notif":{"name":"Trixie - Watch in awe!"},"dash\/notif":{"name":"Rainbow Dash - Aww yeah!"},"pinkie\/notif2":{"name":"Pinkie Pie - *rimshot*"},"applej\/notif":{"name":"Applejack - Yeehaw!"},"flutter\/notif2":{"name":"Fluttershy - Yay!"},"rarity\/notif":{"name":"Rarity - This is whining!"},"applebloom\/notif":{"name":"Apple Bloom - That'll be four bits"},"bigmac\/notif":{"name":"Big Macintosh - Eeyup"},"colgate\/notif":{"name":"Colgate - Why you don't brush your teeth"},"derpy\/notif":{"name":"Derpy Hooves - I brought you a letter!"},"luna\/notif":{"name":"Luna - Huzzah!"},"_sound\/roidrage_yeah":{"name":"Roid Rage\/Snowflake - YEAH!"},"sweetieb\/notif":{"name":"Sweetie Belle - Oh come on!"},"vinyl\/notif":{"name":"Vinyl Scratch - Yeah!","seperator":true},"twilight\/notif":{"name":"Twilight Sparkle - It's not over yet!"},"_sound\/grin2":{"name":"Fluttershy - *squee*"},"_sound\/dash_dundundun":{"name":"Rainbow Dash - DUN DUN DUN"},"_sound\/dash_egghead":{"name":"Rainbow Dash - I'm an egghead"},"_sound\/pinkie_boring":{"name":"Pinkie Pie - Booooring!"},"_sound\/pinkie_gasp":{"name":"Pinkie Pie - *gasp*"},"_sound\/pinkie_partycannon":{"name":"Pinkie Pie - Party cannon"},"_sound\/pinkie_pinkiepiestyle":{"name":"Pinkie Pie - Pinkie Pie style!"},"_sound\/flutter_woohoo":{"name":"Fluttershy - Woo hoo"},"_sound\/rarity_dumbrock":{"name":"Rarity - Dumb rock!"},"_sound\/rarity_itison":{"name":"Rarity - Oh. It. Is. On!"},"_sound\/rarity_wahaha":{"name":"Rarity - Wahaha!"},"_sound\/octavia_nevermess":{"name":"Octavia - Never mess with Octavia"},"_sound\/vinyl_awyeah":{"name":"Vinyl Scratch - Aw yeah!"},"_sound\/vinyl_mybasscannon":{"name":"Vinyl Scratch - My bass cannon!"},"_sound\/vinyl_wubwubwub":{"name":"Vinyl Scratch - Wubwubwub"},"_sound\/vinyl_wubedubdub":{"name":"Vinyl Scratch - Wubedubdub"},"_sound\/vinyl_yougotwubs":{"name":"Vinyl Scratch - You got wubs"}};
1251 var SOUNDS_CHAT
= {"_sound\/grin2":{"name":"Fluttershy - *squee*"},"_sound\/chat_boing":{"name":"Boing"}};
1252 var HTMLCLASS_SETTINGS
= ['login_bg', 'disable_animation', 'pinkieproof', 'disable_emoticons'];
1253 var DEFAULTSETTINGS
= {
1254 'theme':CURRENTPONY
,
1255 'login_bg':false, 'customBg':null, //'allowLoginScreen':true,
1256 'sounds':false, 'soundsFile':'AUTO', 'soundsNotifTypeBlacklist':'', 'soundsVolume':1, 'chatSound':true, 'chatSoundFile':'_sound/grin2',
1257 //'show_messages_other':true,
1258 'pinkieproof':false, 'forceEnglish':false, 'disable_emoticons':false, 'randomPonies':'', 'costume': '', //'commentBrohoofed':true,
1259 'disable_animation':false, 'disableDomNodeInserted':false, //'disableCommentBrohoofed':false,
1260 'customcss':'', 'debug_dominserted_console':false, 'debug_slow_load':false, 'debug_disablelog':false, 'debug_noMutationObserver':false, 'debug_mutationDebug':false, 'debug_exposed':false, 'debug_betaFacebookLinks':false //,'debug_mutationObserver':false,
1263 //'survivedTheNight', 'chatSound1401', 'randomSettingMigrated'
1265 var STACKS_LANG
= [{"stack":"pony","people":"ponies","person":"pony","friend":"pal","friends":"pals","friend_logic":"pal","friends_logic":"pals","like":"brohoof","likes":"brohoofs","unlike":"unbrohoof","like_past":"brohoof","likes_past":"brohoofs","liked":"brohoof'd","liked_button":"brohoof'd","liking":"brohoofing","findFriendship":"Find Friendship"},{"stack":"chrysalis","people":"changelings","person":"changeling","friend":"prey","friends":"prey","friend_logic":"changeling","friends_logic":"changelings","like":"feed","likes":"feeds","unlike":"unfeed","like_past":"fed on","likes_past":"fed on","liked":"fed on","liked_button":"fed","liking":"feeding","findFriendship":"Find Prey"},{"stack":"villian","people":"ponies","person":"pony","friend":"pal","friends":"pals","friend_logic":"pal","friends_logic":"pals","like":"brohoof","likes":"brohoofs","unlike":"unbrohoof","like_past":"brohoof","likes_past":"brohoofs","liked":"brohoof'd","liked_button":"brohoof'd","liking":"brohoofing","findFriendship":"Find Friendship"}];
1266 var CURRENTSTACK
= STACKS_LANG
[0];
1267 var COSTUMESX
= {"winterwrapup":{"name":"Winter Wrap Up","characters":["twilight","dash","pinkie","applej","flutter","rarity","derpy"]},"nightmarenight":{"name":"Nightmare Night","characters":["twilight","dash","pinkie","applej","flutter","applebloom","bigmac","derpy","luna","scootaloo","spike","sweetieb","zecora"]},"hearthwarming":{"name":"Hearth's Warming","characters":["twilight","dash","pinkie","applej","flutter","rarity"]},"season3premiere":{"name":"Season 3 Premiere","characters":["twilight","rarity"]},"crystal":{"name":"Crystal Pony","characters":["twilight","dash","pinkie","applej","flutter","rarity","cadance"]},"wedding":{"name":"Canterlot Wedding","characters":["sweetieb"]},"coronation":{"name":"Princess Coronation Dresses","characters":["dash","pinkie","applej","flutter","rarity","cadance"]},"princess":{"name":"Princess Twilight Sparkle","characters":["twilight"]}};
1268 var SOUNDS_NOTIFTYPE
= {
1269 poke: {name:"Nuzzles", type:"poke"}
1270 ,like: {name:"Brohoofs", type:"like"}
1271 ,group_activity: {name:"New posts in herds and tags about you", type:"group_activity"}
1272 ,group_r2j: {name:"Herd join requests", type:"group_r2j"}
1273 ,group_added_to_group: {name:"Herd invites from friends", type:"group_added_to_group"}
1274 ,plan_reminder: {name:"Adventure reminders", type:"plan_reminder"}
1275 ,follow_profile: {name:"New followers", type:"follow_profile"}
1276 //,photo_made_profile_pic: {name:"Made your pony pic his/her profile picture", type:"photo_made_profile_pic"}
1277 ,answers_answered: {name:"New answers on the Facebook Help Center", type:"answers_answered"}
1279 ,app_invite: {name:"Game/app requests", type:"app_invite"}
1280 ,close_friend_activity: {name:"Posts from Close Friends", type:"close_friend_activity"}
1281 ,notify_me: {name:"Page posts that you subscribed to", type:"notify_me"}
1283 //,fbpage_presence: {name:"Facebook nagging you to post to your page", type:"fbpage_presence"}
1284 ,fbpage_fan_invite: {name:"Page invites from friends", type:"fbpage_fan_invite"}
1285 ,page_new_likes: {name:"New page brohoofs", type:"page_new_likes"}
1286 //,fbpage_new_message: {name:"New private messages on your page", type:"fbpage_new_message"}
1289 var THEMEURL
= w
.location
.protocol
+ '//hoof.little.my/files/';
1290 var THEMECSS
= THEMEURL
+'';
1291 var THEMECSS_EXT
= '.css?userscript_version='+VERSION
;
1292 var UPDATEURL
= w
.location
.protocol
+ '//hoof.little.my/files/update_check.js?' + (+new Date());
1294 var PONYHOOF_PAGE
= '197956210325433';
1295 var PONYHOOF_URL
= '//'+getFbDomain()+'/Ponyhoof';
1296 var PONYHOOF_README
= '//hoof.little.my/files/_welcome/readme.htm?version='+VERSION
+'&distribution='+DISTRIBUTION
;
1298 var _ext_messageId
= 0;
1299 var _ext_messageCallback
= {};
1302 var chrome_sendMessage = function(message
, callback
) {
1304 if (chrome
.extension
.sendMessage
) {
1305 chrome
.extension
.sendMessage(message
, callback
);
1307 chrome
.extension
.sendRequest(message
, callback
);
1310 if (e
.toString().indexOf('Error: Error connecting to extension ') === 0) {
1311 extUpdatedError(e
.toString());
1317 var chrome_storageFallback
= false;
1318 var chrome_getValue = function(name
, callback
) {
1319 if (chrome
.storage
&& !chrome_storageFallback
) {
1320 if (chrome_isExtUpdated()) {
1321 extUpdatedError("[chrome_getValue("+name
+")]");
1326 chrome
.storage
.local
.get(name
, function(item
) {
1327 if (chrome
.runtime
&& chrome
.runtime
.lastError
) {
1328 // Fallback to old storage method
1329 chrome_storageFallback
= true;
1330 chrome_getValue(name
, callback
);
1334 if (Object
.keys(item
).length
=== 0) {
1338 callback(item
[name
]);
1344 chrome_sendMessage({'command':'getValue', 'name':name
}, function(response
) {
1345 if (response
&& typeof response
.val
!= 'undefined') {
1346 callback(response
.val
);
1358 var chrome_setValue = function(name
, val
) {
1359 if (chrome
.storage
&& !chrome_storageFallback
) {
1360 if (chrome_isExtUpdated()) {
1361 extUpdatedError("[chrome_setValue("+name
+")]");
1367 chrome
.storage
.local
.set(toSet
, function() {
1368 if (chrome
.runtime
&& chrome
.runtime
.lastError
) {
1369 saveValueError(chrome
.runtime
.lastError
);
1376 chrome_sendMessage({'command':'setValue', 'name':name
, 'val':val
}, function() {});
1379 var chrome_clearStorage = function() {
1380 if (chrome
.storage
) {
1381 chrome
.storage
.local
.clear();
1383 chrome_sendMessage({'command':'clearStorage'}, function() {});
1386 var chrome_ajax = function(details
) {
1387 chrome_sendMessage({'command': 'ajax', 'details': details
}, function(response
) {
1388 if (response
&& response
.val
=== 'success') {
1389 if (details
.onload
) {
1390 details
.onload(response
.request
);
1393 if (details
.onerror
) {
1394 details
.onerror(response
.request
);
1400 var chrome_isExtUpdated = function() {
1401 return (typeof chrome
.i18n
=== 'undefined' || typeof chrome
.i18n
.getMessage('@@extension_id') === 'undefined');
1405 if (opera
.extension
) {
1406 opera
.extension
.onmessage = function(message
) {
1408 var response
= message
.data
;
1409 var callback
= _ext_messageCallback
[response
.messageid
];
1411 callback(response
.val
);
1417 var opera_getValue = function(name
, callback
) {
1418 _ext_messageCallback
[_ext_messageId
] = callback
;
1419 opera
.extension
.postMessage({'command':'getValue', 'messageid':_ext_messageId
, 'name':name
});
1420 _ext_messageId
+= 1;
1423 var opera_setValue = function(name
, val
) {
1424 opera
.extension
.postMessage({'command':'setValue', 'name':name
, 'val':val
});
1427 var opera_clearStorage = function() {
1428 opera
.extension
.postMessage({'command':'clearStorage'});
1431 var opera_ajax = function(details
) {
1432 _ext_messageCallback
[_ext_messageId
] = function(response
) {
1433 if (response
.val
== 'success') {
1434 if (details
.onload
) {
1435 details
.onload(response
.request
);
1438 if (details
.onerror
) {
1439 details
.onerror(response
.request
);
1444 'method': details
.method
1446 ,'headers': details
.headers
1447 ,'data': details
.data
1449 opera
.extension
.postMessage({'command':'ajax', 'messageid':_ext_messageId
, 'details':detailsX
});
1450 _ext_messageId
+= 1;
1455 if (typeof safari
!= 'undefined') {
1456 safari
.self
.addEventListener('message', function(message
) {
1457 var data
= message
.message
;
1459 var response
= data
;
1460 var callback
= _ext_messageCallback
[message
.name
];
1462 callback(response
.val
);
1468 var safari_getValue = function(name
, callback
) {
1469 _ext_messageId
= md5(Math
.random().toString()); // safari, you don't know what's message passing/callbacks, do you?
1470 _ext_messageCallback
[_ext_messageId
] = callback
;
1471 safari
.self
.tab
.dispatchMessage('getValue', {'messageid':_ext_messageId
, 'name':name
});
1472 //_ext_messageId += 1;
1475 var safari_setValue = function(name
, val
) {
1476 safari
.self
.tab
.dispatchMessage('setValue', {'name':name
, 'val':val
});
1479 var safari_clearStorage = function() {
1480 safari
.self
.tab
.dispatchMessage('clearStorage', {});
1483 var safari_ajax = function(details
) {
1484 _ext_messageId
= md5(Math
.random().toString());
1485 _ext_messageCallback
[_ext_messageId
] = function(response
) {
1486 if (response
.val
== 'success') {
1487 if (details
.onload
) {
1488 details
.onload(response
.request
);
1491 if (details
.onerror
) {
1492 details
.onerror(response
.request
);
1497 'method': details
.method
1499 ,'headers': details
.headers
1500 ,'data': details
.data
1502 safari
.self
.tab
.dispatchMessage('ajax', {'messageid':_ext_messageId
, 'details':detailsX
});
1503 //_ext_messageId += 1;
1507 if (typeof self
!= 'undefined' && typeof self
.on
!= 'undefined') {
1508 self
.on('message', function(message
) {
1511 var response
= data
;
1512 var callback
= _ext_messageCallback
[message
.messageid
];
1514 callback(response
.val
);
1519 var xpi_getValue = function(name
, callback
) {
1520 _ext_messageCallback
[_ext_messageId
] = callback
;
1521 self
.postMessage({'command':'getValue', 'messageid':_ext_messageId
, 'name':name
});
1522 _ext_messageId
+= 1;
1525 var xpi_setValue = function(name
, val
) {
1526 self
.postMessage({'command':'setValue', 'name':name
, 'val':val
});
1529 var xpi_clearStorage = function() {
1530 self
.postMessage({'command':'clearStorage'});
1533 var xpi_ajax = function(details
) {
1534 _ext_messageCallback
[_ext_messageId
] = function(response
) {
1535 if (response
.val
== 'success') {
1536 if (details
.onload
) {
1537 details
.onload(response
.request
);
1540 if (details
.onerror
) {
1541 details
.onerror(response
.request
);
1546 'method': details
.method
1548 ,'headers': details
.headers
1549 ,'data': details
.data
1551 self
.postMessage({'command':'ajax', 'messageid':_ext_messageId
, 'details':detailsX
});
1552 _ext_messageId
+= 1;
1555 var xpi_sendMessage = function(message
, callback
) {
1556 _ext_messageCallback
[_ext_messageId
] = callback
;
1557 message
.messageid
= _ext_messageId
;
1558 self
.postMessage(message
);
1559 _ext_messageId
+= 1;
1563 if (typeof w
.external
!= 'undefined' && typeof w
.external
.mxGetRuntime
!= 'undefined') {
1564 var maxthonRuntime
= w
.external
.mxGetRuntime();
1565 maxthonRuntime
.listen('messageContentScript', function(message
) {
1568 var response
= data
;
1569 var callback
= _ext_messageCallback
[message
.messageid
];
1571 callback(response
.val
);
1576 var mxaddon_getValue = function(name
, callback
) {
1578 callback(maxthonRuntime
.storage
.getConfig(name
));
1580 if (e
.message
&& e
.message
=== 'No LocalStorage Service Extension! (206)') {
1581 extUpdatedError(e
.message
);
1587 var mxaddon_setValue = function(name
, val
) {
1589 maxthonRuntime
.storage
.setConfig(name
, val
);
1591 if (e
.message
&& e
.message
=== 'No LocalStorage Service Extension! (206)') {
1592 extUpdatedError(e
.message
);
1598 var mxaddon_clearStorage = function() {
1599 // Maxthon does not have a clear storage function
1602 var mxaddon_ajax = function(details
) {
1603 _ext_messageCallback
[_ext_messageId
] = function(response
) {
1604 if (response
.val
== 'success') {
1605 if (details
.onload
) {
1606 details
.onload(response
.request
);
1609 if (details
.onerror
) {
1610 details
.onerror(response
.request
);
1615 'method': details
.method
1617 ,'headers': details
.headers
1618 ,'data': details
.data
1621 maxthonRuntime
.post('messageBackground', {'command':'ajax', 'messageid':_ext_messageId
, 'details':detailsX
});
1623 if (e
.message
&& e
.message
=== 'No Platform_Message Service Extension! (355)') {
1624 extUpdatedError(e
.message
);
1628 _ext_messageId
+= 1;
1632 function ajax(obj
) {
1633 switch (STORAGEMETHOD
) {
1634 case 'greasemonkey':
1635 return GM_xmlhttpRequest(obj
);
1638 return chrome_ajax(obj
);
1641 return opera_ajax(obj
);
1644 return safari_ajax(obj
);
1647 return xpi_ajax(obj
);
1650 return mxaddon_ajax(obj
);
1662 ,statusText:'No GM_xmlhttpRequest support'
1666 function isPonyhoofPage(id
) {
1667 if (id
== PONYHOOF_PAGE
) {
1673 function capitaliseFirstLetter(string
) {
1674 return string
.charAt(0).toUpperCase() + string
.slice(1);
1678 for (var i
in HTMLCLASS_SETTINGS
) {
1679 if (!DEFAULTSETTINGS
[HTMLCLASS_SETTINGS
[i
]]) {
1680 DEFAULTSETTINGS
[HTMLCLASS_SETTINGS
[i
]] = false;
1683 //DEFAULTSETTINGS.show_messages_other = true;
1685 DEFAULTSETTINGS
.disable_animation
= true;
1688 function getValueError(extra
) {
1689 if (chrome_isExtUpdatedError(extra
)) {
1690 extUpdatedError(extra
);
1692 createSimpleDialog('localStorageError_getValue', "Ponyhoof derp'd", "Whoops, Ponyhoof can't load your settings. Please try again later.<br><br>If you keep seeing this error, please update to the latest version of Ponyhoof if available and <a href=\""+w
.location
.protocol
+PONYHOOF_URL
+"\" data-hovercard=\"/ajax/hovercard/page.php?id="+PONYHOOF_PAGE
+"\">visit and post to the Ponyhoof page for help</a>.<br><br><code>"+extra
+"</code>");
1698 function saveValueError(extra
) {
1699 var desc
= "Whoops, Ponyhoof can't save your settings. Please try again later.";
1700 if (ISFIREFOX
&& STORAGEMETHOD
=== 'greasemonkey' && userSettings
.customBg
) {
1701 desc
+= "<br><br>This may be caused by a large custom background that you have set. Please try removing it.";
1703 desc
+= "<br><br>If you keep seeing this error, please update to the latest version of Ponyhoof if available and <a href=\""+w
.location
.protocol
+PONYHOOF_URL
+"\" data-hovercard=\"/ajax/hovercard/page.php?id="+PONYHOOF_PAGE
+"\">visit and post to the Ponyhoof page for help</a>.<br><br><code>"+extra
+"</code>";
1704 createSimpleDialog('localStorageError_saveValue', "Ponyhoof derp'd", desc
);
1709 function ponyhoofError(extra
) {
1710 createSimpleDialog('ponyhoofError', "Ponyhoof derp'd", "Whoops, Ponyhoof encountered an internal error. Please try again later.<br><br>If you keep seeing this error, please update to the latest version of Ponyhoof if available and <a href=\""+w
.location
.protocol
+PONYHOOF_URL
+"\" data-hovercard=\"/ajax/hovercard/page.php?id="+PONYHOOF_PAGE
+"\">visit and post to the Ponyhoof page for help</a>.<br><br><code>"+extra
+"</code>");
1715 var chrome_isExtUpdatedError = function(message
) {
1716 var a
= 'ModuleSystem has been deleted';
1717 var b
= 'TypeError: Cannot read property \'sendMessage\' of undefined';
1718 return (message
=== a
|| message
=== b
);
1721 var extUpdatedError = function(extra
) {
1722 createSimpleDialog('localStorageError_extUpdatedError', "Ponyhoof derp'd", "Ponyhoof has been updated/disabled recently. Please reload the page in order for Ponyhoof to work properly.<br><br><code>"+extra
+"</code>");
1725 function getValue(name
, callback
) {
1726 switch (STORAGEMETHOD
) {
1727 case 'greasemonkey':
1728 callback(GM_getValue(name
));
1732 chrome_getValue(name
, callback
);
1736 opera_getValue(name
, callback
);
1740 safari_getValue(name
, callback
);
1744 xpi_getValue(name
, callback
);
1748 mxaddon_getValue(name
, callback
);
1751 case 'localstorage':
1753 name
= 'ponyhoof_'+name
;
1754 callback(w
.localStorage
.getItem(name
));
1759 function saveValue(name
, v
) {
1760 switch (STORAGEMETHOD
) {
1761 case 'greasemonkey':
1762 GM_setValue(name
, v
);
1766 chrome_setValue(name
, v
);
1770 opera_setValue(name
, v
);
1774 safari_setValue(name
, v
);
1778 xpi_setValue(name
, v
);
1782 mxaddon_setValue(name
, v
);
1785 case 'localstorage':
1787 name
= 'ponyhoof_'+name
;
1788 w
.localStorage
.setItem(name
, v
);
1793 function loadSettings(callback
, opts
) {
1794 // opts => prefix, defaultsettings
1795 var opts
= opts
|| {prefix:null};
1796 var settingsKey
= 'settings';
1797 if (opts
.prefix
!= null) {
1798 settingsKey
= opts
.prefix
+settingsKey
;
1800 settingsKey
= SETTINGSPREFIX
+settingsKey
;
1802 if (!opts
.defaultSettings
) {
1803 opts
.defaultSettings
= DEFAULTSETTINGS
;
1807 getValue(settingsKey
, function(s
) {
1816 for (var i
in opts
.defaultSettings
) {
1817 if (!s
.hasOwnProperty(i
)) {
1818 s
[i
] = opts
.defaultSettings
[i
];
1830 extra
= e
.toString();
1833 getValueError(extra
);
1835 onPageReady(function() {
1837 getValueError(extra
);
1846 function saveSettings(opts
) {
1847 // opts => prefix, settings
1848 var opts
= opts
|| {prefix:null, settings:userSettings
};
1849 var settingsKey
= 'settings';
1850 if (opts
.prefix
!= null) {
1851 settingsKey
= opts
.prefix
+settingsKey
;
1853 settingsKey
= SETTINGSPREFIX
+settingsKey
;
1855 var settings
= userSettings
;
1856 if (opts
.settings
) {
1857 settings
= opts
.settings
;
1861 saveValue(settingsKey
, JSON
.stringify(settings
));
1868 if (e
.message
== 'ModuleSystem has been deleted' || e
.message
== 'TypeError: Cannot read property \'sendMessage\' of undefined') {
1869 extUpdatedError(e
.message
);
1876 extra
= e
.toString();
1878 saveValueError(extra
);
1883 var saveGlobalSettings = function() {
1884 saveSettings({prefix:'global_', settings:globalSettings
});
1887 function statTrack(stat
) {
1888 var i
= d
.createElement('iframe');
1889 i
.style
.position
= 'absolute';
1890 i
.style
.top
= '-9999px';
1891 i
.style
.left
= '-9999px';
1892 i
.setAttribute('aria-hidden', 'true');
1893 i
.src
= '//hoof.little.my/files/_htm/stat_'+stat
+'.htm?version='+VERSION
;
1894 d
.body
.appendChild(i
);
1897 var canPlayFlash = function() {
1898 return !!w
.navigator
.mimeTypes
['application/x-shockwave-flash'];
1902 var PonySelector = function(p
, param
) {
1914 k
.oldPony
= CURRENTPONY
;
1915 k
.customClick = function() {};
1916 k
.customCheckCondition
= false;
1917 k
.overrideClickAction
= false;
1921 k
.createSelector = function() {
1928 var currentPonyData
= convertCodeToData(CURRENTPONY
);
1929 var name
= "(Nopony)";
1930 if (currentPonyData
) {
1931 name
= currentPonyData
.name
;
1932 } else if (CURRENTPONY
== 'RANDOM') {
1936 var iu
= INTERNALUPDATE
;
1937 INTERNALUPDATE
= true;
1939 k
.menu
= new Menu('ponies_'+p
.id
, k
.p
/*, {checkable:true}*/);
1940 k
.button
= k
.menu
.createButton(name
);
1941 k
.menu
.alwaysOverflow
= true;
1942 k
.menu
.searchNoResultsMessage
= "No ponies :(";
1943 k
.menu
.createMenu();
1944 k
.menu
.attachButton();
1946 if (k
.allowRandom
) {
1948 if (CURRENTPONY
== 'RANDOM') {
1952 k
.menu
.createMenuItem({
1954 ,title: "To choose which characters to randomize, go to the Misc tab"
1957 ,onclick: function(menuItem
, menuClass
) {
1958 CURRENTPONY
= 'RANDOM';
1960 changeThemeSmart('RANDOM');
1962 userSettings
.theme
= 'RANDOM';
1966 menuClass
.changeButtonText("(Random)");
1967 menuClass
.changeChecked(menuItem
);
1970 if (k
.customClick
) {
1971 k
.customClick(menuItem
, menuClass
);
1977 if (k
.allowRandom
) {
1978 k
.menu
.createSeperator();
1981 if (k
.param
.feature
&& k
.param
.feature
!= -1) {
1982 k
._createItem(PONIES
[k
.param
.feature
], true);
1983 k
.menu
.createSeperator();
1986 for (var i
= 0, len
= PONIES
.length
; i
< len
; i
+= 1) {
1987 if (k
.param
.feature
&& k
.param
.feature
!= -1 && PONIES
[k
.param
.feature
].code
== PONIES
[i
].code
) {
1988 if (PONIES
[i
].seperator
) {
1989 k
.menu
.createSeperator();
1995 if (k
.customCheckCondition
) {
1996 if (k
.customCheckCondition(PONIES
[i
].code
)) {
2000 if (PONIES
[i
].code
== CURRENTPONY
) {
2005 k
._createItem(PONIES
[i
], check
);
2007 if (PONIES
[i
].seperator
) {
2008 k
.menu
.createSeperator();
2012 var img
= d
.createElement('span');
2013 img
.className
= 'ponyhoof_loading ponyhoof_show_if_injected ponyhoof_loading_pony';
2014 k
.menu
.wrap
.appendChild(img
);
2016 INTERNALUPDATE
= iu
;
2019 k
._createItem = function(ponyData
, check
) {
2020 var unsearchable
= false;
2021 if (ponyData
.hidden
) {
2022 unsearchable
= true;
2024 var menuItem
= k
.menu
.createMenuItem({
2026 ,title: ponyData
.menu_title
2027 ,data: ponyData
.code
2029 ,unsearchable: unsearchable
2030 ,searchAlternate: ponyData
.search
2031 ,onclick: function(menuItem
, menuClass
) {
2032 if (!k
.overrideClickAction
) {
2033 var code
= ponyData
.code
;
2036 changeThemeSmart(code
);
2038 userSettings
.theme
= code
;
2042 menuClass
.changeButtonText(ponyData
.name
);
2043 menuClass
.changeChecked(menuItem
);
2047 if (k
.customClick
) {
2048 k
.customClick(menuItem
, menuClass
);
2052 if (ponyData
.hidden
) {
2053 addClass(menuItem
.menuItem
, 'ponyhoof_pony_hidden');
2057 k
.injectStyle = function() {
2059 css
+= 'html .ponyhoof_pony_hidden {display:none;}';
2060 for (var i
= 0, len
= PONIES
.length
; i
< len
; i
+= 1) {
2061 if (PONIES
[i
].color
) {
2062 css
+= 'html .ponyhoof_menuitem[data-ponyhoof-menu-data="'+PONIES
[i
].code
+'"]:hover, html .ponyhoof_menuitem[data-ponyhoof-menu-data="'+PONIES
[i
].code
+'"]:active, html .ponyhoof_menuitem[data-ponyhoof-menu-data="'+PONIES
[i
].code
+'"]:focus {background-color:#'+PONIES
[i
].color
[0]+' !important;border-top-color:#'+PONIES
[i
].color
[1]+' !important;border-bottom-color:#'+PONIES
[i
].color
[1]+' !important;}';
2066 injectManualStyle(css
, 'ponySelector');
2071 var _soundCache
= {};
2072 var PonySound = function(id
) {
2076 k
.sound
= d
.createElement('audio');
2078 // Don't loop sounds for 3 seconds
2080 k
.respectSettings
= true;
2081 k
.respectVolumeSetting
= true;
2086 k
.changeSource = function(source
) {
2090 k
.changeSourceSmart = function(source
) {
2091 if (k
.canPlayMp3()) {
2092 source
= source
.replace(/\.EXT/, '.mp3');
2093 } else if (k
.canPlayOgg()) {
2094 source
= source
.replace(/\.EXT/, '.ogg');
2096 throw new Error("No supported audio formats");
2099 k
.changeSource(source
);
2102 k
.play = function() {
2103 if (k
.respectSettings
) {
2104 if (!userSettings
.sounds
) {
2109 if (STORAGEMETHOD
=== 'chrome' && chrome_isExtUpdated()) {
2110 extUpdatedError("PonySound.play()");
2115 k
.continuePlaying();
2119 // Make sure we aren't playing it on another page already
2120 k
._time
= Math
.floor(Date
.now() / 1000);
2123 getValue(SETTINGSPREFIX
+'soundCache', function(s
) {
2124 if (typeof s
!= 'undefined') {
2126 _soundCache
= JSON
.parse(s
);
2131 if (_soundCache
== null) {
2135 if (_soundCache
[k
.id
]) {
2136 if (_soundCache
[k
.id
]+k
.wait
<= k
._time
) {
2143 k
.continuePlaying();
2146 // k.continuePlaying();
2150 k
.continuePlaying = function() {
2152 _soundCache
[k
.id
] = k
._time
;
2153 saveValue(SETTINGSPREFIX
+'soundCache', JSON
.stringify(_soundCache
));
2156 if (k
.respectVolumeSetting
) {
2157 k
.sound
.volume
= userSettings
.soundsVolume
;
2159 k
.sound
.src
= k
.source
;
2163 // http://html5doctor.com/native-audio-in-the-browser/
2164 k
.audioTagSupported = function() {
2165 return !!(k
.sound
.canPlayType
);
2168 k
.canPlayMp3 = function() {
2169 return !!k
.sound
.canPlayType
&& '' != k
.sound
.canPlayType('audio/mpeg');
2172 k
.canPlayOgg = function() {
2173 return !!k
.sound
.canPlayType
&& '' != k
.sound
.canPlayType('audio/ogg; codecs="vorbis"');
2177 var ponySounds
= {};
2178 function initPonySound(id
, source
) {
2179 var source
= source
|| '';
2181 if (ponySounds
[id
]) {
2183 ponySounds
[id
].changeSourceSmart(source
);
2186 return ponySounds
[id
];
2189 var sound
= new PonySound(id
);
2191 if (!sound
.audioTagSupported()) {
2192 throw new Error('No <audio> tag support');
2196 sound
.changeSourceSmart(source
);
2199 ponySounds
[id
] = sound
;
2205 var Updater = function() {
2208 k
.classChecking
= 'ponyhoof_updater_checking';
2209 k
.classLatest
= 'ponyhoof_updater_latest';
2210 k
.classError
= 'ponyhoof_updater_error';
2211 k
.classNewVersion
= 'ponyhoof_updater_newVersion';
2212 k
.classVersionNum
= 'ponyhoof_updater_versionNum';
2213 k
.classUpdateButton
= 'ponyhoof_updater_updateNow';
2215 k
.update_url
= UPDATEURL
;
2219 k
.checkForUpdates = function() {
2220 loopClassName(k
.classUpdateButton
, function(ele
) {
2221 if (ISSAFARI
&& STORAGEMETHOD
!= 'safari') {
2222 // NinjaKit is bugged and only listens to install script requests on page load, no DOMNodeInserted, so we plan to open a new window
2223 ele
.target
= '_blank';
2226 ele
.addEventListener('click', k
._updateNowButton
, false);
2229 log("Checking for updates...");
2234 ,onload: function(response
) {
2235 if (response
.status
!= 200) {
2236 k
._onError(response
);
2241 var json
= JSON
.parse(response
.responseText
);
2243 k
._onError(response
);
2247 if (json
.version
> VERSION
) {
2248 k
._newVersion(json
);
2253 ,onerror: function(response
) {
2254 k
._onError(response
);
2262 k
._noNewVersion = function() {
2263 // Hide checking for updates
2264 loopClassName(k
.classChecking
, function(ele
) {
2265 ele
.style
.display
= 'none';
2269 loopClassName(k
.classLatest
, function(ele
) {
2270 ele
.style
.display
= 'block';
2273 k
._newVersion = function(json
) {
2274 k
.update_json
= json
;
2276 // Hide checking for updates
2277 loopClassName(k
.classChecking
, function(ele
) {
2278 ele
.style
.display
= 'none';
2281 // Show version number
2282 loopClassName(k
.classVersionNum
, function(ele
) {
2283 ele
.textContent
= json
.version
;
2285 // Show that we have a new version
2286 loopClassName(k
.classNewVersion
, function(ele
) {
2287 ele
.style
.display
= 'block';
2289 // Change the update now button to point to the new link
2290 loopClassName(k
.classUpdateButton
, function(ele
) {
2291 if (ISSAFARI
&& STORAGEMETHOD
!= 'safari') {
2292 ele
.href
= json
.safari
;
2296 switch (STORAGEMETHOD
) {
2299 ele
.href
= json
.chrome_url
;
2303 ele
.href
= json
.opera_url
;
2308 ele
.href
= json
.safariextz
;
2313 ele
.href
= json
.xpi
;
2317 ele
.href
= json
.mxaddon_instruction
;
2321 ele
.href
= json
.update_url
;
2326 k
._onError = function(response
) {
2327 // Hide checking for updates
2328 loopClassName(k
.classChecking
, function(ele
) {
2329 ele
.style
.display
= 'none';
2333 loopClassName(k
.classError
, function(ele
) {
2334 ele
.style
.display
= 'block';
2337 error("Error checking for updates.");
2341 k
.updateDialog
= null;
2342 k
._updateNowButton = function() {
2343 statTrack('updateNowButton');
2345 switch (STORAGEMETHOD
) {
2355 k
.safariInstruction();
2362 // Maxthon 4.2.0.2200 starts blocking off-store extensions
2371 if (DIALOGS
.updater_dialog
) {
2372 k
.updateDialog
.show();
2376 var c
= "The update will load after you reload Facebook.";
2377 if (STORAGEMETHOD
=== 'mxaddon') {
2378 c
= "Follow the instructions in the new window and reload Facebook when you are done.";
2379 } else if (ISCHROME
) { // still localstorage
2380 c
= "Click Continue on the bottom of this window and click Add to finish updating. The update will load after you reload Facebook.";
2381 } else if (ISSAFARI
) { // still ninjakit
2382 c
= "Follow the instructions in the new window and reload Facebook when you are done.";
2383 } else if (ISOPERA
) { // still localstorage
2384 c
= "Follow the instructions in the new window and reload Facebook when you are done.";
2385 } else if (STORAGEMETHOD
=== 'greasemonkey') {
2386 c
= "Click <strong>Install</strong> when you see this dialog. The update will load after you reload Facebook.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/firefox/install.png' alt='' width='552' height='110' class='ponyhoof_image_shadow'>";
2387 injectManualStyle('#ponyhoof_dialog_updater_dialog .generic_dialog_popup, #ponyhoof_dialog_updater_dialog .popup {width:600px;}', 'updater_dialog');
2391 bottom
+= '<div class="lfloat"><a href="#" class="retry hidden_elem">Retry</a></div>';
2392 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.reloadNow
+'</span></a>';
2393 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.notNow
+'</span></a>';
2395 k
.updateDialog
= new Dialog('updater_dialog');
2396 k
.updateDialog
.alwaysModal
= true;
2397 k
.updateDialog
.create();
2398 k
.updateDialog
.changeTitle(CURRENTLANG
['updater_title']);
2399 k
.updateDialog
.changeContent(c
);
2400 k
.updateDialog
.changeBottom(bottom
);
2402 if (!ISCHROME
&& STORAGEMETHOD
== 'greasemonkey') {
2403 var retry
= k
.updateDialog
.dialog
.getElementsByClassName('retry');
2406 retry
.href
= k
.update_json
.update_url
;
2407 removeClass(retry
, 'hidden_elem');
2410 k
._initReloadButtons(k
.updateDialog
);
2416 k
.cwsWaitDialog
= null;
2417 k
.cwsOneClickSuccess
= false;
2418 k
._cws = function() {
2419 if (k
.cwsWaitDialog
) {
2420 k
._cws_showDialog();
2425 loopClassName(k
.classUpdateButton
, function(ele
) {
2426 if (hasClass(ele
, 'uiButtonDisabled')) {
2429 addClass(ele
, 'uiButtonDisabled');
2436 var c
= "Updating... <span class='ponyhoof_loading'></span>";
2437 k
.cwsWaitDialog
= new Dialog('update_cwsWait');
2438 k
.cwsWaitDialog
.alwaysModal
= true;
2439 k
.cwsWaitDialog
.noBottom
= true;
2440 k
.cwsWaitDialog
.canCloseByEscapeKey
= false;
2441 k
.cwsWaitDialog
.create();
2442 k
.cwsWaitDialog
.changeTitle(CURRENTLANG
['updater_title']);
2443 k
.cwsWaitDialog
.changeContent(c
);
2445 chrome_sendMessage({'command':'checkForUpdates'}, function(status
, details
) {
2446 if (status
== 'update_available') {
2447 var c
= "Downloading update... <span class='ponyhoof_loading'></span>";
2448 k
.cwsWaitDialog
.changeContent(c
);
2449 chrome_sendMessage({'command':'onUpdateAvailable'}, function(status
) {
2450 if (status
== 'updated') {
2451 k
.cwsOneClickSuccess
= true;
2453 var successText
= '';
2454 var ponyData
= convertCodeToData(REALPONY
);
2455 if (ponyData
.successText
) {
2456 successText
= ponyData
.successText
;
2458 successText
= "Yay!";
2460 var c
= successText
+" Update complete, reloading... <span class='ponyhoof_loading'></span>";
2461 k
.cwsWaitDialog
.changeContent(c
);
2464 chrome_sendMessage({'command':'reloadNow'}, function() {});
2465 w
.setTimeout(function() {
2466 w
.location
.reload();
2478 w
.setTimeout(k
._cws_fallback
, 8000);
2481 k
._cws_fallback = function() {
2482 if (k
.cwsOneClickSuccess
) {
2485 k
.cwsOneClickSuccess
= true;
2487 k
.cwsWaitDialog
.close();
2488 loopClassName(k
.classUpdateButton
, function(ele
) {
2489 removeClass(ele
, 'uiButtonDisabled');
2491 k
._cws_showDialog();
2494 k
._cws_showDialog = function() {
2501 if (DISTRIBUTION
== 'cws') {
2502 if (!ISOPERABLINK
) {
2503 header
= "Ponyhoof automatically updates from the Chrome Web Store.";
2505 header
= "Ponyhoof automatically updates on Opera.";
2508 header
= "Ponyhoof automatically updates on Google Chrome.";
2511 var newversion
= k
.update_json
.version
;
2512 var c
= "<strong>"+header
+"</strong><br><br>To update now, go to <a href='#' class='ponyhoof_updater_cws_openExtensions'><strong>about:extensions</strong></a> in the address bar, enable <strong>Developer mode</strong> at the top-right and click <strong>Update extensions now</strong>.";
2514 c
+= "<br><br>Verify that the version changes from "+VERSION
+" to "+parseFloat(newversion
)+" and reload Facebook.";
2516 c
+= "<br><br><"+"img src='"+THEMEURL
+"_welcome/chrome_forceupdate.png' alt='' width='177' height='108' class='ponyhoof_image_shadow'>";
2519 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm ponyhoof_updater_cws_openExtensions" role="button"><span class="uiButtonText">Open Extensions</span></a>';
2520 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.reloadNow
+'</span></a>';
2521 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.notNow
+'</span></a>';
2523 k
.cwsDialog
= new Dialog('update_cws');
2524 k
.cwsDialog
.alwaysModal
= true;
2525 k
.cwsDialog
.create();
2526 k
.cwsDialog
.changeTitle(CURRENTLANG
['updater_title']);
2527 k
.cwsDialog
.changeContent(c
);
2528 k
.cwsDialog
.changeBottom(bottom
);
2530 $$(k
.cwsDialog
.dialog
, '.ponyhoof_updater_cws_openExtensions', function(button
) {
2531 button
.addEventListener('click', function(e
) {
2533 if (!hasClass(this, 'uiButtonDisabled')) {
2534 chrome_sendMessage({'command':'openExtensions'}, function() {});
2539 k
._initReloadButtons(k
.cwsDialog
);
2542 k
.operaDialog
= null;
2543 k
._opera = function() {
2544 if ($('ponyhoof_dialog_update_opera')) {
2545 k
.operaDialog
.show();
2549 var version
= getBrowserVersion();
2552 if (parseFloat(version
.full
) >= 12.10) {
2553 c
+= "<div class='ponyhoof_message uiBoxYellow'>If Opera blocks the update, then <a href='http://jointheherd.little.my' target='_top'>please visit the installer at http://jointheherd.little.my</a> for instructions.</div><br>";
2555 c
+= "New versions of Opera will block extensions that aren't from the official Opera Add-ons Gallery. Therefore, please set up Opera to trust our website for future updates.<br><br>";
2556 //c += "If you can't update anymore, then <a href='http://jointheherd.little.my' target='_top'>please visit the installer at http://jointheherd.little.my</a> for instructions.<br><br>";
2557 c
+= "If you get this security prompt, check <strong>Always allow installation from this location</strong> and click <strong>OK</strong>.<br><br><"+"img src='"+THEMEURL
+"_welcome/installv2/install_opera_1.png' alt='' width='385' height='170' class='ponyhoof_image_shadow'><br><br>";
2559 c
+= "Click <strong>Install</strong> when you see this dialog. The update will load after you reload Facebook.<br><br><"+"img src='"+THEMEURL
+"_welcome/installv2/install_opera_2.png' alt='' width='316' height='201' class='ponyhoof_image_shadow'>";
2562 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.reloadNow
+'</span></a>';
2563 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.notNow
+'</span></a>';
2565 k
.operaDialog
= new Dialog('update_opera');
2566 k
.operaDialog
.alwaysModal
= true;
2567 k
.operaDialog
.create();
2568 k
.operaDialog
.changeTitle(CURRENTLANG
.updater_title
);
2569 k
.operaDialog
.changeContent(c
);
2570 k
.operaDialog
.changeBottom(bottom
);
2572 k
._initReloadButtons(k
.operaDialog
);
2575 k
.safariDialog
= null;
2576 k
.safariInstruction = function() {
2577 if (k
.safariDialog
) {
2578 k
.safariDialog
.show();
2582 injectManualStyle('#ponyhoof_dialog_update_safari .generic_dialog_popup, #ponyhoof_dialog_update_safari .popup {width:600px;}', 'update_safari');
2585 if (w
.navigator
.userAgent
.indexOf('Mac OS X') != -1) {
2586 c
+= "On the top-right of the Safari window, click on the Downloads button and then double-click <strong>ponyhoof.safariextz</strong><br><br><"+"img src='"+THEMEURL
+"_welcome/guide/safari_mac/install_1.png' alt='' width='276' height='201' class='ponyhoof_image_shadow noshadow'><br><br>";
2587 c
+= "Click <strong>Install</strong>. The update will load after you reload Facebook.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/safari_mac/install_2.png' alt='' width='518' height='285' class='ponyhoof_image_shadow'>";
2589 c
+= "When you see this download dialog, click <strong>Open</strong>.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/safari5/install_1.png' alt='' width='500' height='222' class='ponyhoof_image_shadow'><br><br>";
2590 c
+= "Click <strong>Install</strong>. The update will load after you reload Facebook.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/safari5/install_2.png' alt='' width='524' height='226' class='ponyhoof_image_shadow'>";
2594 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.reloadNow
+'</span></a>';
2595 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
.notNow
+'</span></a>';
2597 k
.safariDialog
= new Dialog('update_safari');
2598 k
.safariDialog
.alwaysModal
= true;
2599 k
.safariDialog
.create();
2600 k
.safariDialog
.changeTitle(CURRENTLANG
.updater_title
);
2601 k
.safariDialog
.changeContent(c
);
2602 k
.safariDialog
.changeBottom(bottom
);
2604 k
._initReloadButtons(k
.safariDialog
);
2608 k
.xpiWaitDialog
= null;
2609 k
.xpiOneClickSuccess
= false;
2610 k
._xpi = function() {
2611 if (k
.xpiWaitDialog
) {
2612 k
._xpi_showDialog();
2616 var c
= "Updating... <span class='ponyhoof_loading'></span>";
2617 k
.xpiWaitDialog
= new Dialog('update_xpiWait');
2618 k
.xpiWaitDialog
.alwaysModal
= true;
2619 k
.xpiWaitDialog
.noBottom
= true;
2620 k
.xpiWaitDialog
.canCloseByEscapeKey
= false;
2621 k
.xpiWaitDialog
.create();
2622 k
.xpiWaitDialog
.changeTitle(CURRENTLANG
['updater_title']);
2623 k
.xpiWaitDialog
.changeContent(c
);
2625 xpi_sendMessage({'command':'checkForUpdates'}, function(val
) {
2626 if (val
!= 'update_available') {
2631 xpi_sendMessage({'command':'onUpdateAvailable'}, function(val
) {
2636 switch (val
.status
) {
2637 case 'onDownloadStarted':
2638 c
= "Downloading update...";
2641 case 'onDownloadEnded':
2642 c
= "Preparing to install...";
2645 case 'onInstallStarted':
2646 c
= "Installing update...";
2648 w
.setTimeout(function() {
2649 k
.xpiOneClickSuccess
= true;
2652 var successText
= '';
2653 var ponyData
= convertCodeToData(REALPONY
);
2654 if (ponyData
.successText
) {
2655 successText
= ponyData
.successText
;
2657 successText
= "Yay!";
2659 c
= successText
+" Update complete, reloading...";
2660 k
.xpiWaitDialog
.changeContent(c
);
2662 w
.location
.reload();
2667 case 'onDownloadFailed':
2668 case 'onInstallFailed':
2676 c
+= " <span class='ponyhoof_loading'></span>";
2677 k
.xpiWaitDialog
.changeContent(c
);
2682 w
.setTimeout(k
._xpi_fallback
, 10000);
2685 k
._xpi_fallback = function() {
2686 if (k
.xpiOneClickSuccess
) {
2689 k
.xpiOneClickSuccess
= true;
2691 k
.xpiWaitDialog
.close();
2692 k
._xpi_showDialog();
2695 k
._xpi_showDialog = function() {
2697 c
+= "Firefox may prompt a security warning at the top-left, click <strong>Allow</strong>.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/firefox/xpi_1_facebook.png' alt='' width='409' height='144' class='ponyhoof_image_shadow'><br>";
2698 c
+= "When you see the Software Installation dialog, click <strong>Install Now</strong>. The update will load after you reload Facebook, you do not need to restart Firefox.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/firefox/xpi_2.png' alt='' width='400' height='412' class='ponyhoof_image_shadow'>";
2701 bottom
+= '<div class="lfloat hidden_elem"><a href="#" class="retry">Retry</a></div>';
2702 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
['reloadNow']+'</span></a>';
2703 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
['notNow']+'</span></a>';
2705 k
.xpiDialog
= new Dialog('update_xpi');
2706 k
.xpiDialog
.alwaysModal
= true;
2707 k
.xpiDialog
.create();
2708 k
.xpiDialog
.changeTitle(CURRENTLANG
['updater_title']);
2709 k
.xpiDialog
.changeContent(c
);
2710 k
.xpiDialog
.changeBottom(bottom
);
2712 if (k
.update_json
.xpi
) {
2713 var retry
= k
.xpiDialog
.dialog
.getElementsByClassName('retry');
2716 retry
.href
= k
.update_json
.xpi
;
2717 removeClass(retry
.parentNode
, 'hidden_elem');
2719 k
._initReloadButtons(k
.xpiDialog
);
2722 USW
.InstallTrigger
.install({
2724 URL: k
.update_json
.xpi
2725 ,IconURL: 'https://hoof.little.my/files/app32.png'
2734 k
.mxaddonDialog
= null;
2735 k
.mxaddon = function() {
2736 if (k
.mxaddonDialog
) {
2737 k
.mxaddonDialog
.show();
2741 injectManualStyle('#ponyhoof_dialog_update_mxaddon .generic_dialog_popup, #ponyhoof_dialog_update_mxaddon .popup {width:500px;}', 'update_mxaddon');
2743 var c
= "Click <strong>Update</strong> when you see this dialog. The update will load after you reload Facebook.<br><br><"+"img src='"+THEMEURL
+"_welcome/guide/maxthon/update.png' alt='' width='446' height='419' class='ponyhoof_image_shadow'>";
2746 bottom
+= '<div class="lfloat"><a href="#" class="retry hidden_elem">Retry</a></div>';
2747 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG
['reloadNow']+'</span></a>';
2748 bottom
+= '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG
['notNow']+'</span></a>';
2750 k
.mxaddonDialog
= new Dialog('update_mxaddon');
2751 k
.mxaddonDialog
.alwaysModal
= true;
2752 k
.mxaddonDialog
.create();
2753 k
.mxaddonDialog
.changeTitle(CURRENTLANG
['updater_title']);
2754 k
.mxaddonDialog
.changeContent(c
);
2755 k
.mxaddonDialog
.changeBottom(bottom
);
2757 var retry
= k
.mxaddonDialog
.dialog
.getElementsByClassName('retry');
2760 retry
.addEventListener('click', function(e
) {
2762 k
._mxaddonInstallNow();
2764 removeClass(retry
, 'hidden_elem');
2766 k
._initReloadButtons(k
.mxaddonDialog
);
2768 k
._mxaddonInstallNow();
2771 k
._mxaddonInstallNow = function() {
2773 w
.external
.mxCall('InstallApp', k
.update_json
.mxaddon
);
2779 k
._initReloadButtons = function(dialog
) {
2780 $$(dialog
.dialog
, '.reloadNow', function(ele
) {
2781 ele
.addEventListener('click', function() {
2782 if (!hasClass(this, 'uiButtonDisabled')) {
2783 dialog
.canCloseByEscapeKey
= false;
2784 $$(dialog
.dialog
, '.uiButton', function(ele
) {
2785 addClass(ele
, 'uiButtonDisabled');
2787 w
.location
.reload();
2793 $$(dialog
.dialog
, '.notNow', function(ele
) {
2794 ele
.addEventListener('click', function() {
2795 if (!hasClass(this, 'uiButtonDisabled')) {
2804 var BrowserPoniesHoof = function() {
2808 k
.url
= 'https://hoof.little.my/_browserponies/';
2809 k
.initLoaded
= false;
2811 k
.ponySelected
= 'RANDOM';
2812 k
.doneCallback = function() {};
2814 k
.selectPoniesMenu
= null;
2815 k
.selectPoniesButton
= null;
2817 k
.errorDialog
= null;
2818 k
.errorDialogShown
= false;
2820 k
.run = function() {
2821 if (!k
.initLoaded
) {
2824 w
.setTimeout(function() {
2825 if (!k
.initLoaded
) {
2826 if (k
.errorCallback
) {
2827 k
.errorCallback('timeout');
2835 k
.spawnPony(k
.ponySelected
);
2837 if (k
.doneCallback
) {
2842 k
._init = function(callback
) {
2843 k
.errorDialogShown
= false;
2844 k
._getAjax(k
.url
+'BrowserPoniesBaseConfig.json?userscript_version='+VERSION
, function(response
) {
2846 var tempPonies
= JSON
.parse(response
.responseText
);
2848 if (k
.errorCallback
) {
2849 k
.errorCallback(response
);
2853 contentEval("var BrowserPoniesBaseConfig = "+response
.responseText
);
2855 for (var i
= 0, len
= tempPonies
.ponies
.length
; i
< len
; i
+= 1) {
2856 var pony
= tempPonies
.ponies
[i
].ini
.split(/\r?\n/);
2857 for (var j
= 0, jLen
= pony
.length
; j
< jLen
; j
+= 1) {
2858 var temp
= pony
[j
].split(',');
2859 if (temp
&& temp
[0].toLowerCase() == 'name') {
2860 k
.ponies
.push(temp
[1].replace(/\"/g, ''));
2866 k
._getAjax(k
.url
+'browserponies.js?userscript_version='+VERSION
, function(response
) {
2867 contentEval(response
.responseText
);
2868 k
.initLoaded
= true;
2870 contentEval(function(arg
) {
2873 if (typeof(window
.BrowserPoniesConfig
) === "undefined") {
2874 window
.BrowserPoniesConfig
= {};
2876 window
.BrowserPonies
.setBaseUrl(cfg
.baseurl
);
2877 if (!window
.BrowserPoniesBaseConfig
.loaded
) {
2878 window
.BrowserPonies
.loadConfig(window
.BrowserPoniesBaseConfig
);
2879 window
.BrowserPoniesBaseConfig
.loaded
= true;
2881 window
.BrowserPonies
.loadConfig(cfg
);
2882 })({"baseurl":arg
.baseurl
,"fadeDuration":500,"volume":1,"fps":25,"speed":3,"audioEnabled":false,"showFps":false,"showLoadProgress":true,"speakProbability":0.1});
2884 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
2885 console
.log("Unable to hook to BrowserPonies");
2889 }, {"CANLOG":CANLOG
, "baseurl":k
.url
});
2893 if (k
.errorDialog
) {
2894 k
.errorDialog
.close();
2900 k
._getAjax = function(url
, callback
) {
2905 ,onload: function(response
) {
2906 if (response
.status
!= 200) {
2907 if (k
.errorCallback
) {
2908 k
.errorCallback(response
);
2915 ,onerror: function(response
) {
2916 if (k
.errorCallback
) {
2917 k
.errorCallback(response
);
2922 if (k
.errorCallback
) {
2928 k
.createDialog = function() {
2929 if ($('ponyhoof_dialog_browserponies')) {
2937 c
+= '<div id="ponyhoof_bp_select"></div><br>';
2938 c
+= '<a href="#" class="uiButton uiButtonConfirm" role="button" id="ponyhoof_bp_more"><span class="uiButtonText">MORE PONY!</span></a><br><br>';
2939 c
+= '<a href="#" class="uiButton" role="button" id="ponyhoof_bp_close"><span class="uiButtonText">Hide this</span></a><br><br>';
2940 c
+= '<a href="#" class="uiButton" role="button" id="ponyhoof_bp_remove"><span class="uiButtonText">Reset</span></a>';
2942 k
.dialog
= new Dialog('browserponies');
2943 k
.dialog
.canCloseByEscapeKey
= false;
2944 k
.dialog
.canCardspace
= false;
2945 k
.dialog
.noTitle
= true;
2946 k
.dialog
.noBottom
= true;
2948 k
.dialog
.changeContent(c
);
2950 $('ponyhoof_bp_more').addEventListener('click', k
.morePonies
, false);
2951 $('ponyhoof_bp_close').addEventListener('click', k
.closeDialog
, false);
2952 $('ponyhoof_bp_remove').addEventListener('click', k
.clearAll
, false);
2954 k
.selectPoniesMenu
= new Menu('browserponies_select', $('ponyhoof_bp_select'));
2955 k
.selectPoniesMenu
.rightFaced
= true;
2956 k
.selectPoniesMenu
.buttonTextClipped
= 59;
2957 k
.selectPoniesButton
= k
.selectPoniesMenu
.createButton("(Random)");
2958 k
.selectPoniesMenu
.searchNoResultsMessage
= "No ponies :(";
2959 k
.selectPoniesMenu
.createMenu();
2960 k
.selectPoniesMenu
.attachButton();
2962 k
.selectPoniesMenu
.createMenuItem({
2966 ,onclick: function(menuItem
, menuClass
) {
2967 k
._select_spawn(menuItem
, menuClass
, 'RANDOM');
2970 for (var code
in k
.ponies
) {
2971 if (k
.ponies
.hasOwnProperty(code
)) {
2972 k
._select_item(code
);
2979 k
._select_item = function(code
) {
2980 var pony
= k
.ponies
[code
];
2981 k
.selectPoniesMenu
.createMenuItem({
2983 ,onclick: function(menuItem
, menuClass
) {
2984 k
._select_spawn(menuItem
, menuClass
, pony
);
2989 k
._select_spawn = function(menuItem
, menuClass
, pony
) {
2990 menuClass
.changeChecked(menuItem
);
2993 if (pony
== 'RANDOM') {
2994 menuClass
.changeButtonText("(Random)");
2996 menuClass
.changeButtonText(pony
);
2999 k
.ponySelected
= pony
;
3003 k
.spawnPony = function(pony
) {
3004 contentEval(function(arg
) {
3006 if (arg
.pony
== 'RANDOM') {
3007 window
.BrowserPonies
.spawnRandom();
3009 window
.BrowserPonies
.spawn(arg
.pony
);
3011 if (!window
.BrowserPonies
.running()) {
3012 window
.BrowserPonies
.start();
3015 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
3016 console
.log("Unable to hook to BrowserPonies");
3020 }, {"CANLOG":CANLOG
, "pony":pony
});
3023 k
.createErrorDialog = function(response
) {
3024 if (!k
.errorDialogShown
) {
3026 k
.errorDialog
= createSimpleDialog('browserponies_error', "Browser Ponies derp'd", "Whoops, there was a problem loading Browser Ponies. Please try again later.<br><br>If you keep seeing this error, please update to the latest version of Ponyhoof if available and <a href=\""+w
.location
.protocol
+PONYHOOF_URL
+"\" data-hovercard=\"/ajax/hovercard/page.php?id="+PONYHOOF_PAGE
+"\">visit and post to the Ponyhoof page for help</a>.");
3028 k
.errorDialogShown
= true;
3032 k
.injectStyle = function() {
3034 css
+= '#ponyhoof_dialog_browserponies .generic_dialog {z-index:100000000 !important;}';
3035 css
+= '#ponyhoof_dialog_browserponies .generic_dialog_popup {width:'+(88+8+8+8+10+10)+'px;margin:'+(38+8)+'px 8px 0 auto;}';
3036 css
+= 'body.hasSmurfbar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(42+8)+'px;}';
3037 css
+= 'body.hasVoiceBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(56+8)+'px;}';
3038 css
+= 'body.hasSmurfbar.hasVoiceBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(70+8)+'px;}';
3039 css
+= 'body.hasViewasChromeBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(76+8)+'px;}';
3040 css
+= 'body.hasSmurfbar.hasViewasChromeBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(80+8)+'px;}';
3041 css
+= '.sidebarMode #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-right:213px;}';
3042 css
+= '._4g5r #ponyhoof_dialog_browserponies .generic_dialog_popup, .-cx-PUBLIC-hasLitestandBookmarksSidebar__root #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-right:8px;}';
3043 css
+= '#ponyhoof_dialog_browserponies .popup {width:'+(88+8+8+8)+'px;margin:0;opacity:.6;-webkit-transition:opacity .3s linear;-moz-transition:opacity .3s linear;-o-transition:opacity .3s linear;transition:opacity .3s linear;}';
3044 css
+= '#ponyhoof_dialog_browserponies .popup:hover {opacity:1;}';
3045 css
+= '#ponyhoof_dialog_browserponies .content {background:#F2F2F2;text-align:center;}';
3046 css
+= '#ponyhoof_dialog_browserponies .uiButton {text-align:left;}';
3047 css
+= '#browser-ponies img {-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
3048 injectManualStyle(css
, 'browserponies');
3051 k
.copyrightDialog = function() {
3052 createSimpleDialog('browserponies_copyright', "Browser Ponies", "<a href='http://panzi.github.io/Browser-Ponies/' target='_blank'>Browser Ponies</a> is created by Mathias Panzenböck, licensed under the <a href='http://opensource.org/licenses/mit-license.html' target='_blank'>MIT License</a>. Based on Desktop Ponies written by <a href='mailto:random.anonymous.pony@gmail.com'>random.anonymous.pony@gmail.com</a>");
3055 k
.morePonies = function(e
) {
3056 k
.spawnPony(k
.ponySelected
);
3062 k
.closeDialog = function(e
) {
3069 k
.clearAll = function(e
) {
3071 contentEval(function(arg
) {
3073 window
.BrowserPonies
.unspawnAll();
3074 window
.BrowserPonies
.stop();
3076 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
3077 console
.log("Unable to hook to BrowserPonies");
3081 }, {"CANLOG":CANLOG
});
3089 var Options = function() {
3093 k
.saveButton
= null;
3095 k
.needToSaveLabel
= false;
3096 k
.needToRefresh
= false;
3097 k
.canSaveSettings
= true;
3099 k
._stack
= CURRENTSTACK
;
3102 k
.create = function() {
3103 // Did we create our Options interface already?
3104 if ($('ponyhoof_dialog_options')) {
3114 extra
= '<br><br><a href="http://jointheherd.little.my" target="_top">Please update to the latest version of Ponyhoof here.</a>';
3117 k
.dialog
= new Dialog('options_force_run');
3119 k
.dialog
.changeTitle("Ponyhoof does not run on "+w
.location
.hostname
);
3120 k
.dialog
.changeContent("Unfortunately, your browser stores settings seperately for each domain ("+w
.location
.protocol
+"//www.facebook.com is different from "+w
.location
.protocol
+"//"+w
.location
.hostname
+")"+extra
);
3121 k
.dialog
.addCloseButton();
3126 c
+= '<div class="ponyhoof_tabs clearfix">';
3127 c
+= '<a href="#" class="active" data-ponyhoof-tab="main">'+CURRENTLANG
.options_tabs_main
+'</a>';
3128 c
+= '<a href="#" class="ponyhoof_show_if_injected" data-ponyhoof-tab="background">'+CURRENTLANG
.options_tabs_background
+'</a>';
3129 c
+= '<a href="#" class="ponyhoof_show_if_injected" data-ponyhoof-tab="sounds">'+CURRENTLANG
.options_tabs_sounds
+'</a>';
3130 c
+= '<a href="#" data-ponyhoof-tab="extras">'+CURRENTLANG
.options_tabs_extras
+'</a>';
3131 c
+= '<a href="#" data-ponyhoof-tab="advanced">'+CURRENTLANG
.options_tabs_advanced
+'</a>';
3132 c
+= '<a href="#" data-ponyhoof-tab="about">'+CURRENTLANG
.options_tabs_about
+'</a>';
3135 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_main" style="display:block;">';
3136 //c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_main">';
3137 c
+= '<div class="clearfix">';
3138 c
+= renderBrowserConfigWarning();
3140 c
+= '<a href="#" ajaxify="/ajax/sharer/?s=18&p[]='+PONYHOOF_PAGE
+'" rel="dialog" class="uiButton uiButtonSpecial rfloat ponyhoof_noShareIsCare" role="button" data-hover="tooltip" data-tooltip-alignh="right" aria-label="'+CURRENTLANG
['fb_share_tooltip']+'"><span class="uiButtonText">Share with your pals!</span></a>';
3142 var visitPageText
= CURRENTLANG
.settings_main_visitPage
;
3143 if (ISUSINGBUSINESS
) {
3144 visitPageText
= CURRENTLANG
.settings_main_visitPageBusiness
;
3147 c
+= '<div class="ponyhoof_show_if_injected">Select your favorite character:</div>';
3148 c
+= '<div class="ponyhoof_hide_if_injected">Select your favorite character to re-enable Ponyhoof:</div>';
3149 c
+= '<div id="ponyhoof_options_pony"></div>';
3150 c
+= '<div id="ponyhoof_options_likebox_div" class="notPage notBusiness"><iframe src="about:blank" id="ponyhoof_options_likebox" scrolling="no" frameborder="0" allowTransparency="true" class="ponyhoof_options_framerefresh"></iframe></div>';
3151 c
+= '<a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" class="ponyhoof_options_linkclick ponyhoof_options_fatlink" data-hovercard="/ajax/hovercard/page.php?id='+PONYHOOF_PAGE
+'">'+visitPageText
+'</a>';
3152 c
+= '<a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_browserponies" data-hover="tooltip" aria-label="Run Desktop Ponies on this page for MOAR ponies!!">Run Browser Ponies<span class="ponyhoof_loading"></span></a>';
3153 c
+= '<div class="ponyhoof_show_if_injected"><a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_options_disable">Disable Ponyhoof</a></div>';
3155 c
+= '<div class="ponyhoof_message uiBoxYellow ponyhoof_updater_newVersion">';
3156 c
+= '<a href="#" class="uiButton uiButtonSpecial rfloat ponyhoof_updater_updateNow" role="button"><span class="uiButtonText">Update now</span></a>';
3157 c
+= '<span class="wrap">An update (v<span class="ponyhoof_updater_versionNum"></span>) for Ponyhoof is available.</span>';
3159 c
+= '<div class="ponyhoof_message uiBoxRed ponyhoof_updater_error">Ponyhoof cannot check for updates at this moment. <a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" class="ponyhoof_options_linkclick">Please visit the Ponyhoof page for the latest news.</a></div>';
3163 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_background">';
3164 c
+= '<div class="ponyhoof_show_if_injected">';
3165 c
+= 'Use as background:';
3166 c
+= '<ul class="ponyhoof_options_fatradio clearfix">';
3167 c
+= '<li id="ponyhoof_options_background_cutie" data-ponyhoof-background="cutie"><a href="#"><span>Cutie mark</span><div class="wrap"><i></i></div></a></li>';
3168 c
+= '<li id="ponyhoof_options_background_loginbg" data-ponyhoof-background="loginbg"><a href="#"><span>Background</span><div class="wrap"><i></i></div></a></li>';
3169 c
+= '<li id="ponyhoof_options_background_custom" data-ponyhoof-background="custom"><a href="#"><span>Custom</span><div class="wrap"><i></i></div></a></li>';
3172 c
+= '<div class="ponyhoof_message uiBoxRed hidden_elem" id="ponyhoof_options_background_error"></div>';
3173 c
+= '<div class="ponyhoof_message uiBoxYellow hidden_elem" id="ponyhoof_options_background_message"></div>';
3174 c
+= '<div id="ponyhoof_options_background_drop">';
3175 c
+= '<div id="ponyhoof_options_background_drop_notdrop">';
3176 c
+= 'Drag and drop a pony pic here to customize your background. <a href="#" class="uiHelpLink" data-hover="tooltip" data-tooltip-alignh="center" aria-label=""></a><br><br>';
3177 c
+= '<span class="ponyhoof_menu_label">Or browse for a pony pic: </span>';
3178 c
+= '<div id="ponyhoof_options_background_selectOuterWrap"><a href="#" class="uiButton" role="button" aria-hidden="true" tabindex="-1"><span class="uiButtonText">Browse...</span></a><div id="ponyhoof_options_background_selectFileWrap"><input type="file" id="ponyhoof_options_background_select" accept="image/*" title="Choose a file..."></div></div>';
3180 c
+= '<div id="ponyhoof_options_background_drop_dropping">Drop here</div>';
3185 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_sounds">';
3186 c
+= '<div class="ponyhoof_show_if_injected">';
3187 c
+= '<div class="ponyhoof_message uiBoxRed hidden_elem unavailable">'+CURRENTLANG
.settings_sounds_unavailable
+'</div>';
3189 var soundsText
= CURRENTLANG
.settings_sounds
;
3190 if (ISUSINGPAGE
|| ISUSINGBUSINESS
) {
3191 soundsText
= CURRENTLANG
.settings_sounds_noNotification
;
3194 c
+= '<div class="available">';
3195 c
+= '<div class="ponyhoof_message uiBoxRed usingPage">Notification sounds are not available when you are using Facebook as your page.</div>';
3196 c
+= k
.generateCheckbox('sounds', soundsText
, {customFunc:k
.soundsClicked
});
3197 c
+= '<div class="notPage notBusiness">';
3198 c
+= '<div id="ponyhoof_options_soundsSettingsWrap"><br>';
3199 c
+= '<div id="ponyhoof_options_soundsSetting" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Notification sound: </span></div>';
3200 c
+= '<div id="ponyhoof_options_soundsNotifType" class="ponyhoof_menu_withlabel ponyhoof_menu_labelbreak"><span class="ponyhoof_menu_label">Don\'t play sounds for these types of notifications:</span></div>';
3201 c
+= '<span class="ponyhoof_menu_label">Volume: </span><input type="range" id="ponyhoof_options_soundsVolume" min="1" max="100"> <a href="#" class="uiButton" role="button" id="ponyhoof_options_soundsVolumePreview"><span class="uiButtonText">Preview</span></a><span class="ponyhoof_menu_label" id="ponyhoof_options_soundsVolumeValue"></span>';
3205 c
+= '<div class="notPage notBusiness"><br>';
3206 c
+= '<span class="ponyhoof_dialog_header">Chat</span>';
3207 c
+= '<div class="ponyhoof_message uiBoxYellow notPage hidden_elem" id="ponyhoof_options_soundsChatSoundWarning">';
3208 c
+= '<a href="#" class="uiButton uiButtonConfirm rfloat" role="button"><span class="uiButtonText">Enable now</span></a>';
3209 c
+= '<span class="wrap">The chat sound option built into Facebook needs to be enabled.</span>';
3211 c
+= '<div class="ponyhoof_message uiBoxYellow notPage hidden_elem" id="ponyhoof_options_soundsMessengerForWindowsWarning">Please turn off Facebook Messenger for Windows for chat sounds to work properly.</div>';
3212 c
+= k
.generateCheckbox('chatSound', "Change chat sound", {customFunc:k
.chatSound
});
3213 c
+= '<div id="ponyhoof_options_soundsChatWrap">';
3214 c
+= '<div id="ponyhoof_options_soundsChatSetting" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Chat sound: </span></div>';
3217 c
+= '</div>'; // .available
3219 c
+= '<div class="ponyhoof_hide_if_injected ponyhoof_message uiBoxRed">';
3220 c
+= 'You must enable Ponyhoof to use Ponyhoof sounds.';
3224 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_extras">';
3225 c
+= '<div class="ponyhoof_show_if_injected">';
3226 c
+= k
.generateCheckbox('pinkieproof', "Strengthen the fourth wall", {title:"Prevents Pinkie Pie from breaking the fourth wall for non-villains"});
3228 c
+= k
.generateCheckbox('forceEnglish', "Always use Ponyhoof in English", {title:"Ponyhoof tries to use your Facebook language, but you can force Ponyhoof to always use English", refresh:true});
3229 c
+= '<div class="ponyhoof_show_if_injected">';
3230 c
+= k
.generateCheckbox('disable_emoticons', "Disable emoticon ponification");
3231 c
+= '<div id="ponyhoof_options_randomPonies" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Characters to randomize: </span></div>';
3232 c
+= '<div id="ponyhoof_options_costume" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Appearance: </span></div>';
3234 c
+= '<div class="ponyhoof_hide_if_injected"><br></div>';
3236 c
+= '<span class="ponyhoof_dialog_header">Multi-user</span>';
3237 c
+= k
.generateCheckbox('allowLoginScreen', "Run Ponyhoof on the Facebook login screen", {global:true, customFunc:k
.allowLoginScreenClicked
});
3238 c
+= k
.generateCheckbox('runForNewUsers', "Run Ponyhoof for new users", {title:CURRENTLANG
['settings_extras_runForNewUsers_explain'], global:true});
3241 c
+= '<div class="ponyhoof_show_if_injected">';
3242 c
+= '<span class="ponyhoof_dialog_header">Performance</span>';
3243 c
+= k
.generateCheckbox('disable_animation', "Disable all animations");
3244 c
+= k
.generateCheckbox('disableDomNodeInserted', "Disable HTML detection", {title:"Disables Ponyhoof from ponifying certain stuff that is not possible to do with styling alone such as notifications and dialogs (Some features require this to be enabled)", customFunc:k
.disableDomNodeInsertedClicked
});
3247 c
+= '<a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_options_resetSettings" data-hover="tooltip" aria-label="Reset your Ponyhoof settings and show the welcome screen">Reset settings</a>';
3248 c
+= '<a href="http://ponyhoof.little.my/faq" class="ponyhoof_options_fatlink" target="_blank" data-hover="tooltip" aria-label="View frequently asked questions, such as how to uninstall or update">View the Ponyhoof FAQ</a>';
3251 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_advanced">';
3252 c
+= '<div class="ponyhoof_message uiBoxYellow">These features are unsupported and used for debugging. This should be used by advanced users only.</div><br>';
3253 c
+= '<span class="ponyhoof_show_if_loaded inline">Style version <span class="ponyhoof_VERSION_CSS"></span><br><br></span>';
3255 c
+= '<textarea id="ponyhoof_options_technical" READONLY spellcheck="false"></textarea><br><br>';
3257 if (STORAGEMETHOD
== 'localstorage') {
3258 c
+= '<span class="ponyhoof_dialog_header">localStorage dump</span>';
3259 c
+= '<textarea id="ponyhoof_options_dump" READONLY spellcheck="false"></textarea><br><br>';
3262 c
+= '<span class="ponyhoof_dialog_header">Chat config</span>';
3263 c
+= '<textarea id="ponyhoof_options_chatconfig" READONLY spellcheck="false"></textarea><br><br>';
3265 c
+= '<div class="ponyhoof_show_if_injected">';
3266 c
+= '<span class="ponyhoof_dialog_header">Custom CSS</span>';
3267 c
+= '<textarea id="ponyhoof_options_customcss" placeholder="Enter any custom CSS to load after Ponyhoof is loaded." title="Enter any custom CSS to load after Ponyhoof is loaded." spellcheck="false"></textarea><br>';
3268 c
+= '<a href="#" class="uiButton" role="button" id="ponyhoof_options_customcss_preview"><span class="uiButtonText">Preview</span></a><br><br>';
3271 c
+= '<span class="ponyhoof_dialog_header">Settings</span>';
3272 c
+= '<textarea id="ponyhoof_options_debug_settings" spellcheck="false"></textarea>';
3273 c
+= '<a href="#" class="uiButton" role="button" id="ponyhoof_options_debug_settings_export"><span class="uiButtonText">Export settings</span></a> <a href="#" class="uiButton" role="button" id="ponyhoof_options_debug_settings_saveall"><span class="uiButtonText">Import settings</span></a><br><br>';
3275 c
+= '<span class="ponyhoof_dialog_header">Other</span>';
3276 c
+= '<div class="ponyhoof_hide_if_injected ponyhoof_message uiBoxYellow">';
3277 c
+= 'You must enable Ponyhoof to use custom CSS or dump debug data.';
3280 c
+= k
.generateCheckbox('debug_exposed', "Always show Debug tab");
3281 c
+= k
.generateCheckbox('debug_slow_load', "Disable fast load");
3282 c
+= '<div class="ponyhoof_show_if_injected">';
3283 c
+= k
.generateCheckbox('debug_dominserted_console', "Dump DOMNodeInserted data to console");
3284 c
+= k
.generateCheckbox('debug_disablelog', "Disable console logging", {customFunc:k
.debug_disablelog
});
3285 c
+= k
.generateCheckbox('debug_noMutationObserver', "Use legacy HTML detection (slower)", {refresh:true});
3286 c
+= k
.generateCheckbox('debug_mutationDebug', "Dump mutation debug info to console");
3287 c
+= k
.generateCheckbox('debug_betaFacebookLinks', "Rewrite links on beta.facebook.com", {refresh:true});
3288 c
+= '<a href="#" id="ponyhoof_options_tempRemove" class="ponyhoof_options_fatlink">Remove style</a>';
3290 c
+= '<a href="#" id="ponyhoof_options_sendSource" class="ponyhoof_options_fatlink">Send page source</a>';
3291 if (STORAGEMETHOD
!= 'mxaddon') {
3292 c
+= '<a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_options_clearLocalStorage" data-hover="tooltip">Reset all settings (including global)</a>';
3296 c
+= '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_about">';
3297 c
+= '<div class="clearfix">';
3298 c
+= '<div class="top">';
3299 c
+= '<div class="rfloat"><a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" class="ponyhoof_options_linkclick" data-hovercard="/ajax/hovercard/page.php?id='+PONYHOOF_PAGE
+'" id="ponyhoof_options_devpic" data-hovercard-instant="1"><'+'img src="'+THEMEURL
+'icon100.png" alt="" width="50" height="50"></a>';
3301 c
+= '<strong>Ponyhoof v'+VERSION
+'</strong><br>';
3302 c
+= 'By <a href="'+w
.location
.protocol
+'//'+getFbDomain()+'/ngyikp" class="ponyhoof_options_linkclick" data-hovercard="/ajax/hovercard/user.php?id=100000971648506">Ng Yik Phang</a> and <a href="http://ponyhoof.little.my/credits" class="ponyhoof_options_linkclick" data-hover="tooltip" aria-label="View all the ponies, artists and contributors that made Ponyhoof come to life">many contributors</a>';
3304 c
+= '<a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" class="ponyhoof_options_linkclick ponyhoof_options_fatlink notBusiness" data-hovercard="/ajax/hovercard/page.php?id='+PONYHOOF_PAGE
+'">Send feedback and suggestions on our page</a>';
3305 if (ISCHROME
|| (STORAGEMETHOD
== 'chrome' && !ISOPERABLINK
)) {
3306 c
+= '<a href="http://ponyhoof.little.my/cwsreview" target="_blank" class="ponyhoof_options_fatlink">Rate us 5 stars and write a review on the Chrome Web Store</a>';
3308 c
+= '<iframe src="about:blank" id="ponyhoof_options_twitter" allowtransparency="true" frameborder="0" scrolling="no"></iframe>';
3309 if (ISCHROME
|| STORAGEMETHOD
== 'chrome') {
3310 c
+= '<div id="ponyhoof_options_plusone"><div class="g-plusone" data-size="medium" data-annotation="inline" data-width="443" data-href="https://chrome.google.com/webstore/detail/efjjgphedlaihnlgaibiaihhmhaejjdd"></div></div>';
3313 c
+= '<div class="ponyhoof_options_aboutsection"><div class="inner">';
3314 c
+= '<strong>If you love Ponyhoof, then please help us a hoof and contribute to support development! Thanks!</strong><br><br>';
3315 c
+= '<div id="ponyhoof_donate" class="clearfix">';
3316 c
+= '<div class="inner"><form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" id="ponyhoof_options_donatepaypal"><input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="paypal@little.my"><input type="hidden" name="currency_code" value="USD"><input type="hidden" name="item_name" value="Support Ponyhoof"><a href="#" id="ponyhoof_options_donatepaypal_link">Contribute with PayPal</a></form></div>';
3317 c
+= '<div class="inner"><iframe src="about:blank" id="ponyhoof_donate_flattr_iframe" allowtransparency="true" frameborder="0" scrolling="no"></iframe></div>'; //<a href="//flattr.com/thing/641591/Ponyhoof" target="_blank" id="ponyhoof_donate_flattr">Flattr this!</a>
3319 c
+= '</div></div>';
3321 c
+= '<div class="ponyhoof_options_aboutsection"><div class="inner">The Ponyhoof extension for Facebook is not affiliated or endorsed by Facebook and/or Hasbro in any way. MY LITTLE PONY, FRIENDSHIP IS MAGIC and all related characters are trademarks of Hasbro. © '+(new Date().getFullYear())+' Hasbro. All Rights Reserved.</div></div>';
3325 var successText
= '';
3326 var ponyData
= convertCodeToData(REALPONY
);
3327 if (ponyData
.successText
) {
3328 successText
= ponyData
.successText
+' ';
3331 bottom
+= '<div class="lfloat"><span class="ponyhoof_updater_checking">Checking for updates...</span><span class="ponyhoof_updater_latest">'+successText
+'Ponyhoof is up-to-date.</span></div>';
3332 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_options_save"><span class="uiButtonText">'+CURRENTLANG
.close
+'</span></a>';
3334 k
.dialog
= new Dialog('options');
3336 k
.dialog
.changeTitle(CURRENTLANG
.options_title
);
3337 k
.dialog
.changeContent(c
);
3338 k
.dialog
.changeBottom(bottom
);
3339 k
.dialog
.onclose
= k
.dialogOnClose
;
3340 k
.dialog
.onclosefinish
= k
.dialogOnCloseFinish
;
3344 k
.dialog
.dialog
.className
+= ' ponyhoof_dialog_localstorageWarningEmbedded';
3346 k
.saveButton
= $('ponyhoof_options_save');
3347 k
.saveButton
.addEventListener('click', k
.saveButtonClick
, false);
3349 k
.dialog
.dialog
.getElementsByClassName('ponyhoof_noShareIsCare')[0].addEventListener('click', function() {
3353 var l
= k
.dialog
.dialog
.getElementsByClassName('ponyhoof_options_linkclick');
3354 for (var i
= 0, len
= l
.length
; i
< len
; i
+= 1) {
3355 l
[i
].addEventListener('click', function() {
3361 w
.setTimeout(function() {
3362 var update
= new Updater();
3363 update
.checkForUpdates();
3369 // @todo make k.mainInit non-dependant
3374 if (userSettings
.debug_exposed
) {
3375 addClass(k
.dialog
.dialog
, 'ponyhoof_options_debugExposed');
3379 k
._refreshDialog = function() {
3381 k
.disableDomNodeInserted();
3383 if (k
.debugLoaded
) {
3384 $('ponyhoof_options_technical').textContent
= k
.techInfo();
3385 //$('ponyhoof_options_linkedcss').textContent = k.linkedCss();
3389 k
.debugLoaded
= false;
3390 k
.techInfo = function() {
3391 var cxPrivate
= false;
3392 if (d
.getElementsByClassName('-cx-PRIVATE-fbLayout__root').length
) {
3396 var tech
= SIG
+ " " + new Date().toString() + "\n";
3397 tech
+= "USERID: " + USERID
+ "\n";
3398 tech
+= "CURRENTPONY: " + CURRENTPONY
+ "\n";
3399 tech
+= "REALPONY: " + REALPONY
+ "\n";
3400 tech
+= "CURRENTSTACK: " + CURRENTSTACK
.stack
+ "\n";
3401 tech
+= "STORAGEMETHOD: " + STORAGEMETHOD
+ "\n";
3402 tech
+= "DISTRIBUTION: " + DISTRIBUTION
+ "\n";
3403 if (STORAGEMETHOD
== 'localstorage') {
3404 tech
+= "localStorage.length: " + w
.localStorage
.length
+ "\n";
3407 tech
+= "navigator.userAgent: " + w
.navigator
.userAgent
+ "\n";
3408 tech
+= "document.documentElement.className: " + d
.documentElement
.className
+ "\n";
3409 tech
+= "document.body.className: " + d
.body
.className
+ "\n";
3410 tech
+= "Has cx-PRIVATE: " + cxPrivate
+ "\n";
3411 tech
+= "window.location.href: " + w
.location
.href
+ "\n";
3413 tech
+= k
.linkedCss();
3415 tech
+= k
.linkedScript();
3417 tech
+= k
.linkedIframe();
3422 if ($('bfb_options_button')) {
3423 ext
.push("Social Fixer");
3425 if (d
.getElementsByClassName('rg3fbpz-tooltip').length
) {
3426 ext
.push("Photo Zoom for Facebook");
3428 if ($('fbpoptslink')) {
3429 ext
.push("FB Purity");
3431 if ($('fbfPopupContainer')) {
3434 if ($('unfriend_finder')) {
3435 ext
.push("Unfriend Finder");
3437 if ($('window-resizer-tooltip')) {
3438 ext
.push("Window Resizer");
3441 ext
.push("Hover Zoom");
3443 if ($('myGlobalPonies')) {
3444 ext
.push("My Global Ponies");
3446 if ($('memeticonStyle')) {
3447 ext
.push("Memeticon (ads)");
3449 if ($('socialplus')) {
3450 ext
.push("SocialPlus! (ads)");
3452 if (d
.querySelector('script[src^="chrome-extension://igdhbblpcellaljokkpfhcjlagemhgjl"]')) {
3453 ext
.push("Iminent (ads)");
3455 if ($('_fbm-emoticons-wrapper')) {
3456 ext
.push("myemoticons.com");
3458 if (d
.querySelector('script[src^="chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl"]')) {
3459 ext
.push("Skype plugin");
3461 if (d
.querySelector('script[src^="chrome-extension://jmfkcklnlgedgbglfkkgedjfmejoahla"]')) {
3462 ext
.push("AVG Safe Search");
3464 if ($('DAPPlugin')) {
3465 ext
.push("Download Accelerator Plus");
3468 if ($('bfb_theme')) {
3469 conflict
.push("Social Fixer theme");
3471 if ($('mycssstyle')) {
3472 conflict
.push("SocialPlus! theme");
3474 if ($('ColourChanger')) {
3475 conflict
.push("Facebook Colour Changer");
3477 if (hasClass(d
.documentElement
, 'myFacebook')) {
3478 conflict
.push("Color My Facebook");
3480 if (w
.navigator
.userAgent
.match(/Mozilla
\/4\.0 \(compatible
\; MSIE
7\.0\; Windows
/)) {
3481 conflict
.push("IE 7 user-agent spoofing");
3483 tech
+= "Installed extensions: ";
3485 for (var i
= 0, len
= ext
.length
; i
< len
; i
+= 1) {
3487 if (ext
.length
-1 != i
) {
3492 tech
+= "None detected";
3496 tech
+= "Conflicts: ";
3497 if (conflict
.length
) {
3498 for (var i
= 0, len
= conflict
.length
; i
< len
; i
+= 1) {
3499 tech
+= conflict
[i
];
3500 if (conflict
.length
-1 != i
) {
3505 tech
+= "None detected";
3512 k
.linkedCss = function() {
3513 var css
= d
.getElementsByTagName('link');
3515 for (var i
= 0, len
= css
.length
; i
< len
; i
+= 1) {
3516 if (css
[i
].rel
== 'stylesheet') {
3517 t
+= css
[i
].href
+ "\n";
3524 k
.linkedScript = function() {
3525 var script
= d
.getElementsByTagName('script');
3527 for (var i
= 0, len
= script
.length
; i
< len
; i
+= 1) {
3528 if (script
[i
].src
) {
3529 t
+= script
[i
].src
+ "\n";
3536 k
.linkedIframe = function() {
3537 var iframe
= d
.getElementsByTagName('iframe');
3539 for (var i
= 0, len
= iframe
.length
; i
< len
; i
+= 1) {
3540 if (iframe
[i
].src
&& iframe
[i
].src
.indexOf('://'+getFbDomain()+'/ai.php') == -1) {
3541 t
+= iframe
[i
].src
+ "\n";
3548 k
.debugInfo = function() {
3549 if (k
.debugLoaded
) {
3552 k
.debugLoaded
= true;
3555 var customcss
= $('ponyhoof_options_customcss');
3556 if (userSettings
.customcss
) {
3557 customcss
.value
= userSettings
.customcss
;
3559 customcss
.addEventListener('input', function() {
3560 if (!k
.needsToRefresh
) {
3561 k
.needsToRefresh
= true;
3562 k
.updateCloseButton();
3565 $('ponyhoof_options_customcss_preview').addEventListener('click', function() {
3566 if (!$('ponyhoof_style_customcss')) {
3567 injectManualStyle('', 'customcss');
3570 $('ponyhoof_style_customcss').textContent
= '/* '+SIG
+' */'+customcss
.value
;
3573 if (STORAGEMETHOD
== 'localstorage') {
3575 for (var i
in localStorage
) {
3576 dump
+= i
+": "+localStorage
[i
]+"\n";
3578 $('ponyhoof_options_dump').value
= dump
;
3581 contentEval(function(arg
) {
3583 if (typeof window
.requireLazy
== 'function') {
3584 window
.requireLazy(['ChatConfig'], function(ChatConfig
) {
3585 document
.getElementById('ponyhoof_options_chatconfig').value
= JSON
.stringify(ChatConfig
.getDebugInfo());
3589 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
3590 console
.log("Unable to hook to ChatConfig");
3594 }, {"CANLOG":CANLOG
});
3597 var settingsTextarea
= $('ponyhoof_options_debug_settings');
3599 $('ponyhoof_options_debug_settings_export').addEventListener('click', function() {
3600 settingsTextarea
.value
= JSON
.stringify(userSettings
);
3603 $('ponyhoof_options_debug_settings_saveall').addEventListener('click', function(e
) {
3606 var s
= JSON
.parse(settingsTextarea
.value
);
3608 createSimpleDialog('debug_settingsKey_error', "Derp'd", "Invalid JSON<br><br><code>\n\n"+e
.toString()+"</code>");
3612 if (confirm(SIG
+" Are you sure you want to overwrite your settings? Facebook will be reloaded immediately after saving.")) {
3615 w
.location
.reload();
3620 $('ponyhoof_options_tempRemove').addEventListener('click', k
._debugRemoveStyle
, false);
3621 k
._debugNoMutationObserver();
3623 $('ponyhoof_options_sendSource').addEventListener('click', function() {
3624 if (confirm(SIG
+" Are you sure you want to send the page source for debugging? Only the Ponyhoof developers can view the page. Please send the page source only when necessary.\n\nNote that it will take some time to upload, don't close the browser window until it is finished.")) {
3627 var temp
= $('ponyhoof_options_technical').value
;
3628 $('ponyhoof_options_technical').value
= '';
3629 if ($('ponyhoof_sourceSend_input')) {
3630 $('ponyhoof_sourceSend_input').value
= '';
3631 var sourceSend
= $('ponyhoof_sourceSend_input').parentNode
;
3635 for (var x
in userSettings
) {
3636 settings
[x
] = userSettings
[x
];
3638 settings
['customBg'] = null;
3640 var t
= d
.documentElement
.innerHTML
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
3641 t
= '<!DOCTYPE html><html class="'+d
.documentElement
.className
+'" id="'+d
.documentElement
.id
+'"><!-- '+k
.techInfo()+"\n\n"+JSON
.stringify(settings
)+' -->'+t
+'</html>';
3643 if ($('ponyhoof_sourceSend_input')) {
3644 $('ponyhoof_sourceSend_input').value
= t
;
3646 var sourceSendTxt
= d
.createElement('input');
3647 sourceSendTxt
.type
= 'hidden';
3648 sourceSendTxt
.id
= 'ponyhoof_sourceSend_input';
3649 sourceSendTxt
.name
= 'post';
3650 sourceSendTxt
.value
= t
;
3652 var sourceSend
= d
.createElement('form');
3653 sourceSend
.method
= 'POST';
3654 sourceSend
.action
= 'https://paste.little.my/post/';
3655 sourceSend
.target
= '_blank';
3656 sourceSend
.appendChild(sourceSendTxt
);
3657 d
.body
.appendChild(sourceSend
);
3660 sourceSend
.submit();
3662 $('ponyhoof_options_technical').value
= temp
;
3667 $('ponyhoof_options_technical').textContent
= k
.techInfo();
3668 //$('ponyhoof_options_linkedcss').textContent = k.linkedCss();
3671 k
._debugRemoveStyle = function(e
) {
3672 changeThemeSmart('NONE');
3674 d
.removeEventListener('DOMNodeInserted', DOMNodeInserted
, true);
3675 if (mutationObserverMain
) {
3676 mutationObserverMain
.disconnect();
3683 k
._debugNoMutationObserver = function() {
3684 var mutationObserver
= w
.WebKitMutationObserver
|| w
.MutationObserver
|| false;
3685 if (!mutationObserver
) {
3686 var option
= $('ponyhoof_options_debug_noMutationObserver');
3687 option
.disabled
= true;
3688 option
.checked
= true;
3690 var label
= $('ponyhoof_options_label_debug_noMutationObserver');
3691 addClass(label
, 'ponyhoof_options_unavailable');
3692 label
.setAttribute('data-hover', 'tooltip');
3693 label
.setAttribute('aria-label', "The new HTML detection method is not supported on your browser. Please update your browser if possible.");
3697 k
.mainInitLoaded
= false;
3698 k
.mainInit = function() {
3699 if (k
.mainInitLoaded
) {
3704 var ponySelector
= new PonySelector($('ponyhoof_options_pony'), {});
3705 ponySelector
.allowRandom
= true;
3706 ponySelector
.customClick = function(menuItem
, menuClass
) {
3707 if (ponySelector
.oldPony
== 'NONE' || CURRENTPONY
== 'NONE') {
3708 if (ponySelector
.oldPony
== 'NONE' && CURRENTPONY
!= 'NONE') {
3710 runDOMNodeInserted();
3713 if (ponySelector
.oldPony
!= 'NONE' && CURRENTPONY
== 'NONE') {
3714 k
.needsToRefresh
= true;
3716 if (k
._stack
!= CURRENTSTACK
) {
3717 k
.needsToRefresh
= true;
3719 k
.needToSaveLabel
= true;
3720 k
.updateCloseButton();
3722 var f
= k
.dialog
.dialog
.getElementsByClassName('ponyhoof_options_framerefresh');
3723 for (var i
= 0, len
= f
.length
; i
< len
; i
+= 1) {
3726 fadeOut(iframe
, function() {
3727 w
.setTimeout(function() {
3728 iframe
.style
.display
= '';
3729 removeClass(iframe
, 'ponyhoof_fadeout');
3731 iframe
.src
= iframe
.src
.replace(/\href\=/, '&href=');
3737 ponySelector
.createSelector();
3739 if (!ISUSINGPAGE
&& !ISUSINGBUSINESS
) {
3740 w
.setTimeout(function() {
3741 $('ponyhoof_options_likebox').src
= '//'+getFbDomain()+'/plugins/like.php?href=http%3A%2F%2Fwww.facebook.com%2Fprofile.php%3Fid%3D'+PONYHOOF_PAGE
+'&send=false&layout=standard&show_faces=true&action=like&colorscheme=light&ponyhoof_runme';
3746 $('ponyhoof_options_disable').addEventListener('click', k
.disablePonyhoof
, false);
3749 $('ponyhoof_browserponies').addEventListener('click', k
.runBrowserPonies
, false);
3751 k
.mainInitLoaded
= true;
3754 k
.extrasInitLoaded
= false;
3755 k
.extrasInit = function() {
3756 if (k
.extrasInitLoaded
) {
3763 // Disable animations
3764 if (!supportsCssTransition()) {
3765 var option
= $('ponyhoof_options_disable_animation');
3766 option
.disabled
= true;
3767 option
.checked
= true;
3769 var label
= $('ponyhoof_options_label_disable_animation');
3770 addClass(label
, 'ponyhoof_options_unavailable');
3771 label
.setAttribute('data-hover', 'tooltip');
3772 label
.setAttribute('aria-label', "Animations are not supported on your browser. Please update your browser if possible.");
3776 $('ponyhoof_options_resetSettings').addEventListener('click', k
.resetSettings
, false);
3778 var clearLocalStorage
= $('ponyhoof_options_clearLocalStorage');
3779 if (clearLocalStorage
) {
3780 clearLocalStorage
.addEventListener('click', k
.clearStorage
, false);
3783 k
.extrasInitLoaded
= true;
3786 k
.extrasCostumeMenu
= null;
3787 k
.extrasCostumeButton
= null;
3788 k
.extrasCostumeMenuItemNormal
= null;
3789 k
.extrasCostumeMenuItems
= {};
3790 k
.costumesInit = function() {
3791 var desc
= "(Normal)";
3793 if (userSettings
.costume
&& doesCharacterHaveCostume(REALPONY
, userSettings
.costume
)) {
3794 desc
= COSTUMESX
[userSettings
.costume
].name
;
3798 k
.extrasCostumeMenu
= new Menu('costume', $('ponyhoof_options_costume'));
3799 k
.extrasCostumeButton
= k
.extrasCostumeMenu
.createButton(desc
);
3800 k
.extrasCostumeButton
.setAttribute('data-hover', 'tooltip');
3801 k
.extrasCostumeButton
.setAttribute('aria-label', CURRENTLANG
.costume_tooltip
);
3802 k
.extrasCostumeMenu
.canSearch
= false;
3803 k
.extrasCostumeMenu
.createMenu();
3804 k
.extrasCostumeMenu
.attachButton();
3805 k
.extrasCostumeMenuItemNormal
= k
.extrasCostumeMenu
.createMenuItem({
3809 ,onclick: function(menuItem
, menuClass
) {
3810 k
._costumesInit_save(menuItem
, menuClass
, '');
3814 for (var code
in COSTUMESX
) {
3815 if (COSTUMESX
.hasOwnProperty(code
)) {
3816 k
._costumesInit_item(code
);
3820 changeThemeFuncQueue
.push(function() {
3821 if (doesCharacterHaveCostume(REALPONY
, userSettings
.costume
)) {
3822 k
.extrasCostumeMenu
.changeButtonText(COSTUMESX
[userSettings
.costume
].name
);
3823 k
.extrasCostumeMenu
.changeChecked(k
.extrasCostumeMenuItems
[userSettings
.costume
]);
3825 k
.extrasCostumeMenu
.changeButtonText("(Normal)");
3826 k
.extrasCostumeMenu
.changeChecked(k
.extrasCostumeMenuItemNormal
);
3829 for (var code
in COSTUMESX
) {
3830 if (COSTUMESX
.hasOwnProperty(code
)) {
3831 if (doesCharacterHaveCostume(REALPONY
, code
)) {
3832 removeClass(k
.extrasCostumeMenuItems
[code
].menuItem
, 'hidden_elem');
3834 addClass(k
.extrasCostumeMenuItems
[code
].menuItem
, 'hidden_elem');
3841 k
._costumesInit_item = function(code
) {
3843 var extraClass
= '';
3844 if (doesCharacterHaveCostume(REALPONY
, code
)) {
3845 if (userSettings
.costume
== code
) {
3849 extraClass
+= ' hidden_elem';
3852 k
.extrasCostumeMenuItems
[code
] = k
.extrasCostumeMenu
.createMenuItem({
3853 html: COSTUMESX
[code
].name
3856 ,extraClass: extraClass
3857 ,onclick: function(menuItem
, menuClass
) {
3858 k
._costumesInit_save(menuItem
, menuClass
, code
);
3863 k
._costumesInit_save = function(menuItem
, menuClass
, code
) {
3864 if (!COSTUMESX
[code
] && code
!= '') {
3868 changeCostume(code
);
3869 userSettings
.costume
= code
;
3872 if (COSTUMESX
[code
]) {
3873 menuClass
.changeButtonText(COSTUMESX
[code
].name
);
3875 menuClass
.changeButtonText("(Normal)");
3877 menuClass
.changeChecked(menuItem
);
3880 k
.needToSaveLabel
= true;
3881 k
.updateCloseButton();
3884 k
.resetSettings = function(e
) {
3890 saveValue(SETTINGSPREFIX
+'soundCache', JSON
.stringify(null));
3892 k
.canSaveSettings
= false;
3894 w
.location
.reload();
3897 k
.clearStorage = function(e
) {
3900 k
.canSaveSettings
= false;
3902 if (typeof GM_listValues
!= 'undefined') {
3904 var keys
= GM_listValues();
3905 for (var i
= 0, len
= keys
.length
; i
< len
; i
+= 1) {
3906 GM_deleteValue(keys
[i
]);
3909 alert(e
.toString());
3913 switch (STORAGEMETHOD
) {
3914 case 'localstorage':
3915 if (confirm(SIG
+" localStorage must be cleared in order to reset settings. Doing this may cause other extensions to lose their settings.")) {
3917 w
.localStorage
.clear();
3919 alert("Can't clear localStorage :(\n\n"+e
.toString());
3927 chrome_clearStorage();
3931 opera_clearStorage();
3935 safari_clearStorage();
3943 // Maxthon does not have a clear storage function
3951 w
.location
.reload();
3954 k
.donateLoaded
= false;
3955 k
.loadDonate = function() {
3956 if (k
.donateLoaded
) {
3960 statTrack('aboutclicked');
3962 $('ponyhoof_options_twitter').src
= 'https://platform.twitter.com/widgets/follow_button.html?screen_name=ponyhoof&show_screen_name=true&show_count=true';
3963 if (ISCHROME
|| STORAGEMETHOD
== 'chrome') {
3965 var po
= document
.createElement('script'); po
.type
= 'text/javascript'; po
.async
= true;
3966 po
.src
= 'https://apis.google.com/js/plusone.js';
3967 var s
= document
.getElementsByTagName('script')[0]; s
.parentNode
.insertBefore(po
, s
);
3971 $('ponyhoof_options_donatepaypal_link').addEventListener('click', function() {
3972 $('ponyhoof_options_donatepaypal').submit();
3973 statTrack('paypalClicked');
3977 $('ponyhoof_donate_flattr_iframe').src
= THEMEURL
+'_welcome/flattrStandalone.htm';
3979 k
.donateLoaded
= true;
3982 k
.randomInit = function() {
3984 if (userSettings
.randomPonies
) {
3985 current
= userSettings
.randomPonies
.split('|');
3988 var outerwrap
= $('ponyhoof_options_randomPonies');
3989 var ponySelector
= new PonySelector(outerwrap
, {});
3990 ponySelector
.overrideClickAction
= true;
3991 ponySelector
.customCheckCondition = function(code
) {
3992 if (current
.indexOf(code
) != -1) {
3998 ponySelector
.customClick = function(menuItem
, menuClass
) {
3999 var code
= menuItem
.menuItem
.getAttribute('data-ponyhoof-menu-data');
4001 if (!hasClass(menuItem
.menuItem
, 'ponyhoof_menuitem_checked')) {
4002 menuItem
.menuItem
.className
+= ' ponyhoof_menuitem_checked';
4006 removeClass(menuItem
.menuItem
, 'ponyhoof_menuitem_checked');
4008 current
.splice(current
.indexOf(code
), 1);
4010 userSettings
.randomPonies
= current
.join('|');
4013 k
._randomUpdateButtonText(current
, menuClass
);
4014 k
.needToSaveLabel
= true;
4015 k
.updateCloseButton();
4017 ponySelector
.createSelector();
4018 k
._randomUpdateButtonText(current
, ponySelector
.menu
);
4020 var mass
= d
.createElement('a');
4022 mass
.className
= 'uiButton';
4023 mass
.setAttribute('role', 'button');
4024 mass
.id
= 'ponyhoof_options_randomPonies_mass';
4025 mass
.innerHTML
= '<span class="uiButtonText">'+CURRENTLANG
.invertSelection
+'</span>';
4026 mass
.addEventListener('click', function(e
) {
4027 var newCurrent
= [];
4028 for (var i
= 0, len
= PONIES
.length
; i
< len
; i
+= 1) {
4029 var menuitem
= ponySelector
.menu
.menu
.querySelector('.ponyhoof_menuitem[data-ponyhoof-menu-data="'+PONIES
[i
].code
+'"]');
4030 if (PONIES
[i
].hidden
) {
4032 removeClass(menuitem
, 'ponyhoof_menuitem_checked');
4036 if (current
.indexOf(PONIES
[i
].code
) == -1) {
4037 newCurrent
.push(PONIES
[i
].code
);
4040 addClass(menuitem
, 'ponyhoof_menuitem_checked');
4044 removeClass(menuitem
, 'ponyhoof_menuitem_checked');
4048 current
= newCurrent
;
4049 userSettings
.randomPonies
= current
.join('|');
4052 k
._randomUpdateButtonText(current
, ponySelector
.menu
);
4053 k
.needToSaveLabel
= true;
4054 k
.updateCloseButton();
4055 w
.setTimeout(function() {
4056 ponySelector
.menu
.open();
4061 outerwrap
.appendChild(mass
);
4064 k
._randomUpdateButtonText = function(current
, menuClass
) {
4065 var buttonText
= "("+current
.length
+" characters)";
4066 if (current
.length
== 0) {
4067 buttonText
= "(All characters)";
4068 } else if (current
.length
== 1) {
4069 var data
= convertCodeToData(current
[0]);
4070 buttonText
= data
.name
;
4072 menuClass
.changeButtonText(buttonText
);
4075 k
.soundsMenu
= null;
4076 k
.soundsButton
= null;
4077 k
.soundsInitLoaded
= false;
4078 k
.soundsNotifTypeMenu
= null;
4079 k
.soundsNotifTypeButton
= null;
4080 k
.soundsSettingsWrap
= null;
4082 k
.soundsChatSoundWarning
= null;
4083 k
.soundsChatLoaded
= false;
4084 k
.soundsChatWrap
= null;
4085 k
.soundsChatMenu
= null;
4086 k
.soundsChatButton
= null;
4087 k
.soundsInit = function() {
4088 if (k
.soundsInitLoaded
) {
4093 if (typeof w
.Audio
=== 'undefined') {
4096 initPonySound('soundsTest');
4098 $$(k
.dialog
.dialog
, '.unavailable', function(ele
) {
4099 removeClass(ele
, 'hidden_elem');
4101 $$(k
.dialog
.dialog
, '.available', function(ele
) {
4102 addClass(ele
, 'hidden_elem');
4104 k
.soundsInitLoaded
= true;
4108 var desc
= "(Auto-select)";
4109 if (SOUNDS
[userSettings
.soundsFile
] && SOUNDS
[userSettings
.soundsFile
].name
) {
4110 desc
= SOUNDS
[userSettings
.soundsFile
].name
;
4113 k
.soundsMenu
= new Menu('sounds', $('ponyhoof_options_soundsSetting'));
4114 k
.soundsButton
= k
.soundsMenu
.createButton(desc
);
4115 k
.soundsMenu
.searchNoResultsMessage
= "No sounds found";
4116 k
.soundsMenu
.createMenu();
4117 k
.soundsMenu
.attachButton();
4119 for (var code
in SOUNDS
) {
4120 if (SOUNDS
.hasOwnProperty(code
)) {
4121 k
._soundsMenu_item(code
);
4123 if (SOUNDS
[code
].seperator
) {
4124 k
.soundsMenu
.createSeperator();
4129 k
._soundsNotifTypeInit();
4131 var volumeInput
= $('ponyhoof_options_soundsVolume');
4132 var volumePreview
= $('ponyhoof_options_soundsVolumePreview');
4133 var volumeValue
= $('ponyhoof_options_soundsVolumeValue');
4134 var volumeTimeout
= null;
4136 volumeInput
.value
= userSettings
.soundsVolume
* 100;
4137 if (supportsRange()) {
4138 volumePreview
.style
.display
= 'none';
4139 volumeValue
.style
.display
= 'inline';
4140 volumeValue
.innerText
= volumeInput
.value
+"%";
4141 volumeInput
.addEventListener('change', function() {
4142 volumeValue
.innerText
= volumeInput
.value
+"%";
4144 w
.clearTimeout(volumeTimeout
);
4145 volumeTimeout
= w
.setTimeout(function() {
4146 var volume
= volumeInput
.value
/ 100;
4147 userSettings
.soundsVolume
= Math
.max(0, Math
.min(volume
, 1));
4150 k
._soundsPreview(userSettings
.soundsFile
);
4154 volumeInput
.type
= 'number';
4155 volumeInput
.className
= 'inputtext';
4156 volumeInput
.setAttribute('data-hover', 'tooltip');
4157 volumeInput
.setAttribute('aria-label', "Enter a number between 1-100");
4158 volumePreview
.addEventListener('click', function(e
) {
4159 var volume
= volumeInput
.value
/ 100;
4160 userSettings
.soundsVolume
= Math
.max(0, Math
.min(volume
, 1));
4163 k
._soundsPreview(userSettings
.soundsFile
);
4170 // Detect chat sound enabled setting
4171 k
.soundsChatSoundWarning
= $('ponyhoof_options_soundsChatSoundWarning');
4172 k
.soundsChatWrap
= $('ponyhoof_options_soundsChatWrap');
4174 if (typeof USW
.requireLazy
== 'function') {
4175 USW
.requireLazy(['ChatOptions', 'Arbiter'], function(ChatOptions
, Arbiter
) {
4176 if (userSettings
.chatSound
) {
4177 k
._soundsChatSoundWarn(ChatOptions
.getSetting('sound'));
4179 addClass(k
.soundsChatSoundWarning
, 'hidden_elem');
4182 Arbiter
.subscribe('chat/option-changed', function(e
, option
) {
4183 if (!userSettings
.chatSound
) {
4186 if (option
.name
== 'sound') {
4187 k
._soundsChatSoundWarn(option
.value
);
4193 error("Unable to hook to ChatOptions and Arbiter");
4197 // Detect Facebook Messenger for Windows
4198 if (w
.navigator
.plugins
) {
4199 w
.navigator
.plugins
.refresh(false);
4201 for (var i
= 0, len
= w
.navigator
.plugins
.length
; i
< len
; i
+= 1) {
4202 var plugin
= w
.navigator
.plugins
[i
];
4203 if (plugin
[0] && plugin
[0].type
=== 'application/x-facebook-desktop-1') {
4204 removeClass($('ponyhoof_options_soundsMessengerForWindowsWarning'), 'hidden_elem');
4210 k
._soundsChatLoad();
4211 k
._soundsChatInit();
4213 var button
= k
.soundsChatSoundWarning
.getElementsByClassName('uiButton');
4214 button
[0].addEventListener('click', function() {
4215 k
._soundsTurnOnFbSound();
4218 k
.soundsInitLoaded
= true;
4221 // Create a menu item for notification sounds
4222 // Used only on k.soundsInit()
4223 k
._soundsMenu_item = function(code
) {
4225 if (userSettings
.soundsFile
== code
) {
4229 k
.soundsMenu
.createMenuItem({
4230 html: SOUNDS
[code
].name
4231 ,title: SOUNDS
[code
].title
4234 ,onclick: function(menuItem
, menuClass
) {
4235 if (!SOUNDS
[code
] || !SOUNDS
[code
].name
) {
4239 //$('ponyhoof_options_sounds').checked = true;
4240 //userSettings.sounds = true;
4241 userSettings
.soundsFile
= code
;
4244 k
._soundsPreview(code
);
4246 menuClass
.changeButtonText(menuItem
.getText());
4247 menuClass
.changeChecked(menuItem
);
4249 k
.needToSaveLabel
= true;
4250 k
.updateCloseButton();
4255 // Warn people that Facebook's own chat sound needs to be enabled
4256 // Used 2 times on k.soundsInit()
4257 k
._soundsChatSoundWarn = function(isFbSoundEnabled
) {
4258 if (isFbSoundEnabled
) {
4259 addClass(k
.soundsChatSoundWarning
, 'hidden_elem');
4260 $('ponyhoof_options_chatSound').disabled
= false;
4261 if (userSettings
.chatSound
) {
4262 $('ponyhoof_options_chatSound').checked
= true;
4265 removeClass(k
.soundsChatSoundWarning
, 'hidden_elem');
4266 $('ponyhoof_options_chatSound').disabled
= true;
4267 $('ponyhoof_options_chatSound').checked
= false;
4271 // Turn on Facebook chat sounds
4272 // Used on k.soundsInit() and k.chatSound()
4273 k
._soundsTurnOnFbSound = function() {
4275 if (typeof USW
.requireLazy
== 'function') {
4276 USW
.requireLazy(['ChatOptions', 'ChatSidebarDropdown'], function(ChatOptions
, ChatSidebarDropdown
) {
4277 ChatOptions
.setSetting('sound', 1);
4278 ChatSidebarDropdown
.prototype.changeSetting('sound', 1);
4282 error("Unable to hook to ChatOptions and ChatSidebarDropdown");
4287 k
._soundsNotifTypeCurrent
= [];
4288 // Initialize the notification sound blacklist and its HTML template
4289 // Used only on k.soundsInit()
4290 k
._soundsNotifTypeInit = function() {
4291 if (userSettings
.soundsNotifTypeBlacklist
) {
4292 var current
= userSettings
.soundsNotifTypeBlacklist
.split('|');
4294 for (var code
in SOUNDS_NOTIFTYPE
) {
4295 if (current
.indexOf(code
) != -1) {
4296 k
._soundsNotifTypeCurrent
.push(code
);
4301 k
.soundsNotifTypeMenu
= new Menu('soundsNotifType', $('ponyhoof_options_soundsNotifType'));
4302 k
.soundsNotifTypeButton
= k
.soundsNotifTypeMenu
.createButton('');
4303 k
.soundsNotifTypeMenu
.canSearch
= false;
4304 k
.soundsNotifTypeMenu
.createMenu();
4305 k
.soundsNotifTypeMenu
.attachButton();
4307 for (var code
in SOUNDS_NOTIFTYPE
) {
4308 if (SOUNDS_NOTIFTYPE
.hasOwnProperty(code
)) {
4309 k
._soundsNotifTypeInit_item(code
);
4312 k
._soundsNotifTypeUpdateButtonText(k
._soundsNotifTypeCurrent
, k
.soundsNotifTypeMenu
);
4315 // Create a menu item for notification sound blacklist
4316 // Used only on k._soundsNotifTypeInit()
4317 k
._soundsNotifTypeInit_item = function(code
) {
4319 if (k
._soundsNotifTypeCurrent
.indexOf(code
) != -1) {
4323 k
.soundsNotifTypeMenu
.createMenuItem({
4324 html: SOUNDS_NOTIFTYPE
[code
].name
4327 ,onclick: function(menuItem
, menuClass
) {
4328 if (!SOUNDS_NOTIFTYPE
[code
] || !SOUNDS_NOTIFTYPE
[code
].name
) {
4332 if (!hasClass(menuItem
.menuItem
, 'ponyhoof_menuitem_checked')) {
4333 menuItem
.menuItem
.className
+= ' ponyhoof_menuitem_checked';
4335 k
._soundsNotifTypeCurrent
.push(code
);
4337 removeClass(menuItem
.menuItem
, 'ponyhoof_menuitem_checked');
4339 k
._soundsNotifTypeCurrent
.splice(k
._soundsNotifTypeCurrent
.indexOf(code
), 1);
4341 userSettings
.soundsNotifTypeBlacklist
= k
._soundsNotifTypeCurrent
.join('|');
4344 k
._soundsNotifTypeUpdateButtonText(k
._soundsNotifTypeCurrent
, menuClass
);
4345 k
.needToSaveLabel
= true;
4346 k
.updateCloseButton();
4351 // Update the notification sound blacklist button text, perhaps after changes
4352 // Used on k._soundsNotifTypeInit() and k._soundsNotifType_item()
4353 k
._soundsNotifTypeUpdateButtonText = function(current
, menuClass
) {
4354 var buttonText
= "("+current
.length
+" types)";
4355 if (current
.length
== 0) {
4356 buttonText
= "(None)";
4357 } else if (current
.length
== 1) {
4358 buttonText
= SOUNDS_NOTIFTYPE
[current
[0]].name
;
4360 menuClass
.changeButtonText(buttonText
);
4363 // Hide/show the extra sound options if the main sound option id disabled/enabled
4364 // Used on k.soundsInit(), the sound option is changed, or DOMNodeInserted is disabled
4365 k
.soundsChanged = function() {
4366 k
.soundsSettingsWrap
= k
.soundsSettingsWrap
|| $('ponyhoof_options_soundsSettingsWrap');
4367 if (userSettings
.sounds
&& !userSettings
.disableDomNodeInserted
) {
4368 removeClass(k
.soundsSettingsWrap
, 'hidden_elem');
4370 addClass(k
.soundsSettingsWrap
, 'hidden_elem');
4374 // Calls the main function k.soundsChanged(), and also performs extra cleanup duties, e.g. if the user disable sounds, we need to update the Close button to "Save and Reload"
4375 // Used when the sound option is changed
4376 k
.soundsClicked = function() {
4379 if (userSettings
.sounds
) {
4380 turnOffFbNotificationSound();
4382 // We already nuked Facebook's sounds, so we need to reload
4383 k
.needsToRefresh
= true;
4384 k
.updateCloseButton();
4388 // The wording of this function is a bit confusing
4389 // Hide/show the extra chat sound options if the chat sound option is disabled/enabled
4390 // Used on k.soundsInit() and k.chatSound()
4391 k
._soundsChatInit = function() {
4392 if (userSettings
.chatSound
) {
4393 removeClass(k
.soundsChatWrap
, 'hidden_elem');
4395 addClass(k
.soundsChatSoundWarning
, 'hidden_elem');
4396 addClass(k
.soundsChatWrap
, 'hidden_elem');
4400 // Initialize the chat sounds options and its HTML template
4401 // Used only on k.soundsInit()
4402 k
._soundsChatLoad = function() {
4403 if (k
.soundsChatLoaded
) {
4407 var desc
= "(Select a chat sound)";
4408 if (SOUNDS_CHAT
[userSettings
.chatSoundFile
] && SOUNDS_CHAT
[userSettings
.chatSoundFile
].name
) {
4409 desc
= SOUNDS_CHAT
[userSettings
.chatSoundFile
].name
;
4411 k
.soundsChatMenu
= new Menu('sounds_chat', $('ponyhoof_options_soundsChatSetting'));
4412 k
.soundsChatButton
= k
.soundsChatMenu
.createButton(desc
);
4413 k
.soundsChatMenu
.canSearch
= false;
4414 k
.soundsChatMenu
.createMenu();
4415 k
.soundsChatMenu
.attachButton();
4416 for (var code
in SOUNDS_CHAT
) {
4417 if (SOUNDS_CHAT
.hasOwnProperty(code
)) {
4418 k
._soundsChatLoad_item(code
);
4421 k
.soundsChatLoaded
= true;
4424 // Create a menu item for chat sound options
4425 // Used only on k._soundsChatLoad()
4426 k
._soundsChatLoad_item = function(code
) {
4428 if (userSettings
.chatSoundFile
== code
) {
4432 k
.soundsChatMenu
.createMenuItem({
4433 html: SOUNDS_CHAT
[code
].name
4434 ,title: SOUNDS_CHAT
[code
].title
4437 ,onclick: function(menuItem
, menuClass
) {
4438 if (!SOUNDS_CHAT
[code
] || !SOUNDS_CHAT
[code
].name
) {
4442 userSettings
.chatSoundFile
= code
;
4445 k
._soundsPreview(code
);
4446 changeChatSound(code
);
4448 menuClass
.changeButtonText(menuItem
.getText());
4449 menuClass
.changeChecked(menuItem
);
4451 k
.needToSaveLabel
= true;
4452 k
.updateCloseButton();
4457 // When the user enables chat sounds, we will turn it on immediately, while if the user chooses to turn it off, we would change the Close button to "Save and Reload"
4458 // Also calls k._soundsChatInit()
4459 // Used when the chat sound option is changed
4460 k
.chatSound = function() {
4461 if (userSettings
.chatSound
) {
4462 // Enable Facebook's chat sound automatically
4463 k
._soundsTurnOnFbSound();
4464 if (SOUNDS_CHAT
[userSettings
.chatSoundFile
] && SOUNDS_CHAT
[userSettings
.chatSoundFile
].name
) {
4465 changeChatSound(userSettings
.chatSoundFile
);
4468 // Chat sounds are already ponified, we need to reload to clear it
4469 k
.needsToRefresh
= true;
4470 k
.updateCloseButton();
4472 k
._soundsChatInit();
4475 // Run a sound preview
4476 k
._soundsPreview = function(code
) {
4478 if (code
== 'AUTO') {
4479 sound
= '_sound/defaultNotification';
4481 var data
= convertCodeToData(REALPONY
);
4482 if (data
.soundNotif
) {
4483 sound
= data
.soundNotif
;
4487 var ps
= initPonySound('soundsTest', THEMEURL
+sound
+'.EXT');
4488 ps
.respectSettings
= false;
4498 k
.bgClearCustomBg
= false;
4499 k
.bgInitLoaded
= false;
4500 k
.bgSizeLimit
= 1024 * 1024;
4501 k
.bgSizeLimitDescription
= '1 MB';
4502 k
._isWebPSupported
= false;
4503 k
.bgInit = function() {
4504 if (k
.bgInitLoaded
) {
4508 k
.bgError
= $('ponyhoof_options_background_error');
4509 k
.bgMessage
= $('ponyhoof_options_background_message');
4510 k
.bgTab
= $('ponyhoof_options_tabs_background');
4511 k
.bgDrop
= $('ponyhoof_options_background_drop');
4513 // Firefox 23 started enforcing a 1MB limit per preference
4514 // http://hg.mozilla.org/mozilla-central/rev/2e46cabb6a11
4515 if (ISFIREFOX
&& STORAGEMETHOD
== 'greasemonkey') {
4516 k
.bgSizeLimit
= 1024 * 512;
4517 k
.bgSizeLimitDescription
= '512 KB';
4520 if (userSettings
.customBg
) {
4521 addClass(k
.bgTab
, 'hasCustom');
4522 addClass($('ponyhoof_options_background_custom'), 'active');
4523 } else if (userSettings
.login_bg
) {
4524 addClass($('ponyhoof_options_background_loginbg'), 'active');
4526 addClass($('ponyhoof_options_background_cutie'), 'active');
4529 $$(k
.bgTab
, '.ponyhoof_options_fatradio a', function(ele
) {
4530 ele
.addEventListener('click', function() {
4531 $$(k
.bgTab
, '.ponyhoof_options_fatradio a', function(ele2
) {
4532 removeClass(ele2
.parentNode
, 'active');
4535 var parent
= this.parentNode
;
4536 var attr
= parent
.getAttribute('data-ponyhoof-background');
4537 if (attr
== 'custom') {
4538 userSettings
.login_bg
= false;
4539 changeCustomBg(userSettings
.customBg
);
4540 k
.bgClearCustomBg
= false;
4541 } else if (attr
== 'loginbg') {
4542 userSettings
.login_bg
= true;
4543 changeCustomBg(null);
4544 addClass(d
.documentElement
, 'ponyhoof_settings_login_bg');
4545 k
.bgClearCustomBg
= true;
4547 userSettings
.login_bg
= false;
4548 changeCustomBg(null);
4549 k
.bgClearCustomBg
= true;
4551 addClass(parent
, 'active');
4554 k
.needToSaveLabel
= true;
4555 k
.updateCloseButton();
4561 $('ponyhoof_options_background_select').addEventListener('change', function(e
) {
4562 if (this.files
&& this.files
[0]) {
4563 k
.bgProcessFile(this.files
[0]);
4567 isWebPSupported(function(result
) {
4568 k
._isWebPSupported
= result
;
4570 var desc
= 'Maximum file size is '+k
.bgSizeLimitDescription
+'.\n\nFor best results, the resolution of your pony pic should be '+w
.screen
.width
+'x'+w
.screen
.height
+' to fill the entire screen.';
4571 if (isCanvasSupported()) {
4572 var filetype
= 'JPEG';
4573 if (k
._isWebPSupported
) {
4574 filetype
= 'JPEG/WebP';
4577 desc
= 'If the file size of your pony pic is too big, we will attempt to automatically convert to '+filetype
+' and resize it.\n\nFor best results, the resolution of your pony pic should be '+w
.screen
.width
+'x'+w
.screen
.height
+' to fill the entire screen.';
4580 var uiHelpLink
= k
.bgDrop
.getElementsByClassName('uiHelpLink');
4581 if (uiHelpLink
.length
) {
4582 uiHelpLink
[0].setAttribute('aria-label', desc
);
4588 k
.bgInitLoaded
= true;
4591 k
.bgDropInit = function() {
4592 if (typeof w
.FileReader
== 'undefined') {
4593 k
.bgError
.textContent
= "Custom background pony pics are not supported on your browser. Please update your browser if possible.";
4594 removeClass(k
.bgError
, 'hidden_elem');
4595 addClass(k
.bgDrop
, 'hidden_elem');
4599 k
.bgDrop
.addEventListener('drop', function(e
) {
4600 e
.stopPropagation();
4603 removeClass(this, 'ponyhoof_dropping');
4605 if (e
.dataTransfer
.files
&& e
.dataTransfer
.files
[0]) {
4606 k
.bgProcessFile(e
.dataTransfer
.files
[0]);
4610 k
.bgDrop
.addEventListener('dragover', function(e
) {
4611 e
.stopPropagation();
4614 e
.dataTransfer
.dropEffect
= 'copy';
4617 k
.bgDrop
.addEventListener('dragenter', function(e
) {
4618 addClass(k
.bgDrop
, 'ponyhoof_dropping');
4622 k
.bgDrop
.addEventListener('dragend', function(e
) {
4623 removeClass(k
.bgDrop
, 'ponyhoof_dropping')
4627 k
.bgReaderFile
= null;
4628 k
.bgReaderBg
= null;
4629 k
.bgProcessFile = function(file
) {
4630 k
.bgReaderFile
= file
;
4631 addClass(k
.bgError
, 'hidden_elem');
4632 addClass(k
.bgMessage
, 'hidden_elem');
4634 if (!file
.type
.match(/image.*/)) {
4636 k
.bgError
.textContent
= "The file ("+file
.name
+") doesn't seem to be a pony pic ("+file
.type
+").";
4638 k
.bgError
.textContent
= "The file ("+file
.name
+") doesn't seem to be a pony pic.";
4640 removeClass(k
.bgError
, 'hidden_elem');
4644 var reader
= new w
.FileReader();
4645 reader
.onload
= k
.bgReaderLoad
;
4646 reader
.onerror
= k
.bgReaderError
;
4647 reader
.readAsDataURL(file
);
4650 k
.bgReaderLoad = function(e
) {
4651 k
.bgReaderBg
= e
.target
.result
;
4652 if (e
.target
.result
.length
> k
.bgSizeLimit
) {
4653 // base64 result is too big to fit, convertion required
4654 if (isCanvasSupported()) {
4655 k
.bgPerformConvertion();
4660 k
.bgChangeSuccess();
4664 k
.bgReaderError = function(e
) {
4665 k
.bgError
.textContent
= "An error occurred reading the file. Please try again.";
4666 removeClass(k
.bgError
, 'hidden_elem');
4670 k
.bgErrorTooBig = function() {
4671 if (k
.bgReaderFile
.type
&& k
.bgReaderFile
.type
!= 'image/jpeg' && !isCanvasSupported()) {
4672 k
.bgError
.textContent
= "Sorry, the file size of your pony pic is too big (over "+k
.bgSizeLimitDescription
+") and may not save properly. Try saving your pony pic as a JPEG, resize your pony pic, or use a different pony pic.";
4674 k
.bgError
.textContent
= "Sorry, the file size of your pony pic is too big (over "+k
.bgSizeLimitDescription
+") and may not save properly. Try resizing your pony pic or use a different pony pic.";
4676 removeClass(k
.bgError
, 'hidden_elem');
4679 k
.bgChangeSuccess = function() {
4680 addClass(k
.bgError
, 'hidden_elem');
4681 addClass(k
.bgTab
, 'hasCustom');
4683 $$(k
.bgTab
, '.ponyhoof_options_fatradio a', function(ele
) {
4684 removeClass(ele
.parentNode
, 'active');
4686 addClass($('ponyhoof_options_background_custom'), 'active');
4687 k
.bgClearCustomBg
= false;
4689 userSettings
.login_bg
= false;
4690 userSettings
.customBg
= k
.bgReaderBg
;
4693 k
.needToSaveLabel
= true;
4694 k
.updateCloseButton();
4696 changeCustomBg(k
.bgReaderBg
);
4699 k
.bgPerformConvertion = function() {
4700 var img
= new w
.Image();
4702 img
.onload = function() {
4703 // First try converting to JPEG/WebP
4704 if (k
.bgReaderFile
.type
!= 'image/jpeg' || (k
._isWebPSupported
&& k
.bgReaderFile
.type
!= 'image/webp')) {
4705 var transformed
= k
.bgCanvasTransform(img
, img
.width
, img
.height
);
4706 if (transformed
.length
<= k
.bgSizeLimit
) {
4707 k
.bgReaderBg
= transformed
;
4708 k
.bgChangeSuccess();
4717 // Now try resizing to screen resolution
4718 var transformed
= k
.bgCanvasTransform(img
, Math
.min(w
.screen
.width
, img
.width
), Math
.min(w
.screen
.height
, img
.height
));
4719 if (transformed
.length
<= k
.bgSizeLimit
) {
4720 k
.bgMessage
.textContent
= "Automatically resized to screen resolution. For best results, we recommend using an image editor and resize/crop your pony pic.";
4721 removeClass(k
.bgMessage
, 'hidden_elem');
4723 k
.bgReaderBg
= transformed
;
4724 k
.bgChangeSuccess();
4736 img
.src
= k
.bgReaderBg
;
4742 k
.bgCanvasTransform = function(img
, width
, height
) {
4743 var canvas
= d
.createElement('canvas');
4744 canvas
.width
= width
;
4745 canvas
.height
= height
;
4746 var ctx
= canvas
.getContext('2d');
4747 ctx
.drawImage(img
, 0, 0, width
, height
);
4749 var type
= 'image/jpeg';
4750 if (k
._isWebPSupported
) {
4751 type
= 'image/webp';
4754 return canvas
.toDataURL(type
);
4757 k
.disableDomNodeInserted = function() {
4758 k
.soundsChanged(); // to set k.soundsSettingsWrap
4760 var affectedOptions
= ['sounds', 'debug_dominserted_console', 'debug_noMutationObserver', 'debug_mutationDebug', 'debug_betaFacebookLinks'];
4761 //'disableCommentBrohoofed','debug_mutationObserver'
4762 for (var i
= 0, len
= affectedOptions
.length
; i
< len
; i
+= 1) {
4763 var option
= $('ponyhoof_options_'+affectedOptions
[i
]);
4764 var label
= $('ponyhoof_options_label_'+affectedOptions
[i
]);
4765 if (userSettings
.disableDomNodeInserted
) {
4766 if (ranDOMNodeInserted
) {
4767 k
.needsToRefresh
= true;
4768 k
.updateCloseButton();
4771 option
.disabled
= true;
4772 option
.checked
= false;
4774 addClass(label
, 'ponyhoof_options_unavailable');
4775 label
.setAttribute('data-hover', 'tooltip');
4776 label
.setAttribute('aria-label', "This feature is not available because HTML detection is disabled, re-enable it at the Misc tab");
4778 var option
= $('ponyhoof_options_'+affectedOptions
[i
]);
4779 option
.disabled
= false;
4780 if (userSettings
[affectedOptions
[i
]]) {
4781 option
.checked
= true;
4784 removeClass(label
, 'ponyhoof_options_unavailable');
4785 label
.removeAttribute('data-hover');
4786 label
.removeAttribute('aria-label');
4787 label
.removeAttribute('aria-owns');
4788 label
.removeAttribute('aria-controls');
4789 label
.removeAttribute('aria-haspopup');
4792 k
._debugNoMutationObserver();
4795 k
.disableDomNodeInsertedClicked = function() {
4796 if (!userSettings
.disableDomNodeInserted
) {
4797 runDOMNodeInserted();
4799 k
.disableDomNodeInserted();
4802 k
.allowLoginScreenClicked = function() {
4803 if (globalSettings
.allowLoginScreen
) {
4804 globalSettings
.lastUserId
= USERID
;
4806 globalSettings
.lastUserId
= null;
4808 saveGlobalSettings();
4811 k
.debug_disablelog = function() {
4812 if ($('ponyhoof_options_debug_disablelog').checked
) {
4819 k
.disableDialog
= null;
4820 k
.disablePonyhoof = function() {
4821 if ($('ponyhoof_dialog_disable')) {
4822 $('ponyhoof_disable_allowLoginScreen').checked
= !globalSettings
.allowLoginScreen
;
4823 $('ponyhoof_disable_runForNewUsers').checked
= !globalSettings
.runForNewUsers
;
4826 k
.disableDialog
.show();
4827 $('ponyhoof_disable_ok').focus();
4832 c
+= "<strong>Are you sure you want to disable Ponyhoof for yourself?</strong><br><br>";
4833 c
+= "You can re-enable Ponyhoof for yourself at any time by going back to Ponyhoof Options and re-select a character.<br><br>";
4834 c
+= '<div class="uiInputLabel"><input type="checkbox" class="uiInputLabelCheckbox" id="ponyhoof_disable_allowLoginScreen"><label for="ponyhoof_disable_allowLoginScreen">Don\'t run Ponyhoof on the Facebook login screen</label></div>';
4835 c
+= '<div class="uiInputLabel" data-hover="tooltip" aria-label="'+CURRENTLANG
['settings_disable_runForNewUsers_explain']+'"><input type="checkbox" class="uiInputLabelCheckbox" id="ponyhoof_disable_runForNewUsers"><label for="ponyhoof_disable_runForNewUsers">Don\'t run Ponyhoof for new users <a href="#" class="uiHelpLink"></a></label></div>';
4838 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_disable_ok"><span class="uiButtonText">Disable</span></a>';
4839 bottom
+= '<a href="#" class="uiButton uiButtonLarge" role="button" id="ponyhoof_disable_no"><span class="uiButtonText">Cancel</span></a>';
4842 k
.disableDialog
= new Dialog('disable');
4843 k
.disableDialog
.alwaysModal
= true;
4844 k
.disableDialog
.create();
4845 k
.disableDialog
.changeTitle("Disable Ponyhoof");
4846 k
.disableDialog
.changeContent(c
);
4847 k
.disableDialog
.changeBottom(bottom
);
4849 $('ponyhoof_disable_allowLoginScreen').checked
= !globalSettings
.allowLoginScreen
;
4850 $('ponyhoof_disable_runForNewUsers').checked
= !globalSettings
.runForNewUsers
;
4852 k
.disableDialog
.show();
4853 k
.disableDialog
.onclose = function() {
4857 $('ponyhoof_disable_ok').focus();
4858 $('ponyhoof_disable_ok').addEventListener('click', function() {
4859 userSettings
.theme
= 'NONE';
4862 globalSettings
.allowLoginScreen
= !$('ponyhoof_disable_allowLoginScreen').checked
;
4863 globalSettings
.runForNewUsers
= !$('ponyhoof_disable_runForNewUsers').checked
;
4864 saveGlobalSettings();
4866 k
.disableDialog
.canCloseByEscapeKey
= false;
4867 d
.body
.style
.cursor
= 'progress';
4868 $('ponyhoof_disable_allowLoginScreen').disabled
= true;
4869 $('ponyhoof_disable_runForNewUsers').disabled
= true;
4870 $('ponyhoof_disable_ok').className
+= ' uiButtonDisabled';
4871 $('ponyhoof_disable_no').className
+= ' uiButtonDisabled';
4872 w
.location
.reload();
4877 $('ponyhoof_disable_no').addEventListener('click', function() {
4878 k
.disableDialog
.close();
4885 k
.browserPonies
= null;
4886 k
.runBrowserPonies = function() {
4888 if (hasClass(link
, 'ponyhoof_browserponies_loading')) {
4892 var alreadyLoaded
= (k
.browserPonies
&& k
.browserPonies
.initLoaded
);
4893 addClass(link
, 'ponyhoof_browserponies_loading');
4895 if (!k
.browserPonies
) {
4896 k
.browserPonies
= new BrowserPoniesHoof();
4898 k
.browserPonies
.doneCallback = function() {
4900 removeClass(link
, 'ponyhoof_browserponies_loading');
4901 if (!alreadyLoaded
) {
4902 k
.browserPonies
.copyrightDialog();
4904 k
.browserPonies
.createDialog();
4906 k
.browserPonies
.errorCallback = function(error
) {
4907 removeClass(link
, 'ponyhoof_browserponies_loading');
4908 k
.browserPonies
.createErrorDialog(error
);
4910 k
.browserPonies
.run();
4915 k
.checkboxStore
= {};
4916 k
.generateCheckbox = function(id
, label
, data
) {
4921 if ((!data
.global
&& userSettings
[id
]) || (data
.global
&& globalSettings
[id
])) {
4922 checkmark
+= ' CHECKED';
4924 data
.extraClass
= data
.extraClass
|| '';
4926 label
+= ' <a href="#" class="uiHelpLink"></a>';
4927 ex
+= ' data-hover="tooltip" aria-label="'+data
.title
+'"';
4930 label
+= ' <a href="#" class="uiHelpLink ponyhoof_tip_trigger"><div class="ponyhoof_tip_wrapper"><span class="ponyhoof_tip"><span class="ponyhoof_tip_body">'+data
.tip
+'</span><span class="ponyhoof_tip_arrow"></span></span></div></a>';
4933 k
.checkboxStore
[id
] = data
;
4935 return '<div class="uiInputLabel '+data
.extraClass
+'"'+ex
+' id="ponyhoof_options_label_'+id
+'"><input type="checkbox" class="uiInputLabelCheckbox" id="ponyhoof_options_'+id
+'" data-ponyhoof-checkmark="'+id
+'" '+checkmark
+'><label for="ponyhoof_options_'+id
+'">'+label
+'</label></div>';
4938 k
.checkboxInit = function() {
4939 var extras
= $('ponyhoof_dialog_options').querySelectorAll('input[type="checkbox"]');
4940 for (var i
= 0, len
= extras
.length
; i
< len
; i
+= 1) {
4941 var checkmark
= extras
[i
].getAttribute('data-ponyhoof-checkmark');
4943 if (k
.checkboxStore
[checkmark
]) {
4944 data
= k
.checkboxStore
[checkmark
];
4946 if (data
.tooltipPosition
) {
4947 extras
[i
].parentNode
.setAttribute('data-tooltip-position', data
.tooltipPosition
);
4950 extras
[i
].addEventListener('click', function() {
4951 var checkmark
= this.getAttribute('data-ponyhoof-checkmark');
4953 if (k
.checkboxStore
[checkmark
]) {
4954 data
= k
.checkboxStore
[checkmark
];
4958 userSettings
[checkmark
] = this.checked
;
4961 globalSettings
[checkmark
] = this.checked
;
4962 saveGlobalSettings();
4966 addClass(d
.documentElement
, 'ponyhoof_settings_'+checkmark
);
4968 removeClass(d
.documentElement
, 'ponyhoof_settings_'+checkmark
);
4971 k
.needsToRefresh
= true;
4973 if (data
.customFunc
) {
4977 k
.needToSaveLabel
= true;
4978 k
.updateCloseButton();
4983 k
.tabsExposeDebug
= 0;
4984 k
.tabsInit = function() {
4985 var tabs
= k
.dialog
.dialog
.querySelectorAll('.ponyhoof_tabs a');
4986 for (var i
= 0, len
= tabs
.length
; i
< len
; i
+= 1) {
4987 tabs
[i
].addEventListener('click', function(e
) {
4988 var tabName
= this.getAttribute('data-ponyhoof-tab');
4989 if (tabName
== 'extras') {
4990 if (!userSettings
.debug_exposed
&& k
.tabsExposeDebug
< 5) {
4991 k
.tabsExposeDebug
+= 1;
4992 if (k
.tabsExposeDebug
>= 5) {
4993 addClass(k
.dialog
.dialog
, 'ponyhoof_options_debugExposed');
4994 k
.switchTab('advanced');
4999 k
.tabsExposeDebug
= 0;
5002 k
.switchTab(tabName
);
5008 k
.switchTab = function(tabName
) {
5011 ,'background': k
.bgInit
5012 ,'sounds': k
.soundsInit
5013 ,'extras': k
.extrasInit
5014 ,'advanced': k
.debugInfo
5015 ,'about': k
.loadDonate
5017 removeClass(k
.dialog
.dialog
.querySelector('.ponyhoof_tabs a.active'), 'active');
5018 addClass(k
.dialog
.dialog
.querySelector('.ponyhoof_tabs a[data-ponyhoof-tab="'+tabName
+'"]'), 'active');
5021 if (tabActions
[tabName
]) {
5022 tabActions
[tabName
]();
5026 ponyhoofError(e
.toString());
5029 $$(k
.dialog
.dialog
, '.ponyhoof_tabs_section', function(section
) {
5030 section
.style
.display
= 'none';
5032 $('ponyhoof_options_tabs_'+tabName
).style
.display
= 'block';
5034 k
.dialog
.cardSpaceTick();
5037 k
.saveButtonClick = function() {
5042 k
.dialogOnClose = function() {
5043 d
.removeEventListener('keydown', k
.kf
, true);
5045 if (k
.debugLoaded
) {
5046 if ($('ponyhoof_options_customcss').value
== "Enter any custom CSS to load after Ponyhoof is loaded.") {
5047 userSettings
.customcss
= '';
5049 userSettings
.customcss
= $('ponyhoof_options_customcss').value
;
5052 if (k
.canSaveSettings
) {
5056 if (k
.needsToRefresh
) {
5057 w
.location
.reload();
5061 k
.dialogOnCloseFinish = function() {
5062 k
.saveButton
.getElementsByClassName('uiButtonText')[0].innerHTML
= CURRENTLANG
.close
;
5064 if (k
.canSaveSettings
) {
5065 if (k
.bgClearCustomBg
) {
5066 removeClass(k
.bgTab
, 'hasCustom');
5067 userSettings
.customBg
= null;
5073 k
.updateCloseButton = function() {
5074 var button
= k
.saveButton
.getElementsByClassName('uiButtonText')[0];
5075 var text
= CURRENTLANG
.close
;
5077 if (k
.needToSaveLabel
) {
5078 text
= "Save & Close";
5081 if (k
.needsToRefresh
) {
5082 text
= "Save & Reload";
5085 button
.innerHTML
= text
;
5088 k
.injectStyle = function() {
5090 //css += '#ponyhoof_options_tabs_main .clearfix {margin-bottom:10px;}';
5091 css
+= '#ponyhoof_dialog_options .generic_dialog_popup, #ponyhoof_dialog_options .popup {width:480px;}';
5092 css
+= '#ponyhoof_options_likebox_div {height:80px;}';
5093 //css += 'html.ponyhoof_isusingpage #ponyhoof_options_likebox_div {display:none;}';
5094 css
+= '#ponyhoof_options_likebox {border:none;overflow:hidden;width:100%;height:80px;}';
5095 css
+= '#ponyhoof_options_pony {margin:8px 0 16px;}';
5096 css
+= '.ponyhoof_options_fatlink {display:block;margin-top:10px;}';
5097 css
+= '.ponyhoof_options_unavailable label {cursor:default;}';
5098 css
+= '#ponyhoof_dialog_options .usingPage, html.ponyhoof_isusingpage #ponyhoof_dialog_options .notPage {display:none;}';
5099 css
+= 'html.ponyhoof_isusingpage #ponyhoof_dialog_options .usingPage {display:block;}';
5100 css
+= 'html.ponyhoof_isusingbusiness #ponyhoof_dialog_options .notBusiness {display:none;}';
5102 css
+= '#ponyhoof_dialog_options .uiHelpLink {margin-left:2px;}';
5103 css
+= '#ponyhoof_dialog_options textarea, #ponyhoof_options_tabs_advanced input[type="text"] {font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;}';
5104 css
+= '#ponyhoof_dialog_options textarea {resize:vertical;width:100%;height:60px;min-height:60px;line-height:normal;}';
5105 css
+= '#ponyhoof_dialog_options .ponyhoof_tabs > a[data-ponyhoof-tab="advanced"] {display:none;}';
5106 css
+= '#ponyhoof_dialog_options.ponyhoof_options_debugExposed .ponyhoof_tabs > a[data-ponyhoof-tab="advanced"] {display:block;}';
5109 css
+= '.ponyhoof_options_fatradio {margin:10px 0;}';
5110 css
+= '.ponyhoof_options_fatradio li {width:222px;float:left;margin-left:12px;}';
5111 css
+= '#ponyhoof_options_tabs_background.hasCustom .ponyhoof_options_fatradio li {width:144px;}';
5112 css
+= '.ponyhoof_options_fatradio li:first-child {margin:0;}';
5113 css
+= '.ponyhoof_options_fatradio a {border:1px solid rgba(0,0,0,.3);display:block;text-align:center;width:100%;text-decoration:none;border-radius:3px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;}';
5114 css
+= '.ponyhoof_options_fatradio a:hover {box-shadow:0 0 8px rgba(0,0,0,.3);}';
5115 css
+= '.ponyhoof_options_fatradio a:active {background:#ECEFF5;box-shadow:0 0 8px rgba(0,0,0,.7);}';
5116 css
+= '.ponyhoof_options_fatradio li.active a {background-color:#6D84B4;border-color:#3b5998;color:#fff;}';
5117 css
+= '.ponyhoof_options_fatradio span {padding:4px;display:block;}';
5118 css
+= '.ponyhoof_options_fatradio .wrap i {height:200px;width:100%;display:block;=webkit-transition:all .2s ease-in;-moz-transition:.2s ease-in;-o-transition:.2s ease-in;transition:.2s ease-in;}';
5119 css
+= '#ponyhoof_options_tabs_background.hasCustom .ponyhoof_options_fatradio .wrap i {height:144px;}';
5120 css
+= '#ponyhoof_options_background_cutie .wrap {padding:8px;}';
5121 css
+= '#ponyhoof_options_background_cutie .wrap i {width:206px;height:184px;}';
5122 css
+= '#ponyhoof_options_tabs_background.hasCustom #ponyhoof_options_background_cutie .wrap i {width:128px;height:128px;}';
5123 css
+= '#ponyhoof_options_background_custom {display:none;}';
5124 css
+= '#ponyhoof_options_tabs_background.hasCustom #ponyhoof_options_background_custom {display:block;}';
5125 css
+= '#ponyhoof_options_background_custom .wrap i {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAABh0lEQVRIx82WP2oCURDGFwsrSWEVPIMH8AAWSwiL4H6/BSuxCDlCSBHIESRFziMWOYFFqlRiIRZWi6QwRQxslvfP7K5k4FVvZ35vZ+Z986LoDANGwC7LsmOWZUdgB4yipqwIK0IrBZX0AByAjaS4uFeG/aySP5IWwIukjg/2VDp9XoT6gJJmJf+lFSppagoG5MANMLIBgZGke8veUlLbVJ+5LWDVBQxNwAGQNwTs29Ia1w2VNPM1Tgx8XgR2AraBbQ1p3BqbxQCcOIKsJZEkSS9Jkp4kgLXjDydeuXLA3iV1DQfsAqsA/28ZDIGdTpu6NDYwzbsotCZxHF85ytAJjXN5YGhKXWPorJRKSoF9wMerik2zN/ZBwLVIJV2fVnr2tTAA7+qStfF4fOuDTWsW7bw8xIuF7zc0KXJgYAIOG5yHc6NoS3qzOHyESB9wsDTP1HqBgaVhxLQkpR7Za5nmKfDsa5wO8CppIYk/vNpiYAMcJD1WekKGAAvW+p8PYU+6f8mgVa4c9gXXnNjGKCXX6gAAAABJRU5ErkJggg==") no-repeat center center;}';
5127 css
+= '#ponyhoof_options_background_error, #ponyhoof_options_background_message {margin-bottom:10px;}';
5128 css
+= '#ponyhoof_options_background_drop {background:#fff;border:2px dashed #75a3f5;padding:8px;position:relative;}'; //margin-bottom:8px;
5129 css
+= '#ponyhoof_options_background_drop_dropping {background:#fff;background:rgba(255,255,255,.95);border:2px dashed #75a3f5;color:#75a3f5;position:absolute;top:-2px;left:-2px;width:100%;height:100%;font-size:16px;line-height:64px;text-align:center;font-weight:bold;display:none;}';
5130 css
+= '#ponyhoof_options_background_drop.ponyhoof_dropping #ponyhoof_options_background_drop_dropping {display:block;}';
5131 css
+= '#ponyhoof_options_background_selectOuterWrap {position:relative;display:inline-block;top:-3px;}';
5132 css
+= '#ponyhoof_options_background_selectFileWrap {position:absolute;width:100%;height:100%;top:0;left:0;overflow:hidden;}';
5133 css
+= '#ponyhoof_options_background_select {font-size:1000px !important;opacity:0;padding:0;margin:0;position:absolute;bottom:0;right:0;cursor:pointer;}';
5135 css
+= '#ponyhoof_options_tabs_main .ponyhoof_message {margin-top:10px;}';
5136 css
+= '#ponyhoof_browserponies .ponyhoof_loading {display:none;margin-top:0;vertical-align:text-bottom;}';
5137 css
+= '#ponyhoof_browserponies.ponyhoof_browserponies_loading .ponyhoof_loading {display:inline-block;}';
5138 css
+= '#ponyhoof_options_randomPonies .ponyhoof_loading {display:none !important;}';
5139 css
+= '#ponyhoof_options_randomPonies .ponyhoof_menuitem_checked {display:block;}';
5140 css
+= '#ponyhoof_options_tabs_sounds .ponyhoof_message.unavailable {margin-bottom:10px;}';
5141 css
+= '#ponyhoof_options_soundsSettingsWrap {margin-top:-14px;}';
5142 css
+= '#ponyhoof_options_soundsVolume {vertical-align:middle;width:50px;}';
5143 css
+= '#ponyhoof_options_soundsVolume[type="range"] {cursor:pointer;width:200px;}';
5144 css
+= '#ponyhoof_options_soundsVolumePreview {vertical-align:middle;}';
5145 css
+= '#ponyhoof_options_soundsVolumeValue {display:none;padding-left:3px;}';
5146 css
+= '#ponyhoof_options_soundsChatSoundWarning, #ponyhoof_options_soundsMessengerForWindowsWarning {margin-bottom:10px;}';
5147 css
+= '#ponyhoof_options_soundsChatSetting {margin:0;}';
5148 css
+= '#ponyhoof_options_tabs_extras .ponyhoof_show_if_injected + .uiInputLabel, #ponyhoof_options_tabs_extras .uiInputLabel + .ponyhoof_show_if_injected, #ponyhoof_options_tabs_advanced .uiInputLabel + .ponyhoof_show_if_injected {margin-top:3px;}';
5149 css
+= '#ponyhoof_options_tabs_advanced .ponyhoof_hide_if_injected.ponyhoof_message {margin-bottom:10px;}';
5150 css
+= '.ponyhoof_options_aboutsection {border-top:1px solid #ccc;margin:10px -10px 0;}';
5151 css
+= '.ponyhoof_options_aboutsection > .inner {border-top:1px solid #E9E9E9;padding:10px 10px 0;}';
5152 css
+= '#ponyhoof_options_devpic {display:block;}';
5153 css
+= '#ponyhoof_options_devpic img {width:50px !important;height:50px !important;}';
5154 css
+= '#ponyhoof_options_twitter {margin-top:10px;width:100%;height:20px;}';
5155 css
+= '#ponyhoof_options_plusone {margin-top:10px;height:23px;}';
5157 css
+= '.ponyhoof_tip_wrapper {position:relative;z-index:10;}';
5158 css
+= '.ponyhoof_tip_trigger, .ponyhoof_tip_trigger:hover {text-decoration:none;}';
5159 css
+= '.ponyhoof_tip_trigger:hover .ponyhoof_tip {display:block;}';
5160 css
+= '.ponyhoof_options_unavailable .ponyhoof_tip_trigger {display:none !important;}';
5161 css
+= '.ponyhoof_tip {text-align:left;position:absolute;z-index:-1;display:none;top:11px;padding:4px 0 0;right:-7px;color:#000;font-weight:normal;}';
5162 css
+= '.ponyhoof_tip_body {line-height:15px;width:300px;white-space:normal;background:#fff;border:1px solid;border-color:#888 #999;display:block;left:0;padding:6px 8px;box-shadow:0 1px 0 rgba(0,0,0,.1);}';
5163 css
+= '.ponyhoof_tip_arrow {position:absolute;top:0;right:10px;border:solid transparent;border-width:0 3px 5px 4px;border-bottom-color:#888;}';
5165 css
+= '#ponyhoof_donate {background:#EDEFF4;border:1px solid #D2DBEA;color:#9CADCF;font-family:Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;}';
5166 css
+= '#ponyhoof_donate .inner {background:#EDEFF4;display:block;font-size:16px;font-weight:bold;height:75px;line-height:75px;text-align:center;float:left;width:50%;}';
5167 css
+= '#ponyhoof_donate a {display:block;width:100%;color:#9CADCF;text-decoration:none;}';
5168 css
+= '#ponyhoof_options_donatepaypal {border-right:1px solid #D2DBEA;}';
5169 //css += '#ponyhoof_donate_flattr {background-image:url("//api.flattr.com/button/flattr-badge-large.png");background-position:center center;background-repeat:no-repeat;text-indent:-99999px;}';
5170 css
+= '#ponyhoof_donate_flattr_iframe {width:55px;height:62px;margin-top:6px;}';
5171 css
+= '#ponyhoof_donate a:hover {background-color:#DEDFE7;color:#3B5998;}';
5173 injectManualStyle(css
, 'options');
5176 k
.show = function() {
5185 k
.kc
= '\x33\x38\x2C\x33\x38\x2C\x34\x30\x2C\x34\x30\x2C\x33\x37\x2C\x33\x39\x2C\x33\x37\x2C\x33\x39\x2C\x36\x36\x2C\x36\x35';
5186 k
.kf = function(e
) {
5192 if (k
.ks
.join(',').indexOf(k
.kc
) > -1) {
5199 injectManualStyle('#ponyhoof_dialog_ky .generic_dialog_popup,#ponyhoof_dialog_ky .popup{width:740px;}#ponyhoof_dialog_ky .generic_dialog{z-index:250 !important;}#ponyhoof_kc_align{margin:8px auto 0;text-align:center;}', 'kx');
5200 var di
= new Dialog('ky');
5201 di
.alwaysModal
= true;
5203 di
.changeTitle("\x54\x48\x45\x20\x55\x4C\x54\x49\x4D\x41\x54\x45\x20\x42\x52\x4F\x4E\x59\x20\x43\x48\x41\x4C\x4C\x45\x4E\x47\x45");
5204 di
.changeContent('<iframe src="//hoof.little.my/files/zR7V_bCyZe0.htm" width="100%" height="405" scrolling="auto" frameborder="0" allowTransparency="true"></iframe><div id="ponyhoof_kc_align"><a href="#" class="uiButton uiButtonSpecial ponyhoof_noShareIsCare" id="ponyhoof_kc_share" role="button" data-hover="tooltip" aria-label="\x53\x4F\x20\x4D\x55\x43\x48\x20\x50\x4F\x4E\x59" data-tooltip-alignh="center"><span class="uiButtonText">\x53\x48\x41\x52\x45\x20\x57\x49\x54\x48\x20\x59\x4F\x55\x52\x20\x50\x41\x4C\x53\x21</span></a></div>');
5205 di
.addCloseButton();
5206 di
.onclosefinish = function() {
5207 di
.changeContent('');
5210 $('ponyhoof_kc_share').addEventListener('click', function() {
5213 w
.open('//'+getFbDomain()+'/sharer/sharer.php?u=http://www.youtube.com/watch?v=zR7V_bCyZe0', 'ponyhoof_kc_sharer', 'left='+((screen
.width
-width
)/2)+',top='+(((screen.height-height)/2)-50)+',width='+width
+',height='+height
);
5220 d
.addEventListener('keydown', k
.kf
, true);
5224 var optionsGlobal
= null;
5225 function optionsOpen() {
5226 log("Opening options...");
5228 if (!optionsGlobal
) {
5229 optionsGlobal
= new Options();
5231 optionsGlobal
.create();
5232 optionsGlobal
.show();
5234 $$($('ponyhoof_dialog_options'), '#ponyhoof_options_pony .ponyhoof_button_menu', function(button
) {
5242 var WelcomeUI = function(param
) {
5250 k
.dialogFirst
= null;
5251 k
.dialogPinkie
= null;
5252 k
.dialogFinish
= null;
5256 k
.start = function() {
5259 addClass(d
.documentElement
, 'ponyhoof_welcome_html');
5260 statTrack('welcomeUI');
5265 k
.showWelcome = function() {
5266 if ($('ponyhoof_dialog_welcome')) {
5270 addClass(d
.documentElement
, 'ponyhoof_welcome_html_scenery_loaded');
5273 co
+= '<div class="ponyhoof_message uiBoxYellow ponyhoof_updater_newVersion">';
5274 co
+= '<a href="#" class="uiButton uiButtonSpecial rfloat ponyhoof_updater_updateNow" role="button"><span class="uiButtonText">Update now</span></a>';
5275 co
+= '<span class="wrap">An update (v<span class="ponyhoof_updater_versionNum"></span>) for Ponyhoof is available.</span>';
5278 co
+= renderBrowserConfigWarning();
5280 if (STORAGEMETHOD
== 'chrome' && chrome
.extension
.inIncognitoContext
) {
5281 co
+= '<div class="ponyhoof_message uiBoxYellow">Please note that your Ponyhoof settings are saved and not cleared, even if you are using Chrome incognito mode. Please disable Ponyhoof from running in incognito mode if you do not want others to know that you logged on to this browser.</div><br>';
5284 co
+= '<strong>Select your favorite character to get started:</strong>';
5285 co
+= '<div id="ponyhoof_welcome_pony"></div>';
5286 co
+= '<div id="ponyhoof_welcome_afterClose">You can re-select your character in Ponyhoof Options at the Account menu.</div>';
5289 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm uiButtonDisabled" role="button" id="ponyhoof_welcome_next"><span class="uiButtonText">Next</span></a>';
5293 k
.dialogFirst
= new Dialog('welcome');
5294 k
.dialogFirst
.canCardspace
= false;
5295 k
.dialogFirst
.canCloseByEscapeKey
= false;
5296 k
.dialogFirst
.create();
5297 k
.dialogFirst
.generic_dialogDiv
.className
+= ' generic_dialog_fixed_overflow';
5299 k
.dialogFirst
.changeTitle("Welcome to Ponyhoof, "+BRONYNAME
+"!");
5301 k
.dialogFirst
.changeTitle("Welcome to Ponyhoof!");
5303 k
.dialogFirst
.changeContent(co
);
5304 k
.dialogFirst
.changeBottom(bottom
);
5306 k
.dialogFirst
.dialog
.className
+= ' ponyhoof_dialog_localstorageWarningEmbedded';
5310 var menuClosed
= false;
5311 var ponySelector
= new PonySelector($('ponyhoof_welcome_pony'), k
.param
);
5312 ponySelector
.saveTheme
= false;
5313 ponySelector
.createSelector();
5314 w
.setTimeout(function() {
5315 ponySelector
.menu
.open();
5317 ponySelector
.menu
.afterClose = function() {
5320 addClass($('ponyhoof_welcome_afterClose'), 'show');
5322 addClass(d
.documentElement
, 'ponyhoof_welcome_showmedemo');
5323 if ($('navAccount')) {
5324 addClass($('navAccount'), 'openToggler');
5326 //addClass($('ponyhoof_account_options'), 'active');
5328 w
.setTimeout(function() {
5329 removeClass($('ponyhoof_welcome_next'), 'uiButtonDisabled');
5334 w
.setTimeout(function() {
5335 changeThemeSmart(CURRENTPONY
);
5337 k
._stack
= CURRENTSTACK
;
5339 w
.setTimeout(function() {
5340 var update
= new Updater();
5341 update
.checkForUpdates();
5344 // Detect if the Facebook's chat sound setting is turned off
5345 // We need to do this here as it is async
5347 if (typeof USW
.requireLazy
== 'function') {
5348 USW
.requireLazy(['ChatOptions'], function(ChatOptions
) {
5349 if (!ChatOptions
.getSetting('sound')) {
5350 userSettings
.chatSound
= false;
5355 error("Unable to hook to ChatOptions");
5359 $('ponyhoof_welcome_next').addEventListener('click', function(e
) {
5361 if (hasClass(this, 'uiButtonDisabled')) {
5365 k
.dialogFirst
.close();
5366 fadeOut($('ponyhoof_welcome_scenery'));
5368 w
.setTimeout(function() {
5369 removeClass(d
.documentElement
, 'ponyhoof_welcome_showmedemo');
5370 removeClass($('navAccount'), 'openToggler');
5371 //removeClass($('ponyhoof_account_options'), 'active');
5374 userSettings
.theme
= CURRENTPONY
;
5375 userSettings
.chatSound1401
= true;
5378 globalSettings
.lastVersion
= VERSION
;
5379 if (globalSettings
.allowLoginScreen
) {
5380 globalSettings
.lastUserId
= USERID
;
5382 saveGlobalSettings();
5384 if (CURRENTPONY
== 'pinkie') {
5387 k
.createFinalDialog();
5392 k
.pinkieWelcome = function() {
5393 removeClass(d
.documentElement
, 'ponyhoof_welcome_html_scenery_loaded');
5399 bottom
+= '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_welcome_pinkie_next"><span class="uiButtonText">Stop being silly, Pinkie</span></a>';
5401 k
.dialogPinkie
= new Dialog('welcome_pinkie');
5402 k
.dialogPinkie
.alwaysModal
= true;
5403 k
.dialogPinkie
.create();
5404 k
.dialogPinkie
.changeTitle("\x59\x4F\x55\x20\x43\x48\x4F\x4F\x53\x45\x20\x50\x49\x4E\x4B\x49\x45\x21\x3F\x21");
5405 k
.dialogPinkie
.changeContent('<iframe src="//hoof.little.my/files/aEPDsG6R4dY.htm" width="100%" height="405" scrolling="auto" frameborder="0" allowTransparency="true"></iframe>');
5406 k
.dialogPinkie
.changeBottom(bottom
);
5407 k
.dialogPinkie
.onclose = function() {
5408 fadeOut($('ponyhoof_welcome_scenery'));
5409 k
.createFinalDialog();
5411 k
.dialogPinkie
.onclosefinish = function() {
5412 k
.dialogPinkie
.changeContent('');
5415 $('ponyhoof_welcome_pinkie_next').addEventListener('click', function(e
) {
5416 k
.dialogPinkie
.close();
5421 k
.createFinalDialog = function() {
5422 removeClass(d
.documentElement
, 'ponyhoof_welcome_html');
5423 removeClass(d
.documentElement
, 'ponyhoof_welcome_html_scenery_loaded');
5427 var lang
= getDefaultUiLang();
5428 if (lang
!= 'en_US' && lang
!= 'en_GB') {
5429 c
+= '<div class="ponyhoof_message uiBoxYellow"><'+'a href="//'+getFbDomain()+'/ajax/intl/language_dialog.php" rel="dialog" id="ponyhoof_welcome_final_changelanguage">For the best Ponyhoof experience, we recommend switching your Facebook language to English (US). Why? Because ponies!</a></div><br>';
5432 if (!ISUSINGBUSINESS
) {
5433 c
+= '<span class="ponyhoof_brohoof_button">'+capitaliseFirstLetter(CURRENTSTACK
['like'])+'</span> us to receive news and help for Ponyhoof!';
5434 c
+= '<div id="ponyhoof_welcome_likeWrap"><iframe src="about:blank" id="ponyhoof_welcome_like" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div>';
5435 c
+= 'Got somepony else that you want to suggest? Want to leave some feedback? <a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" target="_top" id="ponyhoof_welcome_posttowall">Let us know at our page!</a>';
5437 c
+= '<a href="'+w
.location
.protocol
+PONYHOOF_URL
+'" target="_top" id="ponyhoof_welcome_posttowall">Visit our Ponyhoof page for the latest news!</a>';
5440 var successText
= '';
5441 var ponyData
= convertCodeToData(REALPONY
);
5442 if (ponyData
.successText
) {
5443 successText
= ponyData
.successText
;
5445 successText
= "Yay!";
5448 k
.dialogFinish
= new Dialog('welcome_final');
5449 if (k
._stack
!= CURRENTSTACK
) {
5450 k
.dialogFinish
.alwaysModal
= true;
5452 k
.dialogFinish
.create();
5453 k
.dialogFinish
.changeTitle(successText
);
5454 k
.dialogFinish
.changeContent(c
);
5455 var buttonText
= CURRENTLANG
.done
;
5456 if (k
._stack
!= CURRENTSTACK
) {
5457 buttonText
= CURRENTLANG
.finish
;
5459 k
.dialogFinish
.changeBottom('<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_welcomefinal_ok"><span class="uiButtonText">'+buttonText
+'</span></a>');
5460 k
.dialogFinish
.onclose = function() {
5461 if (k
._stack
!= CURRENTSTACK
) {
5462 w
.location
.reload();
5466 $('ponyhoof_welcomefinal_ok').addEventListener('click', k
.dialogFinishOk
, false);
5467 $('ponyhoof_welcomefinal_ok').focus();
5469 if (!ISUSINGBUSINESS
) {
5470 w
.setTimeout(function() {
5471 $('ponyhoof_welcome_like').src
= '//'+getFbDomain()+'/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Fprofile.php%3Fid%3D'+PONYHOOF_PAGE
+'&width=292&height=62&colorscheme=light&show_faces=false&stream=false&header=false&ponyhoof_runme';
5475 $('ponyhoof_welcome_posttowall').addEventListener('click', function(e
) {
5476 k
.dialogFinish
.onclose = function() {};
5477 k
.dialogFinish
.close();
5481 k
.dialogFinishOk = function(e
) {
5482 if (k
._stack
!= CURRENTSTACK
) {
5483 if (hasClass(this, 'uiButtonDisabled')) {
5487 this.className
+= ' uiButtonDisabled';
5488 w
.location
.reload();
5490 k
.dialogFinish
.close();
5495 k
.createScenery = function() {
5496 if ($('ponyhoof_welcome_scenery')) {
5497 $('ponyhoof_welcome_scenery').style
.display
= 'block';
5501 var n
= d
.createElement('div');
5502 n
.id
= 'ponyhoof_welcome_scenery';
5503 d
.body
.appendChild(n
);
5508 k
.injectStyle = function() {
5510 css
+= 'html.ponyhoof_welcome_html {overflow:hidden;}';
5511 css
+= 'html.ponyhoof_welcome_html .fbPageBanner, html.ponyhoof_welcome_html .uiLayer[data-ownerid="userNavigationLabel"], html.ponyhoof_welcome_html ._50d1, html.ponyhoof_welcome_html .-cx-PUBLIC-notificationBeeper__list {display:none !important;}';
5512 css
+= 'html #ponyhoof_dialog_welcome .generic_dialog_fixed_overflow {background:transparent !important;}';
5513 css
+= '#ponyhoof_welcome_scenery {width:100%;height:100%;position:fixed;top:0;left:0;background-color:#fff;background-color:rgba(252,252,252,.9);background-repeat:no-repeat;background-position:center center;z-index:'+(DIALOGCOUNT
-6)+';}';
5515 //css += '#ponyhoof_dialog_welcome .generic_dialog {z-index:401 !important;}';
5516 css
+= '#ponyhoof_dialog_welcome .generic_dialog_popup, #ponyhoof_dialog_welcome .popup {width:475px !important;}';
5517 //css += '#ponyhoof_dialog_welcome .content {-webkit-transition:.3s linear;-webkit-transition-property:min-height, padding-top;-moz-transition:.3s linear;-moz-transition-property:min-height, padding-top;-o-transition:.3s linear;-o-transition-property:min-height, padding-top;transition:.3s linear;transition-property:min-height, padding-top;}';
5518 css
+= '#ponyhoof_dialog_welcome .ponyhoof_updater_newVersion {margin-bottom:10px;}';
5520 css
+= '#ponyhoof_welcome_newVersion {display:none;margin:0 0 10px;}';
5521 css
+= '#ponyhoof_welcome_pony {margin:8px 0;}';
5522 css
+= '#ponyhoof_welcome_afterClose {visibility:hidden;opacity:0;}';
5523 css
+= '#ponyhoof_welcome_afterClose.show {visibility:visible;opacity:1;-webkit-transition:opacity .3s linear;-moz-transition:opacity .3s linear;-o-transition:opacity .3s linear;transition:opacity .3s linear;}';
5525 css
+= 'html.ponyhoof_welcome_html_scenery_loaded #blueBar, html.ponyhoof_welcome_html_scenery_loaded #blueBar.fixed_elem {opacity:0;-webkit-transition:opacity .3s linear;-moz-transition:opacity .3s linear;-o-transition:opacity .3s linear;transition:opacity .3s linear;}';
5526 css
+= 'html.ponyhoof_welcome_showmedemo {cursor:not-allowed;}';
5527 css
+= 'html.ponyhoof_welcome_showmedemo .popup {cursor:default;}';
5528 css
+= 'html.ponyhoof_welcome_showmedemo #blueBar #pageHead {width:981px !important;padding-right:0 !important;}';
5529 css
+= 'html.sidebarMode.ponyhoof_welcome_showmedemo #pageHead, html.sidebarMode.ponyhoof_welcome_showmedemo .sidebarMode #globalContainer {left:0 !important;}';
5530 css
+= 'html.ponyhoof_welcome_showmedemo #blueBar, html.ponyhoof_welcome_showmedemo.tinyViewport #blueBar, html.ponyhoof_welcome_showmedemo #blueBar.fixed_elem, html.ponyhoof_welcome_showmedemo.tinyViewport #blueBar.fixed_elem {position:fixed !important;z-index:'+(DIALOGCOUNT
-4)+';opacity:1;margin-left:0 !important;left:0 !important;right:0 !important;top:0 !important;}';
5532 css
+= '#ponyhoof_dialog_welcome_pinkie .generic_dialog_popup, #ponyhoof_dialog_welcome_pinkie .popup {width:720px;}';
5533 css
+= '#ponyhoof_dialog_welcome_pinkie .content {line-height:0;padding:0;}';
5535 css
+= '#ponyhoof_welcome_likeWrap {margin:8px 0;}';
5536 css
+= '#ponyhoof_welcome_like {border:none;overflow:hidden;width:292px;height:62px;margin:0;}';
5539 css
+= '#ponyhoof_welcome_scenery {background-image:none !important;}';
5542 injectManualStyle(css
, 'welcome');
5546 var renderBrowserConfigWarning = function() {
5548 if (STORAGEMETHOD
== 'localstorage') {
5549 c
+= '<div class="ponyhoof_message uiBoxRed">Ponyhoof is not supported on this browser configuration. Your settings will get cleared out from time to time, and some features such as update-checking and Browser Ponies will not work.</div><br>';
5550 } else if (ISMOBILE
) {
5551 c
+= '<div class="ponyhoof_message uiBoxYellow">Mobile support for Ponyhoof is provided as a courtesy and is not officially supported.</div><br>';
5557 function getFaviconTag() {
5558 var l
= d
.getElementsByTagName('link');
5559 for (var i
= 0, len
= l
.length
; i
< len
; i
+= 1) {
5560 if (l
[i
].getAttribute('rel') == 'shortcut icon') {
5568 function changeFavicon(character
) {
5569 if (userSettings
.noFavicon
) {
5573 var favicon
= getFaviconTag();
5576 // Don't change the favicon on apps.facebook.com
5577 if (w
.location
.hostname
.indexOf('apps.') === 0) {
5578 if (favicon
.href
.indexOf('.ico') !== favicon
.href
.length
-('.ico'.length
)) {
5583 var newIcon
= favicon
.cloneNode(true);
5585 var newIcon
= d
.createElement('link');
5586 newIcon
.rel
= 'shortcut icon';
5589 if (character
!= 'NONE') {
5590 newIcon
.type
= 'image/png';
5592 var data
= convertCodeToData(character
);
5594 newIcon
.href
= THEMEURL
+data
.icon16
;
5596 newIcon
.href
= THEMEURL
+character
+'/icon16.png';
5599 newIcon
.type
= 'image/x-icon';
5600 newIcon
.href
= '//fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico';
5604 favicon
.parentNode
.replaceChild(newIcon
, favicon
);
5606 d
.head
.appendChild(newIcon
);
5610 function changeStack(character
) {
5611 var pony
= convertCodeToData(character
);
5612 CURRENTSTACK
= STACKS_LANG
[0];
5614 for (var i
= 0, len
= STACKS_LANG
.length
; i
< len
; i
+= 1) {
5615 if (STACKS_LANG
[i
].stack
== pony
.stack
) {
5616 CURRENTSTACK
= STACKS_LANG
[i
];
5622 if (UILANG
== 'fb_LT') {
5623 if (CURRENTSTACK
['people'] == 'ponies') {
5624 CURRENTSTACK
['people'] = 'pwnies';
5626 if (CURRENTSTACK
['person'] == 'pony') {
5627 CURRENTSTACK
['person'] = 'pwnie';
5629 if (CURRENTSTACK
['like'] == 'brohoof') {
5630 CURRENTSTACK
['like'] = '/)';
5632 if (CURRENTSTACK
['likes'] == 'brohoofs') {
5633 CURRENTSTACK
['likes'] = '/)';
5635 //if (CURRENTSTACK['unlike'] == 'unbrohoof') {
5636 // CURRENTSTACK['unlike'] = '/)(\\';
5638 if (CURRENTSTACK
['like_past'] == 'brohoof') {
5639 CURRENTSTACK
['like_past'] = '/)';
5641 if (CURRENTSTACK
['likes_past'] == 'brohoofs') {
5642 CURRENTSTACK
['likes_past'] = '/)';
5644 if (CURRENTSTACK
['liked'] == 'brohoof\'d') {
5645 CURRENTSTACK
['liked'] = '/)';
5647 if (CURRENTSTACK
['liked_button'] == 'brohoof\'d') {
5648 CURRENTSTACK
['liked_button'] = '/)';
5650 if (CURRENTSTACK
['liking'] == 'brohoofing') {
5651 CURRENTSTACK
['liking'] = '/)';
5656 var changeThemeFuncQueue
= [];
5657 function changeTheme(character
) {
5658 addClass(d
.documentElement
, 'ponyhoof_injected');
5660 REALPONY
= character
;
5661 d
.documentElement
.setAttribute('data-ponyhoof-character', character
);
5663 changeFavicon(character
);
5664 changeStack(character
);
5667 if (changeThemeFuncQueue
) {
5668 for (var x
in changeThemeFuncQueue
) {
5669 if (changeThemeFuncQueue
.hasOwnProperty(x
) && changeThemeFuncQueue
[x
]) {
5670 changeThemeFuncQueue
[x
]();
5675 // Did we injected our theme already?
5676 if ($('ponyhoof_userscript_style')) {
5677 changeCostume(userSettings
.costume
);
5678 $('ponyhoof_userscript_style').href
= THEMECSS
+character
+THEMECSS_EXT
;
5682 addClass(d
.documentElement
, 'ponyhoof_initial');
5683 w
.setTimeout(function() {
5684 removeClass(d
.documentElement
, 'ponyhoof_initial');
5687 var n
= d
.createElement('link');
5688 n
.href
= THEMECSS
+character
+THEMECSS_EXT
;
5689 n
.type
= 'text/css';
5690 n
.rel
= 'stylesheet';
5691 n
.id
= 'ponyhoof_userscript_style';
5692 d
.head
.appendChild(n
);
5694 changeCostume(userSettings
.costume
);
5697 function getRandomPony() {
5699 var r
= randNum(0, PONIES
.length
-1);
5700 if (!PONIES
[r
].hidden
) {
5701 return PONIES
[r
].code
;
5706 function getRandomMane6() {
5708 var r
= randNum(0, PONIES
.length
-1);
5709 if (PONIES
[r
].mane6
) {
5710 return PONIES
[r
].code
;
5715 function convertCodeToData(code
) {
5716 for (var i
= 0, len
= PONIES
.length
; i
< len
; i
+= 1) {
5717 if (PONIES
[i
].code
== code
) {
5725 function changeThemeSmart(theme
) {
5728 removeClass(d
.documentElement
, 'ponyhoof_injected');
5729 changeFavicon('NONE');
5730 changeCostume(null);
5732 var style
= $('ponyhoof_userscript_style');
5734 style
.parentNode
.removeChild(style
);
5740 if (userSettings
.randomPonies
) {
5741 current
= userSettings
.randomPonies
.split('|');
5742 changeTheme(current
[Math
.floor(Math
.random() * current
.length
)]);
5744 changeTheme(getRandomPony());
5750 if (theme
== 'login' || convertCodeToData(theme
)) {
5753 error("changeThemeSmart: "+theme
+" is not a valid theme");
5754 userSettings
.theme
= null;
5755 CURRENTPONY
= REALPONY
= 'NONE';
5761 function changeCustomBg(base64
) {
5763 removeClass(d
.documentElement
, 'ponyhoof_settings_login_bg');
5764 removeClass(d
.documentElement
, 'ponyhoof_settings_customBg');
5766 var style
= $('ponyhoof_style_custombg');
5768 style
.parentNode
.removeChild(style
);
5773 addClass(d
.documentElement
, 'ponyhoof_settings_login_bg');
5774 addClass(d
.documentElement
, 'ponyhoof_settings_customBg');
5776 if (!$('ponyhoof_style_custombg')) {
5777 injectManualStyle('', 'custombg');
5779 $('ponyhoof_style_custombg').textContent
= '/* '+SIG
+' */html,.fbIndex{background-position:center center !important;background-image:url("'+base64
+'") !important;background-repeat:no-repeat;}';
5782 var changeCostume = function(costume
) {
5783 // Make sure the costume exists
5784 if (!COSTUMESX
[costume
]) {
5789 // Make sure the character has the costume
5790 if (!doesCharacterHaveCostume(REALPONY
, costume
)) {
5791 //removeCostume(); // leaving the costume alone wouldn't hurt...
5795 d
.documentElement
.setAttribute('data-ponyhoof-costume', costume
);
5798 var removeCostume = function() {
5799 d
.documentElement
.removeAttribute('data-ponyhoof-costume');
5802 var doesCharacterHaveCostume = function(character
, costume
) {
5803 return (COSTUMESX
[costume
] && COSTUMESX
[costume
].characters
&& COSTUMESX
[costume
].characters
.indexOf(character
) != -1);
5806 function getBronyName() {
5807 var name
= d
.querySelector('.headerTinymanName, #navTimeline > .navLink, .fbxWelcomeBoxName, ._521h ._4g5y, .-cx-PRIVATE-litestandSidebarBookmarks__profilewrapper .-cx-PRIVATE-litestandSidebarBookmarks__name');
5809 BRONYNAME
= name
.textContent
;
5815 function getDefaultUiLang() {
5819 var classes
= d
.body
.className
.split(' ');
5820 for (var i
= 0, len
= classes
.length
; i
< len
; i
+= 1) {
5821 if (classes
[i
].indexOf('Locale_') == 0) {
5822 return classes
[i
].substring('Locale_'.length
);
5830 var screenSaverTimer
= null;
5831 var screenSaverActive
= false;
5832 var screenSaverInactivity = function() {
5833 if (!screenSaverActive
) {
5834 addClass(d
.body
, 'ponyhoof_screensaver');
5836 screenSaverActive
= true;
5838 var screenSaverActivity = function() {
5839 if (screenSaverActive
) {
5840 removeClass(d
.body
, 'ponyhoof_screensaver');
5842 screenSaverActive
= false;
5844 w
.clearTimeout(screenSaverTimer
);
5845 screenSaverTimer
= w
.setTimeout(screenSaverInactivity
, 30000);
5847 var screenSaverActivate = function() {
5851 d
.addEventListener('click', screenSaverActivity
, true);
5852 d
.addEventListener('mousemove', function(e
) {
5853 if (mousemoveX
== e
.clientX
&& mousemoveY
== e
.clientY
) {
5856 mousemoveX
= e
.clientX
;
5857 mousemoveY
= e
.clientY
;
5859 screenSaverActivity();
5861 d
.addEventListener('keydown', screenSaverActivity
, true);
5862 d
.addEventListener('contextmenu', screenSaverActivity
, true);
5863 d
.addEventListener('mousewheel', screenSaverActivity
, true);
5864 d
.addEventListener('touchstart', screenSaverActivity
, true);
5866 screenSaverActivity();
5870 var domReplaceText = function(ele
, cn
, deeper
, regex
, text
) {
5872 var id
= ele
.getAttribute('id');
5873 if ((cn
== '' && deeper
== '') || (cn
&& hasClass(ele
, cn
)) || (cn
&& id
&& id
== nc
)) {
5875 t
= t
.replace(regex
, text
);
5876 if (ele
.innerHTML
!= t
) {
5884 var query
= ele
.querySelectorAll(deeper
);
5886 for (var i
= 0, len
= query
.length
; i
< len
; i
+= 1) {
5887 t
= query
[i
].innerHTML
;
5888 t
= t
.replace(regex
, text
);
5889 if (query
[i
].innerHTML
!= t
) {
5890 query
[i
].innerHTML
= t
;
5897 var _fb_input_placeholderChanged
= false;
5898 var domChangeTextbox = function(ele
, cn
, text
) {
5899 var query
= ele
.querySelectorAll(cn
);
5900 if (!query
.length
) {
5903 if (!_fb_input_placeholderChanged
) {
5904 contentEval(function(arg
) {
5906 if (typeof window
.requireLazy
== 'function') {
5907 window
.requireLazy(['Input'], function(Input
) {
5908 var _setPlaceholder
= Input
.setPlaceholder
;
5909 Input
.setPlaceholder = function(textbox
, t
) {
5910 if (!textbox
.getAttribute('data-ponyhoof-ponified-overridefb')) {
5911 if (textbox
!= document
.activeElement
) {
5912 _setPlaceholder(textbox
, t
);
5914 textbox
.setAttribute('data-ponyhoof-ponified-overridefb', 1);
5916 // we already overridden, now FB wants to change the placeholder
5917 if (textbox
.getAttribute('placeholder') == '' && t
) {
5918 if (textbox
.title
) {
5920 _setPlaceholder(textbox
, textbox
.title
);
5922 // for typeahead (share dialog > private message)
5923 _setPlaceholder(textbox
, t
);
5925 } else if (t
== '') {
5926 // allow blanking placeholder (for typeahead)
5927 _setPlaceholder(textbox
, t
);
5934 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
5935 console
.log("Unable to override Input.setPlaceholder()");
5939 }, {"CANLOG":CANLOG
});
5940 _fb_input_placeholderChanged
= true;
5943 var placeholders
= [];
5944 for (var i
= 0, len
= query
.length
; i
< len
; i
+= 1) {
5945 var textbox
= query
[i
];
5946 if (textbox
.getAttribute('data-ponyhoof-ponified')) {
5949 textbox
.setAttribute('data-ponyhoof-ponified', 1);
5951 if (typeof text
== 'function') {
5952 placeholders
[i
] = text(textbox
);
5954 placeholders
[i
] = text
;
5957 textbox
.title
= placeholders
[i
];
5958 textbox
.setAttribute('aria-label', placeholders
[i
]);
5959 textbox
.setAttribute('placeholder', placeholders
[i
]);
5961 if (hasClass(textbox
, 'DOMControl_placeholder')) {
5962 textbox
.value
= placeholders
[i
];
5968 if (typeof USW.requireLazy == 'function') {
5969 USW.requireLazy(['TextAreaControl'], function(TextAreaControl) {
5970 for (var i = 0; i < query.length; i++) {
5971 if (placeholders[i]) {
5972 //if (query[i] != d.activeElement) {
5973 TextAreaControl.getInstance(query[i]).setPlaceholderText(placeholders[i]);
5979 for (var i
= 0, len
= query
.length
; i
< len
; i
+= 1) {
5980 if (placeholders
[i
]) {
5981 var textbox
= query
[i
];
5982 if (!textbox
.getAttribute('data-ponyhoof-ponified-overridefb')) {
5983 textbox
.setAttribute('aria-label', placeholders
[i
]);
5984 textbox
.setAttribute('placeholder', placeholders
[i
]);
5985 textbox
.setAttribute('data-ponyhoof-ponified-overridefb', 1);
5986 if (textbox
== d
.activeElement
) {
5989 if (textbox
.value
== '' || hasClass(textbox
, 'DOMControl_placeholder')) {
5990 if (placeholders
[i
]) {
5991 addClass(textbox
, 'DOMControl_placeholder');
5993 removeClass(textbox
, 'DOMControl_placeholder');
5995 textbox
.value
= placeholders
[i
] || '';
6002 error("Unable to hook to TextAreaControl");
6007 var domReplaceFunc = function(ele
, cn
, deeper
, func
) {
6008 if (!ele
|| (cn
== '' && deeper
== '')) {
6012 var id
= ele
.getAttribute('id');
6013 if ((cn
&& hasClass(ele
, cn
)) || (cn
&& id
&& id
== cn
)) {
6019 var query
= ele
.querySelectorAll(deeper
);
6021 for (var i
= 0, len
= query
.length
; i
< len
; i
+= 1) {
6028 var replaceText = function(arr
, t
) {
6029 var lowercase
= t
.toLowerCase();
6030 for (var i
= 0, len
= arr
.length
; i
< len
; i
+= 1) {
6031 if (arr
[i
][0] instanceof RegExp
) {
6032 t
= t
.replace(arr
[i
][0], arr
[i
][1]);
6034 if (arr
[i
][0].toLowerCase() == lowercase
) {
6043 var loopChildText = function(ele
, func
) {
6044 if (!ele
|| !ele
.childNodes
) {
6047 for (var i
= 0, len
= ele
.childNodes
.length
; i
< len
; i
+= 1) {
6048 func(ele
.childNodes
[i
]);
6052 var buttonTitles
= [];
6053 var dialogTitles
= [];
6054 var tooltipTitles
= [];
6055 var headerTitles
= [];
6056 var menuTitles
= [];
6057 var menuPrivacyOnlyTitles
= [];
6058 var dialogDerpTitles
= [];
6059 var headerInsightsTitles
= [];
6060 var dialogDescriptionTitles
= [];
6061 function buildStackLang() {
6062 var ponyData
= convertCodeToData(REALPONY
);
6067 ,["Done Editing", "Eeyup"]
6068 ,["Save Changes", "Eeyup"]
6071 ,[/everyone/i, "Everypony"] // for Everyone (Most Recent)
6072 ,["Everybody", "Everypony"]
6073 ,["Public", "Everypony"]
6074 ,["Anyone", "Anypony"]
6075 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6076 ,["Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6077 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Guests"]
6078 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Contributors"]
6079 ,["Only Me", "Alone"]
6080 ,["Only me", "Alone"]
6081 ,["Only Me (+)", "Alone (+)"]
6082 ,["Only me (+)", "Alone (+)"]
6083 ,["No One", "Alone"]
6084 ,["Nobody", "Nopony"]
6086 ,["Add Friend", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friend'])]
6087 ,["Friend Request Sent", "Friendship Request Sent"]
6088 ,["Respond to Friend Request", "Respond to Friendship Request"]
6089 ,["Like", capitaliseFirstLetter(CURRENTSTACK
['like'])]
6090 ,["Liked", capitaliseFirstLetter(CURRENTSTACK
['liked_button'])]
6091 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK
['unlike'])]
6092 ,["Like Page", capitaliseFirstLetter(CURRENTSTACK
['like'])+" Page"]
6093 ,["Like This Page", capitaliseFirstLetter(CURRENTSTACK
['like'])+" This Page"]
6094 ,["Suggest Friends", "Suggest "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6095 ,["Suggest Friend", "Suggest "+capitaliseFirstLetter(CURRENTSTACK
['friend'])]
6096 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6097 ,["All friends", "All "+CURRENTSTACK
['friends']]
6099 ,["Request Deleted", "Request Nuked"]
6101 ,["Likes", capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6102 ,["Friends' Posts", capitaliseFirstLetter(CURRENTSTACK
['friends'])+"' Posts"]
6104 ,["Photos", "Pony Pics"]
6105 ,["People", capitaliseFirstLetter(CURRENTSTACK
['people'])]
6106 ,["Banned", "Banished to Moon"]
6107 ,["Blocked", "Banished to Moon"]
6108 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK
.people
)+" that "+CURRENTSTACK
.like_past
+" this"]
6109 ,["Pages that like this", "Pages that "+CURRENTSTACK
.like_past
+" this"]
6111 ,["Delete and Ban User", "Nuke and Banish to Moon"]
6112 ,["Remove from Friends", "Banish to Moon"]
6114 ,["Delete Photo", "Nuke Pony Pic"]
6115 ,["Delete Page", "Nuke Page"]
6116 ,["Delete All", "Nuke All"]
6117 ,["Delete Selected", "Nuke Selected"]
6118 ,["Delete Conversation", "Nuke Conversation"]
6119 ,["Delete Message", "Nuke Friendship Report"]
6120 ,["Delete Messages", "Nuke Friendship Reports"]
6121 ,["Delete Post", "Nuke Post"]
6123 ,["Delete Report", "Nuke This Whining"]
6124 ,["Report", "Whine"]
6125 ,["Report as Spam", "Whine as Spam"]
6126 ,["Clear Searches", "Nuke Searches"]
6127 ,["Report/Remove Tags", "Whine/Nuke Tags"]
6128 ,["Untag Photo", "Untag Pony Pic"]
6129 ,["Untag Photos", "Untag Pony Pics"]
6130 ,["Delete My Account", "Nuke My Account"]
6131 ,["Allowed on Timeline", "Allowed on Journal"]
6132 ,["Hidden from Timeline", "Hidden from Journal"]
6133 ,["Unban", "Unbanish"]
6134 ,["Delete Album", "Nuke Album"]
6135 ,["Cancel Report", "Cancel Whining"]
6136 ,["Unfriend", "Banish to Moon"]
6137 ,["Delete List", "Nuke List"]
6139 ,["Messages", "Trough"]
6140 ,["New Message", "Write a Friendship Report"]
6141 ,["Other Messages", "Other Friendship Reports"]
6142 ,["Stay on Message", "Stay on Friendship Report"]
6144 ,["Share Photo", "Share Pony Pic"]
6145 ,["Share Application", "Share Magic"]
6146 ,["Share Note", "Share Scroll"]
6147 ,["Share Question", "Share Query"]
6148 ,["Share Event", "Share Adventure"]
6149 ,["Share Group", "Share Herd"]
6150 ,["Send Message", "Send Friendship Letter"]
6151 ,["Share Photos", "Share Pony Pics"]
6152 ,["Share This Note", "Share This Scroll"] // entstream
6153 ,["Share This Photo", "Share This Pony Pic"]
6155 ,["Add Friends", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6156 ,["Go to App", "Go to Magic"]
6157 ,["Back to Timeline", "Back to Journal"]
6158 ,["Add App", "Add Magic"]
6159 ,["Get More Likes", "Get More "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6160 ,["Advertise Your App", "Advertise Your Magic"]
6161 ,["Leave App", "Leave Magic"]
6162 ,["Find another app", "Find another magic"]
6163 ,["Post on your timeline", "Post on your journal"]
6164 ,["App Center", "Magic Center"]
6165 ,["View App Center", "View Magic Center"]
6167 ,["Events", "Adventures"]
6168 ,["Page Events", "Page Adventures"]
6169 ,["Suggested Events", "Suggested Adventures"]
6170 ,["Past Events", "Past Adventures"]
6171 ,["Declined Events", "Declined Adventures"]
6172 ,["Create Event", "Plan an Adventure"]
6173 ,["Save Event", "Save Adventure"]
6174 ,["Back to Event", "Back to Adventure"]
6175 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])]
6176 ,["Page Event", "Page Adventures"]
6177 ,["Upcoming Events", "Upcoming Adventures"]
6178 ,["Group Events", "Herd Adventures"]
6179 ,["Change Event Photo", "Change Pony Pic for Adventure"]
6180 ,["Add Event Photo", "Add Pony Pic for Adventure"]
6181 ,["+ Create an Event", "+ Plan an Adventure"]
6183 ,["Friend Activity", capitaliseFirstLetter(CURRENTSTACK
['friend'])+" Activity"]
6184 ,["Activity Log", "Adventure Log"]
6186 ,["Invite More Friends", "Invite More Pals"]
6187 ,["Find Friends", CURRENTSTACK
['findFriendship']]
6188 //,["Pages I Like", "Pages I "+capitaliseFirstLetter(CURRENTSTACK['like_past'])]
6189 ,["Find My Friends", CURRENTSTACK
['findFriendship']]
6191 ,["Leave Group", "Leave Herd"]
6192 ,["Set Up Group Address", "Set Up Herd Address"]
6193 ,["Change Group Photo", "Change Herd Pony Pic"]
6194 //,["Notifications", "Sparks"]
6195 ,["Start Chat", "Start Whinny Chat"]
6196 ,["Create Group", "Create Herd"]
6197 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])]
6198 ,["Groups", "Herds"]
6199 ,["Join Group", "Join the Herd"]
6200 ,["View group", "View herd"]
6201 ,["Create New Group", "Create New Herd"]
6202 ,["Set Up Group", "Set Up Herd"] // tour
6204 ,["Move photo", "Move pony pic"]
6205 ,["Delete Photos", "Nuke Pony Pics"]
6206 ,["Keep Photos", "Keep Pony Pics"]
6207 ,["Save Photo", "Save Pony Pic"]
6208 ,["Tag Photos", "Tag Pony Pics"]
6209 ,["Add Photos", "Add Pony Pics"]
6210 ,["Upload Photos", "Upload Pony Pics"]
6211 ,["Tag Photo", "Tag Pony Pic"]
6212 ,["Add More Photos", "Add More Pony Pics"]
6213 ,["Post Photos", "Post Pony Pics"]
6214 ,["Add Photos to Map", "Add Pony Pics to Map"]
6215 ,["Add Photo", "Add Pony Pic"]
6217 ,["On your own timeline", "On your own journal"]
6218 ,["On a friend's timeline", "On a "+CURRENTSTACK
['friend']+"'s journal"]
6219 ,["In a group", "In a herd"]
6220 ,["In a private message", "In a private friendship report"]
6222 ,["Timeline", "Journal"]
6223 ,["Notes", "Scrolls"]
6224 ,["Comments", "Friendship Letters"]
6225 ,["Posts and Apps", "Posts and Magic"]
6226 ,["Timeline Review", "Journal Review"]
6227 ,["Pokes", "Nuzzles"]
6228 ,["Add to Timeline", "Add to Journal"]
6230 ,["Photo", "Pony Pic"]
6231 ,["Question", "Query"]
6233 //,["Create List", "Create Directory"]
6234 ,["See All Friends", "See All "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6235 //,["Manage List", "Manage Directory"]
6236 ,["Write a Note", "Write a Scroll"]
6237 ,["Add Note", "Add Scroll"]
6238 ,["Edit Featured Likes", "Edit Featured "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6239 ,["Add Featured Likes", "Add Featured "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6240 ,["Add profile picture", "Add journal pony pic"]
6241 ,["Edit Profile Picture", "Edit Journal Pony Pic"]
6242 //,["Create an Ad", "Buy a Cupcake"]
6243 //,["On This List", "On This Directory"]
6244 ,["Friend Requests", "Friendship Requests"]
6245 //,["Add Friends to List", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" to Directory"]
6246 ,["Add Friends to List", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+" to List"]
6248 ,[/^Pages I Like
$/, "Pages I "+capitaliseFirstLetter(CURRENTSTACK
['like_past'])]
6249 ,[/^Pages I like
$/, "Pages I "+CURRENTSTACK
['like_past']]
6250 ,["My Friends", "My "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6251 ,["Tell Friends", "Tell "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6253 ,["Add to Profile", "Add to Journal"]
6254 ,["Add Likes", "Add "+capitaliseFirstLetter(CURRENTSTACK
.likes
)]
6255 ,["Set as Profile Picture", "Set as Journal Pony Pic"]
6256 ,["View Activity Log", "View Adventure Log"]
6257 ,["Invite Your Friends", "Invite Your "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6258 ,["Suggest Photo", "Suggest Pony Pic"]
6259 ,["All Apps", "All Magic"]
6260 ,["Link My Profile to Twitter", "Link My Journal to Twitter"]
6261 ,["Link profile to Twitter", "Link journal to Twitter"]
6262 //,["The app sends you a notification", "The magic sends you a spark"]
6263 ,["The app sends you a notification", "The magic sends you a notification"]
6264 ,["Upload a Photo", "Upload a Pony Pic"]
6265 ,["Take a Photo", "Take a Pony Pic"]
6266 ,["Take a Picture", "Take a Pony Pic"] // edit page
6267 ,["Search All Friends", "Search All "+capitaliseFirstLetter(CURRENTSTACK
.friends
)] // invite friends
6268 ,["Top Comments", "Top Friendship Letters"] // comment resort
6269 ,["Go to Activity Log", "Go to Adventure Log"] // checkpoint
6270 ,["Upload Photo", "Upload Pony Pic"] // composer warning
6271 ,["Poke Back", "Nuzzle Back"] // newsfeed flyout
6272 ,["Friends to Invite", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" to Invite"] // app invite
6273 ,["Inbox", "Trough"] // page inbox
6274 ,["Save Profile Info", "Save Journal Info"] // welcome
6275 ,["Like Pages", capitaliseFirstLetter(CURRENTSTACK
['like'])+" Pages"] // litestand Following
6276 ,["Visit App Center", "Visit Magic Center"] // litestand Games
6277 ,["Go to App Center", "Go to Magic Center"] // no https on app
6278 ,["Set Profile Picture", "Set Journal Pony Pic"] // page nux
6279 ,["Edit Offer Image", "Edit Offer Pony Pic"] // page composer
6282 ,["Likers", "Brohoofers"] // @todo likers
6283 ,["Liked by", capitaliseFirstLetter(CURRENTSTACK
['liked'])+" by"] // @todo likers
6285 ,["Create New App", "Create New Magic"]
6286 ,["Submit App Detail Page", "Submit Magic Detail Page"]
6287 ,["Edit App", "Edit Magic"]
6288 ,["Promote App", "Promote Magic"]
6289 ,["Make Friends", "Make "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6290 ,["Add to Other Apps", "Add to Other Magic"]
6291 ,["Delete Image", "Nuke Pony Pic"]
6295 [/People who like
/, capitaliseFirstLetter(CURRENTSTACK
['people'])+" who "+CURRENTSTACK
['like_past']+" "]
6296 ,[/People Who Like
/, capitaliseFirstLetter(CURRENTSTACK
['people'])+" Who "+capitaliseFirstLetter(CURRENTSTACK
['like_past'])+" "]
6297 ,[/Friends who like
/i
, capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])+" who "+CURRENTSTACK
['like_past']+" "]
6298 ,["People who voted for this option", capitaliseFirstLetter(CURRENTSTACK
['people'])+" who voted for this option"]
6299 ,["People who are following this question", capitaliseFirstLetter(CURRENTSTACK
['people'])+" who are following this question"]
6300 ,[/People Connected to
/, capitaliseFirstLetter(CURRENTSTACK
['people'])+" Connected to "]
6301 ,["People who saw this", capitaliseFirstLetter(CURRENTSTACK
['people'])+" who saw this"]
6302 ,["Added Friends", "Added "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6303 ,["People who can repro this", capitaliseFirstLetter(CURRENTSTACK
['people'])+" who can repro this"]
6304 ,["Friends that like this", capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])+" that "+CURRENTSTACK
['like_past']+" this"]
6305 ,["People", capitaliseFirstLetter(CURRENTSTACK
['people'])] // gifts
6306 ,["Choose friends to help translate", "Choose "+CURRENTSTACK
['friends']+" to help translate"]
6308 ,["Share this Profile", "Share this Journal"]
6309 ,["Share This Photo", "Share This Pony Pic"]
6310 //,["Share this Album", ""]
6311 ,["Share this Note", "Share this Scroll"]
6312 ,["Share this Group", "Share this Herd"]
6313 ,["Share this Event", "Share this Adventure"]
6314 //,["Share this Ad", ""]
6315 ,["Share this Application", "Share this Magic"]
6316 //,["Share this Video", ""]
6317 //,["Share this Page", "Share this Landmark"]
6318 //,["Share this Page", "You gotta share!"]
6319 //,["Share this Job", ""]
6320 //,["Share this Status", "You gotta share!"]
6321 ,["Share this Question", "Share this Query"]
6322 //,["Share this Link", "You gotta share!"]
6323 ,["Share", "You gotta share!"]
6324 //,["Share this Help Content", ""]
6325 ,["Send This Photo", "Send This Pony Pic"]
6326 ,["Share Photo", "Share Pony Pic"]
6328 ,["Timeline and Tagging", "Journal and Tagging"]
6329 ,["Timeline Review", "Journal Review"]
6330 //,["Friends Can Check You Into Places", capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" Can Check You Into Landmarks"]
6331 //,["Limit The Audience for Old Posts on Your Timeline", "Limit The Audience for Old Posts on Your Journal"]
6332 //,["How people bring your info to apps they use", "How "+CURRENTSTACK['people']+" bring your info to magic they use"]
6333 //,["Turn off Apps, Plugins and Websites", "Turn off Magic, Plugins and Websites"]
6335 ,["Likes", capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6336 ,["Edit Featured Likes", "Edit Featured "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6337 ,["Change Date", "Time Travel"]
6338 ,["Date Saved", "Time Traveled"]
6341 ,["Delete Comment", "Nuke Friendship Letter"]
6342 ,["Delete Photo", "Nuke Pony Pic"]
6343 ,["Remove Picture?", "Nuke Pony Pic?"]
6344 ,["Delete Video?", "Nuke Video?"]
6345 ,["Delete Milestone", "Nuke Milestone"]
6346 ,["Delete Page?", "Nuke Page?"]
6347 ,["Delete This Message?", "Nuke This Friendship Report?"]
6348 ,["Delete This Entire Conversation?", "Nuke This Entire Conversation?"]
6349 ,["Delete These Messages?", "Nuke These Friendship Reports?"]
6350 ,["Delete Post", "Nuke Post"]
6351 ,["Delete Post?", "Nuke Post?"]
6352 ,["Delete Page Permanently?", "Nuke Page Permanently?"]
6353 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK
['unlike'])]
6354 ,["Remove Search", "Nuke Search"]
6355 //,["Clear Searches", "Nuke Searches"]
6356 ,["Untag Photo", "Untag Pony Pic"]
6357 ,["Untag Photos", "Untag Pony Pics"]
6358 ,["Permanently Delete Account", "Permanently Nuke Account"]
6360 ,["Delete and Ban Member", "Nuke and Banish to Moon"]
6361 ,["Delete Album", "Nuke Album"]
6362 ,["Are you sure you want to clear all your searches?", "Are you sure you want to nuke all your searches?"]
6363 ,["Remove Photo?", "Nuke Pony Pic?"]
6364 ,["Removed Group Photo", "Nuked Herd Pony Pic"]
6365 ,["Post Deleted", "Post Nuked"]
6366 ,["Remove Event", "Nuke Adventure"]
6367 ,["Delete Entry?", "Nuke Entry?"]
6368 ,["Delete Video", "Nuke Video"]
6369 ,["Delete Event", "Nuke Adventure"] // for group admin
6370 ,["Remove Profile Picture", "Nuke Journal Pony Pic"]
6371 ,["Delete Photo?", "Nuke Pony Pic?"]
6372 ,["Remove App", "Nuke Magic"]
6374 ,["Report and/or Block This Person", "Whine and/or Block This "+capitaliseFirstLetter(CURRENTSTACK
['person'])] // 0
6375 ,["Report This Photo", "Whine About This Pony Pic"]
6376 ,["Report This Event", "Whine About This Adventure"]
6377 ,["Report Conversation", "Whine About Conversation"]
6378 ,["Report as Spam?", "Whine as Spam?"]
6379 ,["Invalid Report", "Invalid Whining"]
6380 ,["Report This Page", "Whine About This Page"]
6381 ,["Report This Doc Revision", "Whine About This Doc Revision"]
6382 ,["Confirm Report", "Confirm Whining"]
6383 ,["Report This Place", "Whine About This Place"] // 64
6384 ,["Thanks For This Report", "Thanks For Whining"]
6385 ,["Send Message", "Send Friendship Report"] // social report
6386 ,["Send Messages", "Send Friendship Reports"]
6387 ,["Why don't you like these photos?", "Why don't you like these pony pics?"]
6388 ,["Photos Untagged and Messages Sent", "Pony Pics Untagged and Friendship Reports Sent"]
6389 ,["Report This Post", "Whine About This Post"] // report lists as a page
6390 ,["Report This?", "Whine About This?"]
6391 ,["Report Recommendation", "Whine About Recommendation"] // 108
6392 ,["Why don't you like this photo?", "Why don't you like this pony pic?"]
6393 ,["Report Spam or Abuse", "Whine as Spam or Abuse"] // messages
6394 ,["Report Incorrect External Link", "Whine About Incorrect External Link"] // page vertex // 87
6395 ,["Post Reported", "Whined About Post"]
6396 ,[" Report a Problem ", "Whine About a Problem"]
6397 ,["Report a Problem", "Whine About a Problem"]
6399 // report types: 5: links / 125: status / 70: group post / 86: og post
6400 ,["Is this post about you or a friend?", "Is this post about you or a "+CURRENTSTACK
.friend
+"?"]
6401 ,["Why are you reporting this Page?", "Why are you whining about this Page?"] // 23
6402 ,["Is this group about you or a friend?", "Is this herd about you or a "+CURRENTSTACK
['friend']+"?"] // 1
6403 ,["Is this comment about you or a friend?", "Is this friendship letter about you or a "+CURRENTSTACK
['friend']+"?"] // 71 / 74: page comment
6404 //,["Is this list about you or a friend?", "Is this directory about you a "+CURRENTSTACK.friend+"?"] // 92
6405 ,["Is this list about you or a friend?", "Is this list about you a "+CURRENTSTACK
.friend
+"?"] // 92
6406 ,["Is this photo about you or a friend?", "Is this pony pic about you or a "+CURRENTSTACK
['friend']+"?"] // 2
6407 ,["Is this note about you or a friend?", "Is this scroll about you or a "+CURRENTSTACK
['friend']+"?"] // 4
6408 ,["Is this video about you or a friend?", "Is this video about you or a "+CURRENTSTACK
['friend']+"?"] // 13
6409 ,["Is this event about you or a friend?", "Is this adventure about you or a "+CURRENTSTACK
['friend']+"?"] // 81
6411 ,["How to Report Posts", "How to Whine About Posts"]
6412 ,["How to Report Posts on My Timeline", "How to Whine About Posts on My Journal"]
6413 ,["How to Report the Profile Picture", "How to Whine About the Journal Pony Pic"]
6414 ,["Why are you reporting this photo?", "Why are you whining about this pony pic?"]
6415 ,["How to Report the Cover", "How to Whine About the Cover"]
6416 ,["How to Report Messages", "How to Whine About Friendship Reports"]
6417 ,["How to Report a Page", "How to Whine About a Page"]
6418 ,["How to Report a Group", "How to Whine About a Herd"]
6419 ,["How to Report an Event", "How to Whine About an Adventure"]
6420 ,["How to Report Page Posts", "How to Whine About Page Posts"]
6422 ,["New Message", "Write a Friendship Report"]
6423 ,["Forward Message", "Forward this Friendship Report"]
6424 ,["Delete This Message?", "Nuke This Friendship Report?"]
6425 ,["Message Not Sent", "Friendship Report Not Sent"]
6426 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])]
6427 ,["Add Photos", "Add Pony Pics"]
6428 ,["People in this message", capitaliseFirstLetter(CURRENTSTACK
['people'])+" in this friendship report"]
6429 ,["Message Sent", "Friendship Report Sent"]
6430 ,["Message Filtering Preferences", "Friendship Report Filtering Preferences"]
6431 ,["Don't Send Message?", "Don't Send Friendship Report?"] // webmessenger
6433 ,["Create New Group", "Create New Herd"]
6434 ,[/Create New Event
/, "Plan an Adventure"]
6435 //,["Notification Settings", "Spark Settings"]
6436 ,["Create Group Email Address", "Create Herd Email Address"]
6437 ,["Set Up Group Web and Email Address", "Set Up Herd Web and Email Address"]
6438 ,["Mute Chat?", "Mute Whinny Chat?"]
6439 ,["Add Friends to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])+" to the Herd"]
6440 ,["Add People to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])+" to the Herd"]
6441 ,["Not a member of the group", "Not a member of the herd"]
6442 ,["Invite People to Group by Email", "Invite "+capitaliseFirstLetter(CURRENTSTACK
.people
)+" to Herd by Email"]
6443 ,["Remove Group Admin", "Remove Herd Admin"]
6444 ,["Add Group Admin", "Add Herd Admin"]
6445 ,["Group Admins", "Herd Admins"]
6446 ,["Change Group Privacy?", "Change Herd Privacy?"]
6448 ,["Cancel Event?", "Cancel Adventure?"]
6449 ,["Change Event Photo", "Change Pony Pic for Adventure"]
6450 ,["Add Event Photo", "Add Adventure Pony Pic"]
6451 ,["Export Event", "Export Adventure"]
6452 ,["Edit Event Info", "Edit Adventure Info"]
6453 ,["Create Repeat Event", "Plan a Repeat Adventure"]
6454 ,["Event Invites", "Adventure Invites"]
6456 ,["Hide all recent profile changes?", "Hide all recent journal changes?"]
6457 ,["Edit your profile story settings", "Edit your journal story settings"]
6458 ,["Edit your timeline recent activity settings", "Edit your journal recent activity settings"]
6459 ,["Hide all recent likes activity?", "Hide all recent "+CURRENTSTACK
.likes
+" activity?"]
6460 ,["Edit Privacy of Likes", "Edit Privacy of "+capitaliseFirstLetter(CURRENTSTACK
.likes
)]
6462 ,["Edit News Feed Settings", "Edit Feed Bag Settings"]
6463 //,["Create New List", "Create New Directory"]
6464 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])]
6465 ,["Advanced Chat Settings", "Advanced Whinny Chat Settings"]
6466 //,["Notifications Updated", "Sparks Updated"]
6467 ,["Move photo to another album?", "Move pony pic to another album?"]
6468 ,["Group Muted", "Herd Muted"]
6469 ,["Block App?", "Block Magic?"]
6470 //,["List Notification Settings", "Directory Spark Settings"]
6471 //,["List Notification Settings", "List Spark Settings"]
6472 ,["Like This Photo?", capitaliseFirstLetter(CURRENTSTACK
['like'])+" This Pony Pic?"]
6473 ,["Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6474 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6475 ,["Suggest Friend", "Suggest "+capitaliseFirstLetter(CURRENTSTACK
.friend
)]
6476 ,["Blocked People", "Blocked "+capitaliseFirstLetter(CURRENTSTACK
.people
)]
6477 ,["Block People", "Block "+capitaliseFirstLetter(CURRENTSTACK
.people
)]
6478 ,["Tag Friends", "Tag "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6479 ,["Unable to edit Group", "Unable to edit Herd"]
6480 ,["Thanks for Inviting Your Friends", "Thanks for Inviting Your "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6481 ,["Timeline Gift Preview", "Journal Gift Preview"]
6482 ,["Friend Request Setting", "Friendship Request Setting"]
6483 ,["Invalid Question", "Invalid Query"]
6484 //,["List Subscribers", "Directory Subscribers"]
6485 ,["People Who Shared This", capitaliseFirstLetter(CURRENTSTACK
.people
)+" Who Shared This"]
6486 //,["Edit List Settings", "Edit Directory Settings"]
6487 ,["Turn Off Chat", "Turn Off Whinny Chat"]
6488 ,["Access Log", "Adventure Log"]
6489 ,["Post to Your Wall", "Post to Your Journal"]
6490 ,["About Adding Comments by Email", "About Adding Friendship Letters by Email"]
6491 ,["Find Your Friends", CURRENTSTACK
['findFriendship']]
6492 ,["Upload a profile picture", "Upload a journal pony pic"]
6493 ,["Photo Upload Failed", "Pony Pic Upload Failed"] // chat photo upload
6494 ,["Related Groups", "Related Herds"] // community page
6497 ,["Take a Profile Picture", "Take a Journal Pony Pic"]
6498 ,["Choosing Your Cover Photo", "Choosing Your Cover Pony Pic"]
6499 ,["Choose from Group Photos", "Choose from Herd Pony Pics"]
6500 ,["Group Albums", "Herd Albums"]
6501 ,["Choose From Your Photos", "Choose From Your Pony Pics"]
6502 ,["Choose from Photos", "Choose from Pony Pics"]
6503 ,["Choose Your Cover Photo", "Choose Your Cover Pony Pic"]
6504 ,["Choose from your synced photos", "Choose from your synced pony pics"]
6505 ,["Upload Your Profile Picture", "Upload Your Journal Pony Pic"] // welcome
6507 ,["Create New App", "Create New Magic"]
6508 ,["Add Test Users to other Apps", "Add Test Users to other Magic"]
6509 ,["Upload Page Tab Image", "Upload Page Tab Pony Pic"]
6511 ,["Hidden in Groups", "Hidden in Herds"] // timeline
6512 ,["Add Friends as Contributors", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+" as Contributors"] // shared albums
6513 ,[/^Invite your friends to like
/, "Invite your "+CURRENTSTACK
['friends']+" to "+CURRENTSTACK
['like']+" "] // page invite friends
6515 if (ponyData
.successText
) {
6516 dialogTitles
.push(["Success", ponyData
.successText
]);
6517 dialogTitles
.push(["Success!", ponyData
.successText
]);
6521 [/everyone/gi, "Everypony"]
6522 //,[/\bpublic\b/g, "everypony"]
6523 ,[/\bPublic\b/g, "Everypony"]
6524 ,["People you're not friends with can follow you and see only your public posts.", capitaliseFirstLetter(CURRENTSTACK
.people
)+" you're not pals with can follow you and see only your public posts."]
6525 //,["These people subscribe to the lists you're featured on", "These "+capitaliseFirstLetter(CURRENTSTACK['people'])+" subscribe to the directories you're featured on"]
6526 ,["These people subscribe to the lists you're featured on", "These "+capitaliseFirstLetter(CURRENTSTACK
['people'])+" subscribe to the lists you're featured on"]
6527 ,["Friends of anyone going to this event", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of anypony going to this adventure"]
6528 ,["Friends of guests going to this event can see and join it", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of guests going to this adventure can see and join it"]
6529 ,["Anyone can see and join this event", "Anypony can see and join this adventure"]
6530 ,["Your friends will see your comment in News Feed.", "Your "+CURRENTSTACK
['friends']+" will see your friendship letter in Feed Bag."]
6531 ,[/\bfriends in group
\b/, CURRENTSTACK
['friends']+" in herd"]
6532 ,["Your post will only be promoted to the people who like your Page and their friends", "Your post will only be promoted to the "+CURRENTSTACK
['people']+" who like your Page and their "+CURRENTSTACK
['friends']]
6533 ,["Your post will be promoted to people based on the targeting you choose below.", "Your post will be promoted to "+CURRENTSTACK
['people']+" based on the targeting you choose below."]
6534 ,["Friends and friends of anyone tagged", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" and "+CURRENTSTACK
['friends']+" of anypony tagged"]
6535 ,["Guests of this event will see the comment you write below.", "Guests of this adventure will see the friendship letter you write below."]
6536 ,[/^([0-9,]+?) other friends like
this$/, '$1 other '+CURRENTSTACK
['friends']+' '+CURRENTSTACK
['like']+' this']
6537 ,[/\bfriends of friends
\b/g
, CURRENTSTACK
['friends']+" of "+CURRENTSTACK
['friends']]
6538 ,[/\bFriends of Friends
\b/g
, capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6539 ,[/\bfriends\b/g, CURRENTSTACK
['friends']]
6540 ,[/\bFriends\b/g, capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6541 ,["Only Me", "Alone"]
6542 ,["Only me", "Alone"]
6543 ,["No One", "Alone"]
6544 ,["Only you", "Alone"]
6545 ,["Anyone tagged", "Anypony tagged"]
6546 //,[/cover photos are everypony/i, "Everypony can see your cover pony pics"]
6547 ,["Cover photos are public", "Everypony can see your cover pony pics"]
6548 ,[/any other information you made Everypony
/i
, "any other information that everypony can see"]
6549 ,["Anyone can see this Everypony comment", "Everypony can see this public friendship letter"]
6550 //,["Remember: all place ratings are Everypony.", "Remember: everypony can see all place ratings."]
6551 ,["Everypony can see posts on this Everypony page.", "Everypony can see posts on this public page."]
6552 ,["Name, profile picture, age range, gender, language, country and other public info", "Name, journal pony pic, age range, gender, language, country and other public info"]
6553 //,["Name, profile picture, age range, gender, language, country and other Everypony info", "Name, profile picture, age range, gender, language, country and other public info"]
6554 ,["This will hide you from Everypony attribution", "This will hide you from public attribution"]
6555 ,["Remember: all place ratings are public.", "Remember: everypony can see all place ratings."]
6556 ,["Shared with: Anyone who can see this page", "Shared with: Anypony who can see this page"]
6557 ,["Anyone can see the group, who's in it, and what members post.", "Anypony can see the herd, who's in it, and what members post."]
6558 ,["Anyone can see the group, who's in it and what members post.", "Anypony can see the herd, who's in it and what members post."] // English (UK)
6559 ,["Anyone can see the group and who's in it. Only members see posts.", "Anypony can see the herd and who's in it. Only members see posts."]
6560 ,["Only members see the group, who's in it, and what members post.", "Only members see the herd, who's in it, and what members post."]
6561 ,["Only members see the group, who's in it and what members post.", "Only members see the herd, who's in it and what members post."] // English (UK)
6562 ,["The number of people who have checked in to places you've helped recently", "The number of "+CURRENTSTACK
['people']+" who have checked in to places you've helped recently"]
6563 ,["People you block can still see and comment on stuff you share in groups, apps and other shared places.", capitaliseFirstLetter(CURRENTSTACK
['people'])+" you block can still see and comment on stuff you share in herds, magic and other shared places."]
6564 ,[/^Organic
Reach: ([0-9,]+?) people
\(([0-9]+?)%\)$/, 'Organic Reach: $1 '+CURRENTSTACK
['people']+' ($2%)']
6566 ,["Show comments", "Show friendship letters"]
6567 ,["Comment deleted", "Friendship letter nuked"]
6568 ,[/Comments/, "Friendship Letters"]
6569 ,[/Comment/, "Friendship Letter"]
6572 ,["Edit or Delete", "Edit or Nuke"]
6573 ,["Edit or Remove", "Edit or Nuke"]
6574 ,["Delete Post", "Nuke Post"]
6575 ,["Remove or Report", "Nuke or Whine"]
6576 ,["Report", "Whine"]
6577 ,["Report/Mark as Spam", "Whine/Mark as Spam"]
6578 ,["Report as not relevant", "Whine as not relevant"]
6579 ,["Remove Invite", "Nuke Invite"]
6580 ,["Report/Remove Tag", "Whine/Nuke Tag"]
6582 ,["Delete and Ban", "Nuke and Banish"]
6583 ,["Report Place", "Whine About Place"]
6584 ,["Delete Album", "Nuke Album"]
6586 ,["Shown on Timeline", "Shown on Journal"]
6587 ,["Allow on Timeline", "Allow on Journal"]
6588 ,["Highlighted on Timeline", "Highlighted on Journal"]
6589 ,["Allowed on Timeline", "Allowed on Journal"]
6590 ,["Hidden from Timeline", "Hidden from Journal"]
6592 //,[/likes? this/g, "brohoof'd this"]
6593 ,["Sent from chat", "Sent from whinny chat"]
6594 ,["New Message", "Write a Friendship Report"]
6596 //,[/\bpeople\b/gi, "ponies"]
6597 ,[/See who likes
this/gi
, "See who "+CURRENTSTACK
['likes']+" this"]
6598 ,[/people like
this\./gi
, CURRENTSTACK
['people']+" "+CURRENTSTACK
['like_past']+" this."] // entstream
6599 ,[/like
this\./gi
, CURRENTSTACK
['like_past']+" this."]
6600 ,[/likes
this\./gi
, CURRENTSTACK
['likes_past']+" this."]
6603 ,["Status", "Take a Note"]
6604 ,["Photo / Video", "Add a Pic"]
6605 ,["Event, Milestone +", "Adventure, Milestone +"]
6607 //,["Onsite Notifications", "Onsite Sparks"]
6608 ,["Create Event", "Plan an Adventure"]
6609 ,["Search messages in this conversation", "Search friendship reports in this conversation"]
6610 ,["Open photo viewer", "Open pony pic viewer"]
6611 ,["Choose a unique image for the cover of your timeline.", "Choose a unique pony pic for the cover of your journal."]
6612 ,["Remove from Dashboard", "Remove from Dashieboard"]
6613 ,["Choose a unique cover photo to express what your Page is about.", "Choose a unique cover pony pic to express what your Page is about."]
6615 ,["Each photo has its own privacy setting", "Each pony pic has its own privacy setting"]
6616 ,["You can change the audience for each photo in this album", "You can change the audience for each pony pic in this album"]
6618 ,["View Photo", "View Pony Pic"]
6620 // litestand navigation when collapsed
6621 ,["News Feed", "Feed Bag"]
6622 ,["Messages", "Trough"]
6623 ,["Pokes", "Nuzzles"]
6624 ,["Manage Apps", "Manage Magic"]
6625 ,["Events", "Adventures"]
6626 ,["App Center", "Magic Center"]
6627 ,["Add Friend", "Add "+capitaliseFirstLetter(CURRENTSTACK
['friend'])] // people you may know
6630 ,["Attach a Photo", "Attach a Pony Pic"]
6631 ,["Remove Photo", "Nuke Pony Pic"]
6633 ,["Dismiss and go to most recent message", "Dismiss and go to most recent friendship letter"] // messages
6634 ,["To create an offer, your Page needs at least 50 likes.", "To create an offer, your Page needs at least 50 "+CURRENTSTACK
['likes']+"."] // page composer
6635 ,["Verified profile", "Verified journal"] // verified
6636 ,["Tags help people find groups about certain topics.", "Tags help "+CURRENTSTACK
['people']+" find herds about certain topics."] // verified
6637 ,["This post is more engaging than many of your other posts. You can boost it to get more likes and comments.", "This post is more engaging than many of your other posts. You can boost it to get more "+CURRENTSTACK
['likes']+" and friendship letters."] // page admin pabel
6638 ,["Help Facebook gather feedback about News Feed. Your input is private and won't be shared.", "Help Facebook gather feedback about Feed Bag. Your input is private and won't be shared."]
6639 ,["Like", capitaliseFirstLetter(CURRENTSTACK
['like'])]
6642 ,["Enable the newsfeed ticker", "Enable the feedbag ticker"]
6643 ,["Add selected users to other apps you own.", "Add selected users to other magic you own."]
6644 ,["Remove selected users from this app.", "Remove selected users from this magic."]
6647 ,["The total number of clicks on your posts, not including likes, comments, or shares, which are broken out above.", "The total number of clicks on your posts, not including "+CURRENTSTACK
['likes']+", friendship letters, or shares, which are broken out above."]
6648 ,["The percentage of people who liked, commented, shared or clicked on your post after having seen it.", "The percentage of "+CURRENTSTACK
['people']+" who "+CURRENTSTACK
['liked']+", commented, shared or clicked on your post after having seen it."]
6649 ,["The unique number of people who liked, commented, shared or clicked on your posts", "The unique number of "+CURRENTSTACK
['people']+" who "+CURRENTSTACK
['liked']+", commented, shared or clicked on your posts"]
6651 ,["The week when the most people were talking about this Page.", "The week when the most "+CURRENTSTACK
['people']+" were talking about this Page."]
6652 ,["The city where most of the people talking about this Page are from.", "The city where most of the "+CURRENTSTACK
['people']+" talking about this Page are from."]
6653 ,["The largest age group of the people talking about this Page.", "The largest age group of the "+CURRENTSTACK
['people']+" talking about this Page."]
6654 ,["The number of photos that have this Page tagged.", "The number of pony pics that have this Page tagged."]
6655 ,["The week when the most people checked in at this Page's location.", "The week when the most "+CURRENTSTACK
['people']+" checked in at this Page's location."]
6657 if (ponyData
.loadingText
) {
6658 tooltipTitles
.push(["Loading...", ponyData
.loadingText
]);
6662 //["List Suggestions", "Directory Suggestions"]
6663 ["People You May Know", capitaliseFirstLetter(CURRENTSTACK
.people
)+" You May Know"]
6664 ,["Sponsored", "Cupcake Money"]
6665 ,["Pokes", "Nuzzles"]
6666 ,["People To Follow", capitaliseFirstLetter(CURRENTSTACK
.people
)+" To Follow"]
6667 ,["Poke Suggestions", "Nuzzle Suggestions"]
6668 ,["Suggested Groups", "Suggested Herds"]
6669 ,["Find More Friends", CURRENTSTACK
['findFriendship']]
6670 ,["Rate Recently Used Apps", "Rate Recently Used Magic"]
6671 ,["Friends' Photos", "Pals' Pony Pics"]
6672 ,["Add a Location to Your Photos", "Add a Location to Your Pony Pics"]
6673 ,["Suggest Friends", "Suggest "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6674 ,["Other Pages You Like", "Other Pages You "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
6675 ,["Entertainment Pages You Might Like", "Entertainment Pages You Might "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
6676 ,["Music Pages You Might Like", "Music Pages You Might "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
6677 ,["Add Personal Contacts as Friends", "Add Personal Contacts as "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6678 ,["Find Friends", CURRENTSTACK
['findFriendship']]
6679 //,[/On This List/, "On This Directory"]
6680 //,["On this list", "On this directory"]
6681 //,["On This List", "On This Directory"]
6682 ,["Related Groups", "Related Herds"]
6683 ,["Entertainment Pages You May Like", "Entertainment Pages You May "+capitaliseFirstLetter(CURRENTSTACK
['like'])]
6684 ,["Music Pages You May Like", "Music Pages You May "+capitaliseFirstLetter(CURRENTSTACK
['like'])]
6685 ,["No New Friend Requests", "No New Friendship Requests"] // /friends/requests/
6686 ,["Games Your Friends Are Playing", "Games Your "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+" Are Playing"]
6687 ,["Promote This Event", "Promote This Adventure"]
6688 ,["Respond to Your Friend Request", "Respond to Your Friendship Request"] // /friends/requests/
6689 ,[/^Respond to
Your ([0-9]+?) Friend Requests
$/, "Respond to Your $1 Friendship Requests"] // /friends/requests/
6690 ,["Add People You Know", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])+" You Know"]
6691 ,["Complete your profile", "Complete your journal"]
6692 ,["No Sent Friend Requests", "No Sent Friendship Requests"] // /friends/requests/
6693 ,["Friend Requests Sent", "Friendship Requests Sent"] // /friends/requests/
6695 //,["Notifications", "Sparks"]
6696 ,["New Likes", "New "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6697 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6698 ,["Get More Likes", "Get More "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6699 ,["Added Apps", "Added Magic"]
6700 ,["Apps You May Like", "Magic You May "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
6701 ,["Your Apps", "Your Magic"]
6702 ,["People Talking About This", capitaliseFirstLetter(CURRENTSTACK
.people
)+" Blabbering About This"]
6703 ,["Total Likes", "Total "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6704 ,["Games You May Like", "Games You May "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
6705 ,["Add To News Feed", "Add To Feed Bag"]
6707 ,["Messages", "Trough"]
6708 //,["Other Messages", "Other Friendship Reports"]
6709 //,["Unread Messages", "Unread Friendship Reports"]
6710 //,["Sent Messages", "Sent Friendship Reports"]
6711 //,["Archived Messages", "Archived Friendship Reports"]
6712 ,["Inbox", "Trough"]
6714 ,["Groups", "Herds"]
6715 //,["Pages and Ads", "Landmarks and Ads"]
6717 ,[/Friends who like
/gi
, capitaliseFirstLetter(CURRENTSTACK
['friends_logic'])+" who "+CURRENTSTACK
['like_past']+" "]
6718 ,["Favorites", capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6719 ,["Likes", capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6720 ,["Events", "Adventures"]
6721 ,["Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6722 ,["Ads", "Cupcakes"]
6723 ,["Mutual Likes", "Mutual "+capitaliseFirstLetter(CURRENTSTACK
.likes
)]
6724 ,[/Mutual Friends
/, "Mutual "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6726 ,["Notes", "Scrolls"]
6727 ,["My Notes", "My Scrolls"]
6728 ,["Notes About Me", "Scrolls About Me"]
6729 ,["Write a Note", "Write a Scroll"]
6730 ,["Edit Note", "Edit Scroll"]
6732 ,["Timeline and Tagging", "Journal and Tagging"]
6733 ,["Ads, Apps and Websites", "Ads, Magic and Websites"]
6734 ,["Blocked People and Apps", "Banished "+capitaliseFirstLetter(CURRENTSTACK
['people'])+" and Magic"]
6735 //,["Notifications Settings", "Sparks Settings"]
6736 ,["App Settings", "Magic Settings"]
6737 ,["Friend Requests", "Friendship Requests"]
6738 ,["People Who Shared This", capitaliseFirstLetter(CURRENTSTACK
.people
)+" Who Shared This"]
6739 //,["Your Notifications", "Your Sparks"]
6740 ,["Timeline and Tagging Settings", "Journal and Tagging Settings"]
6741 ,["Delete My Account", "Nuke My Account"]
6743 ,["Posts in Groups", "Posts in Herds"]
6744 ,["People", capitaliseFirstLetter(CURRENTSTACK
['people'])]
6746 ,["Posts by Friends", "Posts by "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
6747 ,["Support Dashboard", "Support Dashieboard"]
6748 ,["Event Invitations", "Adventure Invitations"]
6749 ,["Who Is in These Photos?", "Who Is in These Pony Pics?"]
6750 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK
.people
)+" that "+CURRENTSTACK
.like_past
+" this"]
6751 //,["List Subscribers", "Directory Subscribers"]
6752 ,["Upcoming Events", "Upcoming Adventures"]
6753 ,["Photos and Videos", "Pony Pics and Videos"]
6754 ,["People Who Are Going", capitaliseFirstLetter(CURRENTSTACK
.people
)+" Who Are Going"]
6755 //,["Would you like to opt out of this email notification?", "Would you like to opt out of this email spark?"]
6756 ,["Confirm Like", "Confirm "+capitaliseFirstLetter(CURRENTSTACK
['like'])]
6758 ,["Invite Friends You Email", "Invite "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+" You Email "]
6759 ,["Invite Your Friends", "Invite Your "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6761 ,["Account Groups", "Account Herds"]
6762 //,["Ads Email Notifications", "Ads Email Sparks"]
6763 //,["Ads Notifications on Facebook", "Ads Sparks on Facebook"]
6765 ,["App Restrictions", "Magic Restrictions"]
6766 ,["App Info", "Magic Info"]
6768 ,["Tagged Photos", "Tagged Pony Pics"]
6770 ,["Add Groups", "Add Herds"] // /addgroup
6771 ,["Photos", "Pony Pics"] // /media/video/
6772 ,["Post to Your Wall", "Post to Your Stall"]
6773 ,["Set Your Profile Picture", "Set Your Journal Pony Pic"] // page nux
6774 ,["Suggested Pokes", "Suggested Nuzzles"]
6776 ,["Timeline Review", "Journal Review"]
6777 ,["Photos of You", "Pony Pics of You"]
6778 ,["Your Photos", "Your Pony Pics"]
6779 ,["Comments", "Friendship Letters"]
6780 ,["Questions", "Queries"]
6781 ,["All Apps", "All Magic"]
6785 ["Everyone", "Everypony"]
6786 ,["Everybody", "Everypony"]
6787 ,["Public", "Everypony"]
6788 ,["Anyone", "Anypony"]
6789 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6790 ,["Friends except Acquaintances", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" except Acquaintances"]
6791 ,["Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6792 ,["Friends ", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6793 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Guests"]
6794 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Contributors"]
6795 ,["Only Me", "Alone"]
6796 ,["Only me", "Alone"]
6797 ,["No One", "Alone"]
6798 ,["Nobody", "Nopony"]
6799 //,["See all lists...", "See entire directory..."]
6801 ,["Mutual Friends", "Mutual "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6802 ,["People You May Know", "Ponies You May Know"]
6803 ,["Poke...", "Nuzzle..."]
6805 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
6806 ,["All friends", "All "+CURRENTSTACK
['friends']]
6808 ,["On your own timeline", "On your own journal"]
6809 ,["On a friend's timeline", "On a "+CURRENTSTACK
['friend']+"'s journal"]
6810 ,["In a group", "In a herd"]
6811 ,["In a private Message", "In a private Friendship Report"]
6813 ,["Friends' Posts", capitaliseFirstLetter(CURRENTSTACK
['friends'])+"' Posts"]
6814 ,["Friend Activity", capitaliseFirstLetter(CURRENTSTACK
['friend'])+" Activity"]
6816 ,["Change Date...", "Time Travel..."]
6817 ,["Reposition Photo...", "Reposition Pony Pic..."]
6818 //,["Manage Notifications", "Manage Sparks"]
6819 ,["Use Activity Log", "Use Adventure Log"]
6820 ,["See Banned Users...", "See Ponies who were Banished to the Moon..."]
6821 ,["Invite Friends...", "Invite "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+"..."]
6822 ,["Like As Your Page...", capitaliseFirstLetter(CURRENTSTACK
.like
)+" As Your Page..."]
6823 ,["Add App to Page", "Add Magic to Page"]
6824 ,["Change Primary Photo", "Change Primary Pony Pic"]
6825 ,["Change Date", "Time Travel"]
6827 ,["People", capitaliseFirstLetter(CURRENTSTACK
['people'])]
6828 //,["Pages", "Landmarks"]
6829 ,["Banned", "Banished to Moon"]
6830 ,["Blocked", "Banished to Moon"]
6831 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK
.people
)+" who "+CURRENTSTACK
.like_past
+" this"]
6832 ,["Pages that like this", "Pages that "+CURRENTSTACK
.like_past
+" this"]
6834 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK
['unlike'])]
6835 ,["Unlike...", capitaliseFirstLetter(CURRENTSTACK
['unlike'])+"..."]
6836 ,["Show in News Feed", "Show in Feed Bag"]
6837 ,["Suggest Friends...", "Suggest "+capitaliseFirstLetter(CURRENTSTACK
['friends'])+"..."]
6838 ,["Unfriend...", "Banish to Moon..."]
6839 ,["Unfriend", "Banish to Moon"]
6840 //,["New List...", "New Directory..."]
6841 //,["Get Notifications", "Get Sparks"]
6842 //,["Add to another list...", "Add to another directory..."]
6844 ,["Create Event", "Plan an Adventure"]
6845 ,["Edit Group", "Edit Herd"]
6846 ,["Report Group", "Whine about Herd"]
6847 ,["Leave Group", "Leave Herd"]
6848 ,["Edit Group Settings", "Edit Herd Settings"]
6849 ,["Choose from Group Photos", "Choose from Herd Pony Pics"]
6850 ,["Upload a Photo", "Upload a Pony Pic"]
6851 ,["Remove from Group", "Banish to Moon"]
6852 ,["Share Group", "Share Herd"]
6853 ,["Create Group", "Create Herd"]
6854 ,["Change group settings", "Change herd settings"]
6855 ,["Add People to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])+" to the Herd"]
6856 ,["Send Message", "Send Friendship Report"]
6857 ,["View Group", "View Herd"]
6858 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])]
6860 ,["Remove App", "Remove Magic"]
6861 ,["Uninstall App", "Uninstall Magic"]
6862 ,["Report App", "Whine about Magic"]
6863 ,["Block App", "Block Magic"]
6864 ,["Find More Apps", "Find More Magic"]
6865 ,["No more apps to add.", "No more magic to add."]
6867 ,["Delete Post And Remove User", "Nuke Post And Banish to Moon"]
6868 ,["Delete Post And Ban User", "Nuke Post And Banish to Moon"]
6869 ,["Hide from Timeline", "Hide from Journal"]
6871 ,["Delete...", "Nuke..."]
6872 ,["Delete Photo", "Nuke Pony Pic..."]
6873 ,["Delete This Photo", "Nuke This Pony Pic"]
6874 ,["Delete Messages...", "Nuke Friendship Reports..."]
6875 ,["Delete Post", "Nuke Post"]
6876 ,["Delete Comment", "Nuke Friendship Letter..."]
6877 ,["Show on Timeline", "Show on Journal"]
6878 ,["Show on Profile", "Show on Journal"]
6879 ,["Shown on Timeline", "Shown on Journal"]
6880 ,["Allow on Timeline", "Allow on Journal"]
6881 ,["Highlighted on Timeline", "Highlighted on Journal"]
6882 ,["Allowed on Timeline", "Allowed on Journal"]
6883 ,["Hidden from Timeline", "Hidden from Journal"]
6885 ,["Delete Photo...", "Nuke Pony Pic..."]
6886 ,["Remove this photo", "Nuke this pony pic"]
6887 ,["Remove photo", "Nuke pony pic"]
6888 ,["Remove...", "Nuke..."]
6889 ,["Delete Conversation...", "Nuke Conversation..."]
6890 ,["Delete Album", "Nuke Album"]
6891 ,["Delete Comment...", "Nuke Friendship Letter..."]
6892 ,["Hide Comment...", "Hide Friendship Letter..."]
6893 ,["Hide Event", "Hide Adventure"]
6894 ,["Hide Comment", "Hide Friendship Letter"]
6895 ,["Delete Post...", "Nuke Post..."]
6896 ,["Delete Video", "Nuke Video"]
6897 ,["Delete Event", "Nuke Adventure"] // for group admin
6899 ,["Report/Block...", "Whine/Block..."]
6900 ,["Report/Mark as Spam", "Whine/Mark as Spam"]
6901 ,["Report Page", "Whine about Page"]
6902 ,["Report Story or Spam", "Whine about Story or Spam"]
6903 ,["Report/Mark as Spam...", "Whine/Mark as Spam..."]
6904 ,["Report story...", "Whine about story..."]
6905 ,["Report as Spam or Abuse...", "Whine as Spam or Abuse..."]
6906 ,["Report Spam or Abuse...", "Whine as Spam or Abuse..."]
6907 ,["Report as Spam...", "Whine as Spam..."]
6908 ,["Report Conversation...", "Whine about Conversation..."]
6909 ,["Report This Photo", "Whine About This Pony Pic"]
6910 ,["Report/Remove Tag", "Whine/Nuke Tag"]
6911 ,["Mark as Spam", "Whine as Spam"]
6912 ,["Report/Remove Tag...", "Whine/Nuke Tag..."]
6913 ,["Report Content", "Whine about Content"]
6914 ,["Report Profile", "Whine about Journal"]
6915 ,["Report User", "Whine about This Pony"]
6916 ,["Report", "Whine"]
6917 ,["Report Place", "Whine about Place"]
6918 ,["Report App", "Whine about Magic"]
6919 //,["Report list", "Whine about directory"]
6920 ,["Report list", "Whine about list"]
6921 ,["Event at a place", "Adventure at a place"]
6922 ,["Report as Abuse", "Whine as Abuse"]
6923 ,["Report to Admin", "Whine to Admin"]
6925 ,["Hide this recent activity story from Timeline", "Hide this recent activity story from Journal"]
6926 ,["Hide Similar Activity from Timeline...", "Hide Similar Activity from Journal..."]
6927 //,["Hide All Recent Lists from Timeline...", "Hide All Recent Directories from Journal..."]
6928 ,["Hide All Recent Lists from Timeline...", "Hide All Recent Lists from Journal..."]
6929 ,["Hide all Friend Highlights from Timeline", "Hide all "+capitaliseFirstLetter(CURRENTSTACK
.friend
)+" Highlights from Journal"]
6930 ,["Hide This Action from Profile...", "Hide This Action from Journal..."]
6931 ,["Hide All Recent profile changes from Profile...", "Hide All Recent journal changes from Journal..."]
6932 ,["Hide All Recent Pages from Timeline...", "Hide All Recent Pages from Journal..."]
6933 ,["See Photos Hidden From Timeline", "See Pony Pics Hidden From Journal"]
6934 ,["Hide Similar Activity from Timeline", "Hide Similar Activity from Journal"]
6936 ,["Upcoming Events", "Upcoming Adventures"]
6937 ,["Suggested Events", "Suggested Adventures"]
6938 ,["Past Events", "Past Adventures"]
6939 ,["Past events", "Past adventures"]
6940 ,["Declined Events", "Declined Adventures"]
6941 ,["Export Events...", "Export Adventures..."]
6942 ,["Add Event Photo", "Add Adventure Pony Pic"]
6943 ,["Cancel Event", "Cancel Adventure"]
6944 ,["Export Event", "Export Adventure"]
6945 ,["Share Event", "Share Adventure"]
6946 //,["Turn Off Notifications", "Turn Off Sparks"]
6947 //,["Turn On Notifications", "Turn On Sparks"]
6948 ,["Promote Event", "Promote Adventure"]
6949 ,["Create Repeat Event", "Create Repeat Adventure"]
6950 ,["Message Guests", "Start Whinny Chat with Guests"]
6951 ,["Edit Event", "Edit Adventure"]
6952 ,["Publish Event on Timeline", "Publish Adventure on Journal"]
6953 ,["Leave Event", "Leave Adventure"]
6955 ,["Add Friends to Chat...", "Add "+capitaliseFirstLetter(CURRENTSTACK
.friends
)+" to Whinny Chat..."]
6956 ,["Chat Sounds", "Whinny Chat Sounds"]
6957 ,["Add People...", "Add "+capitaliseFirstLetter(CURRENTSTACK
['people'])+"..."]
6958 ,["Unread Messages", "Unread Friendship Reports"]
6959 ,["Archived Messages", "Archived Friendship Reports"]
6960 ,["Sent Messages", "Sent Friendship Reports"]
6961 ,["Forward Messages...", "Forward Friendship Reports..."]
6962 ,["Turn Off Chat", "Turn Off Whinny Chat"]
6963 ,["Open in Chat", "Open in Whinny Chat"]
6964 ,["Create Group...", "Create Herd..."]
6965 ,["Turn On Chat", "Turn On Whinny Chat"]
6967 ,["Add/Remove Friends...", "Add/Remove "+capitaliseFirstLetter(CURRENTSTACK
.friends
)+"..."]
6968 ,["Comments and Likes", "Friendship Letters and Brohoofs"]
6969 //,["Archive List", "Archive Directory"]
6970 //,["On This List", "On This Directory"]
6971 //,["Restore List", "Restore Directory"]
6973 //,["Rename List", "Rename Directory"]
6974 //,["Edit List", "Edit Directory"]
6975 //,["Notification Settings...", "Spark Settings..."]
6976 //,["Delete List", "Nuke Directory"]
6977 ,["Delete List", "Nuke List"]
6979 ,["Likes", capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6980 ,["Photos", "Pony Pics"]
6981 ,["Comments", "Friendship Letters"]
6982 ,["Questions", "Queries"]
6983 ,["Events", "Adventures"]
6984 ,["Groups", "Herds"]
6985 ,["Timeline", "Journal"]
6986 ,["Notes", "Scrolls"]
6987 ,["Posts and Apps", "Posts and Magic"]
6988 ,["Recent Likes", "Recent "+capitaliseFirstLetter(CURRENTSTACK
['likes'])]
6989 ,["Recent Comments", "Recent Friendship Letters"]
6990 ,["Timeline Review", "Journal Review"]
6991 ,["Pokes", "Nuzzles"]
6992 ,["Activity Log...", "Adventure Log..."]
6993 ,["Activity Log", "Adventure Log"]
6994 ,["Timeline Settings", "Journal Settings"]
6995 ,["Likers", "Brohoofers"] // @todo likers
6996 ,["Open Groups", "Open Herds"]
6997 ,["Cancel Friend Request", "Cancel Friendship Request"] // activity log
6999 ,["Choose from Photos...", "Choose from Pony Pics..."]
7000 ,["Upload Photo...", "Upload Pony Pic..."]
7001 ,["Take Photo...", "Take Pony Pic..."]
7002 ,["Choose from my Photos", "Choose from my Pony Pics"]
7003 ,["Reposition Photo", "Reposition Pony Pic"]
7004 ,["Add Synced Photo...", "Add Synced Pony Pic..."]
7005 ,["Add Synced Photo", "Add Synced Pony Pic"]
7006 ,["Change Primary Photo...", "Change Primary Pony Pic..."]
7007 ,["Choose from Photo Albums...", "Choose from Pony Pic Albums..."]
7008 ,["Suggest this photo...", "Suggest this pony pic..."]
7010 ,["Photo", "Pony Pic"]
7011 ,["Question", "Query"]
7013 ,["Pages I like", "Pages I "+capitaliseFirstLetter(CURRENTSTACK
.like
)]
7014 ,["My Friends", "My "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
7015 //,["All Notifications", "All Sparks"]
7016 ,["Search All Friends", "Search All "+capitaliseFirstLetter(CURRENTSTACK
.friends
)]
7017 ,["All Apps", "All Magic"]
7018 ,["Pages my friends like", "Pages my "+CURRENTSTACK
['friends']+" "+CURRENTSTACK
['like']]
7020 ,["Page Likes", "Page "+capitaliseFirstLetter(CURRENTSTACK
.likes
)]
7021 ,["Mentions and Photo Tags", "Mentions and Pony Pic Tags"]
7023 ,["Suggest photos", "Suggest pony pics"]
7025 ,["Make Profile Picture", "Make Journal Pony Pic"]
7026 ,["Make Profile Picture for Page", "Make Journal Pony Pic for Page"]
7027 ,["Make Cover Photo", "Make Cover Pony Pic"]
7029 //,["The app sends you a notification", "The magic sends you a spark"]
7030 ,["The app sends you a notification", "The magic sends you a notification"]
7032 ,["Top Comments", "Top Friendship Letters"] // comment resort
7033 ,["See All Groups", "See All Herds"] // timeline
7034 ,["Friends to Invite", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" to Invite"] // app invite
7035 ,["Take a survey to improve News Feed", "Take a survey to improve Feed Bag"] // news feed
7038 ,["Post Clicks / Likes, Comments & Shares", "Post Clicks / "+capitaliseFirstLetter(CURRENTSTACK
['likes'])+", Comments & Shares"]
7039 ,["Likes / Comments / Shares", capitaliseFirstLetter(CURRENTSTACK
['likes'])+" / Comments / Shares"]
7040 ,["Post Hides, Hides of All Posts, Reports of Spam, Unlikes of Page", "Post Hides, Hides of All Posts, Whining of Spam, Unbrohoofs of Page"] // @todo
7041 ,["Likes, Comments & Shares", capitaliseFirstLetter(CURRENTSTACK
['likes'])+", Comments & Shares"]
7044 menuPrivacyOnlyTitles
= [
7045 ["Everyone", "Everypony"]
7046 ,["Public", "Everypony"]
7047 ,["Anyone", "Anypony"]
7048 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK
['friends'])]
7049 ,["Friends except Acquaintances", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" except Acquaintances"]
7050 ,["Friends", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
7051 ,["Friends ", capitaliseFirstLetter(CURRENTSTACK
['friends'])]
7052 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Guests"]
7053 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK
['friends'])+" of Contributors"]
7054 ,["Only Me", "Alone"]
7055 ,["Only me", "Alone"]
7056 //,["See all lists...", "See entire directory..."]
7059 dialogDerpTitles
= [
7060 "Insufficient send permissions"
7062 ,"Failed to upload photo."
7063 ,"Hide Photo Failed"
7064 ,"Undo Mark Spam Failed"
7065 ,"Your Request Couldn't be Processed"
7066 ,"Sorry! The blocking system is overloaded"
7068 ,"Block! You are engaging in behavior that may be considered annoying or abusive by other users."
7069 ,"Already connected."
7072 ,"Failure to hide minifeed story."
7073 ,"Object cannot be liked"
7074 ,"Sorry, something went wrong"
7075 ,"Authentication Failure"
7078 ,"No Permission to Add Comment or Trying to Comment on Deleted Post"
7079 ,"Could not determine coordinates of place"
7080 ,"Sorry, your account is temporarily unavailable."
7081 ,"Don't Have Permission"
7083 ,"No Languages Provided ForUpdate"
7084 ,"Comment Does Not Exist"
7085 ,"Sorry, we got confused"
7086 ,"Database Write Failed"
7087 ,"Editing Bookmarks Failed"
7088 ,"Required Field Missing"
7089 ,"Could Not Load Story"
7091 ,"Cannot connect to yourself."
7092 ,"This content is no longer available"
7093 ,"Error" // poking someone who hasn't poked back yet
7094 ,"Please Try Again Later"
7095 ,"Submitting Documentation Feedback Failed"
7098 ,"Mark as Spam Failed"
7099 ,"Could not post to Wall"
7101 ,"Messages Unavailable"
7102 ,"Don't have Permission"
7103 ,"No file specified."
7106 ,"Vote submission failed."
7107 ,"Web Address is Invalid"
7109 ,"Invalid Recipients"
7110 ,"Add Fan Status Failed"
7111 ,"Adding Member Failed"
7112 ,"Post Has Been Removed"
7113 ,"Unable to edit Group"
7114 ,"Invalid Photo Selected"
7115 ,"Cannot backdate photo"
7116 ,"Invalid Search Query"
7117 ,"Unable to Add Friend"
7118 ,"Cannot Add Member"
7121 ,"Invalid Custom Privacy Setting"
7122 ,"Empty Friend List"
7123 ,"Unable to Add Attachment"
7124 ,"Unable to Change Date"
7126 ,"Your Page Can't Be Promoted"
7128 ,"An error occurred."
7129 ,"Image Resource Invalid"
7130 ,"Confirmation Required"
7131 ,"Error Uploading Video"
7133 ,"Photo Upload Failed"
7135 ,"Could Not Post to Timeline"
7138 headerInsightsTitles
= [
7139 ["People Who Like Your Page (Demographics and Location)", capitaliseFirstLetter(CURRENTSTACK
.people
)+" Who "+capitaliseFirstLetter(CURRENTSTACK
.like
)+" Your Page (Demographics and Location)"]
7140 ,["Where Your Likes Came From", "Where Your "+capitaliseFirstLetter(CURRENTSTACK
.likes
)+" Came From"]
7141 ,["How You Reached People (Reach and Frequency)", "How You Reached "+capitaliseFirstLetter(CURRENTSTACK
.people
)+" (Reach and Frequency)"]
7142 ,["How People Are Talking About Your Page", "How "+capitaliseFirstLetter(CURRENTSTACK
.people
)+" Are Talking About Your Page"]
7145 dialogDescriptionTitles
= [
7146 ["Are you sure you want to delete this?", "Are you sure you want to nuke this?"]
7147 ,["Are you sure you want to delete this video?", "Are you sure you want to nuke this video?"]
7148 ,["Are you sure you want to delete this photo?", "Are you sure you want to nuke this pony pic?"]
7149 ,["Are you sure you want to delete this comment?", "Are you sure you want to nuke this friendship letter?"]
7150 ,["Are you sure you want to delete this event?", "Are you sure you want to nuke this adventure?"]
7151 ,["Are you sure you want to delete this post?", "Are you sure you want to nuke this post?"]
7152 ,["Are you sure you want to remove this picture?", "Are you sure you want to nuke this pony pic?"]
7153 ,["The post or object that you were commenting has been removed by its owner and can no longer be commented on.", "The post or object that you were commenting has been nuked by its owner and can no longer be commented on."]
7154 ,["Are you sure you want to remove this event?", "Are you sure you want to nuke this adventure?"]
7155 ,["Are you sure you want to unlike this?", "Are you sure you want to "+CURRENTSTACK
['unlike']+" this?"]
7156 ,["Are you sure you want to remove this profile picture?", "Are you sure you want to nuke this journal pony pic?"]
7157 ,["Are you sure you want to remove this application?", "Are you sure you want to nuke this magic?"]
7159 ,["Report this if it's not relevant to your search results.", "Whine about this if it's not relevant to your search results."]
7161 ,["Uploading a photo will remove the link preview. Do you want to continue?", "Uploading a pony pic will remove the link preview. Do you want to continue?"]
7162 ,["This post has been reported to the group admin.", "This post has been whined to the group admin."]
7164 ,["You must select some messages to delete. Click on a message to select it.", "You must select some friendship reports to nuke. Click on a friendship report to select it."]
7165 ,["You have not uploaded a picture.", "You have not uploaded a pony pic."]
7166 ,["Please try again. Make sure you are uploading a valid photo.", "Please try again. Make sure you are uploading a valid pony pic."]
7167 ,["There was a problem uploading the image file.", "There was a problem uploading the pony pic file."]
7168 ,["If you leave this page, your message won't be sent.", "If you leave this page, your friendship report won't be sent."]
7172 var DOMNodeInserted = function(dom
) {
7173 domNodeHandlerMain
.run(dom
);
7176 var domNodeHandler = function() {
7178 k
.snowliftPinkieInjected
= false;
7180 k
.run = function(dom
) {
7181 if (INTERNALUPDATE
) {
7185 if (k
.shouldIgnore(dom
)) {
7191 // Start internal update
7192 var iu
= INTERNALUPDATE
;
7193 INTERNALUPDATE
= true;
7196 if (dom
.target
.parentNode
&& dom
.target
.parentNode
.parentNode
) {
7198 var replacer
= buttonTitles
;
7199 if (hasClass(dom
.target
.parentNode
, 'uiButtonText')) {
7200 var buttonText
= dom
.target
.parentNode
;
7201 var button
= dom
.target
.parentNode
.parentNode
;
7204 if (button
.parentNode
&& button
.parentNode
.parentNode
&& hasClass(button
.parentNode
.parentNode
, 'audienceSelector')) {
7205 replacer
= menuPrivacyOnlyTitles
;
7207 } else if (hasClass(dom
.target
.parentNode
, '_42ft') || hasClass(dom
.target
.parentNode
, '-cx-PRIVATE-abstractButton__root')) {
7208 // dropdown on close friends list dialog
7209 // <a class="-cx-PRIVATE-abstractButton__root -cx-PRIVATE-uiButton__root -cx-PRIVATE-uiPopoverButton__root autofocus -cx-PRIVATE-uiPopover__trigger" role="button" href="#" style="max-width: 200px;" aria-haspopup="true" aria-expanded="true" rel="toggle" id="u_i_b" aria-owns="u_i_9">On This List<i class="mls img sp_8noqk7 sx_706bf4"></i></a>
7210 var buttonText
= dom
.target
;
7211 var button
= dom
.target
.parentNode
;
7213 } else if (hasClass(dom
.target
.parentNode
.parentNode
, '_42ft') || hasClass(dom
.target
.parentNode
.parentNode
, '-cx-PRIVATE-abstractButton__root')) {
7214 // hasClass(buttonText, '_55pe') || hasClass(buttonText, '-cx-PUBLIC-abstractPopoverButton__label')
7215 // "share to" dropdown on sharer dialog
7216 // comment resort on entstream
7217 var buttonText
= dom
.target
;
7218 var button
= dom
.target
.parentNode
.parentNode
;
7223 if (buttonText
.nodeType
== 3) {
7224 var orig
= buttonText
.textContent
;
7226 var orig
= buttonText
.innerHTML
;
7228 var replaced
= replaceText(replacer
, orig
);
7229 if (hasClass(button
, 'uiButton') || hasClass(button
, '_42ft') || hasClass(button
, '-cx-PRIVATE-abstractButton__root')) {
7230 // button text that didn't get ponified needs to be considered, e.g. share dialog's "On your Page"
7231 if (button
.getAttribute('data-hover') != 'tooltip') {
7232 if (orig
!= replaced
) {
7234 if (button
.title
== '') {
7235 // tooltip is blank, so it would be OK to set our own
7236 button
.title
= orig
;
7238 // tooltip is NOT blank, this means (1) FB added their own tooltip or (2) we already added our own tooltip
7239 if (button
.title
== button
.getAttribute('data-ponyhoof-button-orig')) {
7240 button
.title
= orig
;
7247 button
.setAttribute('data-ponyhoof-button-orig', orig
);
7248 button
.setAttribute('data-ponyhoof-button-text', replaced
);
7250 if (orig
!= replaced
) {
7251 if (buttonText
.nodeType
== 3) {
7252 buttonText
.textContent
= replaced
;
7254 buttonText
.innerHTML
= replaced
;
7261 if (dom
.target
.nodeType
== 3) {
7263 // firefox in mutationObserver goes to here when it should be characterData
7264 k
.mutateCharacterData(dom
);
7265 INTERNALUPDATE
= iu
;
7269 injectOptionsLink();
7271 k
.snowliftPinkie(dom
);
7272 k
.notificationsFlyoutSettings();
7275 if (k
.fbPhotoSubscribeWrapper(dom
.target
)) {
7276 INTERNALUPDATE
= iu
;
7280 // .ufb-button-input => mutateAttributes
7281 // ._42fu, .-cx-PRIVATE-uiButton__root, ._4jy0, .-cx-PRIVATE-xuiButton__root
7282 domReplaceFunc(dom
.target
, '', '.uiButtonText, .uiButton input, ._42ft, .-cx-PRIVATE-abstractButton__root', function(ele
) {
7283 // <a class="uiButton uiButtonConfirm uiButtonLarge" href="#" role="button"><span class="uiButtonText">Finish</span></a>
7284 // <label class="uiButton uiButtonConfirm"><input value="Okay" type="submit"></label>
7286 // <button class="_42ft _42fu _11b selected _42g-" type="submit">Post</button>
7287 // <a class="_42ft _42fu" role="button" href="#"><i class="mrs img sp_8jfoef sx_d2d7c4"></i>Promote App</a>
7290 if (hasClass(ele
, '_50zy') || hasClass(ele
, '-cx-PRIVATE-xuiCloseButton__root')) {
7295 var replacer
= buttonTitles
;
7296 var tagName
= ele
.tagName
.toUpperCase();
7297 if (tagName
!= 'A' && tagName
!= 'LABEL' && tagName
!= 'BUTTON') {
7298 button
= ele
.parentNode
;
7301 var potentialLabel
= button
.querySelector('._6q-, .-cx-PUBLIC-mercuryComposer__button');
7302 if (potentialLabel
) {
7303 ele
= potentialLabel
;
7306 var potentialLabel
= button
.querySelector('._55pe, .-cx-PUBLIC-abstractPopoverButton__label');
7307 if (potentialLabel
) {
7308 ele
= potentialLabel
;
7310 // Get More Likes button on page admin panel
7311 // <button value="1" class="_42ft _42fu selected _42g- _42gy" id="fanAcquisitionPanelPreviewBodyConfirmButton" type="submit"><span id="u_x_a">Get More Likes</span></button>
7313 // Get More Likes (above)
7314 // comment resort on entstream
7315 if (ele
.childNodes
&& ele
.childNodes
.length
== 1 && ele
.childNodes
[0].tagName
&& ele
.childNodes
[0].tagName
.toUpperCase() == 'SPAN') {
7316 ele
= ele
.childNodes
[0];
7320 (button
.getAttribute('data-ponyhoof-button-orig') == null || (hasClass(button
, '_for') || hasClass(button
, '-cx-PRIVATE-fbVaultBadgedButton__button'))) && // vault buttons are crapped
7321 (hasClass(button
, 'uiButton') || hasClass(button
, '_42ft') || hasClass(button
, '-cx-PRIVATE-abstractButton__root') /*|| hasClass(button, '_42fu') || hasClass(button, '-cx-PRIVATE-uiButton__root') || hasClass(button, '_4jy0') || hasClass(button, '-cx-PRIVATE-xuiButton__root')*/)
7323 if (button
.parentNode
&& button
.parentNode
.parentNode
&& hasClass(button
.parentNode
.parentNode
, 'audienceSelector')) {
7324 replacer
= menuPrivacyOnlyTitles
;
7327 if (tagName
== 'INPUT') {
7328 var orig
= ele
.value
;
7329 button
.setAttribute('data-ponyhoof-button-orig', orig
);
7330 var replaced
= replaceText(replacer
, orig
);
7332 k
.changeButtonText(ele
, replaced
);
7336 loopChildText(ele
, function(child
) {
7337 if (child
.nodeType
== 3) {
7338 orig
+= child
.textContent
;
7339 replaced
+= replaceText(replacer
, child
.textContent
);
7340 if (child
.textContent
!= replaced
) {
7341 child
.textContent
= replaced
;
7345 button
.setAttribute('data-ponyhoof-button-orig', orig
);
7348 if (orig
!= replaced
) {
7349 if (button
.getAttribute('data-hover') != 'tooltip') {
7350 if (button
.title
== '') {
7351 button
.title
= orig
;
7355 button
.setAttribute('data-ponyhoof-button-text', replaced
);
7357 // Top-right "Join Group" and "Notifications" link on groups requires some treatment to avoid long group names from being crapped
7358 var ajaxify
= button
.getAttribute('ajaxify');
7359 if ((ajaxify
&& ajaxify
.indexOf('/ajax/groups/membership/r2j.php?ref=group_jump_header') == 0) || (button
.parentNode
&& button
.parentNode
.parentNode
&& hasClass(button
.parentNode
.parentNode
, 'groupNotificationsSelector'))) {
7360 var groupsJumpTitle
= $('groupsJumpTitle');
7361 if (!groupsJumpTitle
) {
7365 var groupsJumpBarTop
= dom
.target
.getElementsByClassName('groupsJumpBarTop');
7366 if (!groupsJumpBarTop
.length
) {
7369 groupsJumpBarTop
= groupsJumpBarTop
[0];
7371 var rfloat
= groupsJumpBarTop
.getElementsByClassName('rfloat');
7372 if (!rfloat
.length
) {
7377 var groupsCleanLinks
= groupsJumpBarTop
.getElementsByClassName('groupsCleanLinks');
7378 if (!groupsCleanLinks
.length
) {
7381 groupsCleanLinks
= groupsCleanLinks
[0];
7383 groupsJumpTitle
.style
.maxWidth
= (800 - ((groupsCleanLinks
.offsetWidth
|| 0) + (rfloat
.offsetWidth
|| 0) - (groupsJumpTitle
.offsetWidth
|| 0)) - 10) + 'px';
7389 k
.ufiPagerLink(dom
);
7391 if (k
.reactRoot(dom
)) {
7392 INTERNALUPDATE
= iu
;
7398 if (k
.ticker(dom
) || k
.pagesVoiceBarText(dom
.target
) || k
.endOfFeedPymlContainer(dom
.target
) || k
.pubcontentFeedChaining(dom
.target
)) {
7399 INTERNALUPDATE
= iu
;
7403 domReplaceFunc(dom
.target
, '', '.inCommonSectionList, #fbTimelineHeadline .name h2 > div, ._8yb, .-cx-PRIVATE-fbEntstreamAttachmentAvatar__secondarydetaillist, ._508a, .-cx-PRIVATE-pageLikeStory__fancountfooter, .permalinkHeaderInfo > .subscribeOrLikeSentence > .fwn, ._5j2m, ._7ll .pageByline, ._5cnt > .fcg, ._5h4h > .fcg, ._5bxn, ._5l2i', k
.textBrohoof
);
7405 domReplaceFunc(dom
.target
, '', '.uiUfiViewAll, .uiUfiViewPrevious, .uiUfiViewMore', function(ele
) {
7406 var button
= ele
.querySelector('input[type="submit"]');
7407 var t
= button
.value
;
7408 t
= t
.replace(/comments/g, "friendship letters");
7409 t
= t
.replace(/comment/g, "friendship letter");
7410 if (button
.value
!= t
) {
7415 k
.tooltip(dom
.target
);
7417 domReplaceFunc(dom
.target
, 'egoProfileTemplate', '.egoProfileTemplate', function(ele
) {
7418 if (ele
.getAttribute('data-ponyhoof-ponified')) {
7421 var div
= ele
.getElementsByTagName('div');
7423 for (var i
= 0, len
= div
.length
; i
< len
; i
+= 1) {
7424 var t
= div
[i
].innerHTML
;
7425 t
= k
.textStandard(t
);
7426 if (div
[i
].innerHTML
!= t
) {
7427 div
[i
].innerHTML
= t
;
7432 var action
= ele
.getElementsByClassName('uiIconText');
7433 if (action
.length
) {
7435 ele
.setAttribute('data-ponyhoof-iconText', action
.textContent
);
7437 var t
= action
.innerHTML
;
7438 t
= t
.replace(/Like/g, capitaliseFirstLetter(CURRENTSTACK
.like
));
7439 t
= t
.replace(/Join Group
/g
, "Join the Herd");
7440 t
= t
.replace(/Add Friend
/g
, "Add "+capitaliseFirstLetter(CURRENTSTACK
.friend
));
7441 t
= t
.replace(/\bConfirm Friend
\b/g
, "Confirm Friendship");
7442 action
.innerHTML
= t
;
7445 ele
.setAttribute('data-ponyhoof-ponified', 1);
7448 domReplaceFunc(dom
.target
, 'uiInterstitial', '.uiInterstitial', function(ele
) {
7449 if (ele
.getAttribute('data-ponyhoof-ponified')) {
7452 ele
.setAttribute('data-ponyhoof-ponified', 1);
7454 var title
= ele
.getElementsByClassName('uiHeaderTitle');
7458 title
= ele
.querySelector('.fsxl.fwb');
7463 ele
.setAttribute('data-ponyhoof-inters-title', title
.textContent
);
7466 domReplaceFunc(dom
.target
, 'uiLayer', '.uiLayer', function(ele
) {
7467 if (ele
.getAttribute('data-ponyhoof-dialog-title')) {
7471 var titlebar
= ele
.querySelector('.-cx-PUBLIC-uiDialog__title, ._t ._1yw, ._4-i0, .-cx-PRIVATE-xuiDialog__title, .overlayTitle, .fbCalendarOverlayHeader');
7473 var titletext
= ele
.querySelector('._52c9, .-cx-PRIVATE-xuiDialog__titletext');
7475 titletext
= titlebar
;
7480 loopChildText(titletext
, function(child
) {
7481 if (child
.nodeType
== 3) {
7482 orig
+= child
.textContent
;
7483 replaced
+= replaceText(dialogTitles
, child
.textContent
);
7484 if (child
.textContent
!= replaced
) {
7485 child
.textContent
= replaced
;
7489 addClass(titlebar
, 'ponyhoof_fbdialog_title');
7490 if (orig
!= replaced
) {
7491 titlebar
.title
= orig
;
7494 addClass(ele
, 'ponyhoof_fbdialog');
7495 ele
.setAttribute('data-ponyhoof-dialog-title', replaced
);
7496 ele
.setAttribute('data-ponyhoof-dialog-orig', orig
);
7498 var body
= ele
.querySelector('._t ._13, .-cx-PRIVATE-uiDialog__body, ._4-i2, .-cx-PRIVATE-xuiDialog__body, .uiLayerPageContent > .pvm');
7500 addClass(body
, 'ponyhoof_fbdialog_body');
7502 // fix nuke dialog on entstream
7503 var descriptionBody
= body
;
7504 if (descriptionBody
.childNodes
&& descriptionBody
.childNodes
.length
&& descriptionBody
.childNodes
[0]) {
7505 if (descriptionBody
.childNodes
[0].nodeType
=== ELEMENT_NODE
&& hasClass(descriptionBody
.childNodes
[0], '_50f4')) {
7506 descriptionBody
= descriptionBody
.childNodes
[0];
7511 loopChildText(descriptionBody
, function(child
) {
7515 if (child
.nodeType
== TEXT_NODE
) {
7516 var replaced
= replaceText(dialogDescriptionTitles
, child
.textContent
);
7517 if (child
.textContent
!= replaced
) {
7518 child
.textContent
= replaced
;
7524 k
._dialog_insertReadme(body
);
7527 if (hasClass(dom
.target
, 'uiLayer')) {
7528 // dom.target is intentional
7529 // Detect rare cases when HTML detection just got turned on, and there is a dialog at the back
7530 k
._dialog_playSound(replaced
, ele
);
7533 if (USINGMUTATION
) {
7534 k
.updateLayerPosition(ele
);
7538 domChangeTextbox(ele
, '._5nw-, .groupsMemberFlyoutWelcomeTextarea', function(textbox
) {
7539 var orig
= textbox
.getAttribute('placeholder');
7540 var t
= orig
.replace(/\bgroup\b/, 'herd');
7544 return "Welcome him/her to the herd...";
7546 domChangeTextbox(ele
, '.fbEventMemberComment', function(textbox
) {
7547 var orig
= textbox
.getAttribute('placeholder');
7548 var t
= orig
.replace(/\bevent\b/, 'adventure');
7552 return orig
; // for pages "Write something to let her know you're going too."
7556 $$(ele
, '._7lo > .fcg, .-cx-PRIVATE-hovercard__footer > .fcg', function(footer
) {
7557 loopChildText(footer
, k
.textBrohoof
);
7561 domReplaceFunc(dom
.target
, '', 'a[href^="/ajax/sharer/"][rel="dialog"], a[ajaxify^="/ajax/sharer/"], a[href^="/ajax/sharer?"][rel="dialog"], a[href^="/ajax/photos/album/share_dialog.php"], a[ajaxify^="/ajax/video/actions/share/dialog/"]', function(ele
) {
7562 if (CURRENTSTACK
.stack
== 'pony') {
7563 ele
.setAttribute('data-hover', 'tooltip');
7564 ele
.setAttribute('aria-label', CURRENTLANG
.fb_share_tooltip
);
7565 ele
.setAttribute('title', '');
7569 domReplaceFunc(dom
.target
, '', '.uiHeaderTitle, .legacyContextualDialogTitle, ._6dp, .-cx-PRIVATE-litestandRHC__titlename, ._34e, ._50f5._50f7', function(ele
) {
7570 var imgwrap
= ele
.querySelector('._8m, .-cx-PRIVATE-uiImageBlock__content, .adsCategoryTitleLink');
7575 loopChildText(ele
, function(child
) {
7576 if (!child
.children
|| !child
.children
.length
) {
7577 var t
= replaceText(headerTitles
, child
.textContent
);
7578 if (child
.textContent
!= t
) {
7579 child
.textContent
= t
;
7585 /*domReplaceFunc(dom.target, '', '.insights-header .header-title > .ufb-text-content', function(ele) {
7586 var t = replaceText(headerInsightsTitles, ele.textContent);
7587 if (ele.textContent != t) {
7588 ele.textContent = t;
7592 if (k
.fbDockChatBuddylistNub(dom
.target
) || k
.pokesDashboard(dom
.target
)) {
7593 INTERNALUPDATE
= iu
;
7597 k
.commentBrohoofed(dom
);
7599 k
.changeCommentBox(dom
);
7600 k
.changeComposer(dom
);
7602 k
.notification(dom
);
7604 k
.fbRemindersStory(dom
.target
);
7605 if (k
.flyoutLikeForm(dom
.target
)) {
7606 INTERNALUPDATE
= iu
;
7609 k
.pluginButton(dom
.target
);
7610 k
.pluginCommentBox(dom
.target
);
7611 //k.insightsCountry(dom.target);
7612 k
.timelineMutualLikes(dom
.target
);
7613 k
.videoStageContainer(dom
.target
);
7614 k
.uiStreamShareLikePageBox(dom
.target
);
7615 k
.fbTimelineUnit(dom
.target
);
7616 k
.pageBrowserItem(dom
.target
);
7617 k
.EntstreamCollapsedUFISentence(dom
.target
);
7619 domChangeTextbox(dom
.target
, '.MessagingComposerForm textarea, ._1rt ._1rv, .-cx-PRIVATE-webMessengerComposer__composertextarea, ._20y textarea, .-cx-PRIVATE-mercuryComposerDialog__root textarea, ._2oj, .-cx-PRIVATE-mercuryComposerDialog__textarea', "Dear Princess Celestia...");
7620 domChangeTextbox(dom
.target
, '.groupAddMemberTypeaheadBox .inputtext', "Add "+capitaliseFirstLetter(CURRENTSTACK
.friends
)+" to the Herd");
7621 //domChangeTextbox(dom.target, '.friendListAddTypeahead .inputtext', "Add "+CURRENTSTACK.friends+" to this directory");
7622 domChangeTextbox(dom
.target
, '.friendListFeed .friendListAddTypeahead .inputtext', "Add "+CURRENTSTACK
['friends']+" to this list");
7623 domChangeTextbox(dom
.target
, '.groupsJumpHeaderSearch .inputtext', "Search this herd");
7624 domChangeTextbox(dom
.target
, '.MessagingSearchFilter .inputtext', "Search Friendship Reports");
7625 domChangeTextbox(dom
.target
, '#chatFriendsOnline .fbChatTypeahead .inputtext', "Pals on Whinny Chat");
7627 //domChangeTextbox(dom.target, '.uiComposer textarea', "What lessons in friendship have you learned today?");
7628 //domChangeTextbox(dom.target, '.uiComposerMessageBox textarea', "Share your friendship stories...");
7629 //domChangeTextbox(dom.target, '.uiMetaComposerMessageBox textarea', "What lessons in friendship have you learned today?");
7630 domChangeTextbox(dom
.target
, '#q, ._585- ._586f, .-cx-PUBLIC-fbFacebar__root .-cx-PUBLIC-uiStructuredInput__text', function(searchbox
) {
7631 if (CURRENTLANG
.sniff_fb_search_boxAlt
&& searchbox
.getAttribute('placeholder').indexOf(CURRENTLANG
.sniff_fb_search_boxAlt
) != -1) {
7632 return CURRENTLANG
.fb_search_boxAlt
;
7634 return CURRENTLANG
.fb_search_box
;
7637 k
.ponyhoofPageOptions(dom
);
7638 if (userSettings
.debug_betaFacebookLinks
&& w
.location
.hostname
== 'beta.facebook.com') {
7639 k
.debug_betaFacebookLinks(dom
.target
);
7642 INTERNALUPDATE
= iu
;
7645 k
.photos_snowlift
= null;
7646 k
.snowliftPinkie = function(dom
) {
7647 if (!k
.snowliftPinkieInjected
) {
7648 var id
= dom
.target
.getAttribute('id');
7649 if ((id
&& id
== 'photos_snowlift') || hasClass(dom
.target
, 'fbPhotoSnowlift')) {
7650 k
.snowliftPinkieInjected
= true;
7651 k
.photos_snowlift
= dom
.target
;
7653 addClass(k
.photos_snowlift
, 'ponyhoof_snowlift_haspinkiediv');
7654 var n
= d
.createElement('div');
7655 n
.id
= 'ponyhoof_snowlift_pinkie';
7656 k
.photos_snowlift
.appendChild(n
);
7661 k
.notificationsFlyoutSettingsInjected
= false;
7662 k
.notificationsFlyoutSettings = function() {
7664 k
.notificationsFlyoutSettingsInjected
= true;
7667 if (!k
.notificationsFlyoutSettingsInjected
) {
7668 var jewel
= $('fbNotificationsJewel');
7670 var header
= jewel
.getElementsByClassName('uiHeaderTop');
7671 if (!header
.length
|| !header
[0].childNodes
|| !header
[0].childNodes
.length
) {
7676 var settingsLink
= d
.createElement('a');
7677 settingsLink
.href
= '#';
7678 settingsLink
.textContent
= 'Ponyhoof Sounds';
7680 var actions
= jewel
.getElementsByClassName('uiHeaderActions');
7681 if (actions
.length
) {
7682 actions
= actions
[0];
7683 var span
= d
.createElement('span');
7684 span
.innerHTML
= ' · ';
7686 actions
.appendChild(span
);
7687 actions
.appendChild(settingsLink
);
7689 var rfloat
= d
.createElement('div');
7690 rfloat
.className
= 'rfloat';
7691 rfloat
.appendChild(settingsLink
);
7692 header
.insertBefore(rfloat
, header
.childNodes
[0]);
7695 settingsLink
.addEventListener('click', function(e
) {
7698 if (!optionsGlobal
) {
7699 optionsGlobal
= new Options();
7701 optionsGlobal
.create();
7702 optionsGlobal
.switchTab('sounds');
7703 optionsGlobal
.show();
7706 clickLink(jewel
.getElementsByClassName('jewelButton')[0]);
7710 k
.notificationsFlyoutSettingsInjected
= true;
7715 // Change Find Friends link at the top-right to native text for reliability
7716 k
.findFriendsNavInjected
= false;
7717 k
.findFriendsNav = function() {
7718 if (k
.findFriendsNavInjected
|| ISUSINGPAGE
|| ISUSINGBUSINESS
) {
7719 k
.findFriendsNavInjected
= true;
7722 var findFriendsNav
= $('findFriendsNav');
7723 if (!findFriendsNav
|| !findFriendsNav
.childNodes
|| !findFriendsNav
.childNodes
.length
) {
7726 var text
= findFriendsNav
.childNodes
[0]; // this should return the "Find Friends" node
7727 if (text
.nodeType
!= TEXT_NODE
) {
7728 text
= findFriendsNav
.childNodes
[1]; // litestand
7729 if (text
.nodeType
!= TEXT_NODE
) {
7734 text
.textContent
= CURRENTSTACK
['findFriendship'];
7735 addClass(findFriendsNav
, 'ponyhoof_findFriendsNav_native');
7736 k
.findFriendsNavInjected
= true;
7739 k
.fbPhotoSubscribeWrapper = function(target
) {
7740 if (hasClass(target
, 'fbPhotoSubscribeWrapper')) {
7741 var photoViewerFollowLink
= target
.getElementsByClassName('photoViewerFollowLink');
7742 if (photoViewerFollowLink
.length
) {
7743 photoViewerFollowLink
= photoViewerFollowLink
[0];
7745 var orig
= photoViewerFollowLink
.textContent
;
7747 t
= t
.replace(/^Like/, capitaliseFirstLetter(CURRENTSTACK
['like']));
7749 photoViewerFollowLink
.textContent
= t
;
7753 var photoViewerFollowedMsg
= target
.getElementsByClassName('photoViewerFollowedMsg');
7754 if (photoViewerFollowedMsg
.length
) {
7755 photoViewerFollowedMsg
= photoViewerFollowedMsg
[0];
7757 var orig
= photoViewerFollowedMsg
.textContent
;
7759 t
= t
.replace(/^Liked$/, capitaliseFirstLetter(CURRENTSTACK
['liked']));
7761 photoViewerFollowedMsg
.textContent
= t
;
7771 k
.textNodes = function(dom
) {
7773 if (!dom
.target
.parentNode
|| !dom
.target
.parentNode
.parentNode
|| !hasClass(dom
.target
.parentNode
.parentNode
, 'dialog_title')) {
7777 var title
= dom
.target
.parentNode
.parentNode
;
7778 var orig
= dom
.target
.textContent
;
7779 var replaced
= replaceText(dialogTitles
, orig
);
7781 if (dom
.target
.textContent
!= replaced
) {
7782 dom
.target
.textContent
= replaced
;
7784 addClass(title
, 'ponyhoof_fbdialog_title');
7785 if (orig
!= replaced
) {
7789 k
.getParent(title
, function(ele
) {
7790 return hasClass(ele
, 'generic_dialog');
7792 if (hasClass(ele
, 'fbQuestionsPopup')) {
7796 addClass(ele
, 'ponyhoof_fbdialog');
7797 ele
.setAttribute('data-ponyhoof-dialog-title', replaced
);
7798 ele
.setAttribute('data-ponyhoof-dialog-orig', orig
);
7800 var body
= ele
.getElementsByClassName('dialog_body');
7803 addClass(body
, 'ponyhoof_fbdialog_body');
7805 var confirmation_message
= body
.getElementsByClassName('confirmation_message');
7806 if (confirmation_message
.length
) {
7807 confirmation_message
= confirmation_message
[0];
7810 loopChildText(confirmation_message
, function(child
) {
7814 if (child
.nodeType
== TEXT_NODE
) {
7815 var replaced
= replaceText(dialogDescriptionTitles
, child
.textContent
);
7816 if (child
.textContent
!= replaced
) {
7817 child
.textContent
= replaced
;
7823 var video_dialog_text
= body
.getElementsByClassName('video_dialog_text');
7824 if (video_dialog_text
.length
) {
7825 video_dialog_text
= video_dialog_text
[0];
7826 if (video_dialog_text
.childNodes
.length
== 3) {
7828 var texts
= ["Nuking a video is permanent.", "Once you nuke a video, you will not be able to get it back.", "Are you sure you want to nuke this video?"];
7829 loopChildText(video_dialog_text
, function(child
) {
7833 child
.textContent
= texts
[i
];
7839 loopChildText(body
, function(child
) {
7843 if (child
.nodeType
=== TEXT_NODE
) {
7844 var orig
= child
.textContent
;
7845 var replaced
= replaceText(dialogDescriptionTitles
, orig
);
7846 if (orig
!= replaced
) {
7847 child
.textContent
= replaced
;
7856 k
._dialog_playSound(replaced
, ele
);
7865 k
.ufiPagerLink = function(dom
) {
7866 domReplaceFunc(dom
.target
, '', '.UFIPagerLink', function(ele
) {
7867 var t
= ele
.innerHTML
;
7868 t
= t
.replace(/ comments
/, " friendship letters");
7869 t
= t
.replace(/ comment
/, " friendship letter");
7870 if (ele
.innerHTML
!= t
) {
7876 k
.postLike = function(dom
) {
7877 if (hasClass(dom
.target
, 'uiUfiLike') || hasClass(dom
.target
, 'UFILikeSentence')) {
7878 k
._likePostBox(dom
.target
);
7880 /*if (dom.target.parentNode) {
7881 if (hasClass(dom.target.parentNode, 'UFILikeSentence')) {
7882 k._likePostBox(dom.target);
7886 domReplaceFunc(dom
.target
, '', '.uiUfiLike, .UFILikeSentence', k
._likePostBox
);
7890 k
._likePostBox = function(ele
) {
7891 //var inner = ele.querySelector('._42ef, .-cx-PRIVATE-uiFlexibleBlock__flexiblecontent, .lfloat > span, .-cx-PRIVATE-uiImageBlockDeprecated__content, .-cx-PRIVATE-uiImageBlock__content, ._8m, .-cx-PRIVATE-uiFlexibleBlock__flexibleContent');
7894 var inner
= ele
.getElementsByClassName('UFILikeSentenceText');
7897 k
._likePostBox_loop(inner
);
7900 var reorder
= ele
.getElementsByClassName('UFIOrderingModeSelectorDownCaret');
7901 if (reorder
.length
) {
7902 reorder
= reorder
[0];
7903 if (reorder
.previousSibling
) {
7904 k
.UFIOrderingMode(reorder
.previousSibling
);
7909 k
._likePostBox_loop = function(ele
) {
7910 // Change "**profile people test** likes this." -> "**profile people test** brohoofs this."
7911 // Previous versions would change it to "**profile ponies test** brohoofs this."
7912 for (var i
= 0, len
= ele
.childNodes
.length
; i
< len
; i
+= 1) {
7913 if (ele
.childNodes
[i
].nodeType
=== TEXT_NODE
) {
7914 k
._likePostBox_loop_text(ele
.childNodes
[i
]);
7916 /*var ajaxify = ele.childNodes[i].getAttribute('ajaxify');
7917 if (ajaxify && ajaxify.indexOf('/ajax/browser/dialog/likes') != -1) {
7918 k._likePostBox_loop_text(ele.childNodes[i]);
7920 if (!hasClass(ele
.childNodes
[i
], 'profileLink')) {
7921 k
._likePostBox_loop(ele
.childNodes
[i
]);
7927 k
._likePostBox_loop_text = function(ele
) {
7928 var orig
= ele
.textContent
;
7929 var t
= k
.likeSentence(orig
);
7931 ele
.textContent
= t
;
7935 k
.likeSentence = function(t
) {
7936 //t = t.replace(/likes? this\./g, "brohoof'd this.");
7937 t
= t
.replace(/like
this\./g
, CURRENTSTACK
['like_past']+" this.");
7938 t
= t
.replace(/likes
this\./g
, CURRENTSTACK
['likes_past']+" this.");
7939 t
= t
.replace(/\bpeople\b/g, CURRENTSTACK
['people']);
7940 t
= t
.replace(/\bperson\b/g, CURRENTSTACK
['person']); // http://fb.com/647294431950845
7941 /*if (CURRENTSTACK == 'pony') {
7942 t = t.replace(/\<3 7h\!5/g, '/) 7h!5');
7943 t = t.replace(/\<3 7h15/g, '/) 7h!5');
7949 k
._likeCount = function(ufiitem
) {
7950 var likecount
= ufiitem
.getElementsByClassName('comment_like_button');
7951 if (likecount
.length
) {
7952 likecount
= likecount
[0];
7953 var t
= likecount
.innerHTML
;
7954 //t = t.replace(/likes? this\./g, "brohoof'd this.");
7955 t
= t
.replace(/like
this/g
, CURRENTSTACK
['like_past']+" this");
7956 t
= t
.replace(/likes
this/g
, CURRENTSTACK
['likes_past']+" this");
7957 if (likecount
.innerHTML
!= t
) {
7958 likecount
.innerHTML
= t
;
7963 k
.UFIOrderingMode = function(ele
) {
7964 var t
= ele
.textContent
;
7965 t
= t
.replace(/Top Comments
/, "Top Friendship Letters");
7966 if (ele
.textContent
!= t
) {
7967 ele
.textContent
= t
;
7973 k
._likeConditions
= '';
7974 k
._likeIsLikeConditions
= '';
7975 k
.FB_TN_LIKELINK
= '>';
7976 k
.FB_TN_UNLIKELINK
= '?';
7977 k
.commentBrohoofed = function(dom
) {
7978 var targets
= '.UFICommentActions a, .UFILikeLink';
7979 if (!USINGMUTATION
) {
7980 targets
+= ', .UFILikeThumb';
7982 domReplaceFunc(dom
.target
, '', targets
, k
._commentLikeLink
);
7985 k
.commentLikeDescInit = function() {
7986 if (k
._likeDesc
== '') {
7987 var locale
= getDefaultUiLang();
7988 if (LANG
[locale
] && LANG
[locale
].sniff_comment_tooltip_like
) {
7989 k
._likeDesc
= LANG
[locale
].sniff_comment_tooltip_like
;
7991 k
._likeDesc
= LANG
['en_US'].sniff_comment_tooltip_like
;
7993 if (LANG
[locale
] && LANG
[locale
].sniff_comment_tooltip_unlike
) {
7994 k
._unlikeDesc
= LANG
[locale
].sniff_comment_tooltip_unlike
;
7996 k
._unlikeDesc
= LANG
['en_US'].sniff_comment_tooltip_unlike
;
7999 k
._likeConditions
= [
8000 k
._likeDesc
, k
._unlikeDesc
,
8001 capitaliseFirstLetter(CURRENTSTACK
.like
)+" this friendship letter", capitaliseFirstLetter(CURRENTSTACK
.unlike
)+" this friendship letter"
8003 k
._likeIsLikeConditions
= [
8005 capitaliseFirstLetter(CURRENTSTACK
.like
)+" this friendship letter"
8010 k
._commentLikeLink = function(ele
) {
8011 k
.commentLikeDescInit();
8014 var likeThumb
= false;
8015 if (k
._likeConditions
.indexOf(ele
.title
) == -1) {
8017 var trackingNode
= k
.getTrackingNode(ele
);
8018 if (trackingNode
== k
.FB_TN_LIKELINK
|| trackingNode
== k
.FB_TN_UNLIKELINK
) {
8020 } else if (!USINGMUTATION
&& hasClass(ele
, 'UFILikeThumb')) {
8031 if (!hasClass(ele
, 'ponyhoof_brohoof_button')) {
8032 if (!USINGMUTATION
) {
8033 ele
.addEventListener('click', function() {
8035 k
.delayIU(function() {
8037 // UFILikeThumb disappears after a post is brohoof'd
8038 k
._likeBrohoofMagic(ele
, false);
8040 k
._commentLikeLink(ele
);
8045 addClass(ele
, 'ponyhoof_brohoof_button');
8049 if (k
.getTrackingNode(ele
) == k
.FB_TN_LIKELINK
|| likeThumb
|| k
._likeIsLikeConditions
.indexOf(ele
.title
) != -1) {
8053 k
._likeBrohoofMagic(ele
, isLike
);
8056 k
._likeBrohoofMagic = function(ele
, isLike
) {
8057 var comment
= k
.getReactComment(ele
);
8060 removeClass(ele
, 'ponyhoof_brohoof_button_unbrohoof');
8061 title
= capitaliseFirstLetter(CURRENTSTACK
.like
)+" this";
8063 addClass(ele
, 'ponyhoof_brohoof_button_unbrohoof');
8064 title
= capitaliseFirstLetter(CURRENTSTACK
.unlike
)+" this";
8067 title
+= " friendship letter";
8069 ele
.setAttribute('data-ponyhoof-title', ele
.title
);
8071 ele
.setAttribute('data-ponyhoof-title-modified', title
);
8074 k
._markCommentLiked(comment
, isLike
);
8076 // Fix an edge case with jump to comment
8077 if (hasClass(comment
, 'highlightComment')) {
8078 w
.setTimeout(function() {
8079 k
._markCommentLiked(comment
, isLike
);
8083 k
.delayIU(function() {
8084 if (!ele
.parentNode
) {
8085 var ufi
= k
.getReactUfi(ele
);
8092 k
.getParent(ele
, function(form
) {
8093 return (form
.tagName
.toUpperCase() == 'FORM' && hasClass(form
, 'commentable_item'));
8098 /*var ufi = form.getElementsByClassName('UFIList');
8103 if (!ufi.parentNode) {
8108 //removeClass(ufi.parentNode, 'ponyhoof_brohoofed');
8109 removeClass(form
, 'ponyhoof_brohoofed');
8111 //addClass(ufi.parentNode, 'ponyhoof_brohoofed');
8112 addClass(form
, 'ponyhoof_brohoofed');
8119 k
._markCommentLiked = function(ufiitem
, isLike
) {
8121 if (ufiitem
.childNodes
&& ufiitem
.childNodes
.length
&& ufiitem
.childNodes
[0]) {
8122 child
= ufiitem
.childNodes
[0];
8125 removeClass(ufiitem
, 'ponyhoof_comment_liked');
8127 removeClass(child
, 'ponyhoof_comment_liked');
8130 addClass(ufiitem
, 'ponyhoof_comment_liked');
8132 addClass(child
, 'ponyhoof_comment_liked');
8137 k
.REACTROOTID
= '.r['; // https://github.com/facebook/react/commit/8bc2abd367232eca66e4d38ff63b335c8cf23c45
8138 k
.REACTATTRNAME
= 'data-reactid'; // https://github.com/facebook/react/commit/67cf44e7c18e068e3f39462b7ac7149eee58d3e5
8139 k
.getReactId = function(ufiitem
) {
8140 var id
= ufiitem
.getAttribute(k
.REACTATTRNAME
);
8144 return id
.substring(k
.REACTROOTID
.length
, id
.indexOf(']'));
8147 k
.reactRoot = function(dom
) {
8148 var id
= dom
.target
.getAttribute(k
.REACTATTRNAME
);
8149 if (id
|| hasClass(dom
.target
, 'UFILikeIcon')) {
8150 // beeperNotificaton
8151 if (hasClass(dom
.target
, '_3sod') || hasClass(dom
.target
, '-cx-PRIVATE-notificationBeeperItem__beeperitem')) {
8152 var info
= dom
.target
.querySelector('._3sol > span, .-cx-PRIVATE-notificationBeeperItem__imageblockcontent > span');
8156 k
._beepNotification_change(dom
.target
, info
, k
._beepNotification_condition_react
);
8162 if (k
._notification_react(dom
.target
)) {
8165 var notificationReact
= false;
8166 domReplaceFunc(dom
.target
, '', '.'+k
.notification_itemClass
[0]+', .'+k
.notification_itemClass
[1], function(ele
) {
8167 k
._notification_react(ele
);
8168 notificationReact
= true;
8170 if (notificationReact
) {
8175 if (hasClass(dom
.target
, 'UFIComment')) {
8176 k
.commentBrohoofed({target: dom
.target
});
8177 } else if (hasClass(dom
.target
, 'UFIReplyList')) {
8178 k
.changeCommentBox({target: dom
.target
});
8179 k
.commentBrohoofed({target: dom
.target
}); // only 1 reply
8180 } else if (hasClass(dom
.target
, 'UFIAddComment')) {
8181 domChangeTextbox(dom
.target
, 'textarea', k
._changeCommentBox_change
);
8182 } else if (hasClass(dom
.target
, 'UFILikeSentence')) {
8183 k
._likePostBox(dom
.target
);
8184 } else if (hasClass(dom
.target
, 'UFIImageBlockContent')) {
8185 //if (hasClass(dom.target, '_42ef') || hasClass(dom.target, '-cx-PRIVATE-uiFlexibleBlock__flexiblecontent')) {
8186 // on groups with seen, clicking a photo will open in the viewer, but the original post on the group messes up
8187 k
._likePostBox(dom
.target
.parentNode
);
8189 // marking a comment as spam in another section, and then unmark
8190 k
.commentBrohoofed({target: dom
.target
});
8192 } else if (hasClass(dom
.target
, 'UFILikeLink') || (!USINGMUTATION
&& hasClass(dom
.target
, 'UFILikeThumb'))) {
8193 k
._commentLikeLink(dom
.target
);
8194 } else if (dom
.target
.parentNode
) {
8196 if (hasClass(dom
.target
.parentNode
, 'UFIComment')) {
8197 // marking a comment as spam, and then immediately undo
8198 k
.commentBrohoofed({target: dom
.target
.parentNode
});
8199 } else if (hasClass(dom
.target
.parentNode
, 'UFILikeSentence')) {
8200 // groups with seen, from no likes to liked
8201 k
._likePostBox(dom
.target
.parentNode
);
8202 } else if (dom
.target
.parentNode
.parentNode
) {
8204 //if (hasClass(dom.target.parentNode.parentNode, 'UFIImageBlockContent') || hasClass(dom.target.parentNode.parentNode, 'lfloat')) {
8205 if (hasClass(dom
.target
.parentNode
.parentNode
, 'UFILikeSentenceText')) {
8206 // John Amebijeigeba Laverdetberg brohoof this.
8207 // You and John Amebijeigeba Laverdetberg like this.
8208 var ufi
= k
.getReactUfi(dom
.target
);
8210 k
.postLike({target: ufi
});
8212 } else if (dom
.target
.parentNode
.parentNode
.parentNode
) {
8214 //if (hasClass(dom.target.parentNode.parentNode.parentNode, 'UFIImageBlockContent')) {
8215 if (hasClass(dom
.target
.parentNode
.parentNode
.parentNode
, 'UFILikeSentenceText')) {
8216 var ufi
= k
.getReactUfi(dom
.target
);
8218 k
.postLike({target: ufi
});
8226 k
.insightsCountry(dom
.target
);
8234 k
.changeCommentBox = function(dom
) {
8235 domChangeTextbox(dom
.target
, '.commentArea textarea, .UFIAddComment textarea', k
._changeCommentBox_change
);
8237 k
._changeCommentBox_change = function(textbox
) {
8241 if (form
.tagName
.toUpperCase() == 'FORM' && form
.getAttribute('action') == '/ajax/ufi/modify.php') {
8244 form
= form
.parentNode
;
8247 var feedback_params
= JSON
.parse(form
.querySelector('input[name="feedback_params"]').value
);
8248 switch (feedback_params
.assoc_obj_id
) {
8249 case '140792002656140':
8250 case '346855322017980':
8251 return LANG
['ms_MY'].fb_comment_box
;
8253 case '146225765511748':
8254 return CURRENTLANG
.fb_composer_coolstory
;
8259 switch (feedback_params
.target_profile_id
) {
8260 case '496282487062916':
8261 return CURRENTLANG
.fb_composer_coolstory
;
8269 return CURRENTLANG
.fb_comment_box
;
8272 k
.composerPonies
= new RegExp(['pony', 'ponies', 'mlp', 'brony', 'bronies', 'pegasister', 'pega sister', 'pega-sister', 'twilight sparkle', 'rainbow dash', 'pinkie', 'applejack', 'fluttershy', 'rarity', 'celestia', 'derpy', 'equestria', 'canterlot', 'dashie', 'apple jack', 'flutter shy', 'princess luna', 'friendship is magic', 'kuda', 'pinkamena', 'bon bon', 'bonbon'].join('|'), 'i');
8273 k
.composerExclude
= new RegExp(['suck', 'shit', 'fuck', 'assho', 'crap', 'ponyfag', 'faggo', 'retard', 'dick'].join('|'), 'i');
8274 k
.composerSpecialPages
= null;
8275 k
.composerSelectors
= '.uiComposer textarea.mentionsTextarea, .composerTypeahead textarea';
8276 k
.composerButtonSelectors
= '.uiComposerMessageBoxControls .submitBtn input, .uiComposerMessageBoxControls .submitBtn .uiButtonText, ._11b input, .-cx-PRIVATE-fbComposerMessageBox__button input, button._11b, button.-cx-PRIVATE-fbComposerMessageBox__button';
8277 k
.changeComposer = function(dom
) {
8278 if (!k
.composerSpecialPages
) {
8279 k
._changeComposer_initSpecialPages();
8284 // tagging people with "Who are you with?" and new feelings feature
8285 if (hasClass(dom
.target
, 'uiMentionsInput')) {
8286 // fix group composers, ugh
8287 if (dom
.target
.parentNode
&& dom
.target
.parentNode
.parentNode
&& dom
.target
.parentNode
.parentNode
.parentNode
) {
8288 // .uiMentionsInput -> #id -> .-cx-PUBLIC-fbComposerMessageBox__root -> form -> .-cx-PUBLIC-fbComposer__content
8289 k
._changeComposer_fixGroup(dom
.target
.parentNode
.parentNode
.parentNode
);
8292 contentEval(function(arg
) {
8294 if (typeof window
.requireLazy
== 'function') {
8295 window
.requireLazy(['MentionsInput'], function(MentionsInput
) {
8296 var mentions
= MentionsInput
.getInstance(document
.getElementById(arg
.uiMentionsInput
));
8297 mentions
.setPlaceholder(mentions
._input
.title
);
8301 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
8302 console
.log("Unable to hook to MentionsInput");
8306 }, {"CANLOG":CANLOG
, "uiMentionsInput":dom
.target
.id
});
8310 domChangeTextbox(dom
.target
, k
.composerSelectors
, function(composer
) {
8311 var placeholderText
= CURRENTLANG
.fb_composer_lessons
;
8314 var form
= composer
;
8315 var inputContainer
= null;
8317 if (hasClass(form
, 'uiComposer') || hasClass(form
, '_119' /*'_118'*/) || hasClass(form
, '-cx-PRIVATE-fbComposer__root')) {
8320 if (hasClass(form
, 'inputContainer')) {
8321 inputContainer
= form
;
8323 form
= form
.parentNode
;
8327 return placeholderText
;
8330 pageid
= form
.querySelector('input[name="xhpc_targetid"]');
8333 return placeholderText
;
8335 pageid
= pageid
.value
;
8336 form
.setAttribute('data-ponyhoof-xhpc_targetid', pageid
);
8337 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].composer
) {
8338 placeholderText
= k
.composerSpecialPages
[pageid
].composer
;
8341 k
._changeComposerAttachment(dom
, pageid
);
8343 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8344 $$(form
, k
.composerButtonSelectors
, function(submit
) {
8345 k
.changeButtonText(submit
, "Kirim");
8349 composer
.addEventListener('input', function() {
8351 var lang
= CURRENTLANG
;
8352 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8354 lang
= LANG
['ms_MY'];
8357 // we can't guarantee the button anymore, so we have to do this expensive JS :(
8358 // group composers are funky and teleport the textbox to a new <div> onclick
8359 $$(form
, k
.composerButtonSelectors
, function(submit
) {
8360 if (!k
.composerExclude
.test(composer
.value
) && k
.composerPonies
.test(composer
.value
)) {
8361 if (composer
.value
.toUpperCase() == composer
.value
) {
8362 k
.changeButtonText(submit
, lang
.fb_composer_ponies_caps
);
8364 k
.changeButtonText(submit
, lang
.fb_composer_ponies
);
8367 k
.changeButtonText(submit
, "Kirim");
8369 var submitParent
= submit
;
8370 if (submit
.tagName
.toUpperCase() != 'BUTTON') {
8371 submitParent
= submit
.parentNode
;
8373 if (submitParent
.getAttribute('data-ponyhoof-button-text')) {
8374 k
.changeButtonText(submit
, submitParent
.getAttribute('data-ponyhoof-button-text'));
8380 if (isPonyhoofPage(pageid
)) {
8381 composer
.addEventListener('focus', function() {
8382 if (inputContainer
) {
8383 k
._changeComposer_insertReadme(inputContainer
.nextSibling
);
8387 // pages have ComposerX and teleports the textbox here and there
8388 $$(form
, '._2yg, .-cx-PUBLIC-fbComposerMessageBox__root', function(composer
) {
8389 // exclude inactives
8390 if (!composer
.parentNode
|| hasClass(composer
.parentNode
, 'hidden_elem')) {
8394 var temp
= composer
.getElementsByClassName('ponyhoof_page_readme');
8399 // status: before taggersPlaceholder
8400 // photos: after uploader
8401 // fallback: before bottom bar
8402 var insertBefore
= composer
.querySelector('._3-6, .-cx-PRIVATE-fbComposerBootloadStatus__taggersplaceholder');
8403 if (!insertBefore
) {
8404 insertBefore
= composer
.querySelector('._93, .-cx-PRIVATE-fbComposerUploadMedia__root');
8406 insertBefore
= insertBefore
.nextSibling
;
8409 if (!insertBefore
) {
8410 insertBefore
= composer
.querySelector('._1dsp, .-cx-PUBLIC-fbComposerMessageBox__bar');
8412 // abort if no good insertion
8413 if (!insertBefore
) {
8417 k
._changeComposer_insertReadme(insertBefore
);
8420 return "Send feedback for Ponyhoof...";
8422 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].composer
) {
8423 return k
.composerSpecialPages
[pageid
].composer
;
8427 return placeholderText
;
8430 // moved outside for timelineStickyHeader
8432 k
._changeComposerAttachment(dom
, null);
8435 // fix group composers, ugh
8436 //k._changeComposer_fixGroup(dom.target);
8439 k
._changeComposerAttachment = function(dom
, pageid
) {
8440 $$(dom
.target
, '._4_ li a, ._9lb, .-cx-PUBLIC-fbComposerAttachment__link, .uiComposerAttachment', function(attachment
) {
8441 if (attachment
.getAttribute('data-ponyhoof-ponified')) {
8445 var switchit
= false;
8446 switch (attachment
.getAttribute('data-endpoint')) {
8447 case '/ajax/composerx/attachment/status/':
8448 case '/ajax/composerx/attachment/group/post/':
8449 case '/ajax/composerx/attachment/wallpost/':
8450 case '/ajax/metacomposer/attachment/timeline/status.php':
8451 case '/ajax/metacomposer/attachment/timeline/backdated_status.php':
8452 case '/ajax/metacomposer/attachment/timeline/wallpost.php':
8453 switchit
= "Take a Note";
8454 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8455 switchit
= "Tulis Kiriman";
8459 case '/ajax/composerx/attachment/media/chooser/':
8460 case '/ajax/composerx/attachment/media/chooser':
8461 case '/ajax/composerx/attachment/media/upload/':
8462 case '/ajax/metacomposer/attachment/timeline/photo/photo.php':
8463 case '/ajax/metacomposer/attachment/timeline/photo/backdated_upload.php':
8464 case '/ajax/metacomposer/attachment/timeline/backdated_vault.php?max_select=1':
8465 switchit
= "Add a Pic";
8466 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8467 switchit
= "Tambah Gambar / Video";
8471 case '/ajax/composerx/attachment/question/':
8473 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8474 switchit
= "Tanya Soalan";
8478 case '/ajax/composerx/attachment/group/file/':
8479 case '/ajax/composerx/attachment/group/filedropbox/':
8480 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8481 switchit
= "Muat Naik Fail";
8489 if (attachment
.getAttribute('data-endpoint').indexOf('/ajax/composerx/attachment/pages/other') != -1 || attachment
.getAttribute('data-endpoint').indexOf('/ajax/metacomposer/attachment/timeline/pages_other.php') != -1) {
8490 switchit
= "Adventure, Milestone +";
8491 //if (attachment.id == 'offerEventAndOthersButton') {
8492 if (attachment
.textContent
.toLowerCase().indexOf('offer') != -1) {
8493 switchit
= "Offer, Adventure +";
8500 var inner
= attachment
.querySelector('._2-s, .-cx-PUBLIC-fbTimelineComposerAttachment__label');
8502 inner
= attachment
.querySelector('._51z7, .-cx-PUBLIC-fbComposerAttachment__linktext');
8504 // page timelines use ".attachmentName" and are wacky, there are actually two copies of the <div> that show/hide
8505 $$(attachment
, '.attachmentName', function(inner
) {
8506 k
._changeComposerAttachment_inner(inner
, switchit
);
8517 k
._changeComposerAttachment_inner(inner
, switchit
);
8521 attachment
.setAttribute('data-ponyhoof-ponified', 1);
8525 k
._changeComposerAttachment_inner = function(inner
, switchit
) {
8527 loopChildText(inner
, function(child
) {
8531 if (child
.nodeType
== 3) {
8532 child
.textContent
= switchit
;
8538 k
._changeComposer_insertReadme = function(insertBefore
) {
8539 var n
= d
.createElement('iframe');
8540 n
.className
= 'showOnceInteracted ponyhoof_page_readme _4- -cx-PRIVATE-fbComposer__showonceinteracted';
8541 n
.scrolling
= 'auto';
8542 n
.frameborder
= '0';
8543 n
.allowtransparency
= 'true';
8544 n
.src
= PONYHOOF_README
;
8545 insertBefore
.parentNode
.insertBefore(n
, insertBefore
);
8548 k
._changeComposer_fixGroup = function(target
) {
8549 if (hasClass(target
.parentNode
, '_55d0') || hasClass(target
.parentNode
, '.-cx-PUBLIC-fbComposer__content')) {
8550 var pageid
= target
.querySelector('input[name="xhpc_targetid"]');
8554 pageid
= pageid
.value
;
8556 // domChangeTextbox will not work as these <textarea>s already has "data-ponyhoof-ponified"
8557 var composer
= target
.querySelector(k
.composerSelectors
);
8562 $$(target
, k
.composerButtonSelectors
, function(submit
) {
8564 var lang
= CURRENTLANG
;
8565 if (k
.composerSpecialPages
[pageid
] && k
.composerSpecialPages
[pageid
].malay
) {
8567 lang
= LANG
['ms_MY'];
8570 if (!k
.composerExclude
.test(composer
.value
) && k
.composerPonies
.test(composer
.value
)) {
8571 if (composer
.value
.toUpperCase() == composer
.value
) {
8572 k
.changeButtonText(submit
, lang
.fb_composer_ponies_caps
);
8574 k
.changeButtonText(submit
, lang
.fb_composer_ponies
);
8577 k
.changeButtonText(submit
, "Kirim");
8583 k
._changeComposer_initSpecialPages = function() {
8584 k
.composerSpecialPages
= {
8585 '140792002656140': {composer: LANG
['ms_MY'].fb_composer_lessons
, malay:true}
8586 ,'346855322017980': {composer: LANG
['ms_MY'].fb_composer_lessons
, malay:true}
8587 ,'366748370110998': {composer: LANG
['ms_MY'].fb_composer_lessons
, malay:true}
8588 ,'146225765511748': {composer: CURRENTLANG
['fb_composer_coolstory']}
8589 ,'496282487062916': {composer: CURRENTLANG
['fb_composer_coolstory']}
8593 k
.tooltip = function(outer
) {
8594 domReplaceFunc(outer
, '', '.tooltipContent', function(ele
) {
8595 // <div class="tooltipContent"><div class="tooltipText"><span>Hide</span></div></div>
8596 // <div class="tooltipContent"><div>Ponyhoof brohoofs this.</div></div>
8597 // <div class="tooltipContent">xy</div>
8598 // <div class="tooltipContent"><div><div class="-cx-PRIVATE-HubbleTargetingImage__tooltipcontent" data-reactid=""><div data-reactid=""><b data-reactid="">Shared with:</b><br data-reactid=""><span data-reactid="">Public</span></div></div></div></div>
8600 // <div class="uiContextualLayerPositioner uiLayer" style="width: 294px; left: 877px; top: 1299px;" data-ownerid="js_14"><div class="uiContextualLayer uiContextualLayerAboveLeft" style="bottom: 0px;"><div class="uiTooltipX"><div class="tooltipContent"><div class="tooltipText"><span>Excellent</span></div></div><i class="arrow"></i></div></div></div>
8601 var io
= ele
.getElementsByClassName('tooltipText');
8607 var potentialLabel
= target
.querySelector('._5bqd, .-cx-PRIVATE-HubbleInfoTip__content, ._5j1i');
8608 if (potentialLabel
) {
8609 target
= potentialLabel
;
8611 if (target
.childNodes
&& target
.childNodes
.length
&& target
.childNodes
[0] && target
.childNodes
[0].tagName
&& target
.childNodes
[0].tagName
.toUpperCase() == 'DIV') {
8612 target
= target
.childNodes
[0];
8614 if (target
.childNodes
&& target
.childNodes
.length
&& target
.childNodes
[0] && target
.childNodes
[0].tagName
&& target
.childNodes
[0].tagName
.toUpperCase() == 'DIV') { // div soup on insights
8615 target
= target
.childNodes
[0];
8617 if (target
.childNodes
&& target
.childNodes
.length
&& target
.childNodes
[0] && target
.childNodes
[0].tagName
&& target
.childNodes
[0].tagName
.toUpperCase() == 'SPAN') {
8618 target
= target
.childNodes
[0];
8621 // Get the tooltip outer layer
8622 var layer
= k
._tooltipGetLayer(ele
);
8627 //removeClass(layer, 'ponyhoof_tooltip_flip');
8630 var orig
= target
.innerHTML
;
8631 var origText
= target
.textContent
;
8633 t
= replaceText(tooltipTitles
, t
);
8635 //var oldWidth = ele.offsetWidth;
8636 target
.innerHTML
= t
;
8638 if (USINGMUTATION
) {
8639 // Replace text at the parent that we are *really* certain
8640 if (orig
=== origText
) {
8641 var owner
= $(layer
.getAttribute('data-ownerid'));
8643 owner
.setAttribute('aria-label', t
);
8647 // fix horizontal scrollbar
8648 if (hasClass(layer
.parentNode
, 'fbPhotoSnowliftContainer')) {
8649 addClass(layer
, 'ponyhoof_tooltip_widthFix');
8651 removeClass(layer
, 'ponyhoof_tooltip_widthFix');
8654 k
.updateLayerPosition(layer
);
8657 /*// Get the inner layer inside the outer layer (get it...?)
8658 var layerInner = layer.getElementsByClassName('uiContextualLayer');
8659 if (!layerInner.length) {
8662 layerInner = layerInner[0];
8664 if (layerInner.className.match(/Center/)) {
8665 /*var rect = ele.getBoundingClientRect();
8670 layer.style.width = 'auto'; // fix horizontal scrollbar
8671 var left = parseInt(layer.style.left); // relative positioning at photo viewer
8672 var newWidth = ele.offsetWidth;
8673 //if ((rect.left + newWidth) < d.documentElement.clientWidth) {
8674 layer.style.left = (left - Math.round((newWidth - oldWidth) / 2))+'px';
8676 Fix long "X, Y and 2 others like this." tooltips on photo viewer
8677 layer.style.left = (left - (oldWidth / 2) /*+ ((newWidth - oldWidth) / 2) - 18* / )+'px';
8678 addClass(layer, 'ponyhoof_tooltip_flip');
8680 } else if (layerInner.className.match(/Left/)) {
8681 // Fix "Remember: all place ratings are public." tooltips that are being ponified and causing a horizontal page scrollbar
8683 // This is complicated, Facebook caches the ContextualLayer <div>s for tooltips
8684 // If we directly change the classNames like this:
8685 // layerInner.className = layerInner.className.replace(/Left/, 'Right');
8686 // This would cause future tooltips to display incorrectly
8687 // So what we done is add our own "ponyhoof_tooltip_flip" class which flips the tooltip left to right
8689 var rect = ele.getBoundingClientRect();
8693 if (rect.right >= d.documentElement.clientWidth) {
8694 layer.style.width = 'auto'; // bogus anyway
8695 layer.style.left = (parseInt(layer.style.left) - rect.width + 18)+'px'; // 18 is the number of pixels to offset to position the arrow of the tooltip properly
8696 addClass(layer, 'ponyhoof_tooltip_flip');
8703 k
._tooltipGetLayer = function(ele
) {
8704 // <div class="uiContextualLayerPositioner uiLayer" id="js_4" style="width: 862px; left: 309px; top: 1914px;" data-ownerid=""><div class="uiContextualLayer uiContextualLayerAboveCenter" style="bottom: 0px;"><div class="uiTooltipX"><div class="tooltipContent"><div>Loading...</div></div><i class="arrow"></i></div></div></div>
8705 if (!ele
.parentNode
|| !ele
.parentNode
.parentNode
|| !ele
.parentNode
.parentNode
.parentNode
) {
8708 var layer
= ele
.parentNode
.parentNode
.parentNode
;
8709 if (!hasClass(layer
, 'uiContextualLayerPositioner')) {
8715 k
.fbDockChatBuddylistNub = function(target
) {
8716 if (target
.parentNode
&& target
.parentNode
.parentNode
&& target
.parentNode
.parentNode
.getAttribute
&& target
.parentNode
.parentNode
.getAttribute('id') == 'fbDockChatBuddylistNub' && hasClass(target
, 'label')) {
8717 k
._fbDockChatBuddylistNub_change(target
);
8721 var nub
= target
.querySelector('#fbDockChatBuddylistNub .label');
8723 k
._fbDockChatBuddylistNub_change(nub
);
8728 k
._fbDockChatBuddylistNub_change = function(target
) {
8729 if (target
.childNodes
&& target
.childNodes
.length
&& target
.childNodes
[0] && target
.childNodes
[0].nodeType
== TEXT_NODE
) {
8730 var replaced
= target
.childNodes
[0].textContent
.replace(/Chat/, "Whinny");
8731 if (target
.childNodes
[0].textContent
!= replaced
) {
8732 addClass(target
, 'ponyhoof_chatLabel_ponified');
8733 target
.childNodes
[0].textContent
= replaced
;
8738 k
.pokesDashboard = function(target
) {
8739 if (target
.getAttribute
&& target
.getAttribute('id') && target
.getAttribute('id').indexOf('poke_') == 0) {
8740 k
._pokesDashboard_item(target
);
8744 // (Sep 25) Include xuiCard
8745 //$$(target, '.pokesDashboard > .objectListItem', k._pokesDashboard_item);
8746 //$$(target, '.objectListItem[id^="poke_"], ._4-u2[id^="poke_"], .-cx-PRIVATE-xuiCard__root[id^="poke_"]', k._pokesDashboard_item);
8747 $$(target
, '.objectListItem[id^="poke_"], ._5lbv, .-cx-PRIVATE-pokesDashboard__pokercontent', k
._pokesDashboard_item
);
8749 if (hasClass(target
, 'highlight')) {
8750 var t
= target
.textContent
;
8751 t
= t
.replace(/You poked
/, 'You nuzzled ');
8752 if (target
.textContent
!= t
) {
8753 target
.textContent
= t
;
8758 k
._pokesDashboard_pokeLink(target
);
8763 k
._pokesDashboard_item = function(item
) {
8764 //var header = item.getElementsByClassName('pokeHeader');
8765 //if (!header || !header.length) {
8768 //header = header[0];
8771 var header
= item
.querySelector('._5lbt, .-cx-PRIVATE-pokesDashboard__pokername');
8773 // <div class="-cx-PRIVATE-pokesDashboard__pokername _5lbt lfloat"> <a href="" data-hovercard="">John</a> poked you.<br> <span class="-cx-PRIVATE-pokesDashboard__pokertime _5lbs"><abbr title="" data-utime="" class="timestamp">2 seconds ago</abbr></span></div>
8774 if (header
.childNodes
&& header
.childNodes
.length
) {
8775 if (header
.childNodes
[2] && header
.childNodes
[2].nodeType
=== TEXT_NODE
) {
8776 var poke
= header
.childNodes
[2];
8777 var t
= poke
.textContent
;
8778 t
= t
.replace(/ poked you
\./, ' nuzzled you.');
8779 if (poke
.textContent
!= t
) {
8780 poke
.textContent
= t
;
8782 } else if (header
.childNodes
[4] && header
.childNodes
[4].nodeType
=== ELEMENT_NODE
) {
8783 var poke
= header
.childNodes
[4];
8784 if (poke
.textContent
=== "Suggested Poke") {
8785 poke
.textContent
= "Suggested Nuzzle";
8790 var header
= item
.querySelector('.uiProfileBlockContent > ._6a > ._6b > .fwb'); // .-cx-PRIVATE-uiInlineBlock__root > .-cx-PRIVATE-uiInlineBlock__middle
8792 var t
= header
.innerHTML
;
8793 t
= t
.replace(/ poked you
\./, ' nuzzled you.');
8794 if (header
.innerHTML
!= t
) {
8795 header
.innerHTML
= t
;
8798 k
._pokesDashboard_pokeLink(item
);
8803 k
._pokesDashboard_pokeLink = function(target
) {
8804 // (Sep 25) Skip buttons
8805 $$(target
, 'a[ajaxify^="/pokes/inline/"]:not(._42ft)', function(poke
) {
8806 var text
= "Nuzzle";
8807 /*if (poke.getAttribute('ajaxify').indexOf('pokeback=1') != -1) { // http://fb.com/406911932763192
8808 text = "Nuzzle Back";
8811 if (poke
.childNodes
&& poke
.childNodes
.length
&& poke
.childNodes
[1]) {
8812 poke
.childNodes
[1].textContent
= text
;
8817 loopChildText(poke
, function(child
) {
8821 if (child
.nodeType
== TEXT_NODE
) {
8822 child
.textContent
= text
;
8829 k
.notification = function(dom
) {
8830 domReplaceFunc(dom
.target
, 'notification', '.notification', function(ele
) {
8831 k
._notification_change(ele
, '.info', k
._notification_general_metadata
);
8834 if (ONPLUGINPAGE
&& hasClass(dom
.target
, 'notification-item')) {
8835 //.$$(dom.target, '.notification-item', function(ele) {
8836 k
._notification_change(dom
.target
, '.notification-text > .message', k
._notification_messenger_metadata
);
8841 k
.notification_itemClass
= ['_33c', '-cx-PRIVATE-fbNotificationJewelItem__item'];
8842 k
.notification_textClass
= ['_4l_v', '-cx-PRIVATE-fbNotificationJewelItem__text'];
8843 k
.notification_metadataClass
= ['_33f', '-cx-PRIVATE-fbNotificationJewelItem__metadata'];
8844 k
._notification_react = function(ele
) {
8845 for (var i
= 0; i
<= 1; i
+= 1) {
8846 if (hasClass(ele
, k
.notification_itemClass
[i
])) {
8847 k
._notification_change(ele
, '.'+k
.notification_textClass
[i
]+' > span', k
._notification_react_metadata
);
8854 k
._notification_general_metadata = function(node
) {
8855 if (hasClass(node
, 'metadata') || hasClass(node
, 'blueName')) {
8861 k
._notification_messenger_metadata = function(node
) {
8862 // <a href="">X</a> likes your <a href="">comment</a>: "Also, please use this group in the..."
8863 //if (node.nodeType != TEXT_NODE) {
8869 k
._notification_react_metadata = function(node
) {
8870 if (hasClass(node
, 'fwb')) {
8873 if (hasClass(node
, k
.notification_metadataClass
[0]) || hasClass(node
, k
.notification_metadataClass
[1])) {
8879 k
._notification_change = function(ele
, info
, metadataFunc
) {
8880 var info
= ele
.querySelector(info
);
8884 if (!info
.childNodes
|| !info
.childNodes
.length
) {
8888 for (var i
= 0, len
= info
.childNodes
.length
; i
< len
; i
+= 1) {
8889 var node
= info
.childNodes
[i
];
8890 if (!metadataFunc(node
)) {
8894 var text
= node
.textContent
;
8895 if (text
.indexOf('"') != -1) {
8896 var finalText
= k
.textNotification(text
.substring(0, text
.indexOf('"')));
8897 finalText
+= text
.substring(text
.indexOf('"'), text
.length
);
8899 var finalText
= k
.textNotification(text
);
8902 if (node
.textContent
!= finalText
) {
8903 node
.textContent
= finalText
;
8906 if (text
.indexOf('"') != -1) {
8912 k
.menuPrivacyOnlyAjaxify
= [
8914 '%22value%22%3A%2280%22' // Everyone
8915 ,'%22value%22%3A%2250%22' // Friends of Friends
8916 ,'%22value%22%3A%2240%22' // Friends
8917 ,'%22value%22%3A%22127%22' // Friends except Acquaintances
8918 ,'%22value%22%3A%2210%22' // Only Me
8920 // https://www.facebook.com/settings?tab=timeline§ion=posting&view
8924 k
._processMenuXOldWidthDiff
= 0;
8925 k
.menuItems = function(dom
) {
8926 var processMenuX
= false;
8927 var hasScrollableArea
= false;
8928 k
._processMenuXOldWidthDiff
= 0;
8929 domReplaceFunc(dom
.target
, 'uiMenuItem', '.uiMenuItem, ._54ni, .-cx-PUBLIC-abstractMenuItem__root, .ufb-menu-item', function(ele
) {
8930 if (hasClass(ele
, 'ponyhoof_fbmenuitem')) {
8933 addClass(ele
, 'ponyhoof_fbmenuitem');
8935 // pages on share dialog
8936 if (hasClass(ele
, '_90z') || hasClass(ele
, '-cx-PRIVATE-fbShareModePage__smalliconcontainer')) {
8940 // lists/groups on Invite Friends dialogs
8941 var listendpoint
= ele
.getAttribute('data-listendpoint');
8942 if (listendpoint
&& listendpoint
!= '/ajax/chooser/list/friends/all/' && listendpoint
.indexOf('/ajax/chooser/list/friends/') == 0 && listendpoint
.indexOf('/ajax/chooser/list/friends/suggest/?filter=all') == -1 && listendpoint
.indexOf('/ajax/chooser/list/friends/app_all_friends/') == -1 && listendpoint
.indexOf('/ajax/chooser/list/friends/app_non_user/') == -1) {
8946 var replacer
= menuTitles
;
8947 if (hasClass(ele
, 'fbPrivacyAudienceSelectorOption')) {
8948 replacer
= menuPrivacyOnlyTitles
;
8950 // ensure that only FB-provided options get changed
8951 var itemAnchor
= ele
.getElementsByClassName('itemAnchor');
8952 if (itemAnchor
.length
) {
8953 var ajaxify
= itemAnchor
[0].getAttribute('ajaxify');
8954 // Sometimes ajaxify is missing (legacy edit video)
8956 var _menuPrivacyOnlyOk
= false;
8957 for (var i
= 0, len
= k
.menuPrivacyOnlyAjaxify
.length
; i
< len
; i
+= 1) {
8958 if (ajaxify
.indexOf(k
.menuPrivacyOnlyAjaxify
[i
]) != -1) {
8959 _menuPrivacyOnlyOk
= true;
8963 if (!_menuPrivacyOnlyOk
) {
8970 var label
= ele
.querySelector('.itemLabel, ._54nh, .-cx-PUBLIC-abstractMenuItem__label, .ufb-menu-item-label');
8972 //if (label.childNodes.length == 1) {
8973 // timeline post has 2
8974 var io
= label
.getElementsByTagName('span');
8976 if (!hasClass(io
[0], 'hidden_elem')) {
8983 var oldLabelWidth
= 0;
8984 ele
.setAttribute('data-ponyhoof-menuitem-orig', ele
.textContent
);
8985 loopChildText(label
, function(child
) {
8986 if (child
.nodeType
== 3) {
8987 var t
= child
.textContent
;
8989 t
= replaceText(replacer
, t
);
8990 if (child
.textContent
!= t
) {
8991 if (!hasScrollableArea
&& (ele
.parentNode
&& ele
.parentNode
.parentNode
&& hasClass(ele
.parentNode
.parentNode
, 'uiScrollableAreaContent'))) {
8992 hasScrollableArea
= true;
8994 if (hasScrollableArea
) {
8995 label
.style
.display
= 'inline-block';
8996 if (!oldLabelWidth
) {
8997 oldLabelWidth
= label
.offsetWidth
;
9000 child
.textContent
= t
;
9006 orig
= orig
.substr(0, orig
.length
-1);
9007 replaced
= replaced
.substr(0, replaced
.length
-1);
9008 ele
.setAttribute('data-ponyhoof-menuitem-text', replaced
);
9009 ele
.setAttribute('data-label', replaced
); // technically, this is only used for .uiMenuItem
9011 if (orig
!= replaced
) {
9012 if (hasClass(ele
, '_54ni') || hasClass(ele
, '-cx-PUBLIC-abstractMenuItem__root')) {
9013 if (hasScrollableArea
&& oldLabelWidth
) {
9014 var newWidth
= label
.offsetWidth
;
9015 if (newWidth
> oldLabelWidth
) {
9016 k
._processMenuXOldWidthDiff
= Math
.max(newWidth
- oldLabelWidth
, 0);
9017 processMenuX
= true;
9020 processMenuX
= true;
9024 if (hasScrollableArea
) {
9025 label
.style
.display
= '';
9031 if (hasClass(dom
.target
, 'uiContextualLayerPositioner')) {
9032 k
._menuItems_processMenuX(dom
.target
);
9036 k
.getParent(dom
.target
, function(parent
) {
9037 return hasClass(parent
, 'uiContextualLayerPositioner');
9038 }, k
._menuItems_processMenuX
);
9041 k
._menuItems_processMenuX = function(layer
) {
9046 var ownerid
= layer
.getAttribute('data-ownerid');
9050 ownerid
= $(ownerid
);
9055 var menu
= layer
.querySelector('._54nq, .-cx-PUBLIC-abstractMenu__wrapper');
9060 if (k
._processMenuXOldWidthDiff
) {
9061 var uiScrollableArea
= layer
.getElementsByClassName('uiScrollableArea');
9062 var uiScrollableAreaBody
= layer
.getElementsByClassName('uiScrollableAreaBody');
9063 if (uiScrollableArea
&& uiScrollableAreaBody
) {
9064 uiScrollableArea
= uiScrollableArea
[0];
9065 uiScrollableAreaBody
= uiScrollableAreaBody
[0];
9067 uiScrollableArea
.style
.width
= (parseInt(uiScrollableArea
.style
.width
)+k
._processMenuXOldWidthDiff
)+'px';
9068 uiScrollableAreaBody
.style
.width
= (parseInt(uiScrollableAreaBody
.style
.width
)+k
._processMenuXOldWidthDiff
)+'px';
9072 var border
= layer
.querySelector('._54hx, .-cx-PUBLIC-abstractMenu__shortborder');
9076 border
.style
.width
= (Math
.max((menu
.offsetWidth
- ownerid
.offsetWidth
), 0))+'px';
9079 k
.fbRemindersStory = function(target
) {
9080 $$(target
, '.fbRemindersStory', function(item
) {
9081 var reminderType
= '';
9082 if (item
.querySelector('#pages_reminders_link')) {
9083 reminderType
= 'page';
9086 var inner
= item
.querySelector('._42ef > .fcg, .-cx-PRIVATE-uiFlexibleBlock__flexiblecontent > .fcg');
9091 loopChildText(inner
, function(child
) {
9092 if (child
.nodeType
== TEXT_NODE
) {
9093 var t
= child
.textContent
;
9094 if (reminderType
=== 'page') {
9095 t
= t
.replace(/\binvited you to like
\b/, "invite you to "+CURRENTSTACK
['like']);
9097 t
= t
.replace(/\bpoked you
\b/, "nuzzled you");
9099 if (child
.textContent
!= t
) {
9100 child
.textContent
= t
;
9103 if (hasClass(child
, 'fbRemindersTitle')) {
9104 var t
= child
.innerHTML
;
9105 t
= t
.replace(/([0-9]+?) events
/, "$1 adventures")
9106 if (child
.innerHTML
!= t
) {
9107 child
.innerHTML
= t
;
9115 k
.flyoutLikeForm = function(target
) {
9116 //var result = k._flyoutLikeForm(target, 'groupsMemberFlyoutLikeForm', 'unlike');
9117 var result
= k
._flyoutLikeForm(target
, '_5nx0', 'unlike');
9119 result
= k
._flyoutLikeForm(target
, 'fbEventMemberLike', 'liked');
9124 k
._flyoutLikeForm = function(target
, className
, forminput
) {
9125 domReplaceFunc(target
, className
, '.'+className
, function(ele
) {
9126 if (!ele
.elements
[forminput
]) {
9131 if (ele
.elements
[forminput
].value
== 1) {
9135 var submit
= ele
.querySelector('input[type="submit"]');
9140 submit
.value
= capitaliseFirstLetter(CURRENTSTACK
['like']);
9142 submit
.value
= capitaliseFirstLetter(CURRENTSTACK
['unlike']);
9146 if (hasClass(target
, className
)) {
9152 k
.pluginButton = function(target
) {
9153 if (!ONPLUGINPAGE
) {
9157 var root
= target
.getElementsByClassName('pluginConnectButtonLayoutRoot');
9159 var root
= target
.getElementsByClassName('pluginSkinLight');
9166 domReplaceFunc(root
, '', '.pluginButton', function(ele
) {
9168 var div
= ele
.getElementsByClassName('pluginButtonLabel');
9171 if (div
.innerHTML
=== "Like") {
9172 div
.innerHTML
= capitaliseFirstLetter(CURRENTSTACK
['like']);
9178 var div
= ele
.getElementsByTagName('div');
9183 // <div class="pluginButton pluginButtonInline pluginConnectButtonDisconnected hidden_elem" title="Like"><div><button type="submit"><i class="pluginButtonIcon img sp_like sx_like_thumb"></i><span class="accessible_elem">Like</span></button><span aria-hidden="true">Like</span></div></div>
9185 loopChildText(ele
, function(child
) {
9189 if (child
.tagName
.toUpperCase() === 'SPAN') {
9190 if (child
.innerHTML
=== "Like") {
9191 child
.innerHTML
= capitaliseFirstLetter(CURRENTSTACK
['like']);
9198 domReplaceFunc(root
, '', '.uiIconText', function(ele
) {
9199 // <div style="padding-left: 19px;" class="uiIconText"><i class="img sp_like sx_like_fav" style="top: 0px;"></i><span id="u_0_1">You, <a href="https://www.facebook.com/XXX" target="_blank">XXX</a> and 102,502 others like this.</span><span class="hidden_elem" id="u_0_2"><a href="https://www.facebook.com/XXX" target="_blank">XXX</a> and 102,502 others like this.</span></div>
9200 loopChildText(ele
, function(child
) {
9201 loopChildText(child
, function(inner
) {
9202 if (inner
.nodeType
=== TEXT_NODE
) {
9203 var t
= k
.likeSentence(inner
.textContent
);
9204 t
= t
.replace(/\bfriends\b/g, CURRENTSTACK
['friends_logic']); // Be the first of your friends.
9205 if (inner
.textContent
!= t
) {
9206 inner
.textContent
= t
;
9214 $$(root
, '._51mx > .pls > div > span', function(ele
) {
9215 var orig
= ele
.textContent
;
9216 var t
= k
.likeSentence(orig
);
9217 t
= t
.replace(/\bfriends\b/g, CURRENTSTACK
['friends_logic']); // Be the first of your friends.
9219 ele
.textContent
= t
;
9224 k
.pluginCommentBox = function(target
) {
9225 if (!ONPLUGINPAGE
) {
9229 domChangeTextbox(target
, '.fbFeedbackContent .fbFeedbackMentions .mentionsTextarea', CURRENTLANG
['fb_comment_box']);
9232 k
.ticker = function(dom
) {
9233 domReplaceFunc(dom
.target
, 'fbFeedTickerStory', '.fbFeedTickerStory', function(ele
) {
9234 var div
= ele
.getElementsByClassName('uiStreamMessage');
9238 // Ticker messages are really inconsistent
9239 // <span class="passiveName">Friend</span> brohoofs <span class="token">Page</span>'s <span class="token">photo</span>.
9240 // <span class="passiveName">Friend</span> added a new pony pic.
9241 // <span class="passiveName">Friend</span> brohoofs <span class="token">Page</span>'s <span class="token">video</span> Title. // http://fb.com/10200537039965966
9242 var continueTextNodes
= true;
9243 for (var i
= 0, len
= div
.childNodes
.length
; i
< len
; i
+= 1) {
9244 var node
= div
.childNodes
[i
];
9245 if (node
.nodeType
== TEXT_NODE
) {
9246 if (!continueTextNodes
) {
9250 var t
= node
.textContent
;
9253 var haltOnBoundary
= false;
9254 if (t
.indexOf('"') != -1) {
9256 haltOnBoundary
= true;
9257 } else if (t
.indexOf('\'s') != -1) {
9259 continueTextNodes
= false;
9263 var finalText
= k
.textNotification(t
.substring(0, t
.indexOf(boundary
)));
9264 finalText
+= t
.substring(t
.indexOf(boundary
), t
.length
);
9266 var finalText
= k
.textNotification(t
);
9268 //t = t.replace(/\blikes\b/, " "+CURRENTSTACK['likes_past']);
9269 //t = t.replace(/\blike\b/, " "+CURRENTSTACK['like_past']);
9270 if (node
.textContent
!= finalText
) {
9271 node
.textContent
= finalText
;
9274 if (boundary
&& haltOnBoundary
) {
9278 // It's too risky changing legit page names, so we are doing this in isolated cases
9279 if (hasClass(node
, 'token')) {
9281 ['photo', 'pony pic']
9282 ,['a photo', 'a pony pic']
9283 ,['wall', 'journal']
9285 var t
= replaceText(list
, node
.textContent
);
9286 if (node
.textContent
!= t
) {
9287 node
.textContent
= t
;
9294 if (hasClass(dom
.target
, 'fbFeedTickerStory')) {
9300 k
.pagesVoiceBarText = function(target
) {
9301 if (hasClass(target
, 'pagesVoiceBarText')) {
9302 if (target
.childNodes
&& target
.childNodes
.length
&& target
.childNodes
[0]) {
9303 var textNode
= target
.childNodes
[0];
9304 if (textNode
.nodeType
== TEXT_NODE
) {
9305 var t
= textNode
.textContent
;
9306 t
= t
.replace(/\bliking\b/, CURRENTSTACK
['liking']);
9307 if (textNode
.textContent
!= t
) {
9308 textNode
.textContent
= t
;
9317 k
.endOfFeedPymlContainer = function(target
) {
9318 if (target
.getAttribute
&& target
.getAttribute('id') === 'endOfFeedPymlContainer') {
9319 // _5jii - applicable table cell
9320 $$(target
, '._5jii .fsm.fcg', function(ele
) {
9321 var orig
= ele
.textContent
;
9323 t
= t
.replace(/\bLikes\b/, capitaliseFirstLetter(CURRENTSTACK
['likes']));
9324 t
= t
.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK
['like']));
9325 t
= t
.replace(/\blikes\b/, CURRENTSTACK
['likes']);
9326 t
= t
.replace(/\blike\b/, CURRENTSTACK
['like']);
9328 ele
.textContent
= t
;
9331 $$(target
, '._5jii ._5f55', function(link
) {
9332 if (link
.childNodes
&& link
.childNodes
.length
&& link
.childNodes
[1] && link
.childNodes
[1].nodeType
=== TEXT_NODE
) {
9333 var node
= link
.childNodes
[1];
9334 var orig
= node
.textContent
;
9336 t
= t
.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK
['like']));
9338 node
.textContent
= t
;
9348 k
.pubcontentFeedChaining = function(target
) {
9349 if (hasClass(target
, '_5j5u')) {
9350 $$(target
, '._5j5w > .content > div > .fcg', function(fcg
) {
9351 var orig
= fcg
.textContent
;
9353 t
= t
.replace(/\blikes\b/, CURRENTSTACK
['likes']);
9354 t
= t
.replace(/\blike\b/, CURRENTSTACK
['like']);
9356 fcg
.textContent
= t
;
9365 k
._beepNotification_condition_react = function(node
, gt
) {
9366 // <span id=""><span class="fwb" id=""><span id="">XYZ</span></span><span id=""> also commented on a </span><span class="fwb" id=""><span id="">photo</span></span><span id=""> in </span><span class="fwb" id=""><span id="">GROUP NAME</span></span><span id="">: "What?"</span></span>
9367 // <span data-reactid=""><span class="fwb" data-reactid="">NAME</span><span data-reactid=""> commented on your pony pic in </span><span class="fwb" data-reactid="">GROUP NAME</span><span data-reactid="">: "COMMENT"</span></span>
9369 // **XYZ** posted on **Ponyhoof**'s **timeline**: "XYZ"
9370 // **profile people test** posted in **group people test**: "like test"
9371 if (hasClass(node
, 'fwb')) {
9372 if (node
.textContent
=== 'timeline') {
9380 k
._beepNotification_change = function(ele
, info
, condition
) {
9385 var gt
= JSON
.parse(ele
.getAttribute('data-gt'));
9386 ele
.setAttribute('data-ponyhoof-beeper-orig', info
.textContent
);
9387 for (var i
= 0, len
= info
.childNodes
.length
; i
< len
; i
+= 1) {
9388 var node
= info
.childNodes
[i
];
9389 if (condition(node
, gt
)) {
9391 if (node
.nodeType
=== TEXT_NODE
) {
9392 text
= node
.textContent
;
9393 k
._beepNotification_change_text(node
, text
);
9395 // emoticons are smacked together, so we need to run another loop
9396 for (var j
= 0, jLen
= node
.childNodes
.length
; j
< jLen
; j
+= 1) {
9397 var textNode
= node
.childNodes
[j
];
9398 text
= textNode
.textContent
;
9399 k
._beepNotification_change_text(textNode
, text
);
9403 if (text
.indexOf('"') != -1) {
9408 ele
.setAttribute('data-ponyhoof-beeper-message', info
.textContent
);
9410 if (userSettings
.sounds
) {
9412 if (SOUNDS
[userSettings
.soundsFile
]) {
9413 file
= userSettings
.soundsFile
;
9416 if (!file
|| file
== 'AUTO') {
9417 file
= '_sound/defaultNotification';
9419 var data
= convertCodeToData(REALPONY
);
9420 if (data
.soundNotif
) {
9421 file
= data
.soundNotif
;
9425 if (userSettings
.soundsNotifTypeBlacklist
) {
9426 var current
= userSettings
.soundsNotifTypeBlacklist
.split('|');
9428 if (current
.indexOf(gt
.notif_type
) != -1) {
9434 var finalfile
= THEMEURL
+file
+'.EXT';
9435 if (gt
.notif_type
== 'poke' && CURRENTSTACK
.stack
== 'pony') {
9436 finalfile
= THEMEURL
+'_sound/pokeSound.EXT';
9439 var ps
= initPonySound('notif', finalfile
);
9446 k
._beepNotification_change_text = function(node
, text
) {
9450 if (text
.indexOf('"') != -1) {
9451 var finalText
= k
.textNotification(text
.substring(0, text
.indexOf('"')));
9452 finalText
+= text
.substring(text
.indexOf('"'), text
.length
);
9454 var finalText
= k
.textNotification(text
);
9457 if (text
!= finalText
) {
9458 if (node
.nodeType
=== TEXT_NODE
) {
9459 node
.textContent
= finalText
;
9461 node
.innerHTML
= finalText
;
9466 k
.insightsCountryData
= [
9467 ["United States of America", "United States of Amareica"]
9468 ,["Malaysia", "Marelaysia"]
9469 ,["Mexico", "Mexicolt"]
9470 ,["New Zealand", "Neigh Zealand"]
9471 ,["Philippines", "Fillypines"]
9472 ,["Singapore", "Singapony"]
9473 ,["Singapore, Singapore", "Singapony"]
9475 k
.insightsCountry = function(target
) {
9476 /*domReplaceFunc(dom.target, 'breakdown-list-table', '.breakdown-list-table', function(ele) {
9477 if (ele.getAttribute('data-ponyhoof-ponified')) {
9480 ele.setAttribute('data-ponyhoof-ponified', 1);
9481 $$(ele, '.breakdown-key .ufb-text-content', function(country) {
9482 country.textContent = replaceText(k.insightsCountryData, country.textContent);
9486 $$(target
, '._5brx ._55jr', function(ele
) {
9487 var orig
= ele
.textContent
;
9489 t
= replaceText(k
.insightsCountryData
, ele
.textContent
);
9491 ele
.textContent
= t
;
9496 k
.timelineMutualLikes = function(target
) {
9497 $$(target
, '.fbStreamTimelineFavStory', function(root
) {
9498 $$(root
, '.fbStreamTimelineFavInfoContainer', function(ele
) {
9500 loopChildText(ele
, function(child
) {
9504 if (child
.nodeType
== TEXT_NODE
) {
9505 var t
= k
.textStandard(child
.textContent
);
9506 if (child
.textContent
!= t
) {
9507 child
.textContent
= t
;
9514 $$(root
, '.fbStreamTimelineFavFriendContainer > .friendText > .fwn', function(ele
) {
9515 loopChildText(ele
, function(child
) {
9516 if (child
.nodeType
== ELEMENT_NODE
) {
9517 if (!child
.href
|| child
.href
.indexOf('/browse/users/') == -1) {
9521 var t
= k
.textStandard(child
.textContent
);
9522 if (child
.textContent
!= t
) {
9523 child
.textContent
= t
;
9530 // http://fb.com/406714556116263
9531 // http://fb.com/411361928984859
9532 k
.videoStageContainer = function(target
) {
9533 if (hasClass(target
, 'videoStageContainer')) {
9534 addClass(k
.photos_snowlift
, 'ponyhoof_snowlift_video');
9535 } else if (hasClass(target
, 'spotlight')) {
9536 removeClass(k
.photos_snowlift
, 'ponyhoof_snowlift_video');
9540 k
.uiStreamShareLikePageBox = function(target
) {
9541 $$(target
, '.uiStreamShareLikePageBox .uiPageLikeButton.rfloat + div > .fcg', function(ele
) {
9542 var t
= ele
.textContent
;
9543 t
= t
.replace(/likes/g, CURRENTSTACK
['likes']);
9544 t
= t
.replace(/like/g, CURRENTSTACK
['like']);
9545 if (ele
.textContent
!= t
) {
9546 ele
.textContent
= t
;
9551 k
.fbTimelineUnit = function(target
) {
9552 if (!hasClass(target
, 'fbTimelineUnit')) {
9555 if (target
.childNodes
&& target
.childNodes
.length
) {
9556 if (hasClass(target
.childNodes
[1], 'pageFriendSummaryContainer')) {
9557 var headerText
= target
.childNodes
[1].getElementsByClassName('headerText');
9558 if (!headerText
.length
) {
9561 headerText
= headerText
[0];
9564 $$(headerText
, '.fwb > a', function(link
) {
9565 var t
= link
.textContent
;
9566 t
= t
.replace(/\bFriends\b/, capitaliseFirstLetter(CURRENTSTACK
['friends']));
9567 t
= t
.replace(/\bFriend\b/, capitaliseFirstLetter(CURRENTSTACK
['friend']));
9568 if (link
.textContent
!= t
) {
9569 link
.textContent
= t
;
9574 $$(headerText
, '.fcg', function(fcg
) {
9575 var split
= fcg
.textContent
.split(' ');
9577 t
= t
.replace(/\bLikes\b/, capitaliseFirstLetter(CURRENTSTACK
['likes']));
9578 t
= t
.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK
['like']));
9579 if (split
[0] != t
) {
9581 fcg
.textContent
= split
.join(' ');
9588 // Brohoofs section at pages
9589 var liked_pages_timeline_unit_list
= $('liked_pages_timeline_unit_list');
9590 if (liked_pages_timeline_unit_list
) {
9591 $$(liked_pages_timeline_unit_list
, '._42ef .fcg', function(fcg
) {
9592 loopChildText(fcg
, function(child
) {
9593 // <a href="/browse/friended_fans_of/?page_id=X" ajaxify="/ajax/browser/dialog/friended_fans_of/?page_id=X" rel="dialog" role="button">4 friends</a>
9595 var t
= child
.textContent
;
9596 t
= k
.textStandard(t
);
9597 if (child
.textContent
!= t
) {
9598 child
.textContent
= t
;
9606 // https://www.facebook.com/pages
9607 k
.pageBrowserItem = function(target
) {
9608 // lazy-loaded: <div class="_8qg fsm fwn fcg"><a href="" data-hovercard="/ajax/hovercard/user.php?id="></a> likes this.<div class="_43qm mbs _43q9"><ul class="uiList _4cg3 _509- _4ki"><li class="_43q7">FACEPILE</li></ul></div></div>
9609 // <a href="" data-hovercard="/ajax/hovercard/user.php?id="></a> and <a href="/browse/friended_fans_of/?page_id=" ajaxify="/ajax/browser/dialog/friended_fans_of/?page_id=" rel="dialog" role="button">8 other friends</a> like this.
9610 if (hasClass(target
, '_8qg') && hasClass(target
, 'fcg')) {
9611 k
._pageBrowserItem_item(target
);
9615 $$(target
, '._8qg.fcg', function(item
) {
9616 // <div class="_8qg fsm fwn fcg"><div class="_8qg fsm fwn fcg"><div class="fsm fwn fcg">235,674 likes · 40,634 people talking about this</div></div></div>
9617 k
._pageBrowserItem_item(item
);
9621 k
._pageBrowserItem_item = function(item
) {
9622 loopChildText(item
, function(child
) {
9624 if (child
.nodeType
=== ELEMENT_NODE
) {
9625 href
= child
.getAttribute('href');
9627 if (child
.nodeType
=== TEXT_NODE
|| hasClass(child
, 'fcg') || (href
&& href
.indexOf('/browse/friended_fans_of/') != -1)) {
9628 k
.textBrohoof(child
);
9633 k
.EntstreamCollapsedUFISentence = function(target
) {
9634 $$(target
, '._5civ > a', function(link
) {
9635 var ajaxify
= link
.getAttribute('ajaxify');
9636 if (ajaxify
&& ajaxify
.indexOf('/ajax/browser/dialog/likes') === 0) {
9637 k
._EntstreamCollapsedUFISentence_change(link
);
9642 k
._EntstreamCollapsedUFISentence_change = function(link
) {
9643 var orig
= link
.textContent
;
9645 t
= t
.replace(/ Likes
$/, " "+capitaliseFirstLetter(CURRENTSTACK
['likes']));
9646 t
= t
.replace(/ Like
$/, " "+capitaliseFirstLetter(CURRENTSTACK
['like']));
9648 link
.textContent
= t
;
9652 k
._dialog_insertReadme = function(body
) {
9654 $$(body
, '._22i .uiToken > input[type="hidden"]', function(input
) { // @cx
9658 if (input
.getAttribute('name') == 'undefined[]' && isPonyhoofPage(input
.value
)) { // undefined[] is intentional from FB, NOT A TYPO
9659 addClass(body
, 'ponyhoof_composer_hasReadme');
9661 var n
= d
.createElement('iframe');
9662 n
.className
= 'ponyhoof_page_readme';
9663 n
.scrolling
= 'auto';
9664 n
.frameborder
= '0';
9665 n
.allowtransparency
= 'true';
9666 n
.src
= PONYHOOF_README
;
9667 body
.appendChild(n
);
9674 k
._dialog_playSound = function(title
, outer
) {
9678 var lowercase
= title
.toLowerCase();
9679 for (var i
= 0, len
= dialogDerpTitles
.length
; i
< len
; i
+= 1) {
9680 if (dialogDerpTitles
[i
].toLowerCase() == lowercase
) {
9682 addClass(outer
, 'ponyhoof_fbdialog_derp');
9685 if (CURRENTSTACK
.stack
== 'pony' && userSettings
.sounds
&& !isPageHidden()) {
9686 var ps
= initPonySound('ijustdontknowwhatwentwrong', THEMEURL
+'_sound/ijustdontknowwhatwentwrong.EXT');
9695 k
.ponyhoofPageOptions = function(dom
) {
9696 if (!$('pagelet_timeline_page_actions')) {
9699 if ($('ponyhoof_footer_options')) {
9703 var selector
= dom
.target
.querySelector('#pagelet_timeline_page_actions .fbTimelineActionSelector');
9707 var menu
= selector
.getElementsByClassName('uiMenuInner');
9712 var whatpage
= menu
.querySelector('#fbpage_share_action a');
9716 if (whatpage
.getAttribute('href').indexOf('p[]='+PONYHOOF_PAGE
) != -1) {
9717 var button
= selector
.getElementsByClassName('fbTimelineActionSelectorButton');
9718 if (!button
.length
) {
9723 var sep
= d
.createElement('li');
9724 sep
.className
= 'uiMenuSeparator';
9726 var a
= d
.createElement('a');
9727 a
.className
= 'itemAnchor';
9728 a
.setAttribute('role', 'menuitem');
9729 a
.setAttribute('tabindex', '0');
9731 a
.id
= "ponyhoof_footer_options";
9732 a
.innerHTML
= '<span class="itemLabel fsm">'+CURRENTLANG
.options_title
+'</span>';
9733 a
.addEventListener('click', function(e
) {
9743 var li
= d
.createElement('li');
9744 li
.className
= 'uiMenuItem ponyhoof_fbmenuitem';
9745 li
.setAttribute('data-label', CURRENTLANG
.options_title
);
9746 li
.setAttribute('data-ponyhoof-menuitem-orig', CURRENTLANG
.options_title
);
9747 li
.setAttribute('data-ponyhoof-menuitem-text', CURRENTLANG
.options_title
);
9750 menu
.insertBefore(sep
, menu
.firstChild
);
9751 menu
.insertBefore(li
, sep
);
9755 k
.debug_betaFacebookBaseRewrote
= false;
9756 k
.debug_betaFacebookLinks = function(target
) {
9757 if (!k
.debug_betaFacebookBaseRewrote
) {
9758 contentEval(function(arg
) {
9760 if (typeof window
.requireLazy
== 'function') {
9761 window
.requireLazy(['Env'], function(Env
) {
9762 Env
.www_base
= window
.location
.protocol
+'//'+window
.location
.hostname
+'/';
9766 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
9767 console
.log("Unable to hook to Env");
9771 }, {"CANLOG":CANLOG
});
9772 k
.debug_betaFacebookBaseRewrote
= true;
9774 var links
= target
.querySelectorAll('a[href^="http://www.facebook.com"], a[href^="https://www.facebook.com"]');
9775 for (var i
= 0, len
= links
.length
; i
< len
; i
+= 1) {
9776 var link
= links
[i
];
9777 var href
= link
.href
;
9778 href
= href
.replace(/http\:\/\/www.facebook.com\//, 'http://beta.facebook.com/');
9779 href
= href
.replace(/https\:\/\/www.facebook.com\//, 'https://beta.facebook.com/');
9786 k
.mutateCharacterData = function(mutation
) {
9788 if (mutation
.target
&& mutation
.target
.parentNode
) {
9789 parent
= mutation
.target
.parentNode
;
9790 if (parent
.tagName
.toUpperCase() == 'ABBR') {
9795 if (userSettings
.debug_mutationDebug
) {
9797 console
.log('characterData:');
9799 console
.dir(mutation
.target
);
9804 k
.textNodes({target: mutation
.target
});
9809 var id
= parent
.getAttribute(k
.REACTATTRNAME
);
9811 if (parent
.rel
== 'dialog') {
9812 var ajaxify
= parent
.getAttribute('ajaxify');
9813 if (ajaxify
&& ajaxify
.indexOf('/ajax/browser/dialog/likes') === 0) {
9814 if (parent
.parentNode
&& hasClass(parent
.parentNode
, '_5civ')) {
9816 k
._EntstreamCollapsedUFISentence_change(parent
);
9818 k
.getParent(parent
, function(likesentence
) {
9819 return hasClass(likesentence
, 'UFILikeSentence');
9820 }, function(likesentence
) {
9822 k
._likePostBox(likesentence
);
9827 } else if (hasClass(parent
.parentNode
, 'UFIPagerLink')) {
9828 k
.ufiPagerLink({target: parent
.parentNode
.parentNode
});
9829 } else if (hasClass(parent
, 'ponyhoof_brohoof_button')) {
9830 k
._commentLikeLink(parent
);
9831 } else if (parent
.nextSibling
&& hasClass(parent
.nextSibling
, 'UFIOrderingModeSelectorDownCaret')) {
9832 k
.UFIOrderingMode(parent
);
9834 if (parent
.parentNode
&& parent
.parentNode
.parentNode
) {
9835 //if (hasClass(parent.parentNode.parentNode, 'UFIImageBlockContent') || (parent.parentNode.parentNode.parentNode && hasClass(parent.parentNode.parentNode.parentNode, 'UFIImageBlockContent'))) {
9836 if (hasClass(parent
.parentNode
.parentNode
, 'UFILikeSentenceText') || (parent
.parentNode
.parentNode
.parentNode
&& hasClass(parent
.parentNode
.parentNode
.parentNode
, 'UFILikeSentenceText'))) {
9838 // You and John brohoof this.
9840 var ufi
= k
.getReactUfi(parent
);
9842 k
.postLike({target: ufi
});
9845 if (hasClass(parent
.parentNode
.parentNode
, k
.notification_textClass
[0]) || hasClass(parent
.parentNode
.parentNode
, k
.notification_textClass
[1])) {
9846 // gosh, i dislike this...
9847 k
.getParent(parent
, function(notificationItem
) {
9848 return hasClass(notificationItem
, k
.notification_itemClass
[0]) || hasClass(notificationItem
, k
.notification_itemClass
[1]);
9849 }, function(notificationItem
) {
9850 if (!notificationItem
) {
9855 if (hasClass(notificationItem
, k
.notification_itemClass
[1])) {
9859 k
._notification_change(notificationItem
, '.'+k
.notification_textClass
[i
]+' > span', k
._notification_react_metadata
);
9866 if (hasClass(parent
, '_5lbu') || hasClass(parent
, '-cx-PRIVATE-pokesDashboard__pokerbuttons')) {
9868 var t
= mutation
.target
.textContent
;
9869 t
= t
.replace(/\bPoke\b/, 'Nuzzle');
9870 if (mutation
.target
.textContent
!= t
) {
9871 mutation
.target
.textContent
= t
;
9877 k
.mutateAttributes = function(mutation
) {
9878 //if (mutation.attributeName.indexOf('data-ponyhoof-') == 0) {
9881 var target
= mutation
.target
;
9882 if (mutation
.attributeName
== 'title') {
9883 if (target
.title
== target
.getAttribute('data-ponyhoof-title-modified')) {
9887 switch (mutation
.attributeName
) {
9889 var id
= target
.getAttribute(k
.REACTATTRNAME
);
9891 if (hasClass(target
, 'UFILikeLink')) {
9892 if (target
.title
== '' && mutation
.oldValue
!= '') { // thanks a lot Hover Zoom
9893 target
.setAttribute('data-ponyhoof-title', mutation
.oldValue
);
9894 target
.setAttribute('data-ponyhoof-title-modified', mutation
.oldValue
);
9896 var orig
= target
.title
;
9898 t
= t
.replace(/\bcomment\b/, "friendship letter");
9899 t
= t
.replace(/\bLike this \b/, capitaliseFirstLetter(CURRENTSTACK
.like
)+' this ');
9900 t
= t
.replace(/\bUnlike this \b/, capitaliseFirstLetter(CURRENTSTACK
.unlike
)+' this ');
9901 t
= t
.replace(/\bunlike this \b/, CURRENTSTACK
.unlike
+' this ');
9902 t
= t
.replace(/\bliking this \b/, CURRENTSTACK
.liking
+' this ');
9907 target
.setAttribute('data-ponyhoof-title', orig
);
9908 target
.setAttribute('data-ponyhoof-title-modified', t
);
9915 if (/*(target.parentNode && hasClass(target.parentNode, 'uiButton')) || * /hasClass(target, 'ufb-button-input')) {
9916 var button = target.parentNode;
9918 var orig = target.value;
9919 var replaced = replaceText(buttonTitles, orig);
9920 if (/*hasClass(button, 'uiButton') || * /hasClass(button, 'ufb-button')) {
9921 if (button.getAttribute('data-hover') != 'tooltip') {
9922 if (orig != replaced) {
9923 if (button.title == '') {
9924 button.title = orig;
9926 if (button.title == button.getAttribute('data-ponyhoof-button-orig')) {
9927 button.title = orig;
9934 button.setAttribute('data-ponyhoof-button-orig', orig);
9935 button.setAttribute('data-ponyhoof-button-text', replaced);
9937 if (orig != replaced) {
9938 target.value = replaced;
9950 k
.getParent = function(ele
, iffunc
, func
) {
9951 var outer
= ele
.parentNode
;
9953 if (iffunc(outer
)) {
9956 outer
= outer
.parentNode
;
9962 k
.changeButtonText = function(button
, t
) {
9963 if (button
.tagName
.toUpperCase() == 'INPUT') {
9966 button
.innerHTML
= t
;
9970 // Delays and let Facebook finish changing the DOM
9971 // Note that this shouldn't be a problem when MutationObserver is used full-time
9972 k
.delayIU = function(func
, delay
) {
9973 var delay
= delay
|| 10;
9975 if (USINGMUTATION
) {
9980 w
.setTimeout(function() {
9981 var iu
= INTERNALUPDATE
;
9982 INTERNALUPDATE
= true;
9984 INTERNALUPDATE
= iu
;
9988 k
.getReactUfi = function(ele
) {
9989 // .reactRoot[3].[1][0].0.[1].0.0.[2]
9990 var finalid
= k
.getReactId(ele
);
9992 var ufi
= d
.querySelector('div['+k
.REACTATTRNAME
+'=".r['+finalid
+']"]');
9993 if (ufi
&& hasClass(ufi
, 'UFIList')) {
9997 // Rollback to old method
9998 k
.getParent(ele
, function(ufiitem
) {
9999 return hasClass(ufiitem
, 'UFIList');
10000 }, function(ufiitem
) {
10006 k
.getReactCommentComponent = function(ele
) {
10007 // .reactRoot[3].[1][2][1]{comment105273202993369_7901}.0.[1].0.[1].0.[1].[2]
10008 // .reactRoot[1].:1:1:1:comment558202387555478_1973546.:0.:1.:0.:1.:0
10009 var id
= ele
.getAttribute(k
.REACTATTRNAME
);
10013 var open
= id
.indexOf('{comment');
10015 var closeCount
= 1;
10017 open
= id
.indexOf(':comment');
10024 var subEnd
= id
.substring(open
, id
.length
).indexOf(close
);
10025 var component
= id
.substring(0, open
+subEnd
+closeCount
);
10030 k
.getReactComment = function(ele
) {
10031 var component
= k
.getReactCommentComponent(ele
);
10033 var comment
= d
.querySelector('div['+k
.REACTATTRNAME
+'="'+component
+'"]');
10034 if (comment
&& hasClass(comment
, 'UFIComment')) {
10038 // Rollback to old method
10039 k
.getParent(ele
, function(ufiitem
) {
10040 return hasClass(ufiitem
, 'UFIComment');
10041 }, function(ufiitem
) {
10047 k
.getTrackingNode = function(ele
) {
10048 var trackingNode
= ele
.getAttribute('data-ft');
10049 if (trackingNode
) {
10051 trackingNode
= JSON
.parse(trackingNode
);
10052 return trackingNode
.tn
;
10058 k
.updateLayerPosition = function(layer
) {
10059 var tempClass
= 'ponyhoof_temp_'+(+new Date());
10060 addClass(layer
, tempClass
);
10062 contentEval(function(arg
) {
10064 if (typeof window
.requireLazy
== 'function') {
10065 window
.requireLazy(['DataStore'], function(DataStore
) {
10066 var layer
= document
.getElementsByClassName(arg
.tempClass
);
10067 if (!layer
|| !layer
.length
) {
10072 var layerClass
= DataStore
.get(layer
, 'layer');
10073 layerClass
.updatePosition();
10076 if (layer
.classList
) {
10077 layer
.classList
.remove(arg
.tempClass
);
10082 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
10083 console
.log("Unable to hook to DataStore");
10087 }, {'CANLOG':CANLOG
, 'tempClass':tempClass
});
10089 if (!layer
.classList
) {
10090 w
.setTimeout(function() {
10091 removeClass(layer
, tempClass
);
10096 // Ignore irrelevant tags and some classes
10097 k
.shouldIgnore = function(dom
) {
10098 if (dom
.target
.nodeType
== 8) { // comments
10102 if (dom
.target
.nodeType
!= 3) {
10103 var tn
= dom
.target
.tagName
.toUpperCase();
10104 if (tn
== 'SCRIPT' || tn
== 'STYLE' || tn
== 'LINK' || tn
== 'INPUT' || tn
== 'BR' || tn
== 'META') {
10109 if (dom
.target
.parentNode
&& /(DOMControl_shadow|highlighterContent|textMetrics)/.test(dom
.target
.parentNode
.className
)) {
10116 k
.dumpConsole = function(dom
) {
10117 if (!userSettings
.debug_dominserted_console
) {
10121 if (dom
.target
.nodeType
== 8) { // comments
10125 if (dom
.target
.nodeType
== 3) {
10126 if (dom
.target
.parentNode
&& dom
.target
.parentNode
.tagName
.toUpperCase() != 'ABBR') {
10127 if (typeof console
!== 'undefined' && console
.dir
) {
10128 console
.dir(dom
.target
);
10134 var id
= dom
.target
.getAttribute('id');
10135 if (id
&& (id
.indexOf('bfb_') == 0 || id
.indexOf('sfx_') == 0)) {
10139 var className
= dom
.target
.className
;
10140 if (className
.indexOf('bfb_') == 0 || className
.indexOf('sfx_') == 0) {
10144 var tagName
= dom
.target
.tagName
.toUpperCase();
10145 if (tagName
!= 'BODY') {
10146 if (typeof console
!== 'undefined' && console
.log
) {
10147 console
.log(dom
.target
.outerHTML
);
10152 k
.textBrohoof = function(ele
) {
10155 if (ele
.nodeType
=== TEXT_NODE
) {
10156 orig
= ele
.textContent
;
10158 orig
= ele
.innerHTML
;
10161 t
= t
.replace(/\bpeople\b/g, " "+CURRENTSTACK
['people']);
10162 t
= t
.replace(/\bperson\b/g, " "+CURRENTSTACK
['person']);
10163 t
= t
.replace(/likes
this/g
, CURRENTSTACK
['likes']+" this");
10164 t
= t
.replace(/like
this/g
, CURRENTSTACK
['like']+" this");
10165 t
= t
.replace(/Likes/g, capitaliseFirstLetter(CURRENTSTACK
['likes'])); // new news feed page likes
10166 t
= t
.replace(/likes/g, CURRENTSTACK
['likes']);
10167 t
= t
.replace(/like/g, CURRENTSTACK
['like']);
10168 t
= t
.replace(/\btalking about
this\b/g
, "blabbering about this");
10169 t
= t
.replace(/\bfriends\b/g, CURRENTSTACK
['friends_logic']);
10170 t
= t
.replace(/\bfriend\b/g, CURRENTSTACK
['friend_logic']);
10172 if (ele
.nodeType
=== TEXT_NODE
) {
10173 ele
.textContent
= t
;
10180 k
.textStandard = function(t
) {
10181 t
= t
.replace(/\bpeople\b/g, " "+CURRENTSTACK
['people']);
10182 t
= t
.replace(/\bfriends\b/g, " "+CURRENTSTACK
['friends_logic']);
10183 t
= t
.replace(/\bfriend\b/g, " "+CURRENTSTACK
['friend_logic']);
10184 t
= t
.replace(/\blikes\b/g, " "+CURRENTSTACK
['likes_past']);
10185 t
= t
.replace(/\blike\b/g, " "+CURRENTSTACK
['like_past']);
10189 k
.textNotification = function(t
) {
10190 t
= t
.replace(/\bpeople\b/g, " "+CURRENTSTACK
['people']);
10191 t
= t
.replace(/\(friends\b/g, "("+CURRENTSTACK
['friends_logic']);
10192 t
= t
.replace(/\bfriends\b/g, " "+CURRENTSTACK
['friends_logic']);
10193 t
= t
.replace(/\binvited you to like
\b/g
, " invited you to "+CURRENTSTACK
.like
);
10194 t
= t
.replace(/\blikes\b/g, " "+CURRENTSTACK
['likes_past']);
10195 t
= t
.replace(/\blike\b/g, " "+CURRENTSTACK
['like_past']);
10197 t
= t
.replace(/\bcomment\b/g, "friendship letter");
10198 t
= t
.replace(/\bphoto\b/g, "pony pic");
10199 t
= t
.replace(/\bphotos\b/g, "pony pics");
10200 t
= t
.replace(/\bgroup\b/g, "herd");
10201 t
= t
.replace(/\bevent\b/g, "adventure");
10202 t
= t
.replace(/\btimeline\b/g, "journal");
10203 t
= t
.replace(/\bTimeline Review
\b/g
, "Journal Review");
10204 t
= t
.replace(/\bTimeline\b/g, "Journal"); // English UK
10205 t
= t
.replace(/\bnew messages
\b/, "new friendship reports");
10206 t
= t
.replace(/\bnew message
\b/, "new friendship report");
10207 t
= t
.replace(/\bprofile picture
\b/g
, "journal pony pic");
10208 t
= t
.replace(/\bfriend request
\b/g
, "friendship request");
10209 t
= t
.replace(/\bpoked you
/g
, " nuzzled you");
10213 var _optionsLinkInjected
= false;
10214 var injectOptionsLink = function() {
10215 if (_optionsLinkInjected
) {
10219 if ($('logout_form')) {
10220 _optionsLinkInjected
= true;
10222 var optionsLink
= d
.createElement('a');
10223 optionsLink
.href
= '#';
10224 optionsLink
.id
= 'ponyhoof_account_options';
10225 optionsLink
.className
= 'navSubmenu submenuNav'; // submenuNav is for developers.facebook.com
10226 optionsLink
.innerHTML
= CURRENTLANG
.options_title
+" <span class='ponyhoof_hide_if_injected inline'>(Disabled)</span>";
10227 optionsLink
.addEventListener('click', function(e
) {
10231 clickLink($('navAccountLink'));
10234 clickLink($('accountNavArrow'));
10237 e
.preventDefault();
10240 var optionsLinkLi
= d
.createElement('li');
10241 optionsLinkLi
.setAttribute('role', 'menuitem');
10242 optionsLinkLi
.appendChild(optionsLink
);
10244 var logout
= $('logout_form');
10245 logout
.parentNode
.parentNode
.insertBefore(optionsLinkLi
, logout
.parentNode
);
10247 var pageNav
= $('pageNav');
10252 var isBusiness
= pageNav
.querySelector('.navLink[href*="logout.php?h="]');
10257 _optionsLinkInjected
= true;
10259 var optionsLink
= d
.createElement('a');
10260 optionsLink
.href
= '#';
10261 optionsLink
.id
= 'ponyhoof_account_options';
10262 optionsLink
.className
= 'navLink';
10263 optionsLink
.innerHTML
= CURRENTLANG
.options_title
+" <span class='ponyhoof_hide_if_injected inline'>(Disabled)</span>";
10264 optionsLink
.addEventListener('click', function(e
) {
10266 e
.preventDefault();
10269 var optionsLinkLi
= d
.createElement('li');
10270 optionsLinkLi
.className
= 'navItem middleItem';
10271 optionsLinkLi
.appendChild(optionsLink
);
10273 pageNav
.insertBefore(optionsLinkLi
, pageNav
.childNodes
[0]);
10277 var domNodeHandlerMain
= new domNodeHandler();
10278 var mutationObserverMain
= null;
10280 var ranDOMNodeInserted
= false;
10281 var runDOMNodeInserted = function() {
10282 if (ranDOMNodeInserted
) {
10286 ranDOMNodeInserted
= true;
10288 onPageReady(function() {
10290 DOMNodeInserted({target: d
.body
});
10294 if (!userSettings
.debug_noMutationObserver
) {
10296 var mutationObserver
= w
.WebKitMutationObserver
|| w
.MutationObserver
|| false;
10297 if (mutationObserver
) {
10298 var observerOptions
= {attributes:true, childList:true, characterData:true, subtree:true, attributeOldValue:true, attributeFilter:['title'/*, 'class', 'value'*/]};
10299 mutationObserverMain
= new mutationObserver(function(mutations
) {
10300 if (INTERNALUPDATE
) {
10303 mutationObserverMain
.disconnect();
10305 for (var i
= 0, len
= mutations
.length
; i
< len
; i
+= 1) {
10306 switch (mutations
[i
].type
) {
10307 case 'characterData':
10308 var iu
= INTERNALUPDATE
;
10309 INTERNALUPDATE
= true;
10311 domNodeHandlerMain
.mutateCharacterData(mutations
[i
]);
10313 INTERNALUPDATE
= iu
;
10317 for (var j
= 0, jlen
= mutations
[i
].addedNodes
.length
; j
< jlen
; j
+= 1) {
10318 if (userSettings
.debug_mutationDebug
) {
10319 if (mutations
[i
].addedNodes
[j
].parentNode
&& mutations
[i
].addedNodes
[j
].parentNode
.tagName
!= 'ABBR') {
10321 console
.log('childList:');
10323 console
.dir(mutations
[i
].addedNodes
[j
]);
10325 if (typeof mutations
[i
].addedNodes
[j
].className
== 'undefined') {
10326 console
.dir(mutations
[i
].addedNodes
[j
]);
10328 //console.log(' '+mutations[i].addedNodes[j].className);
10329 //console.log(' '+mutations[i].addedNodes[j].innerHTML);
10335 DOMNodeInserted({target: mutations
[i
].addedNodes
[j
]});
10340 var iu
= INTERNALUPDATE
;
10341 INTERNALUPDATE
= true;
10343 domNodeHandlerMain
.mutateAttributes(mutations
[i
]);
10345 INTERNALUPDATE
= iu
;
10352 if (userSettings
.debug_mutationDebug
) {
10353 console
.log('=========================================');
10355 mutationObserverMain
.observe(d
.documentElement
, observerOptions
);
10357 mutationObserverMain
.observe(d
.documentElement
, observerOptions
);
10358 USINGMUTATION
= true;
10361 warn("MutationObserver threw an exception, fallback to DOMNodeInserted");
10365 if (!USINGMUTATION
) {
10366 d
.addEventListener('DOMNodeInserted', DOMNodeInserted
, true);
10370 DOMNodeInserted({target: d
.body
});
10374 var turnOffFbNotificationSound = function() {
10375 contentEval(function(arg
) {
10377 if (typeof window
.requireLazy
== 'function') {
10378 window
.requireLazy(['NotificationSound'], function(NotificationSound
) {
10379 NotificationSound
.prototype.play = function() {};
10383 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
10384 console
.log("Unable to hook to NotificationSound");
10388 }, {"CANLOG":CANLOG
});
10391 var changeChatSound = function(code
) {
10392 onPageReady(function() {
10393 contentEval(function(arg
) {
10395 if (typeof window
.requireLazy
== 'function') {
10396 window
.requireLazy(['ChatConfig'], function(ChatConfig
) {
10397 ChatConfig
.set('sound.notif_ogg_url', arg
.THEMEURL
+arg
.code
+'.ogg');
10398 ChatConfig
.set('sound.notif_mp3_url', arg
.THEMEURL
+arg
.code
+'.mp3');
10402 if (arg
.CANLOG
&& typeof console
!= 'undefined' && console
.log
&& console
.dir
) {
10403 console
.log("Unable to hook to ChatConfig");
10407 }, {"CANLOG":CANLOG
, "THEMEURL":THEMEURL
, 'code':code
});
10411 var ranExtraInjection
= false;
10412 var extraInjection = function() {
10413 if (ranExtraInjection
) {
10416 ranExtraInjection
= true;
10418 for (var x
in HTMLCLASS_SETTINGS
) {
10419 if (userSettings
[HTMLCLASS_SETTINGS
[x
]]) {
10420 addClass(d
.documentElement
, 'ponyhoof_settings_'+HTMLCLASS_SETTINGS
[x
]);
10424 var globalcss
= '';
10425 globalcss
+= '.ponyhoof_page_readme {width:100%;height:300px;border:solid #B4BBCD;border-width:1px 0;-moz-box-sizing:border-box;box-sizing:border-box;}';
10426 globalcss
+= '#fbIndex_swf {position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;}';
10427 globalcss
+= '.ponyhoof_image_shadow {box-shadow:0 3px 8px rgba(0,0,0,.3);margin:0 auto;display:block;margin-bottom:3px;cursor:not-allowed;-webkit-user-drag:none;-moz-user-drag:none;user-drag:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
10428 globalcss
+= '.ponyhoof_image_shadow.noshadow {box-shadow:none;}';
10429 globalcss
+= '.ponyhoof_tooltip_widthFix {width:auto !important;}';
10431 injectManualStyle(globalcss
, 'global');
10433 if (userSettings
.customcss
) {
10434 injectManualStyle(userSettings
.customcss
, 'customcss');
10437 INTERNALUPDATE
= true;
10438 for (var i
= 0; i
< 10; i
+= 1) {
10439 var n
= d
.createElement('div');
10440 n
.id
= 'ponyhoof_extra_'+i
;
10441 d
.body
.appendChild(n
);
10444 var timeShift = function() {
10445 var now
= new Date();
10447 d
.documentElement
.setAttribute('data-ponyhoof-year', now
.getFullYear());
10448 d
.documentElement
.setAttribute('data-ponyhoof-month', now
.getMonth());
10449 d
.documentElement
.setAttribute('data-ponyhoof-date', now
.getDate());
10450 d
.documentElement
.setAttribute('data-ponyhoof-hour', now
.getHours());
10451 d
.documentElement
.setAttribute('data-ponyhoof-minute', now
.getMinutes());
10454 w
.setInterval(timeShift
, 60*1000);
10456 if (userSettings
.chatSound
) {
10457 if (!SOUNDS_CHAT
[userSettings
.chatSoundFile
] || !SOUNDS_CHAT
[userSettings
.chatSoundFile
].name
) {
10458 userSettings
.chatSoundFile
= '_sound/grin2';
10460 if (typeof w
.Audio
!= 'undefined') {
10461 changeChatSound(userSettings
.chatSoundFile
);
10465 if (userSettings
.customBg
&& !ONPLUGINPAGE
) {
10466 changeCustomBg(userSettings
.customBg
);
10469 // Turn off Facebook's own notification sound
10470 if (userSettings
.sounds
) {
10471 turnOffFbNotificationSound();
10474 INTERNALUPDATE
= false;
10477 var detectBrokenFbStyle = function() {
10478 var test
= d
.createElement('div');
10479 test
.className
= 'hidden_elem';
10480 d
.documentElement
.appendChild(test
);
10482 var style
= w
.getComputedStyle(test
, null);
10483 if (style
&& style
.display
!= 'none') {
10484 d
.documentElement
.removeChild(test
);
10489 d
.documentElement
.removeChild(test
);
10493 // Wait for the current page to complete
10494 var scriptStarted
= false;
10495 function startScript() {
10496 if (scriptStarted
) {
10499 scriptStarted
= true;
10501 // Don't run on exclusions
10502 if (w
.location
.hostname
.indexOf('.facebook.com') == w
.location
.hostname
.length
-'.facebook.com'.length
) {
10503 var excludes
= ['/l.php', '/ai.php', '/ajax/'];
10504 for (var i
= 0, len
= excludes
.length
; i
< len
; i
+= 1) {
10505 if (w
.location
.pathname
.indexOf(excludes
[i
]) == 0) {
10511 // Don't run on ajaxpipe
10512 if (w
.location
.search
&& w
.location
.search
.indexOf('ajaxpipe=1') != -1) {
10516 // Don't run on Browser Ponies
10517 if (w
.location
.hostname
== 'hoof.little.my') {
10518 var excludes
= ['.gif', '.png'];
10519 for (var i
= 0, len
= excludes
.length
; i
< len
; i
+= 1) {
10520 if (w
.location
.pathname
.indexOf(excludes
[i
]) != -1) {
10526 // Don't run on Open Graph Debugger
10527 if (w
.location
.hostname
.indexOf('developers.') != -1 && w
.location
.hostname
.indexOf('.facebook.com') != -1 && w
.location
.pathname
== '/tools/debug/og/echo') {
10531 if (w
.location
.hostname
== '0.facebook.com') {
10536 d
.head
= d
.getElementsByTagName('head')[0];
10539 // Are we running in a special Ponyhoof page?
10540 if (d
.documentElement
.id
== 'ponyhoof_page') {
10541 // Modify the <html> tag
10542 addClass(d
.documentElement
, 'ponyhoof_userscript');
10543 d
.documentElement
.setAttribute('data-ponyhoof-userscript-version', VERSION
);
10545 var changeVersion = function() {
10546 var v
= d
.getElementsByClassName('ponyhoof_VERSION');
10547 for (var i
= 0, len
= v
.length
; i
< len
; i
+= 1) {
10548 v
[i
].textContent
= VERSION
;
10552 onPageReady(changeVersion
);
10555 if (d
.documentElement
.getAttribute('data-ponyhoof-update-current') > VERSION
) {
10556 addClass(d
.documentElement
, 'ponyhoof_update_outdated');
10558 addClass(d
.documentElement
, 'ponyhoof_update_newest');
10563 // Determine what storage method to use
10564 STORAGEMETHOD
= 'none';
10566 if (typeof GM_getValue
=== 'function' && typeof GM_setValue
=== 'function') {
10567 // Chrome lies about GM_getValue support
10568 GM_setValue("ponyhoof_test", "ponies");
10569 if (GM_getValue("ponyhoof_test") === "ponies") {
10570 STORAGEMETHOD
= 'greasemonkey';
10575 if (STORAGEMETHOD
== 'none') {
10577 if (typeof chrome
!= 'undefined' && chrome
&& chrome
.extension
&& typeof GM_getValue
== 'undefined') {
10578 STORAGEMETHOD
= 'chrome';
10583 if (STORAGEMETHOD
== 'none') {
10585 if (typeof opera
!= 'undefined' && opera
&& opera
.extension
) {
10586 STORAGEMETHOD
= 'opera';
10591 if (STORAGEMETHOD
== 'none') {
10593 if (typeof safari
!= 'undefined') {
10594 STORAGEMETHOD
= 'safari';
10599 if (STORAGEMETHOD
== 'none') {
10600 if (DISTRIBUTION
== 'xpi') {
10601 STORAGEMETHOD
= 'xpi';
10605 if (STORAGEMETHOD
== 'none') {
10606 if (DISTRIBUTION
== 'mxaddon') {
10607 STORAGEMETHOD
= 'mxaddon';
10611 if (STORAGEMETHOD
== 'none') {
10612 STORAGEMETHOD
= 'localstorage';
10615 if (d
.documentElement
.id
== 'ponyhoof_page') {
10616 addClass(d
.documentElement
, 'ponyhoof_distribution_'+DISTRIBUTION
);
10617 addClass(d
.documentElement
, 'ponyhoof_storagemethod_'+STORAGEMETHOD
);
10621 // Inject the system style so we can do any error trapping
10622 injectSystemStyle();
10625 USERID
= cookie('c_user');
10629 SETTINGSPREFIX
= USERID
+'_';
10632 loadSettings(function(s
) {
10635 loadSettings(function(s
) {
10636 globalSettings
= s
;
10638 if (userSettings
.debug_slow_load
) {
10639 onPageReady(settingsLoaded
);
10643 }, {prefix:'global_', defaultSettings:GLOBALDEFAULTSETTINGS
});
10647 // Check for legacy settings through message passing
10648 var migrateSettingsChromeDone
= false;
10649 var migrateSettingsChrome = function(callback
) {
10650 if (STORAGEMETHOD
== 'chrome') {
10651 if (chrome
.storage
) {
10653 chrome_sendMessage({'command':'getValue', 'name':SETTINGSPREFIX
+'settings'}, function(response
) {
10654 if (response
&& typeof response
.val
!= 'undefined') {
10655 var _settings
= JSON
.parse(response
.val
);
10657 userSettings
= _settings
;
10660 chrome_sendMessage({'command':'clearStorage'}, function() {});
10663 migrateSettingsChromeDone
= true;
10668 error("Failed to read previous settings through message passing");
10670 migrateSettingsChromeDone
= true;
10676 migrateSettingsChromeDone
= true;
10680 // Check for previous settings from unprefixed settings
10681 var migrateSettingsUnprefixedDone
= false;
10682 var migrateSettingsUnprefixed = function(callback
) {
10683 loadSettings(function(s
) {
10684 if (s
.lastVersion
) { // only existed in previous versions
10687 saveValue('settings', JSON
.stringify(null));
10690 migrateSettingsUnprefixedDone
= true;
10695 var globalSettingsTryLastUserDone
= false;
10696 var globalSettingsTryLastUser = function(callback
) {
10697 if (!globalSettings
.lastUserId
) {
10698 globalSettingsTryLastUserDone
= true;
10703 SETTINGSPREFIX
= globalSettings
.lastUserId
+'_';
10704 loadSettings(function(s
) {
10709 globalSettingsTryLastUserDone
= true;
10714 function settingsLoaded() {
10715 if (!userSettings
.theme
&& !migrateSettingsChromeDone
) {
10716 migrateSettingsChrome(settingsLoaded
);
10720 // Migrate for multi-user
10721 if (!userSettings
.theme
&& !migrateSettingsUnprefixedDone
) {
10722 migrateSettingsUnprefixed(settingsLoaded
);
10726 if (!globalSettings
.globalSettingsMigrated
) {
10727 if (!userSettings
.lastVersion
) {
10729 statTrack('install');
10732 for (var i
in GLOBALDEFAULTSETTINGS
) {
10733 if (userSettings
.hasOwnProperty(i
)) {
10734 globalSettings
[i
] = userSettings
[i
];
10737 globalSettings
.globalSettingsMigrated
= true;
10738 saveGlobalSettings();
10741 if (!USERID
&& !globalSettingsTryLastUserDone
) {
10742 // Try loading the last user
10743 globalSettingsTryLastUser(settingsLoaded
);
10747 // If we haven't set up Ponyhoof, don't log
10748 if (!userSettings
.theme
|| userSettings
.debug_disablelog
) {
10752 // Run ONLY on #facebook
10753 if (!(d
.documentElement
.id
== 'facebook' && w
.location
.hostname
.indexOf('.facebook.com') == w
.location
.hostname
.length
-'.facebook.com'.length
) && d
.documentElement
.id
!= 'ponyhoof_page') {
10754 info("Ponyhoof does not run on "+w
.location
.href
+" (html id is not #facebook)");
10758 // Did we already run our script?
10759 if (hasClass(d
.documentElement
, 'ponyhoof_userscript')) {
10760 info("Style already injected at "+w
.location
.href
);
10764 // Don't run in frames
10765 var forceWhiteBackground
= false;
10767 var href
= w
.location
.href
.toLowerCase();
10769 if ((href
.indexOf('/plugins/like.php') != -1 || href
.indexOf('/plugins/likebox.php') != -1 || href
.indexOf('/plugins/subscribe.php') != -1 || href
.indexOf('/plugins/facepile.php') != -1) && (href
.indexOf('login/plugin_roadblock.php') == -1 && (href
.indexOf('#ponyhoof_runme') != -1 || href
.indexOf('&ponyhoof_runme') != -1))) {
10770 // Allow like boxes for the Ponyhoof page (yeah, a bit cheating)
10771 } else if (hasClass(d
.body
, 'chrmxt')) {
10772 // Allow for Facebook Notifications for Chrome
10774 // Allow for some frames
10775 var allowedFrames
= ['/ads/manage/powereditor/funding', '/ads/manage/powereditor/convtrack', '/mobile/iframe_emails.php'];
10776 var allowedFramesOk
= false;
10777 for (var i
= 0, len
= allowedFrames
.length
; i
< len
; i
+= 1) {
10778 if (w
.location
.pathname
.indexOf(allowedFrames
[i
]) == 0) {
10779 allowedFramesOk
= true;
10780 forceWhiteBackground
= true;
10784 // Allow for comment boxes owned by Ponyhoof
10785 // (in theory, we could still be run by http://example/?api_key=231958156911371 but this isn't a big deal)
10786 if (w
.location
.pathname
=== '/plugins/comments.php' || w
.location
.pathname
=== '/plugins/feedback.php') {
10787 if (w
.location
.search
.indexOf('api_key=231958156911371') != -1 || w
.location
.search
.indexOf('api_key=376261472405891') != -1) {
10788 allowedFramesOk
= true;
10792 if (!allowedFramesOk
) {
10793 if (USW
.self
!= USW
.top
) {
10803 // Special instructions for browsers that needs localStorage
10805 if (STORAGEMETHOD
== 'localstorage') {
10806 // Don't run on non-www :(
10807 if (userSettings
.force_run
) {
10808 log("Force running on "+w
.location
.href
);
10810 if (w
.location
.hostname
!= 'www.facebook.com') {
10811 info("w.location.hostname = "+w
.location
.hostname
);
10818 info("Ponyhoof style is not injected on "+w
.location
.href
);
10822 CURRENTPONY
= userSettings
.theme
;
10824 if (!USERID
&& !globalSettings
.allowLoginScreen
) {
10825 info("Ponyhoof will not run when logged out because of a setting.");
10830 // If you would like to end up here, just simply show us that you have no clue about what Ponyhoof is really about and keep hitting "Send page source", don't be a moron please
10831 if (USERID
&& ['e3686058630b7b992b7f10e5ce10aa14', '10e823f70f20d7ef90db87783d96d5a6', 'b002a2d15003dad6a1cf694bba258ea2', 'c2480aa0cd99186aac0430f6d24ff40c', '377533fc17cfd34fae337a4c9a5e4d49', 'a078ca1d2d6a98055fa448b8367a8190', 'b85f32cf81e4153975f1e1f55fecfe58', '40ab65332ad92345ab727aadcc623906', '0147135a7dc2d1b65ca0032c97f89c5b', '6c5b9bf8a304f1a3e0b085f974c53592', '4ab4094e54225dccadf42bee9ac212a9', '2887516d877df760641ed9247cc84b65', '06308ee7060101f04a18e41158408730', 'a95ef44112c18876a808b2d7781e63ba', '57b540dc72835f30d402f6abc566677c', '1f75490e12b25ee5839687e0ffe65502', '24363cd421635e8268983f6187def3c8', '3a420678fb395a9e71ad6b523e880a27', 'd7a9db4027cd407b281c84cc626a9f70', '23d69d7ecfeeb940deef6bc69c3aee00', 'ad3553f919b97dbbb19a69966666641e', '46077eeb2467c70ec9332b672d1d7bd1', 'bc8ef81105cfdc4c6b5ff349622dae8a', 'a21ad36f4c3fc35494626d1399cc4be1', '3a2135f78503521e570608c07c3e6386', '8dc11f39765f8fe83603502afcb630a9', 'ac966d33840736554984577a78d37d95', '11abc5dd16709ff201ec00781c39ac3c', '00e957ff53a5b34518087621165498f9', '025e1b15134402df1803de9421dc7819', '125c419ddbad08ee8c53b88801415887', 'ca94af2350690962e97e1ac1fb98fa06', '62e6c5f16e8ccc79c94aa452aa36f5d8', 'cf7e6ddb2fc7c7984d323a81dfca8dfb', 'df6495bacaeb347a931f7e676fc8ee0b', 'e5ffc53255c20275e2c7d8f0c2ca5201', '31161cecf1fd9804bb66fa4e373733c6', 'cb5f2107815d30a538b30d82df93a1ac', '3a420678fb395a9e71ad6b523e880a27', 'b002c047d235437b8b255173ce73744a'].indexOf(md5(USERID
)) != -1) {
10832 if (globalSettings
.allowLoginScreen
) {
10833 globalSettings
.allowLoginScreen
= false;
10834 saveGlobalSettings();
10839 // If we don't have an old setting...
10840 if (userSettings
.theme
== null) {
10841 // ... and not logged in, DON'T show the welcome screen
10843 // Special exception at home page, we want that cool login background
10844 if (!hasClass(d
.body
, 'fbIndex')) {
10845 info("Ponyhoof does not run for logged out users.");
10850 // Don't run on dialogs
10851 if (w
.location
.pathname
.indexOf('/dialog/') == 0) {
10852 info("Ponyhoof does not run when there is no theme selected and running on dialogs.");
10857 // v1.581: Detect broken Facebook styles and abort if derped
10858 if (userSettings
.theme
&& detectBrokenFbStyle()) {
10859 error("Broken Facebook style: hidden_elem is not expected");
10863 // Modify the <html> tag
10864 addClass(d
.documentElement
, 'ponyhoof_userscript');
10865 addClass(d
.documentElement
, 'ponyhoof_storagemethod_'+STORAGEMETHOD
);
10866 addClass(d
.documentElement
, 'ponyhoof_distribution_'+DISTRIBUTION
);
10867 d
.documentElement
.setAttribute('data-ponyhoof-userscript-version', VERSION
);
10869 // CANLOG previously could be disabled before
10870 if (!userSettings
.debug_disablelog
) {
10874 // Load the language for the options link
10875 CURRENTLANG
= LANG
['en_US'];
10876 if (!userSettings
.forceEnglish
) {
10877 UILANG
= getDefaultUiLang();
10881 for (var i
in LANG
[UILANG
]) {
10882 CURRENTLANG
[i
] = LANG
[UILANG
][i
];
10887 // Inject Ponyhoof Options in the Account dropdown even when DOMNodeInserted is disabled
10888 onPageReady(function() {
10889 injectOptionsLink();
10890 domNodeHandlerMain
.ponyhoofPageOptions({target: d
.body
});
10897 var luckyGuess
= -1;
10898 if (!CURRENTPONY
&& globalSettings
.runForNewUsers
) {
10899 // If we have a "special" name, load the peferred theme for that character if we're in one
10902 for (var i
= 0, len
= PONIES
.length
; i
< len
; i
+= 1) {
10903 if (PONIES
[i
].users
) {
10904 var lowercase
= BRONYNAME
.toLowerCase();
10905 for (var j
= 0, jlen
= PONIES
[i
].users
.length
; j
< jlen
; j
+= 1) {
10906 if (lowercase
.indexOf(PONIES
[i
].users
[j
]) != -1) {
10908 CURRENTPONY
= PONIES
[i
].code
;
10915 error("Failed to get brony name");
10919 // If we still don't have one, then assume none
10920 if (!CURRENTPONY
) {
10921 CURRENTPONY
= 'NONE';
10924 if ($('jewelFansTitle')) {
10925 ISUSINGPAGE
= true;
10926 addClass(d
.documentElement
, 'ponyhoof_isusingpage');
10929 if (d
.querySelector('#pageLogo > a[href*="/business/dashboard/"]')) {
10930 ISUSINGBUSINESS
= true;
10931 addClass(d
.documentElement
, 'ponyhoof_isusingbusiness');
10934 // v1.401: Turn on new chat sound by default
10935 if (!userSettings
.chatSound1401
&& !userSettings
.chatSound
) {
10936 userSettings
.chatSound
= true;
10937 userSettings
.chatSound1401
= true;
10941 // v1.501: Migrate previous randomSetting
10942 if (userSettings
.randomSetting
&& !userSettings
.randomSettingMigrated
) {
10943 if (userSettings
.randomSetting
== 'mane6') {
10944 userSettings
.randomPonies
= 'twilight|dash|pinkie|applej|flutter|rarity';
10946 userSettings
.randomSettingMigrated
= true;
10951 userSettings
.soundsVolume
= Math
.max(0, Math
.min(parseFloat(userSettings
.soundsVolume
), 1));
10954 if (globalSettings
.lastVersion
< 1.6) {
10955 if (userSettings
.customcss
|| userSettings
.debug_dominserted_console
|| userSettings
.debug_slow_load
|| userSettings
.debug_disablelog
|| userSettings
.debug_noMutationObserver
|| userSettings
.debug_mutationDebug
) {
10956 userSettings
.debug_exposed
= true;
10961 // v1.511: Track updates
10962 if (userSettings
.theme
&& globalSettings
.lastVersion
< VERSION
) {
10963 statTrack('updated');
10964 globalSettings
.lastVersion
= VERSION
;
10965 saveGlobalSettings();
10968 if (forceWhiteBackground
|| hasClass(d
.body
, 'plugin') || hasClass(d
.body
, 'transparent_widget') || hasClass(d
.body
, '_1_vn')) {
10969 ONPLUGINPAGE
= true;
10970 addClass(d
.documentElement
, 'ponyhoof_fbplugin');
10971 changeThemeSmart(CURRENTPONY
);
10973 // Are we on homepage?
10974 if (hasClass(d
.body
, 'fbIndex') && globalSettings
.allowLoginScreen
) {
10975 // Activate screen saver
10976 screenSaverActivate();
10978 $$(d
.body
, '#blueBar .loggedout_menubar > .rfloat, ._50dz > .ptl[style*="#3B5998"] .rfloat > #login_form, ._50dz > div[style*="#3B5998"] td > div[style*="float"] #login_form', function() {
10979 addClass(d
.documentElement
, 'ponyhoof_fbIndex_topRightLogin');
10984 if (userSettings
.theme
== null) {
10985 // No theme AND logged out
10987 changeTheme('login');
10988 log("Homepage is default to login.");
10990 if (!userSettings
.disableDomNodeInserted
) {
10991 runDOMNodeInserted();
10996 if (globalSettings
.runForNewUsers
) {
10997 if (luckyGuess
== -1) {
10998 CURRENTPONY
= getRandomMane6();
11001 var welcome
= new WelcomeUI({feature: luckyGuess
});
11005 if (hasClass(d
.body
, 'fbIndex')) {
11006 if (CURRENTPONY
== 'RANDOM' && !userSettings
.randomPonies
) {
11007 log("On login page and theme is RANDOM, choosing 'login'");
11008 changeThemeSmart('login');
11010 changeThemeSmart(CURRENTPONY
);
11013 if (canPlayFlash()) {
11014 var dat
= convertCodeToData(REALPONY
);
11015 if (dat
.fbIndex_swf
&& !userSettings
.disable_animation
) {
11016 addClass(d
.documentElement
, 'ponyhoof_fbIndex_hasswf');
11018 var swf
= d
.createElement('div');
11019 swf
.innerHTML
= '<object type="application/x-shockwave-flash" id="fbIndex_swf" width="100%" height="100%" data="'+THEMEURL
+dat
.fbIndex_swf
+'"><param name="movie" value="'+THEMEURL
+dat
.fbIndex_swf
+'"><param name="wmode" value="opaque"><param name="menu" value="false"><param name="allowscriptaccess" value="never"></object>';
11020 d
.body
.appendChild(swf
);
11024 changeThemeSmart(CURRENTPONY
);
11029 if (CURRENTPONY
!= 'NONE' && !userSettings
.disableDomNodeInserted
) {
11030 runDOMNodeInserted();
11033 if (CURRENTPONY
!= 'NONE') {
11037 // Record the last user to figure out what theme to load at login screen
11038 // This is low priority, if all else fails, we would just load the default Equestria 'login' anyway
11039 if (CURRENTPONY
!= 'NONE' && userSettings
.theme
!= null) { // Make sure we have a pony set
11040 if (USERID
&& globalSettings
.lastUserId
!= USERID
&& globalSettings
.allowLoginScreen
) {
11041 globalSettings
.lastUserId
= USERID
;
11042 saveGlobalSettings();
11047 onPageReady(startScript
);
11048 d
.addEventListener('DOMContentLoaded', startScript
, true);
11050 var _loop = function() {
11055 w
.setTimeout(_loop
, 100);
11061 /* ALL YOUR PONIES ARE BELONG TO US */