]> git.rmz.io Git - dotfiles.git/blob - dwb/greasemonkey/ponyhoof.user.js
add paste.c-p.org
[dotfiles.git] / dwb / greasemonkey / ponyhoof.user.js
1 // ==UserScript==
2 // @name Ponyhoof
3 // @namespace http://www.facebook.com/ponyhoof
4 // @run-at document-start
5 // @version 1.701
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
13 // @contributor James
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/*
41 // ==/UserScript==
42
43 /*******************************************************************************
44 * Please visit http://jointheherd.lttle.my for the official install!
45 *******************************************************************************/
46
47
48 (function() {
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.");
51 WScript.quit(1);
52 }
53
54 if (window.location.hostname.indexOf('facebook.com') == -1 && window.location.hostname.indexOf('little.my') == -1) {
55 return;
56 }
57
58 /**
59 * Hoof Framework
60 *
61 * @author ngyikp (http://www.facebook.com/ngyikp)
62 */
63 var d = document, w = window;
64 var ELEMENT_NODE = 1;
65 var TEXT_NODE = 3;
66
67 var SIG = '[Hoof Framework]';
68 var FRIENDLYNAME = 'Hoof Framework';
69 var CANLOG = true;
70
71 var userSettings = {};
72
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);
83
84 // R.I.P. unsafeWindow in Chrome 27+ http://crbug.com/222652
85 if (typeof unsafeWindow == 'undefined') {
86 var USW = w;
87 } else {
88 var USW = unsafeWindow;
89 }
90
91 function log(msg) {
92 if (CANLOG) {
93 if (typeof console !== 'undefined' && console.log) {
94 console.log(SIG + ' ' + msg);
95 }
96 }
97 }
98
99 function dir(msg) {
100 if (CANLOG) {
101 if (typeof console !== 'undefined' && console.dir) {
102 console.dir(SIG + ' ' + msg);
103 }
104 }
105 }
106
107 function debug(msg) {
108 if (CANLOG) {
109 if (typeof console !== 'undefined') {
110 if (console.debug) {
111 console.debug(SIG + ' ' + msg);
112 } else if (console.log) {
113 console.log(SIG + ' ' + msg);
114 }
115 }
116 }
117 }
118
119 function info(msg) {
120 if (CANLOG) {
121 if (typeof console !== 'undefined') {
122 if (console.info) {
123 console.info(SIG + ' ' + msg);
124 } else if (console.log) {
125 console.log(SIG + ' ' + msg);
126 }
127 }
128 }
129 }
130
131 function warn(msg) {
132 if (CANLOG) {
133 if (typeof console !== 'undefined') {
134 if (console.warn) {
135 console.warn(SIG + ' ' + msg);
136 } else if (console.log) {
137 console.log(SIG + ' ' + msg);
138 }
139 }
140 }
141 }
142
143 function error(msg) {
144 if (CANLOG) {
145 if (typeof console !== 'undefined') {
146 if (console.error) {
147 console.error(SIG + ' ' + msg);
148 } else if (console.log) {
149 console.log(SIG + ' ' + msg);
150 }
151 }
152 }
153 }
154
155 function trace() {
156 if (CANLOG) {
157 if (typeof console !== 'undefined' && console.trace) {
158 console.trace();
159 }
160 }
161 }
162
163 function $(id) {
164 return d.getElementById(id);
165 }
166
167 function randNum(min, max) {
168 return min + Math.floor(Math.random() * (max - min + 1));
169 }
170
171 function hasClass(ele, c) {
172 if (!ele) {
173 return false;
174 }
175 if (ele.classList) {
176 return ele.classList.contains(c);
177 }
178
179 var regex = new RegExp("(^|\\s)"+c+"(\\s|$)");
180 if (ele.className) { // element node
181 return (ele.className && regex.test(ele.className));
182 } else { // string
183 return (ele && regex.test(ele));
184 }
185 }
186
187 function addClass(ele, c) {
188 if (ele.classList) {
189 ele.classList.add(c);
190 } else if (!hasClass(ele, c)) {
191 ele.className += ' '+c;
192 }
193 }
194
195 function removeClass(ele, c) {
196 if (ele.classList) {
197 ele.classList.remove(c);
198 } else {
199 ele.className = ele.className.replace(new RegExp('(^|\\s)'+c+'(?:\\s|$)','g'),'$1').replace(/\s+/g,' ').replace(/^\s*|\s*$/g,'');
200 }
201 }
202
203 function toggleClass(ele, c) {
204 if (hasClass(ele, c)) {
205 removeClass(ele, c);
206 } else {
207 ele.className += ' ' + c;
208 }
209 }
210
211 function clickLink(el) {
212 if (!el) {
213 return false;
214 }
215
216 var evt = d.createEvent('MouseEvents');
217 evt.initMouseEvent('click', true, true, USW, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
218 el.dispatchEvent(evt);
219 return true;
220 }
221
222 function cookie(n) {
223 try {
224 return unescape(d.cookie.match('(^|;)?'+n+'=([^;]*)(;|$)')[2]);
225 } catch (e) {
226 return null;
227 }
228 }
229
230 function injectManualStyle(css, id) {
231 if ($('ponyhoof_style_'+id)) {
232 return $('ponyhoof_style_'+id);
233 }
234
235 var n = d.createElement('style');
236 n.type = 'text/css';
237 if (id) {
238 n.id = 'ponyhoof_style_'+id;
239 }
240 n.textContent = '/* '+SIG+' */'+css;
241
242 if (d.head) {
243 d.head.appendChild(n);
244 } else if (d.body) {
245 d.body.appendChild(n);
246 } else {
247 d.documentElement.appendChild(n);
248 }
249
250 return n;
251 }
252
253 function fadeOut(ele, callback) {
254 addClass(ele, 'ponyhoof_fadeout');
255
256 w.setTimeout(function() {
257 ele.style.display = 'none';
258
259 if (callback) {
260 callback(ele);
261 }
262 }, 250);
263 }
264
265 function getFbDomain() {
266 if (w.location.hostname == 'beta.facebook.com') {
267 return w.location.hostname;
268 }
269 return 'www.facebook.com';
270 }
271
272 function onPageReady(callback) {
273 var _loop = function() {
274 if (/loaded|complete/.test(d.readyState)) {
275 callback();
276 } else {
277 w.setTimeout(_loop, 100);
278 }
279 };
280 _loop();
281 }
282
283 var loopClassName = function(name, func) {
284 var l = d.getElementsByClassName(name);
285 if (l) {
286 for (var i = 0, len = l.length; i < len; i++) {
287 func(l[i]);
288 }
289 }
290 };
291
292 function $$(parent, query, func) {
293 if (!parent) {
294 return;
295 }
296 var l = parent.querySelectorAll(query);
297 if (l.length) {
298 for (var i = 0, len = l.length; i < len; i++) {
299 func(l[i]);
300 }
301 }
302 }
303
304 // Hacky code adapted from http://www.javascripter.net/faq/browsern.htm
305 function getBrowserVersion() {
306 var ua = w.navigator.userAgent;
307 var fullVersion = ''+parseFloat(w.navigator.appVersion);
308 var majorVersion = parseInt(w.navigator.appVersion, 10);
309 var nameOffset, offset, ix;
310
311 if (ua.indexOf('Opera') != -1) {
312 // In Opera, the true version is after 'Opera' or after 'Version'
313 offset = ua.indexOf('Opera');
314 fullVersion = ua.substring(offset + 6);
315
316 if (ua.indexOf('Version') != -1) {
317 offset = ua.indexOf('Version');
318 fullVersion = ua.substring(offset + 8);
319 }
320 } else if (ua.indexOf('OPR/') != -1) {
321 offset = ua.indexOf('OPR/');
322 fullVersion = ua.substring(offset + 4);
323 } else if (ua.indexOf('MSIE') != -1) {
324 // In MSIE, the true version is after 'MSIE' in userAgent
325 offset = ua.indexOf('MSIE');
326 fullVersion = ua.substring(offset + 5);
327 } else if (ua.indexOf('Chrome') != -1) {
328 // In Chrome, the true version is after 'Chrome'
329 offset = ua.indexOf('Chrome');
330 fullVersion = ua.substring(offset + 7);
331 } else if (ua.indexOf('Safari') != -1) {
332 // In Safari, the true version is after 'Safari' or after 'Version'
333 offset = ua.indexOf('Safari');
334 fullVersion = ua.substring(offset + 7);
335
336 if (ua.indexOf('Version') != -1) {
337 offset = ua.indexOf('Version');
338 fullVersion = ua.substring(offset + 8);
339 }
340 } else if (ua.indexOf('Firefox') != -1) {
341 // In Firefox, the true version is after 'Firefox'
342 offset = ua.indexOf('Firefox');
343 fullVersion = ua.substring(offset + 8);
344 } else {
345 throw "Unsupported browser";
346 }
347
348 if ((ix = fullVersion.indexOf(';')) != -1) {
349 fullVersion = fullVersion.substring(0, ix);
350 }
351 if ((ix = fullVersion.indexOf(' ')) != -1) {
352 fullVersion = fullVersion.substring(0, ix);
353 }
354
355 majorVersion = parseInt(''+fullVersion,10);
356 if (isNaN(majorVersion)) {
357 fullVersion = ''+parseFloat(w.navigator.appVersion);
358 majorVersion = parseInt(w.navigator.appVersion,10);
359 }
360
361 return {
362 major: majorVersion
363 ,full: fullVersion
364 };
365 }
366
367 // http://wiki.greasespot.net/Content_Script_Injection
368 var contentEval = function(source, arg) {
369 var arg = arg || {};
370 if (typeof source === 'function') {
371 source = '(' + source + ')(' + JSON.stringify(arg) + ');'
372 }
373
374 var script = d.createElement('script');
375 script.textContent = source;
376 d.documentElement.appendChild(script);
377 d.documentElement.removeChild(script);
378 };
379
380 var supportsRange = function() {
381 var i = d.createElement('input');
382 i.setAttribute('type', 'range');
383 return i.type !== 'text';
384 };
385
386 var supportsCssTransition = function() {
387 var s = d.createElement('div').style;
388 return ('transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s);
389 };
390
391 // Menu
392 var MENUS = {};
393 var Menu = function(id, p) {
394 var k = this;
395
396 k.id = id;
397 MENUS['ponyhoof_menu_'+k.id] = k;
398 k.menu = null; // outer wrap
399 k.selectorMenu = null; // .uiMenu.uiSelectorMenu
400 k.menuInner = null; // .uiMenuInner
401 k.content = null; // .uiScrollableAreaContent
402 k.button = null;
403 k.wrap = null; // ponyhoof_menu_wrap, used to separate button and menu
404
405 k.menuSearch = null; // .ponyhoof_menu_search
406 k.menuSearchInput = null;
407 k.menuSearchNoResults = null;
408 k.focusStealer = null;
409
410 k.hasScrollableArea = false;
411 k.scrollableAreaDiv = null; // .uiScrollableArea
412 k.scrollableArea = null; // FB ScrollableArea class
413
414 k.p = p;
415 k.afterClose = function() {};
416
417 k.canSearch = true;
418 k.alwaysOverflow = false;
419 k.rightFaced = false;
420 k.buttonTextClipped = 0;
421
422 k.createButton = function(startText) {
423 if (!startText) {
424 startText = '';
425 }
426
427 var buttonText = d.createElement('span');
428 buttonText.className = 'uiButtonText';
429 buttonText.innerHTML = startText;
430
431 k.button = d.createElement('a');
432 k.button.href = '#';
433 k.button.className = 'uiButton ponyhoof_button_menu';
434 k.button.setAttribute('role', 'button');
435 k.button.setAttribute('aria-haspopup', 'true');
436 if (k.buttonTextClipped) {
437 k.button.className += ' ponyhoof_button_clipped';
438 buttonText.style.maxWidth = k.buttonTextClipped+'px';
439 }
440 k.button.appendChild(buttonText);
441
442 k.wrap = d.createElement('div');
443 k.wrap.className = 'ponyhoof_menu_wrap';
444 if (k.rightFaced) {
445 k.wrap.className += ' uiSelectorRight';
446 }
447 k.wrap.appendChild(k.button);
448 k.p.appendChild(k.wrap);
449
450 return k.button;
451 }
452
453 k.createMenu = function() {
454 if ($('ponyhoof_menu_'+k.id)) {
455 k.menu = $('ponyhoof_menu_'+k.id);
456 k.menuInner = k.menu.getElementsByClassName('uiMenuInner')[0];
457 return k.menu;
458 }
459
460 k.injectStyle();
461
462 k.menu = d.createElement('div');
463 k.menu.className = 'ponyhoof_menu uiSelectorMenuWrapper';
464 k.menu.id = 'ponyhoof_menu_'+k.id;
465 k.menu.setAttribute('role', 'menu');
466 //k.menu.style.display = 'none';
467 k.menu.addEventListener('click', function(e) {
468 e.stopPropagation();
469 return false;
470 }, false);
471 k.wrap.appendChild(k.menu);
472
473 k.selectorMenu = d.createElement('div');
474 k.selectorMenu.className = 'uiMenu uiSelectorMenu';
475 k.menu.appendChild(k.selectorMenu);
476
477 k.menuInner = d.createElement('div');
478 k.menuInner.className = 'uiMenuInner';
479 k.selectorMenu.appendChild(k.menuInner);
480
481 k.content = d.createElement('div');
482 k.content.className = 'uiScrollableAreaContent';
483 k.menuInner.appendChild(k.content);
484
485 if (k.canSearch) {
486 k.menuSearch = d.createElement('div');
487 k.menuSearch.className = 'ponyhoof_menu_search';
488 k.content.appendChild(k.menuSearch);
489
490 k.menuSearchInput = d.createElement('input');
491 k.menuSearchInput.type = 'text';
492 k.menuSearchInput.className = 'inputtext';
493 k.menuSearchInput.placeholder = "Search";
494 k.menuSearch.appendChild(k.menuSearchInput);
495
496 k.menuSearchNoResults = d.createElement('div');
497 k.menuSearchNoResults.className = 'ponyhoof_menu_search_noResults';
498 k.menuSearchNoResults.textContent = "No results";
499 k.menuSearch.appendChild(k.menuSearchNoResults);
500
501 k.menuSearchInput.addEventListener('keydown', k.searchEscapeKey, false);
502 k.menuSearchInput.addEventListener('input', k.performSearch, false);
503
504 k.focusStealer = d.createElement('input');
505 k.focusStealer.type = 'text';
506 k.focusStealer.setAttribute('aria-hidden', 'true');
507 k.focusStealer.style.position = 'absolute';
508 k.focusStealer.style.top = '-9999px';
509 k.focusStealer.style.left = '-9999px';
510 k.focusStealer.addEventListener('focus', k.focusStealerFocused, false);
511 k.selectorMenu.appendChild(k.focusStealer);
512 }
513
514 return k.menu;
515 };
516
517 k.attachButton = function() {
518 k.button.addEventListener('click', function(e) {
519 k.toggle();
520 e.stopPropagation();
521 e.preventDefault();
522 }, false);
523 };
524
525 k.changeButtonText = function(text) {
526 k.button.getElementsByClassName('uiButtonText')[0].innerHTML = text;
527 k.button.setAttribute('data-ponyhoof-button-orig', text);
528 k.button.setAttribute('data-ponyhoof-button-text', text);
529
530 if (k.buttonTextClipped) {
531 k.button.title = text;
532 }
533 };
534
535 k.createSeperator = function() {
536 var sep = d.createElement('div');
537 sep.className = 'uiMenuSeparator';
538 k.content.appendChild(sep);
539 };
540
541 k.createMenuItem = function(param) {
542 var menuItem = new MenuItem(k);
543 menuItem._create(param);
544
545 k.content.appendChild(menuItem.menuItem);
546
547 return menuItem;
548 };
549
550 k.injectStyle = function() {
551 var css = '';
552 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;}';
553
554 css += 'html .ponyhoof_dialog .ponyhoof_button_menu {background-position:right 0;padding-right:23px;}';
555 css += 'html .ponyhoof_button_menu:active {background-position:right -98px;}';
556 css += 'html .openToggler .ponyhoof_button_menu {background-color:#6D84B4;background-position:right -49px;border-color:#3B5998;border-bottom-color:#6D84B4;-moz-box-shadow:none;box-shadow:none;}';
557 css += 'html .openToggler .ponyhoof_button_menu .uiButtonText {color:#fff;}';
558
559 css += '.ponyhoof_menu_label {padding:7px 4px 0 0;}';
560 css += '.ponyhoof_menu_label, .ponyhoof_menu_withlabel .ponyhoof_menu_wrap {display:inline-block;}';
561 css += '.ponyhoof_menu_withlabel {margin-bottom:8px;}';
562 css += '.ponyhoof_menu_withlabel + .ponyhoof_menu_withlabel {margin-top:-8px;}';
563 css += '.ponyhoof_menu_withlabel .ponyhoof_button_menu {margin-top:-3px;}';
564 css += '.ponyhoof_menu_labelbreak .ponyhoof_menu_label {display:block;padding-bottom:7px;}';
565
566 css += '.ponyhoof_menu_wrap {position:relative;}';
567 css += 'html .ponyhoof_menu {z-index:1999;display:none;min-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
568 css += '.ponyhoof_menu_wrap.openToggler .ponyhoof_menu {display:block;}';
569 css += '.ponyhoof_menu_wrap + .uiButton {margin:4px 0 0 4px;}';
570 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;}';
571 css += '.ponyhoof_menu .uiMenu.overflow {resize:vertical;height:200px;min-height:200px;}';
572 css += '.ponyhoof_menu_wrap.uiSelectorRight .uiMenu {left:auto;right:0;}';
573 css += '.ponyhoof_menu .ponyhoof_menu_search {padding:0 3px;margin-bottom:4px;}';
574 css += '.ponyhoof_menu .ponyhoof_menu_search input {width:100%;resize:none;}';
575 css += '.ponyhoof_menu .ponyhoof_menu_search_noResults {display:none;color:#999;text-align:center;margin-top:7px;width:100px;}';
576 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;}';
577 css += '.ponyhoof_menu .ponyhoof_menuitem {color:#111;}';
578 css += '.ponyhoof_menuitem:hover, .ponyhoof_menuitem:active, .ponyhoof_menuitem:focus {background-color:#6d84b4;border-color:#3b5998;color:#fff;text-decoration:none;}';
579 css += '.ponyhoof_menuitem_checked {background-position:0 -146px;font-weight:bold;}';
580 css += '.ponyhoof_menuitem_checked:hover, .ponyhoof_menuitem_checked:active, .ponyhoof_menuitem_checked:focus {background-position:0 -206px;}';
581 css += '.ponyhoof_menuitem_span {white-space:nowrap;text-overflow:ellipsis;display:inline-block;overflow:hidden;padding-right:16px;max-width:400px;vertical-align:top;}';
582
583 css += '.ponyhoof_button_clipped > .uiButtonText {text-overflow:ellipsis;overflow:hidden;vertical-align:top;}';
584
585 injectManualStyle(css, 'menu');
586 };
587
588 k.open = function() {
589 k.closeAllMenus();
590
591 addClass(k.wrap, 'openToggler');
592
593 if (!hasClass(k.menuInner.parentNode, 'overflow') && (k.menuInner.parentNode.offsetHeight >= 224 || k.alwaysOverflow)) {
594 addClass(k.menuInner.parentNode, 'overflow');
595 }
596
597 if (k.canSearch && !ISMOBILE) {
598 var scrollTop = k.selectorMenu.scrollTop;
599 k.menuSearchInput.focus();
600 k.menuSearchInput.select();
601
602 k.selectorMenu.scrollTop = scrollTop;
603 }
604
605 d.body.addEventListener('keydown', k.documentEscapeKey, false);
606 d.body.addEventListener('click', k.documentClick, false);
607 };
608
609 k.close = function() {
610 if (hasClass(k.wrap, 'openToggler')) {
611 removeClass(k.wrap, 'openToggler');
612 d.body.removeEventListener('keydown', k.documentEscapeKey, false);
613 d.body.removeEventListener('click', k.documentClick, false);
614
615 k.afterClose();
616 }
617 };
618
619 k.closeAllMenus = function() {
620 for (var menu in MENUS) {
621 if (MENUS.hasOwnProperty(menu)) {
622 MENUS[menu].close();
623 }
624 }
625 };
626
627 k.toggle = function() {
628 if (hasClass(k.wrap, 'openToggler')) {
629 k.close();
630 } else {
631 k.open();
632 }
633 };
634
635 k.changeChecked = function(menuItem) {
636 var already = k.menu.getElementsByClassName('ponyhoof_menuitem_checked');
637 if (already.length) {
638 removeClass(already[0], 'ponyhoof_menuitem_checked');
639 }
640 addClass(menuItem.menuItem, 'ponyhoof_menuitem_checked');
641 };
642
643 k.performSearch = function() {
644 var val = k.menuSearchInput.value;
645 var regex = new RegExp(val, 'i');
646
647 var count = 0;
648 $$(k.menu, '.ponyhoof_menuitem', function(menuitem) {
649 if (val == '') {
650 menuitem.style.display = '';
651 return;
652 }
653
654 if (!hasClass(menuitem, 'unsearchable')) {
655 menuitem.style.display = 'none';
656
657 var compare = menuitem.textContent;
658 if (menuitem.getAttribute('data-ponyhoof-menu-searchAlternate')) {
659 compare = menuitem.getAttribute('data-ponyhoof-menu-searchAlternate');
660 }
661
662 if (regex.test(compare)) {
663 menuitem.style.display = 'block';
664 count += 1;
665 }
666 } else {
667 menuitem.style.display = 'none';
668 }
669 });
670
671 $$(k.menu, '.ponyhoof_menu_search_noResults', function(ele) {
672 if (val) {
673 if (!count) {
674 ele.style.display = 'block';
675 } else {
676 ele.style.display = 'none';
677 }
678 } else {
679 ele.style.display = 'none';
680 }
681 });
682
683 $$(k.menu, '.uiMenuSeparator', function(menuitem) {
684 if (val == '') {
685 menuitem.style.display = '';
686 return;
687 }
688
689 menuitem.style.display = 'none';
690 });
691
692 if (k.hasScrollableArea) {
693 k.scrollableArea.poke();
694 }
695 };
696
697 k.searchEscapeKey = function(e) {
698 if (e.which == 27) {
699 if (k.menuSearchInput.value != '') {
700 k.menuSearchInput.value = '';
701 k.performSearch();
702 } else {
703 k.close();
704 if (k.button) {
705 k.button.focus();
706 }
707 }
708 e.stopPropagation();
709 e.cancelBubble = true;
710 }
711 };
712
713 k.documentEscapeKey = function(e) {
714 if (e.which == 27 && hasClass(k.wrap, 'openToggler')) { // esc
715 k.close();
716 e.stopPropagation();
717 e.cancelBubble = true;
718
719 if (k.button) {
720 k.button.focus();
721 }
722 }
723 };
724
725 k.documentClick = function(e) {
726 k.close();
727 e.stopPropagation();
728 e.preventDefault();
729 };
730
731 k.focusStealerFocused = function(e) {
732 if (k.canSearch) {
733 k.menuSearchInput.focus();
734 }
735 };
736 };
737
738 var MenuItem = function(menu) {
739 var k = this;
740
741 k.menuItem = null;
742 k.menu = menu;
743 k.onclick = null;
744
745 k._create = function(param) {
746 k.menuItem = d.createElement('a');
747 k.menuItem.href = '#';
748 k.menuItem.className = 'ponyhoof_menuitem';
749 k.menuItem.setAttribute('role', 'menuitem');
750
751 if (param.check) {
752 k.menuItem.className += ' ponyhoof_menuitem_checked';
753 }
754
755 if (param.data) {
756 k.menuItem.setAttribute('data-ponyhoof-menu-data', param.data);
757 }
758
759 if (param.title) {
760 k.menuItem.setAttribute('aria-label', param.title);
761 k.menuItem.setAttribute('data-hover', 'tooltip');
762 }
763
764 if (param.unsearchable) {
765 k.menuItem.className += ' unsearchable';
766 }
767
768 if (param.searchAlternate) {
769 k.menuItem.setAttribute('data-ponyhoof-menu-searchAlternate', param.searchAlternate);
770 }
771
772 if (param.extraClass) {
773 k.menuItem.className += param.extraClass;
774 }
775
776 k.menuItem.innerHTML = '<span class="ponyhoof_menuitem_span">'+param.html+'</span>';
777
778 if (param.onclick) {
779 k.onclick = param.onclick;
780 }
781 k.menuItem.addEventListener('click', function(e) {
782 e.stopPropagation();
783 if (k.onclick) {
784 k.onclick(k, k.menu);
785 }
786
787 return false;
788 }, false);
789 k.menuItem.addEventListener('dragstart', function() {
790 return false;
791 }, false);
792
793 return k.menuItem;
794 };
795
796 k.getText = function() {
797 return k.menuItem.getElementsByClassName('ponyhoof_menuitem_span')[0].innerHTML;
798 };
799 };
800
801 // Dialog
802 var DIALOGS = {};
803 var DIALOGCOUNT = 2000;
804 var Dialog = function(id) {
805 var k = this;
806
807 k.dialog = null;
808 k.generic_dialogDiv = null;
809 k.popup_dialogDiv = null;
810 k.id = id;
811 k.visible = false;
812
813 k.alwaysModal = false;
814 k.noTitle = false;
815 k.noBottom = false;
816
817 k.canCardspace = true;
818 k.cardSpaceTimer = null;
819 k.cardspaced = false;
820
821 k.onclose = function() {};
822 k.onclosefinish = function() {};
823 k.canCloseByEscapeKey = true;
824
825 k.skeleton = '';
826
827 k.create = function() {
828 //if (DIALOGS[k.id]) {
829 // log("Attempting to recreate dialog ID \""+k.id+"\"");
830 // return DIALOGS[k.id].dialog;
831 //}
832
833 //DIALOGS[k.id] = k;
834
835 log("Creating "+k.id+" dialog...");
836
837 k.injectStyle();
838
839 DIALOGCOUNT += 1;
840 k.skeleton = '<!-- '+SIG+' Dialog -->';
841 k.skeleton += '<div class="generic_dialog pop_dialog" role="dialog" style="z-index:'+(DIALOGCOUNT)+';">';
842 k.skeleton += ' <div class="generic_dialog_popup">';
843 k.skeleton += ' <div class="popup">';
844 k.skeleton += ' <div class="wrap">';
845 k.skeleton += ' <h3 title="This dialog is sent from '+FRIENDLYNAME+'"></h3>';
846 k.skeleton += ' <div class="body">';
847 k.skeleton += ' <div class="content clearfix"></div>';
848 k.skeleton += ' <div class="bottom"></div>';
849 k.skeleton += ' </div>'; // body
850 k.skeleton += ' </div>'; // wrap
851 k.skeleton += ' </div>'; // popup
852 k.skeleton += ' </div>'; // generic_dialog_popup
853 k.skeleton += '</div>';
854
855 INTERNALUPDATE = true;
856
857 k.dialog = d.createElement('div');
858 k.dialog.className = 'ponyhoof_dialog';
859 k.dialog.id = 'ponyhoof_dialog_'+k.id;
860 k.dialog.innerHTML = k.skeleton;
861 d.body.appendChild(k.dialog);
862
863 INTERNALUPDATE = false;
864
865 k.generic_dialogDiv = k.dialog.getElementsByClassName('pop_dialog')[0];
866 k.popup_dialogDiv = k.dialog.getElementsByClassName('popup')[0];
867
868 if (k.alwaysModal) {
869 addClass(k.generic_dialogDiv, 'generic_dialog_modal');
870 }
871 if (k.noTitle) {
872 addClass(k.dialog.getElementsByTagName('h3')[0], 'hidden_elem');
873 }
874 if (k.noBottom) {
875 addClass(k.dialog.getElementsByClassName('bottom')[0], 'hidden_elem');
876 }
877
878 k.show();
879
880 return k.dialog;
881 };
882
883 k.injectStyle = function() {
884 var cx = '._6nw';
885 if (d.getElementsByClassName('-cx-PUBLIC-hasLitestand__body').length) {
886 cx = '.-cx-PUBLIC-hasLitestand__body';
887 }
888
889 var css = '';
890 css += '.ponyhoof_message .wrap {margin-top:3px;background:transparent !important;display:block;}';
891 css += '.ponyhoof_message .uiButton.rfloat {margin-left:10px;}';
892
893 css += '.ponyhoof_dialog, .ponyhoof_dialog .body {font-size:11px;}';
894 css += cx+' .ponyhoof_dialog, '+cx+' .ponyhoof_dialog .body {font-size:12px;}';
895 css += '.ponyhoof_dialog iframe {-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
896 css += '.ponyhoof_dialog textarea, .ponyhoof_dialog input[type="text"] {cursor:text;-moz-box-sizing:border-box;box-sizing:border-box;}';
897 css += '.ponyhoof_dialog .generic_dialog_modal, .ponyhoof_dialog .generic_dialog_fixed_overflow {background-color:rgba(0,0,0,.4) !important;}';
898 css += '.ponyhoof_dialog .generic_dialog {z-index:250;}';
899 css += '.ponyhoof_dialog .generic_dialog_popup {margin-top:80px;}';
900 css += '.ponyhoof_dialog .popup {width:465px;margin:0 auto;cursor:default;-moz-box-shadow:0 2px 26px rgba(0, 0, 0, .3), 0 0 0 1px rgba(0, 0, 0, .1);box-shadow:0 2px 26px rgba(0, 0, 0, .3), 0 0 0 1px rgba(0, 0, 0, .1);}';
901 css += cx+' .ponyhoof_dialog .popup {font-family:"Helvetica Neue", Helvetica, Arial, "lucida grande",tahoma,verdana,arial,sans-serif;}';
902 css += '.ponyhoof_dialog .wrap {background:#fff;color:#000;}';
903 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;}';
904 css += cx+' .ponyhoof_dialog h3 {background:#f5f6f7;border:0;border-bottom:1px solid #e5e5e5;-moz-border-radius:3px 3px 0 0;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;}';
905 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;}';
906 css += cx+' .ponyhoof_dialog h3:before {display:none;}';
907 css += '.ponyhoof_dialog .body {border:1px solid #555;border-top-width:0;}';
908 css += '.ponyhoof_dialog h3.hidden_elem + .body {border-top-width:1px;}';
909 css += cx+' .ponyhoof_dialog .body {border:0;}';
910 css += '.ponyhoof_dialog .content {padding:10px;}';
911 css += '.ponyhoof_dialog .bottom {background:#F2F2F2;border-top:1px solid #ccc;padding:8px 10px 8px 10px;text-align:right;}';
912 css += cx+' .ponyhoof_dialog .bottom {-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}';
913 css += '.ponyhoof_dialog .bottom .lfloat {line-height:17px;margin-top:4px;}';
914
915 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;}';
916 css += '.ponyhoof_tabs {padding:4px 10px 0;background:#F2F2F2;border-bottom:1px solid #ccc;margin:-10px -10px 10px;}';
917 css += '.ponyhoof_tabs a {margin:3px 10px 0 0;padding:5px 8px;float:left;}';
918 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;}';
919 css += '.ponyhoof_tabs_section {display:none;}';
920
921 if (ISMOBILE) {
922 css += '#ponyhoof_welcome_scenery {background-image:none !important;}';
923 css += '.ponyhoof_dialog .generic_dialog {position:absolute;}';
924 css += '.ponyhoof_menu .uiMenu.overflow {resize:none !important;height:auto !important;}';
925 }
926
927 injectManualStyle(css, 'dialog');
928 };
929
930 k.show = function() {
931 removeClass(k.dialog, 'ponyhoof_fadeout');
932 removeClass(k.generic_dialogDiv, 'ponyhoof_fadeout');
933
934 k.visible = true;
935 k.dialog.style.display = 'block';
936 k.generic_dialogDiv.style.display = 'block';
937
938 if (ISMOBILE) {
939 k.canCardspace = false;
940 }
941
942 if (k.canCardspace) {
943 w.addEventListener('resize', k.onBodyResize, false);
944 k.cardSpaceTick();
945 }
946
947 if (k.canCloseByEscapeKey) {
948 d.body.addEventListener('keydown', k.documentEscapeKey, false);
949 }
950 };
951
952 k.close = function(callback) {
953 k.onclose();
954
955 if (!userSettings.disable_animation) {
956 fadeOut(k.dialog, function() {
957 if (callback) {
958 callback();
959 }
960 k.onclosefinish();
961 });
962 if (callback) {
963 log("Legacy dialog close code found [Dialog.close()]");
964 }
965
966 if (ISOPERA) {
967 fadeOut(k.generic_dialogDiv);
968 }
969 } else {
970 k.dialog.style.display = 'none';
971 if (callback) {
972 callback();
973 }
974 k.onclosefinish();
975 }
976
977 k._close();
978 };
979
980 k.hide = function() {
981 k.onclose();
982
983 k.dialog.style.display = 'none';
984
985 k._close();
986 };
987
988 k._close = function() {
989 k.visible = false;
990
991 w.removeEventListener('resize', k.onBodyResize, false);
992 w.clearTimeout(k.cardSpaceTimer);
993
994 if (k.cardspaced) {
995 removeClass(d.documentElement, 'generic_dialog_overflow_mode');
996 if (!k.alwaysModal) {
997 removeClass(k.generic_dialogDiv, 'generic_dialog_modal');
998 }
999 }
1000 removeClass(k.generic_dialogDiv, 'generic_dialog_fixed_overflow');
1001 k.cardspaced = false;
1002
1003 d.body.removeEventListener('keydown', k.documentEscapeKey, false);
1004 };
1005
1006 k.changeTitle = function(c) {
1007 INTERNALUPDATE = true;
1008 var title = k.dialog.getElementsByTagName('h3');
1009 if (title.length) {
1010 title = title[0];
1011 title.innerHTML = c;
1012 }
1013 INTERNALUPDATE = false;
1014 };
1015
1016 k.changeContent = function(c) {
1017 INTERNALUPDATE = true;
1018 var content = k.dialog.getElementsByClassName('content');
1019 if (content.length) {
1020 content = content[0];
1021 content.innerHTML = c;
1022 }
1023 INTERNALUPDATE = false;
1024 };
1025
1026 k.changeBottom = function(c) {
1027 INTERNALUPDATE = true;
1028 var bottom = k.dialog.getElementsByClassName('bottom');
1029 if (bottom.length) {
1030 bottom = bottom[0];
1031 bottom.innerHTML = c;
1032 }
1033 INTERNALUPDATE = false;
1034 };
1035
1036 k.addCloseButton = function(callback) {
1037 var text = "Close";
1038 if (CURRENTLANG && CURRENTLANG.close) {
1039 text = CURRENTLANG.close;
1040 }
1041
1042 var close = '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button"><span class="uiButtonText">'+text+'</span></a>';
1043 k.changeBottom(close);
1044
1045 k.dialog.querySelector('.bottom .uiButton').addEventListener('click', function(e) {
1046 k.close(function() {
1047 if (callback) {
1048 log("Legacy dialog close code found [Dialog.addCloseButton()]");
1049 callback();
1050 }
1051 });
1052 e.preventDefault();
1053 }, false);
1054 };
1055
1056 k.onBodyResize = function() {
1057 if (k.canCardspace) {
1058 var dialogHeight = k.popup_dialogDiv.clientHeight + 80 + 40;
1059 var windowHeight = w.innerHeight;
1060
1061 if (dialogHeight > windowHeight) {
1062 if (!k.cardspaced) {
1063 addClass(d.documentElement, 'generic_dialog_overflow_mode');
1064 if (!k.alwaysModal) {
1065 addClass(k.generic_dialogDiv, 'generic_dialog_modal');
1066 }
1067 addClass(k.generic_dialogDiv, 'generic_dialog_fixed_overflow');
1068
1069 k.cardspaced = true;
1070 }
1071 } else {
1072 if (k.cardspaced) {
1073 removeClass(d.documentElement, 'generic_dialog_overflow_mode');
1074 if (!k.alwaysModal) {
1075 removeClass(k.generic_dialogDiv, 'generic_dialog_modal');
1076 }
1077 removeClass(k.generic_dialogDiv, 'generic_dialog_fixed_overflow');
1078
1079 k.cardspaced = false;
1080 }
1081 }
1082 }
1083 };
1084
1085 k.cardSpaceTick = function() {
1086 if (k.canCardspace && k.visible) {
1087 k.onBodyResize();
1088 k.cardSpaceTimer = w.setTimeout(k.cardSpaceTick, 500);
1089 } else {
1090 w.clearTimeout(k.cardSpaceTimer);
1091 }
1092 };
1093
1094 k.documentEscapeKey = function(e) {
1095 if (k.canCloseByEscapeKey) {
1096 if (e.which == 27 && k.visible) { // esc
1097 k.close();
1098 e.stopPropagation();
1099 e.cancelBubble = true;
1100 }
1101 }
1102 };
1103
1104 if (DIALOGS[k.id]) {
1105 log("Attempting to recreate dialog ID \""+k.id+"\"");
1106 return DIALOGS[k.id];
1107 }
1108 DIALOGS[k.id] = k;
1109 };
1110
1111 function createSimpleDialog(id, title, message) {
1112 if (DIALOGS[id]) {
1113 DIALOGS[id].changeTitle(title);
1114 DIALOGS[id].changeContent(message);
1115 DIALOGS[id].show();
1116 return DIALOGS[id];
1117 }
1118
1119 var di = new Dialog(id);
1120 di.create();
1121 di.changeTitle(title);
1122 di.changeContent(message);
1123 di.addCloseButton();
1124
1125 return di;
1126 };
1127
1128 function injectSystemStyle() {
1129 var css = '';
1130 css += '.ponyhoof_show_if_injected {display:none;}';
1131 css += '.ponyhoof_hide_if_injected {display:block;}';
1132 css += '.ponyhoof_hide_if_injected.inline {display:inline;}';
1133 css += 'html.ponyhoof_injected .ponyhoof_show_if_injected {display:block;}';
1134 css += 'html.ponyhoof_injected .ponyhoof_hide_if_injected {display:none;}';
1135 css += '.ponyhoof_show_if_loaded {display:none;}';
1136 css += '.ponyhoof_updater_latest, .ponyhoof_updater_newVersion, .ponyhoof_updater_error {display:none;}';
1137
1138 css += '.ponyhoof_fadeout {opacity:0;-webkit-transition:opacity .25s linear;-moz-transition:opacity .25s linear;-o-transition:opacity .25s linear;transition:opacity .25s linear;}';
1139 css += '.ponyhoof_message {padding:10px;color:#000;font-weight:bold;overflow:hidden;}';
1140
1141 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;}';
1142 css += '.ponyhoof_loading.ponyhoof_show_if_injected {display:none;}';
1143 css += 'html.ponyhoof_injected .ponyhoof_loading_pony {display:inline-block;}';
1144
1145 css += '.uiHelpLink {background:url("data:image/gif;base64,R0lGODlhDAALAJEAANvb26enp////wAAACH5BAEAAAIALAAAAAAMAAsAAAIblI8WkbcswAtAwWVzwoIbSWliBzWjR5abagoFADs=") no-repeat 0 center;display:inline-block;height:9px;width:12px;}';
1146
1147 css += '.uiInputLabel + .uiInputLabel {margin-top:3px;}';
1148 css += '.uiInputLabelCheckbox {float:left;margin:0;padding:0;}';
1149 css += '.uiInputLabel label {color:#333;display:block;font-weight:normal;margin-left:17px;vertical-align:baseline;}';
1150 css += '.webkit.mac .uiInputLabel label {margin-left:16px;}';
1151 css += '.webkit.mac .uiInputLabelCheckbox {margin-top:2px;}';
1152
1153 injectManualStyle(css, 'system');
1154 }
1155
1156 // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
1157 var _hiddenPropCached = '';
1158 var getHiddenProp = function() {
1159 if (_hiddenPropCached) {
1160 return _hiddenPropCached;
1161 }
1162
1163 var prefixes = ['webkit', 'moz', 'ms', 'o'];
1164
1165 if ('hidden' in document) {
1166 _hiddenPropCached = 'hidden';
1167 return _hiddenPropCached;
1168 }
1169
1170 for (var i = 0, len = prefixes.length; i < len; i++){
1171 if ((prefixes[i] + 'Hidden') in document) {
1172 _hiddenPropCached = prefixes[i] + 'Hidden';
1173 return _hiddenPropCached;
1174 }
1175 }
1176
1177 return null;
1178 };
1179 var isPageHidden = function() {
1180 var prop = getHiddenProp();
1181 if (!prop) {
1182 return false;
1183 }
1184
1185 return document[prop];
1186 };
1187
1188 // http://stackoverflow.com/a/2745459
1189 var isCanvasSupported = function() {
1190 return !!w.CanvasRenderingContext2D;
1191 };
1192
1193 // http://stackoverflow.com/a/10930441
1194 var isWebPSupported = function(callback) {
1195 var webp = new w.Image();
1196 try {
1197 webp.onload = webp.onerror = function() {
1198 callback(webp.height === 2);
1199 };
1200 webp.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
1201 } catch (e) {
1202 callback(false);
1203 }
1204 };
1205
1206 // http://www.myersdaily.org/joseph/javascript/md5.js
1207 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});
1208 var VERSION = 1.701;
1209 var FRIENDLYNAME = 'P'+'onyh'+'oof';
1210 var SIG = '['+FRIENDLYNAME+' v'+VERSION+']';
1211 var DISTRIBUTION = 'userjs';
1212
1213 var runMe = true;
1214 var STORAGEMETHOD = 'none';
1215 var INTERNALUPDATE = false;
1216 var USINGMUTATION = false;
1217
1218 var CURRENTPONY = null;
1219 var REALPONY = CURRENTPONY;
1220 var BRONYNAME = '';
1221 var USERID = 0;
1222 var UILANG = 'en_US';
1223 var CURRENTLANG = {};
1224 var ISUSINGPAGE = false;
1225 var ISUSINGBUSINESS = false;
1226 var ONPLUGINPAGE = false;
1227
1228 var SETTINGSPREFIX = '';
1229 var globalSettings = {};
1230 var GLOBALDEFAULTSETTINGS = {
1231 'allowLoginScreen':true,
1232 'runForNewUsers':true,
1233 'globalSettingsMigrated':false, 'lastUserId':0, 'lastVersion':''
1234 };
1235
1236 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"],"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"],"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","mane6":true,"loadingText":"Hold on there sugarcube!","successText":"Yeehaw!"},{"code":"flutter","name":"Fluttershy","users":["flutter","flut ter"],"search":"fluttershy|flutter shy","color":["b4ae6e","968e3a"],"soundNotif":"flutter\/notif2","mane6":true,"loadingText":"Screaming...","successText":"Yay!"},{"code":"rarity","name":"Rarity","users":["rarity"],"color":["9b6eb4","763a96"],"soundNotif":"rarity\/notif","mane6":true,"loadingText":"Whining...","seperator":true},{"code":"applebloom","name":"Apple Bloom","users":["appleb","apple b"],"search":"apple bloom|applebloom|cmc|cutie mark crusaders","color":["b46e8d","963a63"],"soundNotif":"applebloom\/notif","loadingText":"Getting her cutie mark...","nocutie":true},{"code":"aloe","name":"Aloe","users":["aloe"],"search":"aloe|spa pony|spa ponies","color":["b46e91","963a68"]},{"code":"babsseed","name":"Babs Seed","users":["babs","seed"],"search":"babs seed|babsseed|cmc|cutie mark crusaders","color":["b4976e","96703a"],"nocutie":true},{"code":"berry","name":"Berry Punch","users":["berry"],"color":["a56eb4","823a96"]},{"code":"bigmac","name":"Big Macintosh","users":["bigmac","big mac"],"search":"bigmacintosh|big macintosh|big mcintosh|bigmcintosh","color":["b46e75","963a43"],"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\/icon16_2.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"],"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"],"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"]},{"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"]},{"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"]},{"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"]},{"code":"lotus","name":"Lotus","users":["lotus"],"search":"lotus|spa pony|spa ponies","color":["6ea0b4","3a7c96"]},{"code":"luna","name":"Luna","users":["luna"],"search":"luna|princess luna|nightmare moon|nightmaremoon","color":["6e7eb4","3a5096"],"soundNotif":"luna\/notif","loadingText":"Doubling the fun...","successText":"Huzzah!"},{"code":"lyra","name":"Lyra","users":["lyra"],"search":"lyra heartstrings","color":["6eb49d","3a9677"]},{"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"]},{"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"]},{"code":"scootaloo","name":"Scootaloo","users":["scootaloo"],"search":"scootaloo|cmc|cutie mark crusaders|chicken","color":["b4996e","96733a"],"loadingText":"Getting her cutie mark...","nocutie":true},{"code":"shiningarmor","name":"Shining Armor","users":["shining armor"],"search":"shining armor|shiningarmor","color":["6e7bb4","3a4b96"]},{"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\/icon16_2.png"},{"code":"sweetieb","name":"Sweetie Belle","users":["sweetieb","sweetie b"],"search":"sweetiebelle|sweetie belle|cmc|cutie mark crusaders","color":["a06eb4","7c3a96"],"soundNotif":"sweetieb\/notif","loadingText":"Getting her cutie mark...","nocutie":true},{"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"],"soundNotif":"vinyl\/notif","loadingText":"Wubbing..."},{"code":"thunderlane","name":"Thunderlane","users":["thunder"],"search":"thunderlane|thunder lane","color":["6eb4b4","3a9696"]},{"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"],"hidden":true,"nocutie":true}];
1237 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"}};
1238 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"}};
1239 var SOUNDS_CHAT = {"_sound\/grin2":{"name":"Fluttershy - *squee*"},"_sound\/chat_boing":{"name":"Boing"}};
1240 var HTMLCLASS_SETTINGS = ['login_bg', 'disable_animation', 'pinkieproof', 'disable_emoticons'];
1241 var DEFAULTSETTINGS = {
1242 'theme':CURRENTPONY,
1243 'login_bg':false, 'customBg':null, //'allowLoginScreen':true,
1244 'sounds':false, 'soundsFile':'AUTO', 'soundsNotifTypeBlacklist':'', 'soundsVolume':1, 'chatSound':true, 'chatSoundFile':'_sound/grin2',
1245 //'show_messages_other':true,
1246 'pinkieproof':false, 'forceEnglish':false, 'disable_emoticons':false, 'randomPonies':'', 'costume': '', //'commentBrohoofed':true,
1247 'disable_animation':false, 'disableDomNodeInserted':false, //'disableCommentBrohoofed':false,
1248 '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,
1249 //'lastVersion':''
1250
1251 //'survivedTheNight', 'chatSound1401', 'randomSettingMigrated'
1252 };
1253 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"}];
1254 var CURRENTSTACK = STACKS_LANG[0];
1255 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"]}};
1256 var SOUNDS_NOTIFTYPE = {
1257 poke: {name:"Nuzzles", type:"poke"}
1258 ,like: {name:"Brohoofs", type:"like"}
1259 ,group_activity: {name:"New posts in herds and tags about you", type:"group_activity"}
1260 ,group_r2j: {name:"Herd join requests", type:"group_r2j"}
1261 ,group_added_to_group: {name:"Herd invites from friends", type:"group_added_to_group"}
1262 ,plan_reminder: {name:"Adventure reminders", type:"plan_reminder"}
1263 ,follow_profile: {name:"New followers", type:"follow_profile"}
1264 //,photo_made_profile_pic: {name:"Made your pony pic his/her profile picture", type:"photo_made_profile_pic"}
1265 ,answers_answered: {name:"New answers on the Facebook Help Center", type:"answers_answered"}
1266
1267 ,app_invite: {name:"Game/app requests", type:"app_invite"}
1268 ,close_friend_activity: {name:"Posts from Close Friends", type:"close_friend_activity"}
1269 ,notify_me: {name:"Page posts that you subscribed to", type:"notify_me"}
1270
1271 //,fbpage_presence: {name:"Facebook nagging you to post to your page", type:"fbpage_presence"}
1272 ,fbpage_fan_invite: {name:"Page invites from friends", type:"fbpage_fan_invite"}
1273 ,page_new_likes: {name:"New page brohoofs", type:"page_new_likes"}
1274 //,fbpage_new_message: {name:"New private messages on your page", type:"fbpage_new_message"}
1275 };
1276
1277 var THEMEURL = w.location.protocol + '//hoof.little.my/files/';
1278 var THEMECSS = THEMEURL+'';
1279 var THEMECSS_EXT = '.css?userscript_version='+VERSION;
1280 var UPDATEURL = w.location.protocol + '//hoof.little.my/files/update_check.js?' + (+new Date());
1281
1282 var PONYHOOF_PAGE = '197956210325433';
1283 var PONYHOOF_URL = '//'+getFbDomain()+'/Ponyhoof';
1284 var PONYHOOF_README = '//hoof.little.my/files/_welcome/readme.htm?version='+VERSION+'&distribution='+DISTRIBUTION;
1285
1286 var _ext_messageId = 0;
1287 var _ext_messageCallback = {};
1288
1289 // Chrome
1290 var chrome_sendMessage = function(message, callback) {
1291 try {
1292 if (chrome.extension.sendMessage) {
1293 chrome.extension.sendMessage(message, callback);
1294 } else {
1295 chrome.extension.sendRequest(message, callback);
1296 }
1297 } catch (e) {
1298 if (e.toString().indexOf('Error: Error connecting to extension ') === 0) {
1299 extUpdatedError(e.toString());
1300 }
1301 throw e;
1302 }
1303 };
1304
1305 var chrome_storageFallback = false;
1306 var chrome_getValue = function(name, callback) {
1307 if (chrome.storage && !chrome_storageFallback) {
1308 if (chrome_isExtUpdated()) {
1309 extUpdatedError("[chrome_getValue("+name+")]");
1310 callback(null);
1311 return;
1312 }
1313
1314 chrome.storage.local.get(name, function(item) {
1315 if (chrome.runtime && chrome.runtime.lastError) {
1316 // Fallback to old storage method
1317 chrome_storageFallback = true;
1318 chrome_getValue(name, callback);
1319 return;
1320 }
1321
1322 if (Object.keys(item).length === 0) {
1323 callback(null);
1324 return;
1325 }
1326 callback(item[name]);
1327 });
1328 return;
1329 }
1330
1331 try {
1332 chrome_sendMessage({'command':'getValue', 'name':name}, function(response) {
1333 if (response && typeof response.val != 'undefined') {
1334 callback(response.val);
1335 } else {
1336 callback(null);
1337 }
1338 });
1339 } catch (e) {
1340 dir(e);
1341 getValueError(e);
1342 callback(null);
1343 }
1344 };
1345
1346 var chrome_setValue = function(name, val) {
1347 if (chrome.storage && !chrome_storageFallback) {
1348 if (chrome_isExtUpdated()) {
1349 extUpdatedError("[chrome_setValue("+name+")]");
1350 return;
1351 }
1352
1353 var toSet = {};
1354 toSet[name] = val;
1355 chrome.storage.local.set(toSet, function() {
1356 if (chrome.runtime && chrome.runtime.lastError) {
1357 saveValueError(chrome.runtime.lastError);
1358 return;
1359 }
1360 });
1361 return;
1362 }
1363
1364 chrome_sendMessage({'command':'setValue', 'name':name, 'val':val}, function() {});
1365 };
1366
1367 var chrome_clearStorage = function() {
1368 if (chrome.storage) {
1369 chrome.storage.local.clear();
1370 }
1371 chrome_sendMessage({'command':'clearStorage'}, function() {});
1372 };
1373
1374 var chrome_ajax = function(details) {
1375 chrome_sendMessage({'command': 'ajax', 'details': details}, function(response) {
1376 if (response.val == 'success') {
1377 if (details.onload) {
1378 details.onload(response.request);
1379 }
1380 } else {
1381 if (details.onerror) {
1382 details.onerror(response.request);
1383 }
1384 }
1385 });
1386 };
1387
1388 var chrome_isExtUpdated = function() {
1389 return (typeof chrome.i18n === 'undefined' || typeof chrome.i18n.getMessage('@@extension_id') === 'undefined');
1390 };
1391
1392 if (ISOPERA) {
1393 if (opera.extension) {
1394 opera.extension.onmessage = function(message) {
1395 if (message.data) {
1396 var response = message.data;
1397 var callback = _ext_messageCallback[response.messageid];
1398 if (callback) {
1399 callback(response.val);
1400 }
1401 }
1402 }
1403 }
1404
1405 var opera_getValue = function(name, callback) {
1406 _ext_messageCallback[_ext_messageId] = callback;
1407 opera.extension.postMessage({'command':'getValue', 'messageid':_ext_messageId, 'name':name});
1408 _ext_messageId += 1;
1409 };
1410
1411 var opera_setValue = function(name, val) {
1412 opera.extension.postMessage({'command':'setValue', 'name':name, 'val':val});
1413 };
1414
1415 var opera_clearStorage = function() {
1416 opera.extension.postMessage({'command':'clearStorage'});
1417 };
1418
1419 var opera_ajax = function(details) {
1420 _ext_messageCallback[_ext_messageId] = function(response) {
1421 if (response.val == 'success') {
1422 if (details.onload) {
1423 details.onload(response.request);
1424 }
1425 } else {
1426 if (details.onerror) {
1427 details.onerror(response.request);
1428 }
1429 }
1430 };
1431 var detailsX = {
1432 'method': details.method
1433 ,'url': details.url
1434 ,'headers': details.headers
1435 ,'data': details.data
1436 };
1437 opera.extension.postMessage({'command':'ajax', 'messageid':_ext_messageId, 'details':detailsX});
1438 _ext_messageId += 1;
1439 };
1440 }
1441
1442 if (ISSAFARI) {
1443 if (typeof safari != 'undefined') {
1444 safari.self.addEventListener('message', function(message) {
1445 var data = message.message;
1446 if (data) {
1447 var response = data;
1448 var callback = _ext_messageCallback[message.name];
1449 if (callback) {
1450 callback(response.val);
1451 }
1452 }
1453 });
1454 }
1455
1456 var safari_getValue = function(name, callback) {
1457 _ext_messageId = md5(Math.random().toString()); // safari, you don't know what's message passing/callbacks, do you?
1458 _ext_messageCallback[_ext_messageId] = callback;
1459 safari.self.tab.dispatchMessage('getValue', {'messageid':_ext_messageId, 'name':name});
1460 //_ext_messageId += 1;
1461 };
1462
1463 var safari_setValue = function(name, val) {
1464 safari.self.tab.dispatchMessage('setValue', {'name':name, 'val':val});
1465 };
1466
1467 var safari_clearStorage = function() {
1468 safari.self.tab.dispatchMessage('clearStorage', {});
1469 };
1470
1471 var safari_ajax = function(details) {
1472 _ext_messageId = md5(Math.random().toString());
1473 _ext_messageCallback[_ext_messageId] = function(response) {
1474 if (response.val == 'success') {
1475 if (details.onload) {
1476 details.onload(response.request);
1477 }
1478 } else {
1479 if (details.onerror) {
1480 details.onerror(response.request);
1481 }
1482 }
1483 };
1484 var detailsX = {
1485 'method': details.method
1486 ,'url': details.url
1487 ,'headers': details.headers
1488 ,'data': details.data
1489 };
1490 safari.self.tab.dispatchMessage('ajax', {'messageid':_ext_messageId, 'details':detailsX});
1491 //_ext_messageId += 1;
1492 };
1493 }
1494
1495 if (typeof self != 'undefined' && typeof self.on != 'undefined') {
1496 self.on('message', function(message) {
1497 var data = message;
1498 if (data) {
1499 var response = data;
1500 var callback = _ext_messageCallback[message.messageid];
1501 if (callback) {
1502 callback(response.val);
1503 }
1504 }
1505 });
1506
1507 var xpi_getValue = function(name, callback) {
1508 _ext_messageCallback[_ext_messageId] = callback;
1509 self.postMessage({'command':'getValue', 'messageid':_ext_messageId, 'name':name});
1510 _ext_messageId += 1;
1511 };
1512
1513 var xpi_setValue = function(name, val) {
1514 self.postMessage({'command':'setValue', 'name':name, 'val':val});
1515 };
1516
1517 var xpi_clearStorage = function() {
1518 self.postMessage({'command':'clearStorage'});
1519 };
1520
1521 var xpi_ajax = function(details) {
1522 _ext_messageCallback[_ext_messageId] = function(response) {
1523 if (response.val == 'success') {
1524 if (details.onload) {
1525 details.onload(response.request);
1526 }
1527 } else {
1528 if (details.onerror) {
1529 details.onerror(response.request);
1530 }
1531 }
1532 };
1533 var detailsX = {
1534 'method': details.method
1535 ,'url': details.url
1536 ,'headers': details.headers
1537 ,'data': details.data
1538 };
1539 self.postMessage({'command':'ajax', 'messageid':_ext_messageId, 'details':detailsX});
1540 _ext_messageId += 1;
1541 };
1542
1543 var xpi_sendMessage = function(message, callback) {
1544 _ext_messageCallback[_ext_messageId] = callback;
1545 message.messageid = _ext_messageId;
1546 self.postMessage(message);
1547 _ext_messageId += 1;
1548 };
1549 }
1550
1551 if (typeof w.external != 'undefined' && typeof w.external.mxGetRuntime != 'undefined') {
1552 var maxthonRuntime = w.external.mxGetRuntime();
1553 maxthonRuntime.listen('messageContentScript', function(message) {
1554 var data = message;
1555 if (data) {
1556 var response = data;
1557 var callback = _ext_messageCallback[message.messageid];
1558 if (callback) {
1559 callback(response.val);
1560 }
1561 }
1562 });
1563
1564 var mxaddon_getValue = function(name, callback) {
1565 try {
1566 callback(maxthonRuntime.storage.getConfig(name));
1567 } catch (e) {
1568 if (e.message && e.message === 'No LocalStorage Service Extension! (206)') {
1569 extUpdatedError(e.message);
1570 }
1571 throw e;
1572 }
1573 };
1574
1575 var mxaddon_setValue = function(name, val) {
1576 try {
1577 maxthonRuntime.storage.setConfig(name, val);
1578 } catch (e) {
1579 if (e.message && e.message === 'No LocalStorage Service Extension! (206)') {
1580 extUpdatedError(e.message);
1581 }
1582 throw e;
1583 }
1584 };
1585
1586 var mxaddon_clearStorage = function() {
1587 // Maxthon does not have a clear storage function
1588 };
1589
1590 var mxaddon_ajax = function(details) {
1591 _ext_messageCallback[_ext_messageId] = function(response) {
1592 if (response.val == 'success') {
1593 if (details.onload) {
1594 details.onload(response.request);
1595 }
1596 } else {
1597 if (details.onerror) {
1598 details.onerror(response.request);
1599 }
1600 }
1601 };
1602 var detailsX = {
1603 'method': details.method
1604 ,'url': details.url
1605 ,'headers': details.headers
1606 ,'data': details.data
1607 };
1608 try {
1609 maxthonRuntime.post('messageBackground', {'command':'ajax', 'messageid':_ext_messageId, 'details':detailsX});
1610 } catch (e) {
1611 if (e.message && e.message === 'No Platform_Message Service Extension! (355)') {
1612 extUpdatedError(e.message);
1613 }
1614 throw e;
1615 }
1616 _ext_messageId += 1;
1617 };
1618 }
1619
1620 function ajax(obj) {
1621 switch (STORAGEMETHOD) {
1622 case 'greasemonkey':
1623 return GM_xmlhttpRequest(obj);
1624
1625 case 'chrome':
1626 return chrome_ajax(obj);
1627
1628 case 'opera':
1629 return opera_ajax(obj);
1630
1631 case 'safari':
1632 return safari_ajax(obj);
1633
1634 case 'xpi':
1635 return xpi_ajax(obj);
1636
1637 case 'mxaddon':
1638 return mxaddon_ajax(obj);
1639
1640 default:
1641 break;
1642 }
1643
1644 throw {
1645 responseXML:''
1646 ,responseText:''
1647 ,readyState:4
1648 ,responseHeaders:''
1649 ,status:-100
1650 ,statusText:'No GM_xmlhttpRequest support'
1651 };
1652 }
1653
1654 function isPonyhoofPage(id) {
1655 if (id == PONYHOOF_PAGE) {
1656 return true;
1657 }
1658 return false;
1659 }
1660
1661 function capitaliseFirstLetter(string) {
1662 return string.charAt(0).toUpperCase() + string.slice(1);
1663 }
1664
1665 // Settings
1666 for (var i in HTMLCLASS_SETTINGS) {
1667 if (!DEFAULTSETTINGS[HTMLCLASS_SETTINGS[i]]) {
1668 DEFAULTSETTINGS[HTMLCLASS_SETTINGS[i]] = false;
1669 }
1670 }
1671 //DEFAULTSETTINGS.show_messages_other = true;
1672 if (ISMOBILE) {
1673 DEFAULTSETTINGS.disable_animation = true;
1674 }
1675
1676 function getValueError(extra) {
1677 if (chrome_isExtUpdatedError(extra)) {
1678 extUpdatedError(extra);
1679 } else {
1680 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>");
1681 }
1682
1683 trace();
1684 }
1685
1686 function saveValueError(extra) {
1687 var desc = "Whoops, Ponyhoof can't save your settings. Please try again later.";
1688 if (ISFIREFOX && STORAGEMETHOD === 'greasemonkey' && userSettings.customBg) {
1689 desc += "<br><br>This may be caused by a large custom background that you have set. Please try removing it.";
1690 }
1691 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>";
1692 createSimpleDialog('localStorageError_saveValue', "Ponyhoof derp'd", desc);
1693
1694 trace();
1695 }
1696
1697 function ponyhoofError(extra) {
1698 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>");
1699
1700 trace();
1701 }
1702
1703 var chrome_isExtUpdatedError = function(message) {
1704 var a = 'ModuleSystem has been deleted';
1705 var b = 'TypeError: Cannot read property \'sendMessage\' of undefined';
1706 return (message === a || message === b);
1707 };
1708
1709 var extUpdatedError = function(extra) {
1710 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>");
1711 };
1712
1713 function getValue(name, callback) {
1714 switch (STORAGEMETHOD) {
1715 case 'greasemonkey':
1716 callback(GM_getValue(name));
1717 break;
1718
1719 case 'chrome':
1720 chrome_getValue(name, callback);
1721 break;
1722
1723 case 'opera':
1724 opera_getValue(name, callback);
1725 break;
1726
1727 case 'safari':
1728 safari_getValue(name, callback);
1729 break;
1730
1731 case 'xpi':
1732 xpi_getValue(name, callback);
1733 break;
1734
1735 case 'mxaddon':
1736 mxaddon_getValue(name, callback);
1737 break;
1738
1739 case 'localstorage':
1740 default:
1741 name = 'ponyhoof_'+name;
1742 callback(w.localStorage.getItem(name));
1743 break;
1744 }
1745 }
1746
1747 function saveValue(name, v) {
1748 switch (STORAGEMETHOD) {
1749 case 'greasemonkey':
1750 GM_setValue(name, v);
1751 break;
1752
1753 case 'chrome':
1754 chrome_setValue(name, v);
1755 break;
1756
1757 case 'opera':
1758 opera_setValue(name, v);
1759 break;
1760
1761 case 'safari':
1762 safari_setValue(name, v);
1763 break;
1764
1765 case 'xpi':
1766 xpi_setValue(name, v);
1767 break;
1768
1769 case 'mxaddon':
1770 mxaddon_setValue(name, v);
1771 break;
1772
1773 case 'localstorage':
1774 default:
1775 name = 'ponyhoof_'+name;
1776 w.localStorage.setItem(name, v);
1777 break;
1778 }
1779 }
1780
1781 function loadSettings(callback, opts) {
1782 // opts => prefix, defaultsettings
1783 var opts = opts || {prefix:null};
1784 var settingsKey = 'settings';
1785 if (opts.prefix != null) {
1786 settingsKey = opts.prefix+settingsKey;
1787 } else {
1788 settingsKey = SETTINGSPREFIX+settingsKey;
1789 }
1790 if (!opts.defaultSettings) {
1791 opts.defaultSettings = DEFAULTSETTINGS;
1792 }
1793
1794 try {
1795 getValue(settingsKey, function(s) {
1796 if (s) {
1797 s = JSON.parse(s);
1798 if (!s) {
1799 s = {};
1800 }
1801 } else {
1802 s = {};
1803 }
1804 for (var i in opts.defaultSettings) {
1805 if (!s.hasOwnProperty(i)) {
1806 s[i] = opts.defaultSettings[i];
1807 }
1808 }
1809 callback(s);
1810 });
1811 } catch (e) {
1812 dir(e);
1813
1814 var extra = '';
1815 if (e.message) {
1816 extra = e.message;
1817 } else {
1818 extra = e.toString();
1819 }
1820 try {
1821 getValueError(extra);
1822 } catch (e) {
1823 onPageReady(function() {
1824 if (d.body) {
1825 getValueError(extra);
1826 }
1827 });
1828 }
1829 callback();
1830 return false;
1831 }
1832 }
1833
1834 function saveSettings(opts) {
1835 // opts => prefix, settings
1836 var opts = opts || {prefix:null, settings:userSettings};
1837 var settingsKey = 'settings';
1838 if (opts.prefix != null) {
1839 settingsKey = opts.prefix+settingsKey;
1840 } else {
1841 settingsKey = SETTINGSPREFIX+settingsKey;
1842 }
1843 var settings = userSettings;
1844 if (opts.settings) {
1845 settings = opts.settings;
1846 }
1847
1848 try {
1849 saveValue(settingsKey, JSON.stringify(settings));
1850 return true;
1851 } catch (e) {
1852 dir(e);
1853
1854 var extra = '';
1855 if (e.message) {
1856 if (e.message == 'ModuleSystem has been deleted' || e.message == 'TypeError: Cannot read property \'sendMessage\' of undefined') {
1857 extUpdatedError(e.message);
1858 callback();
1859 return;
1860 }
1861
1862 extra = e.message;
1863 } else {
1864 extra = e.toString();
1865 }
1866 saveValueError(extra);
1867 return false;
1868 }
1869 }
1870
1871 var saveGlobalSettings = function() {
1872 saveSettings({prefix:'global_', settings:globalSettings});
1873 };
1874
1875 function statTrack(stat) {
1876 var i = d.createElement('iframe');
1877 i.style.position = 'absolute';
1878 i.style.top = '-9999px';
1879 i.style.left = '-9999px';
1880 i.setAttribute('aria-hidden', 'true');
1881 i.src = '//hoof.little.my/files/_htm/stat_'+stat+'.htm?version='+VERSION;
1882 d.body.appendChild(i);
1883 }
1884
1885 var canPlayFlash = function() {
1886 return !!w.navigator.mimeTypes['application/x-shockwave-flash'];
1887 };
1888
1889 // Pony selector
1890 var PonySelector = function(p, param) {
1891 var k = this;
1892
1893 if (param) {
1894 k.param = param;
1895 } else {
1896 k.param = {};
1897 }
1898 k.p = p;
1899 k.wrap = null;
1900 k.button = null;
1901
1902 k.oldPony = CURRENTPONY;
1903 k.customClick = function() {};
1904 k.customCheckCondition = false;
1905 k.overrideClickAction = false;
1906 k.saveTheme = true;
1907
1908 k.menu = null;
1909 k.createSelector = function() {
1910 if (k.menu) {
1911 return k.menu;
1912 }
1913
1914 k.injectStyle();
1915
1916 var currentPonyData = convertCodeToData(CURRENTPONY);
1917 var name = "(Nopony)";
1918 if (currentPonyData) {
1919 name = currentPonyData.name;
1920 } else if (CURRENTPONY == 'RANDOM') {
1921 name = "(Random)";
1922 }
1923
1924 var iu = INTERNALUPDATE;
1925 INTERNALUPDATE = true;
1926
1927 k.menu = new Menu('ponies_'+p.id, k.p/*, {checkable:true}*/);
1928 k.button = k.menu.createButton(name);
1929 k.menu.alwaysOverflow = true;
1930 k.menu.createMenu();
1931 k.menu.attachButton();
1932
1933 if (k.allowRandom) {
1934 var check = false;
1935 if (CURRENTPONY == 'RANDOM') {
1936 check = true;
1937 }
1938
1939 k.menu.createMenuItem({
1940 html: "(Random)"
1941 ,title: "To choose which characters to randomize, go to the Misc tab"
1942 ,check: check
1943 ,unsearchable: true
1944 ,onclick: function(menuItem, menuClass) {
1945 CURRENTPONY = 'RANDOM';
1946
1947 changeThemeSmart('RANDOM');
1948 if (k.saveTheme) {
1949 userSettings.theme = 'RANDOM';
1950 saveSettings();
1951 }
1952
1953 menuClass.changeButtonText("(Random)");
1954 menuClass.changeChecked(menuItem);
1955 menuClass.close();
1956
1957 if (k.customClick) {
1958 k.customClick(menuItem, menuClass);
1959 }
1960 }
1961 });
1962 }
1963
1964 if (k.allowRandom) {
1965 k.menu.createSeperator();
1966 }
1967
1968 if (k.param.feature && k.param.feature != -1) {
1969 k._createItem(PONIES[k.param.feature], true);
1970 k.menu.createSeperator();
1971 }
1972
1973 for (var i = 0, len = PONIES.length; i < len; i += 1) {
1974 if (k.param.feature && k.param.feature != -1 && PONIES[k.param.feature].code == PONIES[i].code) {
1975 if (PONIES[i].seperator) {
1976 k.menu.createSeperator();
1977 }
1978 continue;
1979 }
1980
1981 var check = false;
1982 if (k.customCheckCondition) {
1983 if (k.customCheckCondition(PONIES[i].code)) {
1984 check = true;
1985 }
1986 } else {
1987 if (PONIES[i].code == CURRENTPONY) {
1988 check = true;
1989 }
1990 }
1991
1992 k._createItem(PONIES[i], check);
1993
1994 if (PONIES[i].seperator) {
1995 k.menu.createSeperator();
1996 }
1997 }
1998
1999 var img = d.createElement('span');
2000 img.className = 'ponyhoof_loading ponyhoof_show_if_injected ponyhoof_loading_pony';
2001 k.menu.wrap.appendChild(img);
2002
2003 INTERNALUPDATE = iu;
2004 };
2005
2006 k._createItem = function(ponyData, check) {
2007 var unsearchable = false;
2008 if (ponyData.hidden) {
2009 unsearchable = true;
2010 }
2011 var menuItem = k.menu.createMenuItem({
2012 html: ponyData.name
2013 ,title: ponyData.menu_title
2014 ,data: ponyData.code
2015 ,check: check
2016 ,unsearchable: unsearchable
2017 ,searchAlternate: ponyData.search
2018 ,onclick: function(menuItem, menuClass) {
2019 if (!k.overrideClickAction) {
2020 var code = ponyData.code;
2021 CURRENTPONY = code;
2022
2023 changeThemeSmart(code);
2024 if (k.saveTheme) {
2025 userSettings.theme = code;
2026 saveSettings();
2027 }
2028
2029 menuClass.changeButtonText(ponyData.name);
2030 menuClass.changeChecked(menuItem);
2031 menuClass.close();
2032 }
2033
2034 if (k.customClick) {
2035 k.customClick(menuItem, menuClass);
2036 }
2037 }
2038 });
2039 if (ponyData.hidden) {
2040 addClass(menuItem.menuItem, 'ponyhoof_pony_hidden');
2041 }
2042 };
2043
2044 k.injectStyle = function() {
2045 var css = '';
2046 css += 'html .ponyhoof_pony_hidden {display:none;}';
2047 for (var i = 0, len = PONIES.length; i < len; i += 1) {
2048 if (PONIES[i].color) {
2049 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;}';
2050 }
2051 }
2052
2053 injectManualStyle(css, 'ponySelector');
2054 };
2055 };
2056
2057 // Sounds
2058 var _soundCache = {};
2059 var PonySound = function(id) {
2060 var k = this;
2061 k.id = id;
2062
2063 k.sound = d.createElement('audio');
2064
2065 // Don't loop sounds for 3 seconds
2066 k.wait = 3;
2067 k.respectSettings = true;
2068 k.respectVolumeSetting = true;
2069
2070 k._time = 0;
2071
2072 k.source = '';
2073 k.changeSource = function(source) {
2074 k.source = source;
2075 };
2076
2077 k.changeSourceSmart = function(source) {
2078 if (k.canPlayMp3()) {
2079 source = source.replace(/\.EXT/, '.mp3');
2080 } else if (k.canPlayOgg()) {
2081 source = source.replace(/\.EXT/, '.ogg');
2082 } else {
2083 throw new Error("No supported audio formats");
2084 }
2085
2086 k.changeSource(source);
2087 };
2088
2089 k.play = function() {
2090 if (k.respectSettings) {
2091 if (!userSettings.sounds) {
2092 return;
2093 }
2094 }
2095
2096 if (STORAGEMETHOD === 'chrome' && chrome_isExtUpdated()) {
2097 extUpdatedError("PonySound.play()");
2098 return;
2099 }
2100
2101 if (k.wait == 0) {
2102 k.continuePlaying();
2103 return;
2104 }
2105
2106 // Make sure we aren't playing it on another page already
2107 k._time = Math.floor(Date.now() / 1000);
2108
2109 //try {
2110 getValue(SETTINGSPREFIX+'soundCache', function(s) {
2111 if (typeof s != 'undefined') {
2112 try {
2113 _soundCache = JSON.parse(s);
2114 } catch (e) {
2115 _soundCache = {};
2116 }
2117
2118 if (_soundCache == null) {
2119 _soundCache = {};
2120 }
2121
2122 if (_soundCache[k.id]) {
2123 if (_soundCache[k.id]+k.wait <= k._time) {
2124 } else {
2125 return;
2126 }
2127 }
2128 }
2129
2130 k.continuePlaying();
2131 });
2132 //} catch (e) {
2133 // k.continuePlaying();
2134 //}
2135 };
2136
2137 k.continuePlaying = function() {
2138 if (k.wait) {
2139 _soundCache[k.id] = k._time;
2140 saveValue(SETTINGSPREFIX+'soundCache', JSON.stringify(_soundCache));
2141 }
2142
2143 if (k.respectVolumeSetting) {
2144 k.sound.volume = userSettings.soundsVolume;
2145 }
2146 k.sound.src = k.source;
2147 k.sound.play();
2148 };
2149
2150 // http://html5doctor.com/native-audio-in-the-browser/
2151 k.audioTagSupported = function() {
2152 return !!(k.sound.canPlayType);
2153 };
2154
2155 k.canPlayMp3 = function() {
2156 return !!k.sound.canPlayType && '' != k.sound.canPlayType('audio/mpeg');
2157 };
2158
2159 k.canPlayOgg = function() {
2160 return !!k.sound.canPlayType && '' != k.sound.canPlayType('audio/ogg; codecs="vorbis"');
2161 };
2162 };
2163
2164 var ponySounds = {};
2165 function initPonySound(id, source) {
2166 var source = source || '';
2167
2168 if (ponySounds[id]) {
2169 if (source) {
2170 ponySounds[id].changeSourceSmart(source);
2171 }
2172
2173 return ponySounds[id];
2174 }
2175
2176 var sound = new PonySound(id);
2177
2178 if (!sound.audioTagSupported()) {
2179 throw new Error('No <audio> tag support');
2180 }
2181
2182 if (source) {
2183 sound.changeSourceSmart(source);
2184 }
2185
2186 ponySounds[id] = sound;
2187
2188 return sound;
2189 }
2190
2191 // Updater
2192 var Updater = function() {
2193 var k = this;
2194
2195 k.classChecking = 'ponyhoof_updater_checking';
2196 k.classLatest = 'ponyhoof_updater_latest';
2197 k.classError = 'ponyhoof_updater_error';
2198 k.classNewVersion = 'ponyhoof_updater_newVersion';
2199 k.classVersionNum = 'ponyhoof_updater_versionNum';
2200 k.classUpdateButton = 'ponyhoof_updater_updateNow';
2201
2202 k.update_url = UPDATEURL;
2203
2204 k.update_json = {};
2205
2206 k.checkForUpdates = function() {
2207 loopClassName(k.classUpdateButton, function(ele) {
2208 if (ISSAFARI && STORAGEMETHOD != 'safari') {
2209 // NinjaKit is bugged and only listens to install script requests on page load, no DOMNodeInserted, so we plan to open a new window
2210 ele.target = '_blank';
2211 }
2212
2213 ele.addEventListener('click', k._updateNowButton, false);
2214 });
2215
2216 log("Checking for updates...");
2217 try {
2218 ajax({
2219 method: 'GET'
2220 ,url: k.update_url
2221 ,onload: function(response) {
2222 if (response.status != 200) {
2223 k._onError(response);
2224 return;
2225 }
2226
2227 try {
2228 var json = JSON.parse(response.responseText);
2229 } catch (e) {
2230 k._onError(response);
2231 return;
2232 }
2233
2234 if (json.version > VERSION) {
2235 k._newVersion(json);
2236 } else {
2237 k._noNewVersion();
2238 }
2239 }
2240 ,onerror: function(response) {
2241 k._onError(response);
2242 }
2243 });
2244 } catch (e) {
2245 k._onError(e);
2246 }
2247 };
2248
2249 k._noNewVersion = function() {
2250 // Hide checking for updates
2251 loopClassName(k.classChecking, function(ele) {
2252 ele.style.display = 'none';
2253 });
2254
2255 // Show yay
2256 loopClassName(k.classLatest, function(ele) {
2257 ele.style.display = 'block';
2258 });
2259 };
2260 k._newVersion = function(json) {
2261 k.update_json = json;
2262
2263 // Hide checking for updates
2264 loopClassName(k.classChecking, function(ele) {
2265 ele.style.display = 'none';
2266 });
2267
2268 // Show version number
2269 loopClassName(k.classVersionNum, function(ele) {
2270 ele.textContent = json.version;
2271 });
2272 // Show that we have a new version
2273 loopClassName(k.classNewVersion, function(ele) {
2274 ele.style.display = 'block';
2275 });
2276 // Change the update now button to point to the new link
2277 loopClassName(k.classUpdateButton, function(ele) {
2278 if (ISSAFARI && STORAGEMETHOD != 'safari') {
2279 ele.href = json.safari;
2280 return;
2281 }
2282
2283 switch (STORAGEMETHOD) {
2284 // v1.501
2285 case 'chrome':
2286 ele.href = json.chrome_url;
2287 break;
2288
2289 case 'opera':
2290 ele.href = json.opera_url;
2291 break;
2292
2293 // v1.521
2294 case 'safari':
2295 ele.href = json.safariextz;
2296 break;
2297
2298 // v1.611
2299 case 'xpi':
2300 ele.href = json.xpi;
2301 break;
2302
2303 case 'mxaddon':
2304 // Handled by function
2305 break;
2306
2307 default:
2308 ele.href = json.update_url;
2309 break;
2310 }
2311 });
2312 };
2313 k._onError = function(response) {
2314 // Hide checking for updates
2315 loopClassName(k.classChecking, function(ele) {
2316 ele.style.display = 'none';
2317 });
2318
2319 // Show derp
2320 loopClassName(k.classError, function(ele) {
2321 ele.style.display = 'block';
2322 });
2323
2324 error("Error checking for updates.");
2325 dir(response);
2326 };
2327
2328 k.updateDialog = null;
2329 k._updateNowButton = function() {
2330 statTrack('updateNowButton');
2331
2332 switch (STORAGEMETHOD) {
2333 case 'chrome':
2334 k._cws();
2335 return false;
2336
2337 case 'opera':
2338 k._opera();
2339 return false;
2340
2341 case 'safari':
2342 k.safariInstruction();
2343 return false;
2344
2345 case 'xpi':
2346 k._xpi();
2347 return;
2348
2349 case 'mxaddon':
2350 k.mxaddon();
2351 return;
2352
2353 default:
2354 break;
2355 }
2356
2357 if (DIALOGS.updater_dialog) {
2358 k.updateDialog.show();
2359 return;
2360 }
2361
2362 var c = "The update will load after you reload Facebook.";
2363 if (ISCHROME) { // still localstorage
2364 c = "Click Continue on the bottom of this window and click Add to finish updating. The update will load after you reload Facebook.";
2365 } else if (ISSAFARI) { // still ninjakit
2366 c = "Follow the instructions in the new window and reload Facebook when you are done.";
2367 } else if (ISOPERA) { // still localstorage
2368 c = "Follow the instructions in the new window and reload Facebook when you are done.";
2369 } else if (STORAGEMETHOD == 'greasemonkey') {
2370 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'>";
2371 injectManualStyle('#ponyhoof_dialog_updater_dialog .generic_dialog_popup, #ponyhoof_dialog_updater_dialog .popup {width:600px;}', 'updater_dialog');
2372 }
2373
2374 var bottom = '';
2375 bottom += '<div class="lfloat"><a href="#" class="retry hidden_elem">Retry</a></div>';
2376 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG.reloadNow+'</span></a>';
2377 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG.notNow+'</span></a>';
2378
2379 k.updateDialog = new Dialog('updater_dialog');
2380 k.updateDialog.alwaysModal = true;
2381 k.updateDialog.create();
2382 k.updateDialog.changeTitle(CURRENTLANG['updater_title']);
2383 k.updateDialog.changeContent(c);
2384 k.updateDialog.changeBottom(bottom);
2385
2386 if (!ISCHROME && STORAGEMETHOD == 'greasemonkey') {
2387 var retry = k.updateDialog.dialog.getElementsByClassName('retry');
2388 if (retry.length) {
2389 retry = retry[0];
2390 retry.href = k.update_json.update_url;
2391 removeClass(retry, 'hidden_elem');
2392 }
2393 }
2394 k._initReloadButtons(k.updateDialog);
2395
2396 return false;
2397 };
2398
2399 k.cwsDialog = null;
2400 k.cwsWaitDialog = null;
2401 k.cwsOneClickSuccess = false;
2402 k._cws = function() {
2403 if (k.cwsWaitDialog) {
2404 k._cws_showDialog();
2405 return;
2406 }
2407
2408 var ok = true;
2409 loopClassName(k.classUpdateButton, function(ele) {
2410 if (hasClass(ele, 'uiButtonDisabled')) {
2411 ok = false;
2412 } else {
2413 addClass(ele, 'uiButtonDisabled');
2414 }
2415 });
2416 if (!ok) {
2417 return;
2418 }
2419
2420 var c = "Updating... <span class='ponyhoof_loading'></span>";
2421 k.cwsWaitDialog = new Dialog('update_cwsWait');
2422 k.cwsWaitDialog.alwaysModal = true;
2423 k.cwsWaitDialog.noBottom = true;
2424 k.cwsWaitDialog.canCloseByEscapeKey = false;
2425 k.cwsWaitDialog.create();
2426 k.cwsWaitDialog.changeTitle(CURRENTLANG['updater_title']);
2427 k.cwsWaitDialog.changeContent(c);
2428
2429 chrome_sendMessage({'command':'checkForUpdates'}, function(status, details) {
2430 if (status == 'update_available') {
2431 var c = "Downloading update... <span class='ponyhoof_loading'></span>";
2432 k.cwsWaitDialog.changeContent(c);
2433 chrome_sendMessage({'command':'onUpdateAvailable'}, function(status) {
2434 if (status == 'updated') {
2435 k.cwsOneClickSuccess = true;
2436
2437 var successText = '';
2438 var ponyData = convertCodeToData(REALPONY);
2439 if (ponyData.successText) {
2440 successText = ponyData.successText;
2441 } else {
2442 successText = "Yay!";
2443 }
2444 var c = successText+" Update complete, reloading... <span class='ponyhoof_loading'></span>";
2445 k.cwsWaitDialog.changeContent(c);
2446
2447 if (!k.cwsDialog) {
2448 chrome_sendMessage({'command':'reloadNow'}, function() {});
2449 w.setTimeout(function() {
2450 w.location.reload();
2451 }, 1000);
2452 }
2453 } else {
2454 k._cws_fallback();
2455 }
2456 });
2457 } else {
2458 k._cws_fallback();
2459 }
2460 });
2461
2462 w.setTimeout(k._cws_fallback, 8000);
2463 };
2464
2465 k._cws_fallback = function() {
2466 if (k.cwsOneClickSuccess) {
2467 return;
2468 }
2469 k.cwsOneClickSuccess = true;
2470
2471 k.cwsWaitDialog.close();
2472 loopClassName(k.classUpdateButton, function(ele) {
2473 removeClass(ele, 'uiButtonDisabled');
2474 });
2475 k._cws_showDialog();
2476 };
2477
2478 k._cws_showDialog = function() {
2479 if (k.cwsDialog) {
2480 k.cwsDialog.show();
2481 return;
2482 }
2483
2484 var header = '';
2485 if (DISTRIBUTION == 'cws') {
2486 if (!ISOPERABLINK) {
2487 header = "Ponyhoof automatically updates from the Chrome Web Store.";
2488 } else {
2489 header = "Ponyhoof automatically updates on Opera.";
2490 }
2491 } else {
2492 header = "Ponyhoof automatically updates on Google Chrome.";
2493 }
2494
2495 var newversion = k.update_json.version;
2496 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>.";
2497 if (newversion) {
2498 c += "<br><br>Verify that the version changes from "+VERSION+" to "+parseFloat(newversion)+" and reload Facebook.";
2499 }
2500 c += "<br><br><"+"img src='"+THEMEURL+"_welcome/chrome_forceupdate.png' alt='' width='177' height='108' class='ponyhoof_image_shadow'>";
2501
2502 var bottom = '';
2503 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm ponyhoof_updater_cws_openExtensions" role="button"><span class="uiButtonText">Open Extensions</span></a>';
2504 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG.reloadNow+'</span></a>';
2505 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG.notNow+'</span></a>';
2506
2507 k.cwsDialog = new Dialog('update_cws');
2508 k.cwsDialog.alwaysModal = true;
2509 k.cwsDialog.create();
2510 k.cwsDialog.changeTitle(CURRENTLANG['updater_title']);
2511 k.cwsDialog.changeContent(c);
2512 k.cwsDialog.changeBottom(bottom);
2513
2514 $$(k.cwsDialog.dialog, '.ponyhoof_updater_cws_openExtensions', function(button) {
2515 button.addEventListener('click', function(e) {
2516 e.preventDefault();
2517 if (!hasClass(this, 'uiButtonDisabled')) {
2518 chrome_sendMessage({'command':'openExtensions'}, function() {});
2519 }
2520 });
2521 });
2522
2523 k._initReloadButtons(k.cwsDialog);
2524 };
2525
2526 k.operaDialog = null;
2527 k._opera = function() {
2528 if ($('ponyhoof_dialog_update_opera')) {
2529 k.operaDialog.show();
2530 return;
2531 }
2532
2533 var version = getBrowserVersion();
2534
2535 var c = '';
2536 if (parseFloat(version.full) >= 12.10) {
2537 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>";
2538 } else {
2539 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>";
2540 //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>";
2541 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>";
2542 }
2543 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'>";
2544
2545 var bottom = '';
2546 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG.reloadNow+'</span></a>';
2547 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG.notNow+'</span></a>';
2548
2549 k.operaDialog = new Dialog('update_opera');
2550 k.operaDialog.alwaysModal = true;
2551 k.operaDialog.create();
2552 k.operaDialog.changeTitle(CURRENTLANG.updater_title);
2553 k.operaDialog.changeContent(c);
2554 k.operaDialog.changeBottom(bottom);
2555
2556 k._initReloadButtons(k.operaDialog);
2557 };
2558
2559 k.safariDialog = null;
2560 k.safariInstruction = function() {
2561 if (k.safariDialog) {
2562 k.safariDialog.show();
2563 return;
2564 }
2565
2566 injectManualStyle('#ponyhoof_dialog_update_safari .generic_dialog_popup, #ponyhoof_dialog_update_safari .popup {width:600px;}', 'update_safari');
2567
2568 var c = '';
2569 if (w.navigator.userAgent.indexOf('Mac OS X') != -1) {
2570 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>";
2571 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'>";
2572 } else {
2573 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>";
2574 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'>";
2575 }
2576
2577 var bottom = '';
2578 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG.reloadNow+'</span></a>';
2579 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG.notNow+'</span></a>';
2580
2581 k.safariDialog = new Dialog('update_safari');
2582 k.safariDialog.alwaysModal = true;
2583 k.safariDialog.create();
2584 k.safariDialog.changeTitle(CURRENTLANG.updater_title);
2585 k.safariDialog.changeContent(c);
2586 k.safariDialog.changeBottom(bottom);
2587
2588 k._initReloadButtons(k.safariDialog);
2589 };
2590
2591 k.xpiDialog = null;
2592 k.xpiWaitDialog = null;
2593 k.xpiOneClickSuccess = false;
2594 k._xpi = function() {
2595 if (k.xpiWaitDialog) {
2596 k._xpi_showDialog();
2597 return;
2598 }
2599
2600 var c = "Updating... <span class='ponyhoof_loading'></span>";
2601 k.xpiWaitDialog = new Dialog('update_xpiWait');
2602 k.xpiWaitDialog.alwaysModal = true;
2603 k.xpiWaitDialog.noBottom = true;
2604 k.xpiWaitDialog.canCloseByEscapeKey = false;
2605 k.xpiWaitDialog.create();
2606 k.xpiWaitDialog.changeTitle(CURRENTLANG['updater_title']);
2607 k.xpiWaitDialog.changeContent(c);
2608
2609 xpi_sendMessage({'command':'checkForUpdates'}, function(val) {
2610 if (val != 'update_available') {
2611 k._xpi_fallback();
2612 return;
2613 }
2614
2615 xpi_sendMessage({'command':'onUpdateAvailable'}, function(val) {
2616 if (!val.status) {
2617 return;
2618 }
2619 var c = '';
2620 switch (val.status) {
2621 case 'onDownloadStarted':
2622 c = "Downloading update...";
2623 break;
2624
2625 case 'onDownloadEnded':
2626 c = "Preparing to install...";
2627 break;
2628
2629 case 'onInstallStarted':
2630 c = "Installing update...";
2631
2632 w.setTimeout(function() {
2633 k.xpiOneClickSuccess = true;
2634
2635 if (!k.xpiDialog) {
2636 var successText = '';
2637 var ponyData = convertCodeToData(REALPONY);
2638 if (ponyData.successText) {
2639 successText = ponyData.successText;
2640 } else {
2641 successText = "Yay!";
2642 }
2643 c = successText+" Update complete, reloading...";
2644 k.xpiWaitDialog.changeContent(c);
2645
2646 w.location.reload();
2647 }
2648 }, 100);
2649 break;
2650
2651 case 'onDownloadFailed':
2652 case 'onInstallFailed':
2653 k._xpi_fallback();
2654 break;
2655
2656 default:
2657 break;
2658 }
2659 if (c) {
2660 c += " <span class='ponyhoof_loading'></span>";
2661 k.xpiWaitDialog.changeContent(c);
2662 }
2663 });
2664 });
2665
2666 w.setTimeout(k._xpi_fallback, 10000);
2667 };
2668
2669 k._xpi_fallback = function() {
2670 if (k.xpiOneClickSuccess) {
2671 return;
2672 }
2673 k.xpiOneClickSuccess = true;
2674
2675 k.xpiWaitDialog.close();
2676 k._xpi_showDialog();
2677 };
2678
2679 k._xpi_showDialog = function() {
2680 var c = '';
2681 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>";
2682 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'>";
2683
2684 var bottom = '';
2685 bottom += '<div class="lfloat hidden_elem"><a href="#" class="retry">Retry</a></div>';
2686 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG['reloadNow']+'</span></a>';
2687 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG['notNow']+'</span></a>';
2688
2689 k.xpiDialog = new Dialog('update_xpi');
2690 k.xpiDialog.alwaysModal = true;
2691 k.xpiDialog.create();
2692 k.xpiDialog.changeTitle(CURRENTLANG['updater_title']);
2693 k.xpiDialog.changeContent(c);
2694 k.xpiDialog.changeBottom(bottom);
2695
2696 if (k.update_json.xpi) {
2697 var retry = k.xpiDialog.dialog.getElementsByClassName('retry');
2698 if (retry.length) {
2699 retry = retry[0];
2700 retry.href = k.update_json.xpi;
2701 removeClass(retry.parentNode, 'hidden_elem');
2702 }
2703 k._initReloadButtons(k.xpiDialog);
2704
2705 try {
2706 USW.InstallTrigger.install({
2707 "Ponyhoof": {
2708 URL: k.update_json.xpi
2709 ,IconURL: 'https://hoof.little.my/files/app32.png'
2710 }
2711 });
2712 } catch (e) {
2713 dir(e);
2714 }
2715 }
2716 };
2717
2718 k.mxaddonDialog = null;
2719 k.mxaddon = function() {
2720 if (k.mxaddonDialog) {
2721 k.mxaddonDialog.show();
2722 return;
2723 }
2724
2725 injectManualStyle('#ponyhoof_dialog_update_mxaddon .generic_dialog_popup, #ponyhoof_dialog_update_mxaddon .popup {width:500px;}', 'update_mxaddon');
2726
2727 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'>";
2728
2729 var bottom = '';
2730 bottom += '<div class="lfloat"><a href="#" class="retry hidden_elem">Retry</a></div>';
2731 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm reloadNow" role="button"><span class="uiButtonText">'+CURRENTLANG['reloadNow']+'</span></a>';
2732 bottom += '<a href="#" class="uiButton uiButtonLarge notNow" role="button"><span class="uiButtonText">'+CURRENTLANG['notNow']+'</span></a>';
2733
2734 k.mxaddonDialog = new Dialog('update_mxaddon');
2735 k.mxaddonDialog.alwaysModal = true;
2736 k.mxaddonDialog.create();
2737 k.mxaddonDialog.changeTitle(CURRENTLANG['updater_title']);
2738 k.mxaddonDialog.changeContent(c);
2739 k.mxaddonDialog.changeBottom(bottom);
2740
2741 var retry = k.mxaddonDialog.dialog.getElementsByClassName('retry');
2742 if (retry.length) {
2743 retry = retry[0];
2744 retry.addEventListener('click', function(e) {
2745 e.preventDefault();
2746 k._mxaddonInstallNow();
2747 }, false);
2748 removeClass(retry, 'hidden_elem');
2749 }
2750 k._initReloadButtons(k.mxaddonDialog);
2751
2752 k._mxaddonInstallNow();
2753 };
2754
2755 k._mxaddonInstallNow = function() {
2756 try {
2757 w.external.mxCall('InstallApp', k.update_json.mxaddon);
2758 } catch (e) {
2759 dir(e);
2760 }
2761 };
2762
2763 k._initReloadButtons = function(dialog) {
2764 $$(dialog.dialog, '.reloadNow', function(ele) {
2765 ele.addEventListener('click', function() {
2766 if (!hasClass(this, 'uiButtonDisabled')) {
2767 dialog.canCloseByEscapeKey = false;
2768 $$(dialog.dialog, '.uiButton', function(ele) {
2769 addClass(ele, 'uiButtonDisabled');
2770 });
2771 w.location.reload();
2772 }
2773 return false;
2774 });
2775 });
2776
2777 $$(dialog.dialog, '.notNow', function(ele) {
2778 ele.addEventListener('click', function() {
2779 if (!hasClass(this, 'uiButtonDisabled')) {
2780 dialog.close();
2781 }
2782 return false;
2783 });
2784 });
2785 };
2786 };
2787
2788 var BrowserPoniesHoof = function() {
2789 var k = this;
2790
2791 k.dialog = null;
2792 k.errorDialog = null;
2793 k.url = 'https://hoof.little.my/_browserponies/';
2794 k.initLoaded = false;
2795 k.ponies = [];
2796 k.ponySelected = 'RANDOM';
2797 k.doneCallback = function() {};
2798
2799 k.selectPoniesMenu = null;
2800 k.selectPoniesButton = null;
2801
2802 k.run = function() {
2803 if (!k.initLoaded) {
2804 k._init(k.run);
2805 return;
2806 }
2807
2808 k.spawnPony(k.ponySelected);
2809
2810 if (k.doneCallback) {
2811 k.doneCallback();
2812 }
2813 };
2814
2815 k._init = function(callback) {
2816 k._getAjax(k.url+'BrowserPoniesBaseConfig.json?userscript_version='+VERSION, function(response) {
2817 try {
2818 var tempPonies = JSON.parse(response.responseText);
2819 } catch (e) {
2820 if (k.errorCallback) {
2821 k.errorCallback(response);
2822 }
2823 return;
2824 }
2825 contentEval("var BrowserPoniesBaseConfig = "+response.responseText);
2826
2827 for (var i = 0, len = tempPonies.ponies.length; i < len; i += 1) {
2828 var pony = tempPonies.ponies[i].ini.split(/\r?\n/);
2829 for (var j = 0, jLen = pony.length; j < jLen; j += 1) {
2830 var temp = pony[j].split(',');
2831 if (temp && temp[0].toLowerCase() == 'name') {
2832 k.ponies.push(temp[1].replace(/\"/g, ''));
2833 break;
2834 }
2835 }
2836 }
2837
2838 k._getAjax(k.url+'browserponies.js?userscript_version='+VERSION, function(response) {
2839 contentEval(response.responseText);
2840 k.initLoaded = true;
2841
2842 contentEval(function(arg) {
2843 try {
2844 (function(cfg) {
2845 if (typeof(window.BrowserPoniesConfig) === "undefined") {
2846 window.BrowserPoniesConfig = {};
2847 }
2848 window.BrowserPonies.setBaseUrl(cfg.baseurl);
2849 if (!window.BrowserPoniesBaseConfig.loaded) {
2850 window.BrowserPonies.loadConfig(window.BrowserPoniesBaseConfig);
2851 window.BrowserPoniesBaseConfig.loaded = true;
2852 }
2853 window.BrowserPonies.loadConfig(cfg);
2854 })({"baseurl":arg.baseurl,"fadeDuration":500,"volume":1,"fps":25,"speed":3,"audioEnabled":false,"showFps":false,"showLoadProgress":true,"speakProbability":0.1});
2855 } catch (e) {
2856 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
2857 console.log("Unable to hook to BrowserPonies");
2858 console.dir(e);
2859 }
2860 }
2861 }, {"CANLOG":CANLOG, "baseurl":k.url});
2862
2863 callback();
2864 });
2865 });
2866 }
2867
2868 k._getAjax = function(url, callback) {
2869 try {
2870 ajax({
2871 method: 'GET'
2872 ,url: url
2873 ,onload: function(response) {
2874 if (response.status != 200) {
2875 if (k.errorCallback) {
2876 k.errorCallback(response);
2877 }
2878 return;
2879 }
2880
2881 callback(response);
2882 }
2883 ,onerror: function(response) {
2884 if (k.errorCallback) {
2885 k.errorCallback(response);
2886 }
2887 }
2888 });
2889 } catch (e) {
2890 if (k.errorCallback) {
2891 k.errorCallback(e);
2892 }
2893 }
2894 };
2895
2896 k.createDialog = function() {
2897 if ($('ponyhoof_dialog_browserponies')) {
2898 k.dialog.show();
2899 return;
2900 }
2901
2902 k.injectStyle();
2903
2904 var c = '';
2905 c += '<div id="ponyhoof_bp_select"></div><br>';
2906 c += '<a href="#" class="uiButton uiButtonConfirm" role="button" id="ponyhoof_bp_more"><span class="uiButtonText">MORE PONY!</span></a><br><br>';
2907 c += '<a href="#" class="uiButton" role="button" id="ponyhoof_bp_close"><span class="uiButtonText">Hide this</span></a><br><br>';
2908 c += '<a href="#" class="uiButton" role="button" id="ponyhoof_bp_remove"><span class="uiButtonText">Reset</span></a>';
2909
2910 k.dialog = new Dialog('browserponies');
2911 k.dialog.canCloseByEscapeKey = false;
2912 k.dialog.canCardspace = false;
2913 k.dialog.noTitle = true;
2914 k.dialog.noBottom = true;
2915 k.dialog.create();
2916 k.dialog.changeContent(c);
2917
2918 $('ponyhoof_bp_more').addEventListener('click', k.morePonies, false);
2919 $('ponyhoof_bp_close').addEventListener('click', k.closeDialog, false);
2920 $('ponyhoof_bp_remove').addEventListener('click', k.clearAll, false);
2921
2922 k.selectPoniesMenu = new Menu('browserponies_select', $('ponyhoof_bp_select'));
2923 k.selectPoniesMenu.rightFaced = true;
2924 k.selectPoniesMenu.buttonTextClipped = 59;
2925 k.selectPoniesButton = k.selectPoniesMenu.createButton("(Random)");
2926 k.selectPoniesMenu.createMenu();
2927 k.selectPoniesMenu.attachButton();
2928
2929 k.selectPoniesMenu.createMenuItem({
2930 html: "(Random)"
2931 ,check: true
2932 ,unsearchable: true
2933 ,onclick: function(menuItem, menuClass) {
2934 k._select_spawn(menuItem, menuClass, 'RANDOM');
2935 }
2936 });
2937 for (var code in k.ponies) {
2938 if (k.ponies.hasOwnProperty(code)) {
2939 k._select_item(code);
2940 }
2941 }
2942
2943 k.dialog.show();
2944 };
2945
2946 k._select_item = function(code) {
2947 var pony = k.ponies[code];
2948 k.selectPoniesMenu.createMenuItem({
2949 html: pony
2950 ,onclick: function(menuItem, menuClass) {
2951 k._select_spawn(menuItem, menuClass, pony);
2952 }
2953 });
2954 };
2955
2956 k._select_spawn = function(menuItem, menuClass, pony) {
2957 menuClass.changeChecked(menuItem);
2958 menuClass.close();
2959
2960 if (pony == 'RANDOM') {
2961 menuClass.changeButtonText("(Random)");
2962 } else {
2963 menuClass.changeButtonText(pony);
2964 }
2965
2966 k.ponySelected = pony;
2967 k.spawnPony(pony);
2968 };
2969
2970 k.spawnPony = function(pony) {
2971 contentEval(function(arg) {
2972 try {
2973 if (arg.pony == 'RANDOM') {
2974 window.BrowserPonies.spawnRandom();
2975 } else {
2976 window.BrowserPonies.spawn(arg.pony);
2977 }
2978 if (!window.BrowserPonies.running()) {
2979 window.BrowserPonies.start();
2980 }
2981 } catch (e) {
2982 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
2983 console.log("Unable to hook to BrowserPonies");
2984 console.dir(e);
2985 }
2986 }
2987 }, {"CANLOG":CANLOG, "pony":pony});
2988 };
2989
2990 k.createErrorDialog = function(response) {
2991 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>.");
2992 }
2993
2994 k.injectStyle = function() {
2995 var css = '';
2996 css += '#ponyhoof_dialog_browserponies .generic_dialog {z-index:100000000 !important;}';
2997 css += '#ponyhoof_dialog_browserponies .generic_dialog_popup {width:'+(88+8+8+8+10+10)+'px;margin:'+(38+8)+'px 8px 0 auto;}';
2998 css += 'body.hasSmurfbar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(42+8)+'px;}';
2999 css += 'body.hasVoiceBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(56+8)+'px;}';
3000 css += 'body.hasSmurfbar.hasVoiceBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(70+8)+'px;}';
3001 css += 'body.hasViewasChromeBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(76+8)+'px;}';
3002 css += 'body.hasSmurfbar.hasViewasChromeBar #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-top:'+(80+8)+'px;}';
3003 css += '.sidebarMode #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-right:213px;}';
3004 css += '._4g5r #ponyhoof_dialog_browserponies .generic_dialog_popup, .-cx-PUBLIC-hasLitestandBookmarksSidebar__root #ponyhoof_dialog_browserponies .generic_dialog_popup {margin-right:8px;}';
3005 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;}';
3006 css += '#ponyhoof_dialog_browserponies .popup:hover {opacity:1;}';
3007 css += '#ponyhoof_dialog_browserponies .content {background:#F2F2F2;text-align:center;}';
3008 css += '#ponyhoof_dialog_browserponies .uiButton {text-align:left;}';
3009 css += '#browser-ponies img {-webkit-user-select:none;-moz-user-select:none;user-select:none;}';
3010 injectManualStyle(css, 'browserponies');
3011 };
3012
3013 k.copyrightDialog = function() {
3014 createSimpleDialog('browserponies_copyright', "Browser Ponies", "<a href='http://panzi.github.io/Browser-Ponies/' target='_blank'>Browser Ponies</a> is created by Mathias Panzenb&ouml;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>");
3015 };
3016
3017 k.morePonies = function(e) {
3018 k.spawnPony(k.ponySelected);
3019 if (e) {
3020 e.preventDefault();
3021 }
3022 };
3023
3024 k.closeDialog = function(e) {
3025 k.dialog.close();
3026 if (e) {
3027 e.preventDefault();
3028 }
3029 };
3030
3031 k.clearAll = function(e) {
3032 //k.closeDialog();
3033 contentEval(function(arg) {
3034 try {
3035 window.BrowserPonies.unspawnAll();
3036 window.BrowserPonies.stop();
3037 } catch (e) {
3038 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
3039 console.log("Unable to hook to BrowserPonies");
3040 console.dir(e);
3041 }
3042 }
3043 }, {"CANLOG":CANLOG});
3044 if (e) {
3045 e.preventDefault();
3046 }
3047 };
3048 };
3049
3050 // Options
3051 var Options = function() {
3052 var k = this;
3053
3054 k.dialog = null;
3055 k.saveButton = null;
3056
3057 k.needToSaveLabel = false;
3058 k.needToRefresh = false;
3059 k.canSaveSettings = true;
3060
3061 k._stack = CURRENTSTACK;
3062
3063 k.created = false;
3064 k.create = function() {
3065 // Did we create our Options interface already?
3066 if ($('ponyhoof_dialog_options')) {
3067 k._refreshDialog();
3068 return false;
3069 }
3070
3071 k.injectStyle();
3072
3073 if (!runMe) {
3074 var extra = '';
3075 if (ISCHROME) {
3076 extra = '<br><br><a href="http://jointheherd.little.my" target="_top">Please update to the latest version of Ponyhoof here.</a>';
3077 }
3078
3079 k.dialog = new Dialog('options_force_run');
3080 k.dialog.create();
3081 k.dialog.changeTitle("Ponyhoof does not run on "+w.location.hostname);
3082 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);
3083 k.dialog.addCloseButton();
3084 return;
3085 }
3086
3087 var c = '';
3088 c += '<div class="ponyhoof_tabs clearfix">';
3089 c += '<a href="#" class="active" data-ponyhoof-tab="main">'+CURRENTLANG.options_tabs_main+'</a>';
3090 c += '<a href="#" class="ponyhoof_show_if_injected" data-ponyhoof-tab="background">'+CURRENTLANG.options_tabs_background+'</a>';
3091 c += '<a href="#" class="ponyhoof_show_if_injected" data-ponyhoof-tab="sounds">'+CURRENTLANG.options_tabs_sounds+'</a>';
3092 c += '<a href="#" data-ponyhoof-tab="extras">'+CURRENTLANG.options_tabs_extras+'</a>';
3093 c += '<a href="#" data-ponyhoof-tab="advanced">'+CURRENTLANG.options_tabs_advanced+'</a>';
3094 c += '<a href="#" data-ponyhoof-tab="about">'+CURRENTLANG.options_tabs_about+'</a>';
3095 c += '</div>';
3096
3097 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_main" style="display:block;">';
3098 //c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_main">';
3099 c += '<div class="clearfix">';
3100 c += renderBrowserConfigWarning();
3101
3102 c += '<a href="#" ajaxify="/ajax/sharer/?s=18&amp;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>';
3103
3104 var visitPageText = CURRENTLANG.settings_main_visitPage;
3105 if (ISUSINGBUSINESS) {
3106 visitPageText = CURRENTLANG.settings_main_visitPageBusiness;
3107 }
3108
3109 c += '<div class="ponyhoof_show_if_injected">Select your favorite character:</div>';
3110 c += '<div class="ponyhoof_hide_if_injected">Select your favorite character to re-enable Ponyhoof:</div>';
3111 c += '<div id="ponyhoof_options_pony"></div>';
3112 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>';
3113 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>';
3114 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>';
3115 c += '<div class="ponyhoof_show_if_injected"><a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_options_disable">Disable Ponyhoof</a></div>';
3116
3117 c += '<div class="ponyhoof_message uiBoxYellow ponyhoof_updater_newVersion">';
3118 c += '<a href="#" class="uiButton uiButtonSpecial rfloat ponyhoof_updater_updateNow" role="button"><span class="uiButtonText">Update now</span></a>';
3119 c += '<span class="wrap">An update (v<span class="ponyhoof_updater_versionNum"></span>) for Ponyhoof is available.</span>';
3120 c += '</div>';
3121 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>';
3122 c += '</div>';
3123 c += '</div>';
3124
3125 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_background">';
3126 c += '<div class="ponyhoof_show_if_injected">';
3127 c += 'Use as background:';
3128 c += '<ul class="ponyhoof_options_fatradio clearfix">';
3129 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>';
3130 c += '<li id="ponyhoof_options_background_loginbg" data-ponyhoof-background="loginbg"><a href="#"><span>Background</span><div class="wrap"><i></i></div></a></li>';
3131 c += '<li id="ponyhoof_options_background_custom" data-ponyhoof-background="custom"><a href="#"><span>Custom</span><div class="wrap"><i></i></div></a></li>';
3132 c += '</ul>';
3133
3134 c += '<div class="ponyhoof_message uiBoxRed hidden_elem" id="ponyhoof_options_background_error"></div>';
3135 c += '<div class="ponyhoof_message uiBoxYellow hidden_elem" id="ponyhoof_options_background_message"></div>';
3136 c += '<div id="ponyhoof_options_background_drop">';
3137 c += '<div id="ponyhoof_options_background_drop_notdrop">';
3138 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>';
3139 c += '<span class="ponyhoof_menu_label">Or browse for a pony pic: </span>';
3140 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>';
3141 c += '</div>';
3142 c += '<div id="ponyhoof_options_background_drop_dropping">Drop here</div>';
3143 c += '</div>';
3144 c += '</div>';
3145 c += '</div>';
3146
3147 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_sounds">';
3148 c += '<div class="ponyhoof_show_if_injected">';
3149 c += '<div class="ponyhoof_message uiBoxRed hidden_elem unavailable">'+CURRENTLANG.settings_sounds_unavailable+'</div>';
3150
3151 var soundsText = CURRENTLANG.settings_sounds;
3152 if (ISUSINGPAGE || ISUSINGBUSINESS) {
3153 soundsText = CURRENTLANG.settings_sounds_noNotification;
3154 }
3155
3156 c += '<div class="available">';
3157 c += '<div class="ponyhoof_message uiBoxRed usingPage">Notification sounds are not available when you are using Facebook as your page.</div>';
3158 c += k.generateCheckbox('sounds', soundsText, {customFunc:k.soundsClicked});
3159 c += '<div class="notPage notBusiness">';
3160 c += '<div id="ponyhoof_options_soundsSettingsWrap"><br>';
3161 c += '<div id="ponyhoof_options_soundsSetting" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Notification sound: </span></div>';
3162 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>';
3163 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>';
3164 c += '</div>';
3165 c += '</div>';
3166
3167 c += '<div class="notPage notBusiness"><br>';
3168 c += '<span class="ponyhoof_dialog_header">Chat</span>';
3169 c += '<div class="ponyhoof_message uiBoxYellow notPage hidden_elem" id="ponyhoof_options_soundsChatSoundWarning">';
3170 c += '<a href="#" class="uiButton uiButtonConfirm rfloat" role="button"><span class="uiButtonText">Enable now</span></a>';
3171 c += '<span class="wrap">The chat sound option built into Facebook needs to be enabled.</span>';
3172 c += '</div>';
3173 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>';
3174 c += k.generateCheckbox('chatSound', "Change chat sound", {customFunc:k.chatSound});
3175 c += '<div id="ponyhoof_options_soundsChatWrap">';
3176 c += '<div id="ponyhoof_options_soundsChatSetting" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Chat sound: </span></div>';
3177 c += '</div>';
3178 c += '</div>';
3179 c += '</div>'; // .available
3180 c += '</div>';
3181 c += '<div class="ponyhoof_hide_if_injected ponyhoof_message uiBoxRed">';
3182 c += 'You must enable Ponyhoof to use Ponyhoof sounds.';
3183 c += '</div>';
3184 c += '</div>';
3185
3186 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_extras">';
3187 c += '<div class="ponyhoof_show_if_injected">';
3188 c += k.generateCheckbox('pinkieproof', "Strengthen the fourth wall", {title:"Prevents Pinkie Pie from breaking the fourth wall for non-villains"});
3189 c += '</div>';
3190 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});
3191 c += '<div class="ponyhoof_show_if_injected">';
3192 c += k.generateCheckbox('disable_emoticons', "Disable emoticon ponification");
3193 c += '<div id="ponyhoof_options_randomPonies" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Characters to randomize: </span></div>';
3194 c += '<div id="ponyhoof_options_costume" class="ponyhoof_menu_withlabel"><span class="ponyhoof_menu_label">Appearance: </span></div>';
3195 c += '</div>';
3196 c += '<div class="ponyhoof_hide_if_injected"><br></div>';
3197
3198 c += '<span class="ponyhoof_dialog_header">Multi-user</span>';
3199 c += k.generateCheckbox('allowLoginScreen', "Run Ponyhoof on the Facebook login screen", {global:true, customFunc:k.allowLoginScreenClicked});
3200 c += k.generateCheckbox('runForNewUsers', "Run Ponyhoof for new users", {title:CURRENTLANG['settings_extras_runForNewUsers_explain'], global:true});
3201 c += '<br>';
3202
3203 c += '<div class="ponyhoof_show_if_injected">';
3204 c += '<span class="ponyhoof_dialog_header">Performance</span>';
3205 c += k.generateCheckbox('disable_animation', "Disable all animations");
3206 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});
3207 c += '</div>';
3208
3209 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>';
3210 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>';
3211 c += '</div>';
3212
3213 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_advanced">';
3214 c += '<div class="ponyhoof_message uiBoxYellow">These features are unsupported and used for debugging. This should be used by advanced users only.</div><br>';
3215 c += '<span class="ponyhoof_show_if_loaded inline">Style version <span class="ponyhoof_VERSION_CSS"></span><br><br></span>';
3216
3217 c += '<textarea id="ponyhoof_options_technical" READONLY spellcheck="false"></textarea><br><br>';
3218
3219 if (STORAGEMETHOD == 'localstorage') {
3220 c += '<span class="ponyhoof_dialog_header">localStorage dump</span>';
3221 c += '<textarea id="ponyhoof_options_dump" READONLY spellcheck="false"></textarea><br><br>';
3222 }
3223
3224 c += '<div class="ponyhoof_show_if_injected">';
3225 c += '<span class="ponyhoof_dialog_header">Custom CSS</span>';
3226 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>';
3227 c += '<a href="#" class="uiButton" role="button" id="ponyhoof_options_customcss_preview"><span class="uiButtonText">Preview</span></a><br><br>';
3228 c += '</div>';
3229
3230 c += '<span class="ponyhoof_dialog_header">Settings</span>';
3231 c += '<textarea id="ponyhoof_options_debug_settings" spellcheck="false"></textarea>';
3232 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>';
3233
3234 c += '<span class="ponyhoof_dialog_header">Other</span>';
3235 c += '<div class="ponyhoof_hide_if_injected ponyhoof_message uiBoxYellow">';
3236 c += 'You must enable Ponyhoof to use custom CSS or dump debug data.';
3237 c += '</div>';
3238
3239 c += k.generateCheckbox('debug_exposed', "Always show Debug tab");
3240 c += k.generateCheckbox('debug_slow_load', "Disable fast load");
3241 c += '<div class="ponyhoof_show_if_injected">';
3242 c += k.generateCheckbox('debug_dominserted_console', "Dump DOMNodeInserted data to console");
3243 c += k.generateCheckbox('debug_disablelog', "Disable console logging", {customFunc:k.debug_disablelog});
3244 c += k.generateCheckbox('debug_noMutationObserver', "Use legacy HTML detection (slower)", {refresh:true});
3245 c += k.generateCheckbox('debug_mutationDebug', "Dump mutation debug info to console");
3246 c += k.generateCheckbox('debug_betaFacebookLinks', "Rewrite links on beta.facebook.com", {refresh:true});
3247 c += '<a href="#" id="ponyhoof_options_tempRemove" class="ponyhoof_options_fatlink">Remove style</a>';
3248 c += '</div>';
3249 c += '<a href="#" id="ponyhoof_options_sendSource" class="ponyhoof_options_fatlink">Send page source</a>';
3250 if (STORAGEMETHOD != 'mxaddon') {
3251 c += '<a href="#" class="ponyhoof_options_fatlink" id="ponyhoof_options_clearLocalStorage" data-hover="tooltip">Reset all settings (including global)</a>';
3252 }
3253 c += '</div>';
3254
3255 c += '<div class="ponyhoof_tabs_section" id="ponyhoof_options_tabs_about">';
3256 c += '<div class="clearfix">';
3257 c += '<div class="top">';
3258 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>';
3259 c += '</div>';
3260 c += '<strong>Ponyhoof v'+VERSION+'</strong><br>';
3261 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>';
3262 c += '</div>';
3263 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>';
3264 if (ISCHROME || (STORAGEMETHOD == 'chrome' && !ISOPERABLINK)) {
3265 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>';
3266 }
3267 c += '<iframe src="about:blank" id="ponyhoof_options_twitter" allowtransparency="true" frameborder="0" scrolling="no"></iframe>';
3268 if (ISCHROME || STORAGEMETHOD == 'chrome') {
3269 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>';
3270 }
3271
3272 c += '<div class="ponyhoof_options_aboutsection"><div class="inner">';
3273 c += '<strong>If you love Ponyhoof, then please help us a hoof and contribute to support development! Thanks!</strong><br><br>';
3274 c += '<div id="ponyhoof_donate" class="clearfix">';
3275 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>';
3276 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>
3277 c += '</div>';
3278 c += '</div></div>';
3279
3280 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. &copy; '+(new Date().getFullYear())+' Hasbro. All Rights Reserved.</div></div>';
3281 c += '</div>';
3282 c += '</div>';
3283
3284 var successText = '';
3285 var ponyData = convertCodeToData(REALPONY);
3286 if (ponyData.successText) {
3287 successText = ponyData.successText+' ';
3288 }
3289 var bottom = '';
3290 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>';
3291 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_options_save"><span class="uiButtonText">'+CURRENTLANG.close+'</span></a>';
3292
3293 k.dialog = new Dialog('options');
3294 k.dialog.create();
3295 k.dialog.changeTitle(CURRENTLANG.options_title);
3296 k.dialog.changeContent(c);
3297 k.dialog.changeBottom(bottom);
3298 k.dialog.onclose = k.dialogOnClose;
3299 k.dialog.onclosefinish = k.dialogOnCloseFinish;
3300 k.created = true;
3301
3302 // After
3303 k.dialog.dialog.className += ' ponyhoof_dialog_localstorageWarningEmbedded';
3304
3305 k.saveButton = $('ponyhoof_options_save');
3306 k.saveButton.addEventListener('click', k.saveButtonClick, false);
3307
3308 k.dialog.dialog.getElementsByClassName('ponyhoof_noShareIsCare')[0].addEventListener('click', function() {
3309 k.dialog.close();
3310 }, false);
3311
3312 var l = k.dialog.dialog.getElementsByClassName('ponyhoof_options_linkclick');
3313 for (var i = 0, len = l.length; i < len; i += 1) {
3314 l[i].addEventListener('click', function() {
3315 k.dialog.close();
3316 }, false);
3317 }
3318
3319 // Updater
3320 w.setTimeout(function() {
3321 var update = new Updater();
3322 update.checkForUpdates();
3323 }, 500);
3324
3325 k.checkboxInit();
3326 k.tabsInit();
3327
3328 // @todo make k.mainInit non-dependant
3329 k.mainInit();
3330
3331 k._refreshDialog();
3332
3333 if (userSettings.debug_exposed) {
3334 addClass(k.dialog.dialog, 'ponyhoof_options_debugExposed');
3335 }
3336 };
3337
3338 k._refreshDialog = function() {
3339 k.ki();
3340 k.disableDomNodeInserted();
3341
3342 if (k.debugLoaded) {
3343 $('ponyhoof_options_technical').textContent = k.techInfo();
3344 //$('ponyhoof_options_linkedcss').textContent = k.linkedCss();
3345 }
3346 };
3347
3348 k.debugLoaded = false;
3349 k.techInfo = function() {
3350 var cxPrivate = false;
3351 if (d.getElementsByClassName('-cx-PRIVATE-fbLayout__root').length) {
3352 cxPrivate = true;
3353 }
3354
3355 var tech = SIG + " " + new Date().toString() + "\n";
3356 tech += "USERID: " + USERID + "\n";
3357 tech += "CURRENTPONY: " + CURRENTPONY + "\n";
3358 tech += "REALPONY: " + REALPONY + "\n";
3359 tech += "CURRENTSTACK: " + CURRENTSTACK.stack + "\n";
3360 tech += "STORAGEMETHOD: " + STORAGEMETHOD + "\n";
3361 tech += "DISTRIBUTION: " + DISTRIBUTION + "\n";
3362 if (STORAGEMETHOD == 'localstorage') {
3363 tech += "localStorage.length: " + w.localStorage.length + "\n";
3364 }
3365 tech += "\n";
3366 tech += "navigator.userAgent: " + w.navigator.userAgent + "\n";
3367 tech += "document.documentElement.className: " + d.documentElement.className + "\n";
3368 tech += "document.body.className: " + d.body.className + "\n";
3369 tech += "Has cx-PRIVATE: " + cxPrivate + "\n";
3370 tech += "window.location.href: " + w.location.href + "\n";
3371 tech += "\n";
3372 tech += k.linkedCss();
3373 tech += "\n";
3374 tech += k.linkedScript();
3375 tech += "\n";
3376 tech += k.linkedIframe();
3377 tech += "\n";
3378
3379 var ext = [];
3380 var conflict = [];
3381 if ($('bfb_options_button')) {
3382 ext.push("Social Fixer");
3383 }
3384 if (d.getElementsByClassName('rg3fbpz-tooltip').length) {
3385 ext.push("Photo Zoom for Facebook");
3386 }
3387 if ($('fbpoptslink')) {
3388 ext.push("FB Purity");
3389 }
3390 if ($('fbfPopupContainer')) {
3391 ext.push("FFixer");
3392 }
3393 if ($('unfriend_finder')) {
3394 ext.push("Unfriend Finder");
3395 }
3396 if ($('window-resizer-tooltip')) {
3397 ext.push("Window Resizer");
3398 }
3399 if ($('hzImg')) {
3400 ext.push("Hover Zoom");
3401 }
3402 if ($('myGlobalPonies')) {
3403 ext.push("My Global Ponies");
3404 }
3405 if ($('memeticonStyle')) {
3406 ext.push("Memeticon (ads)");
3407 }
3408 if ($('socialplus')) {
3409 ext.push("SocialPlus! (ads)");
3410 }
3411 if (d.querySelector('script[src^="chrome-extension://igdhbblpcellaljokkpfhcjlagemhgjl"]')) {
3412 ext.push("Iminent (ads)");
3413 }
3414 if ($('_fbm-emoticons-wrapper')) {
3415 ext.push("myemoticons.com");
3416 }
3417 if (d.querySelector('script[src^="chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl"]')) {
3418 ext.push("Skype plugin");
3419 }
3420 if (d.querySelector('script[src^="chrome-extension://jmfkcklnlgedgbglfkkgedjfmejoahla"]')) {
3421 ext.push("AVG Safe Search");
3422 }
3423 if ($('DAPPlugin')) {
3424 ext.push("Download Accelerator Plus");
3425 }
3426
3427 if ($('bfb_theme')) {
3428 conflict.push("Social Fixer theme");
3429 }
3430 if ($('mycssstyle')) {
3431 conflict.push("SocialPlus! theme");
3432 }
3433 if ($('ColourChanger')) {
3434 conflict.push("Facebook Colour Changer");
3435 }
3436 if (hasClass(d.documentElement, 'myFacebook')) {
3437 conflict.push("Color My Facebook");
3438 }
3439 if (w.navigator.userAgent.match(/Mozilla\/4\.0 \(compatible\; MSIE 7\.0\; Windows/)) {
3440 conflict.push("IE 7 user-agent spoofing");
3441 }
3442 tech += "Installed extensions: ";
3443 if (ext.length) {
3444 for (var i = 0, len = ext.length; i < len; i += 1) {
3445 tech += ext[i];
3446 if (ext.length-1 != i) {
3447 tech += ', ';
3448 }
3449 }
3450 } else {
3451 tech += "None detected";
3452 }
3453 tech += "\n";
3454
3455 tech += "Conflicts: ";
3456 if (conflict.length) {
3457 for (var i = 0, len = conflict.length; i < len; i += 1) {
3458 tech += conflict[i];
3459 if (conflict.length-1 != i) {
3460 tech += ', ';
3461 }
3462 }
3463 } else {
3464 tech += "None detected";
3465 }
3466 tech += "\n";
3467
3468 return tech;
3469 };
3470
3471 k.linkedCss = function() {
3472 var css = d.getElementsByTagName('link');
3473 var t = '';
3474 for (var i = 0, len = css.length; i < len; i += 1) {
3475 if (css[i].rel == 'stylesheet') {
3476 t += css[i].href + "\n";
3477 }
3478 }
3479
3480 return t;
3481 };
3482
3483 k.linkedScript = function() {
3484 var script = d.getElementsByTagName('script');
3485 var t = '';
3486 for (var i = 0, len = script.length; i < len; i += 1) {
3487 if (script[i].src) {
3488 t += script[i].src + "\n";
3489 }
3490 }
3491
3492 return t;
3493 };
3494
3495 k.linkedIframe = function() {
3496 var iframe = d.getElementsByTagName('iframe');
3497 var t = '';
3498 for (var i = 0, len = iframe.length; i < len; i += 1) {
3499 if (iframe[i].src && iframe[i].src.indexOf('://'+getFbDomain()+'/ai.php') == -1) {
3500 t += iframe[i].src + "\n";
3501 }
3502 }
3503
3504 return t;
3505 };
3506
3507 k.debugInfo = function() {
3508 if (k.debugLoaded) {
3509 return;
3510 }
3511 k.debugLoaded = true;
3512
3513 // Custom CSS
3514 var customcss = $('ponyhoof_options_customcss');
3515 if (userSettings.customcss) {
3516 customcss.value = userSettings.customcss;
3517 }
3518 customcss.addEventListener('input', function() {
3519 if (!k.needsToRefresh) {
3520 k.needsToRefresh = true;
3521 k.updateCloseButton();
3522 }
3523 }, false);
3524 $('ponyhoof_options_customcss_preview').addEventListener('click', function() {
3525 if (!$('ponyhoof_style_customcss')) {
3526 injectManualStyle('', 'customcss');
3527 }
3528
3529 $('ponyhoof_style_customcss').textContent = '/* '+SIG+' */'+customcss.value;
3530 }, false);
3531
3532 // Technical info
3533 var techFirstHover = false;
3534 $('ponyhoof_options_technical').addEventListener('click', function() {
3535 if (!techFirstHover) {
3536 techFirstHover = true;
3537 this.focus();
3538 this.select();
3539 }
3540 }, false);
3541
3542 if (STORAGEMETHOD == 'localstorage') {
3543 var dump = '';
3544 for (var i in localStorage) {
3545 dump += i+": "+localStorage[i]+"\n";
3546 }
3547 $('ponyhoof_options_dump').value = dump;
3548 }
3549
3550 // Settings
3551 var settingsTextarea = $('ponyhoof_options_debug_settings');
3552
3553 $('ponyhoof_options_debug_settings_export').addEventListener('click', function() {
3554 settingsTextarea.value = JSON.stringify(userSettings);
3555 }, false);
3556
3557 $('ponyhoof_options_debug_settings_saveall').addEventListener('click', function(e) {
3558 e.preventDefault();
3559 try {
3560 var s = JSON.parse(settingsTextarea.value);
3561 } catch (e) {
3562 createSimpleDialog('debug_settingsKey_error', "Derp'd", "Invalid JSON<br><br><code>\n\n"+e.toString()+"</code>");
3563 return false;
3564 }
3565
3566 if (confirm(SIG+" Are you sure you want to overwrite your settings? Facebook will be reloaded immediately after saving.")) {
3567 userSettings = s;
3568 saveSettings();
3569 w.location.reload();
3570 }
3571 }, false);
3572
3573 // Other
3574 $('ponyhoof_options_tempRemove').addEventListener('click', k._debugRemoveStyle, false);
3575 k._debugNoMutationObserver();
3576
3577 $('ponyhoof_options_sendSource').addEventListener('click', function() {
3578 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.")) {
3579 k.dialog.hide();
3580
3581 var temp = $('ponyhoof_options_technical').value;
3582 $('ponyhoof_options_technical').value = '';
3583 if ($('ponyhoof_sourceSend_input')) {
3584 $('ponyhoof_sourceSend_input').value = '';
3585 var sourceSend = $('ponyhoof_sourceSend_input').parentNode;
3586 }
3587
3588 var settings = {};
3589 for (var x in userSettings) {
3590 settings[x] = userSettings[x];
3591 }
3592 settings['customBg'] = null;
3593
3594 var t = d.documentElement.innerHTML.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
3595 t = '<!DOCTYPE html><html class="'+d.documentElement.className+'" id="'+d.documentElement.id+'"><!-- '+k.techInfo()+"\n\n"+JSON.stringify(settings)+' -->'+t+'</html>';
3596
3597 if ($('ponyhoof_sourceSend_input')) {
3598 $('ponyhoof_sourceSend_input').value = t;
3599 } else {
3600 var sourceSendTxt = d.createElement('input');
3601 sourceSendTxt.type = 'hidden';
3602 sourceSendTxt.id = 'ponyhoof_sourceSend_input';
3603 sourceSendTxt.name = 'post';
3604 sourceSendTxt.value = t;
3605
3606 var sourceSend = d.createElement('form');
3607 sourceSend.method = 'POST';
3608 sourceSend.action = 'https://paste.little.my/post/';
3609 sourceSend.target = '_blank';
3610 sourceSend.appendChild(sourceSendTxt);
3611 d.body.appendChild(sourceSend);
3612 }
3613
3614 sourceSend.submit();
3615
3616 $('ponyhoof_options_technical').value = temp;
3617 }
3618 return false;
3619 }, false);
3620
3621 $('ponyhoof_options_technical').textContent = k.techInfo();
3622 //$('ponyhoof_options_linkedcss').textContent = k.linkedCss();
3623 };
3624
3625 k._debugRemoveStyle = function(e) {
3626 changeThemeSmart('NONE');
3627
3628 d.removeEventListener('DOMNodeInserted', DOMNodeInserted, true);
3629 if (mutationObserverMain) {
3630 mutationObserverMain.disconnect();
3631 }
3632
3633 k.dialog.close();
3634 e.preventDefault();
3635 };
3636
3637 k._debugNoMutationObserver = function() {
3638 var mutationObserver = w.WebKitMutationObserver || w.MutationObserver || false;
3639 if (!mutationObserver) {
3640 var option = $('ponyhoof_options_debug_noMutationObserver');
3641 option.disabled = true;
3642 option.checked = true;
3643
3644 var label = $('ponyhoof_options_label_debug_noMutationObserver');
3645 addClass(label, 'ponyhoof_options_unavailable');
3646 label.setAttribute('data-hover', 'tooltip');
3647 label.setAttribute('aria-label', "The new HTML detection method is not supported on your browser. Please update your browser if possible.");
3648 }
3649 };
3650
3651 k.mainInitLoaded = false;
3652 k.mainInit = function() {
3653 if (k.mainInitLoaded) {
3654 return;
3655 }
3656
3657 // Pony selector
3658 var ponySelector = new PonySelector($('ponyhoof_options_pony'), {});
3659 ponySelector.allowRandom = true;
3660 ponySelector.customClick = function(menuItem, menuClass) {
3661 if (ponySelector.oldPony == 'NONE' || CURRENTPONY == 'NONE') {
3662 if (ponySelector.oldPony == 'NONE' && CURRENTPONY != 'NONE') {
3663 extraInjection();
3664 runDOMNodeInserted();
3665 }
3666 }
3667 if (ponySelector.oldPony != 'NONE' && CURRENTPONY == 'NONE') {
3668 k.needsToRefresh = true;
3669 }
3670 if (k._stack != CURRENTSTACK) {
3671 k.needsToRefresh = true;
3672 }
3673 k.needToSaveLabel = true;
3674 k.updateCloseButton();
3675
3676 var f = k.dialog.dialog.getElementsByClassName('ponyhoof_options_framerefresh');
3677 for (var i = 0, len = f.length; i < len; i += 1) {
3678 (function() {
3679 var iframe = f[i];
3680 fadeOut(iframe, function() {
3681 w.setTimeout(function() {
3682 iframe.style.display = '';
3683 removeClass(iframe, 'ponyhoof_fadeout');
3684
3685 iframe.src = iframe.src.replace(/\href\=/, '&href=');
3686 }, 250);
3687 });
3688 })();
3689 }
3690 };
3691 ponySelector.createSelector();
3692
3693 if (!ISUSINGPAGE && !ISUSINGBUSINESS) {
3694 w.setTimeout(function() {
3695 $('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';
3696 }, 500);
3697 }
3698
3699 // Disable Ponyhoof
3700 $('ponyhoof_options_disable').addEventListener('click', k.disablePonyhoof, false);
3701
3702 // Browser Ponies
3703 $('ponyhoof_browserponies').addEventListener('click', k.runBrowserPonies, false);
3704
3705 k.mainInitLoaded = true;
3706 };
3707
3708 k.extrasInitLoaded = false;
3709 k.extrasInit = function() {
3710 if (k.extrasInitLoaded) {
3711 return;
3712 }
3713
3714 k.randomInit();
3715 k.costumesInit();
3716
3717 // Disable animations
3718 if (!supportsCssTransition()) {
3719 var option = $('ponyhoof_options_disable_animation');
3720 option.disabled = true;
3721 option.checked = true;
3722
3723 var label = $('ponyhoof_options_label_disable_animation');
3724 addClass(label, 'ponyhoof_options_unavailable');
3725 label.setAttribute('data-hover', 'tooltip');
3726 label.setAttribute('aria-label', "Animations are not supported on your browser. Please update your browser if possible.");
3727 }
3728
3729 // Reset settings
3730 $('ponyhoof_options_resetSettings').addEventListener('click', k.resetSettings, false);
3731
3732 var clearLocalStorage = $('ponyhoof_options_clearLocalStorage');
3733 if (clearLocalStorage) {
3734 clearLocalStorage.addEventListener('click', k.clearStorage, false);
3735 }
3736
3737 k.extrasInitLoaded = true;
3738 };
3739
3740 k.extrasCostumeMenu = null;
3741 k.extrasCostumeButton = null;
3742 k.extrasCostumeMenuItemNormal = null;
3743 k.extrasCostumeMenuItems = {};
3744 k.costumesInit = function() {
3745 var desc = "(Normal)";
3746 var check = true;
3747 if (userSettings.costume && doesCharacterHaveCostume(REALPONY, userSettings.costume)) {
3748 desc = COSTUMESX[userSettings.costume].name;
3749 check = false;
3750 }
3751
3752 k.extrasCostumeMenu = new Menu('costume', $('ponyhoof_options_costume'));
3753 k.extrasCostumeButton = k.extrasCostumeMenu.createButton(desc);
3754 k.extrasCostumeButton.setAttribute('data-hover', 'tooltip');
3755 k.extrasCostumeButton.setAttribute('aria-label', CURRENTLANG.costume_tooltip);
3756 k.extrasCostumeMenu.canSearch = false;
3757 k.extrasCostumeMenu.createMenu();
3758 k.extrasCostumeMenu.attachButton();
3759 k.extrasCostumeMenuItemNormal = k.extrasCostumeMenu.createMenuItem({
3760 html: "(Normal)"
3761 ,data: ''
3762 ,check: check
3763 ,onclick: function(menuItem, menuClass) {
3764 k._costumesInit_save(menuItem, menuClass, '');
3765 }
3766 });
3767
3768 for (var code in COSTUMESX) {
3769 if (COSTUMESX.hasOwnProperty(code)) {
3770 k._costumesInit_item(code);
3771 }
3772 }
3773
3774 changeThemeFuncQueue.push(function() {
3775 if (doesCharacterHaveCostume(REALPONY, userSettings.costume)) {
3776 k.extrasCostumeMenu.changeButtonText(COSTUMESX[userSettings.costume].name);
3777 k.extrasCostumeMenu.changeChecked(k.extrasCostumeMenuItems[userSettings.costume]);
3778 } else {
3779 k.extrasCostumeMenu.changeButtonText("(Normal)");
3780 k.extrasCostumeMenu.changeChecked(k.extrasCostumeMenuItemNormal);
3781 }
3782
3783 for (var code in COSTUMESX) {
3784 if (COSTUMESX.hasOwnProperty(code)) {
3785 if (doesCharacterHaveCostume(REALPONY, code)) {
3786 removeClass(k.extrasCostumeMenuItems[code].menuItem, 'hidden_elem');
3787 } else {
3788 addClass(k.extrasCostumeMenuItems[code].menuItem, 'hidden_elem');
3789 }
3790 }
3791 }
3792 });
3793 };
3794
3795 k._costumesInit_item = function(code) {
3796 var check = false;
3797 var extraClass = '';
3798 if (doesCharacterHaveCostume(REALPONY, code)) {
3799 if (userSettings.costume == code) {
3800 check = true;
3801 }
3802 } else {
3803 extraClass += ' hidden_elem';
3804 }
3805
3806 k.extrasCostumeMenuItems[code] = k.extrasCostumeMenu.createMenuItem({
3807 html: COSTUMESX[code].name
3808 ,data: code
3809 ,check: check
3810 ,extraClass: extraClass
3811 ,onclick: function(menuItem, menuClass) {
3812 k._costumesInit_save(menuItem, menuClass, code);
3813 }
3814 });
3815 };
3816
3817 k._costumesInit_save = function(menuItem, menuClass, code) {
3818 if (!COSTUMESX[code] && code != '') {
3819 return;
3820 }
3821
3822 changeCostume(code);
3823 userSettings.costume = code;
3824 saveSettings();
3825
3826 if (COSTUMESX[code]) {
3827 menuClass.changeButtonText(COSTUMESX[code].name);
3828 } else {
3829 menuClass.changeButtonText("(Normal)");
3830 }
3831 menuClass.changeChecked(menuItem);
3832 menuClass.close();
3833
3834 k.needToSaveLabel = true;
3835 k.updateCloseButton();
3836 };
3837
3838 k.resetSettings = function(e) {
3839 e.preventDefault();
3840
3841 userSettings = {};
3842 saveSettings();
3843
3844 saveValue(SETTINGSPREFIX+'soundCache', JSON.stringify(null));
3845
3846 k.canSaveSettings = false;
3847 k.dialog.close();
3848 w.location.reload();
3849 };
3850
3851 k.clearStorage = function(e) {
3852 e.preventDefault();
3853
3854 k.canSaveSettings = false;
3855
3856 if (typeof GM_listValues != 'undefined') {
3857 try {
3858 var keys = GM_listValues();
3859 for (var i = 0, len = keys.length; i < len; i += 1) {
3860 GM_deleteValue(keys[i]);
3861 }
3862 } catch (e) {
3863 alert(e.toString());
3864 }
3865 }
3866
3867 switch (STORAGEMETHOD) {
3868 case 'localstorage':
3869 if (confirm(SIG+" localStorage must be cleared in order to reset settings. Doing this may cause other extensions to lose their settings.")) {
3870 try {
3871 w.localStorage.clear();
3872 } catch (e) {
3873 alert("Can't clear localStorage :(\n\n"+e.toString());
3874 }
3875 } else {
3876 return;
3877 }
3878 break;
3879
3880 case 'chrome':
3881 chrome_clearStorage();
3882 break;
3883
3884 case 'opera':
3885 opera_clearStorage();
3886 break;
3887
3888 case 'safari':
3889 safari_clearStorage();
3890 break;
3891
3892 case 'xpi':
3893 xpi_clearStorage();
3894 break;
3895
3896 case 'mxaddon':
3897 // Maxthon does not have a clear storage function
3898 break;
3899
3900 default:
3901 break;
3902 }
3903
3904 k.dialog.close();
3905 w.location.reload();
3906 };
3907
3908 k.donateLoaded = false;
3909 k.loadDonate = function() {
3910 if (k.donateLoaded) {
3911 return;
3912 }
3913
3914 statTrack('aboutclicked');
3915
3916 $('ponyhoof_options_twitter').src = 'https://platform.twitter.com/widgets/follow_button.html?screen_name=ponyhoof&show_screen_name=true&show_count=true';
3917 if (ISCHROME || STORAGEMETHOD == 'chrome') {
3918 (function() {
3919 var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
3920 po.src = 'https://apis.google.com/js/plusone.js';
3921 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
3922 })();
3923 }
3924
3925 $('ponyhoof_options_donatepaypal_link').addEventListener('click', function() {
3926 $('ponyhoof_options_donatepaypal').submit();
3927 statTrack('paypalClicked');
3928 return false;
3929 }, false);
3930
3931 $('ponyhoof_donate_flattr_iframe').src = THEMEURL+'_welcome/flattrStandalone.htm';
3932
3933 k.donateLoaded = true;
3934 };
3935
3936 k.randomInit = function() {
3937 var current = [];
3938 if (userSettings.randomPonies) {
3939 current = userSettings.randomPonies.split('|');
3940 }
3941
3942 var outerwrap = $('ponyhoof_options_randomPonies');
3943 var ponySelector = new PonySelector(outerwrap, {});
3944 ponySelector.overrideClickAction = true;
3945 ponySelector.customCheckCondition = function(code) {
3946 if (current.indexOf(code) != -1) {
3947 return true;
3948 }
3949
3950 return false;
3951 };
3952 ponySelector.customClick = function(menuItem, menuClass) {
3953 var code = menuItem.menuItem.getAttribute('data-ponyhoof-menu-data');
3954
3955 if (!hasClass(menuItem.menuItem, 'ponyhoof_menuitem_checked')) {
3956 menuItem.menuItem.className += ' ponyhoof_menuitem_checked';
3957
3958 current.push(code);
3959 } else {
3960 removeClass(menuItem.menuItem, 'ponyhoof_menuitem_checked');
3961
3962 current.splice(current.indexOf(code), 1);
3963 }
3964 userSettings.randomPonies = current.join('|');
3965 saveSettings();
3966
3967 k._randomUpdateButtonText(current, menuClass);
3968 k.needToSaveLabel = true;
3969 k.updateCloseButton();
3970 };
3971 ponySelector.createSelector();
3972 k._randomUpdateButtonText(current, ponySelector.menu);
3973
3974 var mass = d.createElement('a');
3975 mass.href = '#';
3976 mass.className = 'uiButton';
3977 mass.setAttribute('role', 'button');
3978 mass.id = 'ponyhoof_options_randomPonies_mass';
3979 mass.innerHTML = '<span class="uiButtonText">'+CURRENTLANG.invertSelection+'</span>';
3980 mass.addEventListener('click', function(e) {
3981 var newCurrent = [];
3982 for (var i = 0, len = PONIES.length; i < len; i += 1) {
3983 var menuitem = ponySelector.menu.menu.querySelector('.ponyhoof_menuitem[data-ponyhoof-menu-data="'+PONIES[i].code+'"]');
3984 if (PONIES[i].hidden) {
3985 if (menuitem) {
3986 removeClass(menuitem, 'ponyhoof_menuitem_checked');
3987 }
3988 continue;
3989 }
3990 if (current.indexOf(PONIES[i].code) == -1) {
3991 newCurrent.push(PONIES[i].code);
3992
3993 if (menuitem) {
3994 addClass(menuitem, 'ponyhoof_menuitem_checked');
3995 }
3996 } else {
3997 if (menuitem) {
3998 removeClass(menuitem, 'ponyhoof_menuitem_checked');
3999 }
4000 }
4001 }
4002 current = newCurrent;
4003 userSettings.randomPonies = current.join('|');
4004 saveSettings();
4005
4006 k._randomUpdateButtonText(current, ponySelector.menu);
4007 k.needToSaveLabel = true;
4008 k.updateCloseButton();
4009 w.setTimeout(function() {
4010 ponySelector.menu.open();
4011 }, 1);
4012
4013 return false;
4014 }, false);
4015 outerwrap.appendChild(mass);
4016 };
4017
4018 k._randomUpdateButtonText = function(current, menuClass) {
4019 var buttonText = "("+current.length+" characters)";
4020 if (current.length == 0) {
4021 buttonText = "(All characters)";
4022 } else if (current.length == 1) {
4023 var data = convertCodeToData(current[0]);
4024 buttonText = data.name;
4025 }
4026 menuClass.changeButtonText(buttonText);
4027 };
4028
4029 k.soundsMenu = null;
4030 k.soundsButton = null;
4031 k.soundsInitLoaded = false;
4032 k.soundsNotifTypeMenu = null;
4033 k.soundsNotifTypeButton = null;
4034 k.soundsSettingsWrap = null;
4035
4036 k.soundsChatSoundWarning = null;
4037 k.soundsChatLoaded = false;
4038 k.soundsChatWrap = null;
4039 k.soundsChatMenu = null;
4040 k.soundsChatButton = null;
4041 k.soundsInit = function() {
4042 if (k.soundsInitLoaded) {
4043 return;
4044 }
4045
4046 try {
4047 if (typeof w.Audio === 'undefined') {
4048 throw 1;
4049 }
4050 initPonySound('soundsTest');
4051 } catch (e) {
4052 $$(k.dialog.dialog, '.unavailable', function(ele) {
4053 removeClass(ele, 'hidden_elem');
4054 });
4055 $$(k.dialog.dialog, '.available', function(ele) {
4056 addClass(ele, 'hidden_elem');
4057 });
4058 k.soundsInitLoaded = true;
4059 return;
4060 }
4061
4062 var desc = "(Auto-select)";
4063 if (SOUNDS[userSettings.soundsFile] && SOUNDS[userSettings.soundsFile].name) {
4064 desc = SOUNDS[userSettings.soundsFile].name;
4065 }
4066
4067 k.soundsMenu = new Menu('sounds', $('ponyhoof_options_soundsSetting'));
4068 k.soundsButton = k.soundsMenu.createButton(desc);
4069 k.soundsMenu.createMenu();
4070 k.soundsMenu.attachButton();
4071
4072 for (var code in SOUNDS) {
4073 if (SOUNDS.hasOwnProperty(code)) {
4074 k._soundsMenu_item(code);
4075
4076 if (SOUNDS[code].seperator) {
4077 k.soundsMenu.createSeperator();
4078 }
4079 }
4080 }
4081
4082 k._soundsNotifTypeInit();
4083
4084 var volumeInput = $('ponyhoof_options_soundsVolume');
4085 var volumePreview = $('ponyhoof_options_soundsVolumePreview');
4086 var volumeValue = $('ponyhoof_options_soundsVolumeValue');
4087 var volumeTimeout = null;
4088
4089 volumeInput.value = userSettings.soundsVolume * 100;
4090 if (supportsRange()) {
4091 volumePreview.style.display = 'none';
4092 volumeValue.style.display = 'inline';
4093 volumeValue.innerText = volumeInput.value+"%";
4094 volumeInput.addEventListener('change', function() {
4095 volumeValue.innerText = volumeInput.value+"%";
4096
4097 w.clearTimeout(volumeTimeout);
4098 volumeTimeout = w.setTimeout(function() {
4099 var volume = volumeInput.value / 100;
4100 userSettings.soundsVolume = Math.max(0, Math.min(volume, 1));
4101 saveSettings();
4102
4103 k._soundsPreview(userSettings.soundsFile);
4104 }, 300);
4105 }, false);
4106 } else {
4107 volumeInput.type = 'number';
4108 volumeInput.className = 'inputtext';
4109 volumeInput.setAttribute('data-hover', 'tooltip');
4110 volumeInput.setAttribute('aria-label', "Enter a number between 1-100");
4111 volumePreview.addEventListener('click', function(e) {
4112 var volume = volumeInput.value / 100;
4113 userSettings.soundsVolume = Math.max(0, Math.min(volume, 1));
4114 saveSettings();
4115
4116 k._soundsPreview(userSettings.soundsFile);
4117 e.preventDefault();
4118 }, false);
4119 }
4120
4121 k.soundsChanged();
4122
4123 // Detect chat sound enabled setting
4124 k.soundsChatSoundWarning = $('ponyhoof_options_soundsChatSoundWarning');
4125 k.soundsChatWrap = $('ponyhoof_options_soundsChatWrap');
4126 try {
4127 if (typeof USW.requireLazy == 'function') {
4128 USW.requireLazy(['ChatOptions', 'Arbiter'], function(ChatOptions, Arbiter) {
4129 if (userSettings.chatSound) {
4130 k._soundsChatSoundWarn(ChatOptions.getSetting('sound'));
4131 } else {
4132 addClass(k.soundsChatSoundWarning, 'hidden_elem');
4133 }
4134
4135 Arbiter.subscribe('chat/option-changed', function(e, option) {
4136 if (!userSettings.chatSound) {
4137 return;
4138 }
4139 if (option.name == 'sound') {
4140 k._soundsChatSoundWarn(option.value);
4141 }
4142 });
4143 });
4144 }
4145 } catch (e) {
4146 error("Unable to hook to ChatOptions and Arbiter");
4147 dir(e);
4148 }
4149
4150 // Detect Facebook Messenger for Windows
4151 if (w.navigator.plugins) {
4152 w.navigator.plugins.refresh(false);
4153
4154 for (var i = 0, len = w.navigator.plugins.length; i < len; i += 1) {
4155 var plugin = w.navigator.plugins[i];
4156 if (plugin[0] && plugin[0].type === 'application/x-facebook-desktop-1') {
4157 removeClass($('ponyhoof_options_soundsMessengerForWindowsWarning'), 'hidden_elem');
4158 break;
4159 }
4160 }
4161 }
4162
4163 k._soundsChatLoad();
4164 k._soundsChatInit();
4165
4166 var button = k.soundsChatSoundWarning.getElementsByClassName('uiButton');
4167 button[0].addEventListener('click', function() {
4168 k._soundsTurnOnFbSound();
4169 }, false);
4170
4171 k.soundsInitLoaded = true;
4172 };
4173
4174 // Create a menu item for notification sounds
4175 // Used only on k.soundsInit()
4176 k._soundsMenu_item = function(code) {
4177 var check = false;
4178 if (userSettings.soundsFile == code) {
4179 check = true;
4180 }
4181
4182 k.soundsMenu.createMenuItem({
4183 html: SOUNDS[code].name
4184 ,title: SOUNDS[code].title
4185 ,data: code
4186 ,check: check
4187 ,onclick: function(menuItem, menuClass) {
4188 if (!SOUNDS[code] || !SOUNDS[code].name) {
4189 return;
4190 }
4191
4192 //$('ponyhoof_options_sounds').checked = true;
4193 //userSettings.sounds = true;
4194 userSettings.soundsFile = code;
4195 saveSettings();
4196
4197 k._soundsPreview(code);
4198
4199 menuClass.changeButtonText(menuItem.getText());
4200 menuClass.changeChecked(menuItem);
4201
4202 k.needToSaveLabel = true;
4203 k.updateCloseButton();
4204 }
4205 });
4206 };
4207
4208 // Warn people that Facebook's own chat sound needs to be enabled
4209 // Used 2 times on k.soundsInit()
4210 k._soundsChatSoundWarn = function(isFbSoundEnabled) {
4211 if (isFbSoundEnabled) {
4212 addClass(k.soundsChatSoundWarning, 'hidden_elem');
4213 $('ponyhoof_options_chatSound').disabled = false;
4214 if (userSettings.chatSound) {
4215 $('ponyhoof_options_chatSound').checked = true;
4216 }
4217 } else {
4218 removeClass(k.soundsChatSoundWarning, 'hidden_elem');
4219 $('ponyhoof_options_chatSound').disabled = true;
4220 $('ponyhoof_options_chatSound').checked = false;
4221 }
4222 };
4223
4224 // Turn on Facebook chat sounds
4225 // Used on k.soundsInit() and k.chatSound()
4226 k._soundsTurnOnFbSound = function() {
4227 try {
4228 if (typeof USW.requireLazy == 'function') {
4229 USW.requireLazy(['ChatOptions', 'ChatSidebarDropdown'], function(ChatOptions, ChatSidebarDropdown) {
4230 ChatOptions.setSetting('sound', 1);
4231 ChatSidebarDropdown.prototype.changeSetting('sound', 1);
4232 });
4233 }
4234 } catch (e) {
4235 error("Unable to hook to ChatOptions and ChatSidebarDropdown");
4236 dir(e);
4237 }
4238 };
4239
4240 k._soundsNotifTypeCurrent = [];
4241 // Initialize the notification sound blacklist and its HTML template
4242 // Used only on k.soundsInit()
4243 k._soundsNotifTypeInit = function() {
4244 if (userSettings.soundsNotifTypeBlacklist) {
4245 var current = userSettings.soundsNotifTypeBlacklist.split('|');
4246
4247 for (var code in SOUNDS_NOTIFTYPE) {
4248 if (current.indexOf(code) != -1) {
4249 k._soundsNotifTypeCurrent.push(code);
4250 }
4251 }
4252 }
4253
4254 k.soundsNotifTypeMenu = new Menu('soundsNotifType', $('ponyhoof_options_soundsNotifType'));
4255 k.soundsNotifTypeButton = k.soundsNotifTypeMenu.createButton('');
4256 k.soundsNotifTypeMenu.canSearch = false;
4257 k.soundsNotifTypeMenu.createMenu();
4258 k.soundsNotifTypeMenu.attachButton();
4259
4260 for (var code in SOUNDS_NOTIFTYPE) {
4261 if (SOUNDS_NOTIFTYPE.hasOwnProperty(code)) {
4262 k._soundsNotifTypeInit_item(code);
4263 }
4264 }
4265 k._soundsNotifTypeUpdateButtonText(k._soundsNotifTypeCurrent, k.soundsNotifTypeMenu);
4266 };
4267
4268 // Create a menu item for notification sound blacklist
4269 // Used only on k._soundsNotifTypeInit()
4270 k._soundsNotifTypeInit_item = function(code) {
4271 var check = false;
4272 if (k._soundsNotifTypeCurrent.indexOf(code) != -1) {
4273 check = true;
4274 }
4275
4276 k.soundsNotifTypeMenu.createMenuItem({
4277 html: SOUNDS_NOTIFTYPE[code].name
4278 ,data: code
4279 ,check: check
4280 ,onclick: function(menuItem, menuClass) {
4281 if (!SOUNDS_NOTIFTYPE[code] || !SOUNDS_NOTIFTYPE[code].name) {
4282 return;
4283 }
4284
4285 if (!hasClass(menuItem.menuItem, 'ponyhoof_menuitem_checked')) {
4286 menuItem.menuItem.className += ' ponyhoof_menuitem_checked';
4287
4288 k._soundsNotifTypeCurrent.push(code);
4289 } else {
4290 removeClass(menuItem.menuItem, 'ponyhoof_menuitem_checked');
4291
4292 k._soundsNotifTypeCurrent.splice(k._soundsNotifTypeCurrent.indexOf(code), 1);
4293 }
4294 userSettings.soundsNotifTypeBlacklist = k._soundsNotifTypeCurrent.join('|');
4295 saveSettings();
4296
4297 k._soundsNotifTypeUpdateButtonText(k._soundsNotifTypeCurrent, menuClass);
4298 k.needToSaveLabel = true;
4299 k.updateCloseButton();
4300 }
4301 });
4302 };
4303
4304 // Update the notification sound blacklist button text, perhaps after changes
4305 // Used on k._soundsNotifTypeInit() and k._soundsNotifType_item()
4306 k._soundsNotifTypeUpdateButtonText = function(current, menuClass) {
4307 var buttonText = "("+current.length+" types)";
4308 if (current.length == 0) {
4309 buttonText = "(None)";
4310 } else if (current.length == 1) {
4311 buttonText = SOUNDS_NOTIFTYPE[current[0]].name;
4312 }
4313 menuClass.changeButtonText(buttonText);
4314 };
4315
4316 // Hide/show the extra sound options if the main sound option id disabled/enabled
4317 // Used on k.soundsInit(), the sound option is changed, or DOMNodeInserted is disabled
4318 k.soundsChanged = function() {
4319 k.soundsSettingsWrap = k.soundsSettingsWrap || $('ponyhoof_options_soundsSettingsWrap');
4320 if (userSettings.sounds && !userSettings.disableDomNodeInserted) {
4321 removeClass(k.soundsSettingsWrap, 'hidden_elem');
4322 } else {
4323 addClass(k.soundsSettingsWrap, 'hidden_elem');
4324 }
4325 };
4326
4327 // 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"
4328 // Used when the sound option is changed
4329 k.soundsClicked = function() {
4330 k.soundsChanged();
4331
4332 if (userSettings.sounds) {
4333 turnOffFbNotificationSound();
4334 } else {
4335 // We already nuked Facebook's sounds, so we need to reload
4336 k.needsToRefresh = true;
4337 k.updateCloseButton();
4338 }
4339 };
4340
4341 // The wording of this function is a bit confusing
4342 // Hide/show the extra chat sound options if the chat sound option is disabled/enabled
4343 // Used on k.soundsInit() and k.chatSound()
4344 k._soundsChatInit = function() {
4345 if (userSettings.chatSound) {
4346 removeClass(k.soundsChatWrap, 'hidden_elem');
4347 } else {
4348 addClass(k.soundsChatSoundWarning, 'hidden_elem');
4349 addClass(k.soundsChatWrap, 'hidden_elem');
4350 }
4351 };
4352
4353 // Initialize the chat sounds options and its HTML template
4354 // Used only on k.soundsInit()
4355 k._soundsChatLoad = function() {
4356 if (k.soundsChatLoaded) {
4357 return;
4358 }
4359
4360 var desc = "(Select a chat sound)";
4361 if (SOUNDS_CHAT[userSettings.chatSoundFile] && SOUNDS_CHAT[userSettings.chatSoundFile].name) {
4362 desc = SOUNDS_CHAT[userSettings.chatSoundFile].name;
4363 }
4364 k.soundsChatMenu = new Menu('sounds_chat', $('ponyhoof_options_soundsChatSetting'));
4365 k.soundsChatButton = k.soundsChatMenu.createButton(desc);
4366 k.soundsChatMenu.canSearch = false;
4367 k.soundsChatMenu.createMenu();
4368 k.soundsChatMenu.attachButton();
4369 for (var code in SOUNDS_CHAT) {
4370 if (SOUNDS_CHAT.hasOwnProperty(code)) {
4371 k._soundsChatLoad_item(code);
4372 }
4373 }
4374 k.soundsChatLoaded = true;
4375 };
4376
4377 // Create a menu item for chat sound options
4378 // Used only on k._soundsChatLoad()
4379 k._soundsChatLoad_item = function(code) {
4380 var check = false;
4381 if (userSettings.chatSoundFile == code) {
4382 check = true;
4383 }
4384
4385 k.soundsChatMenu.createMenuItem({
4386 html: SOUNDS_CHAT[code].name
4387 ,title: SOUNDS_CHAT[code].title
4388 ,data: code
4389 ,check: check
4390 ,onclick: function(menuItem, menuClass) {
4391 if (!SOUNDS_CHAT[code] || !SOUNDS_CHAT[code].name) {
4392 return;
4393 }
4394
4395 userSettings.chatSoundFile = code;
4396 saveSettings();
4397
4398 k._soundsPreview(code);
4399 changeChatSound(code);
4400
4401 menuClass.changeButtonText(menuItem.getText());
4402 menuClass.changeChecked(menuItem);
4403
4404 k.needToSaveLabel = true;
4405 k.updateCloseButton();
4406 }
4407 });
4408 };
4409
4410 // 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"
4411 // Also calls k._soundsChatInit()
4412 // Used when the chat sound option is changed
4413 k.chatSound = function() {
4414 if (userSettings.chatSound) {
4415 // Enable Facebook's chat sound automatically
4416 k._soundsTurnOnFbSound();
4417 if (SOUNDS_CHAT[userSettings.chatSoundFile] && SOUNDS_CHAT[userSettings.chatSoundFile].name) {
4418 changeChatSound(userSettings.chatSoundFile);
4419 }
4420 } else {
4421 // Chat sounds are already ponified, we need to reload to clear it
4422 k.needsToRefresh = true;
4423 k.updateCloseButton();
4424 }
4425 k._soundsChatInit();
4426 };
4427
4428 // Run a sound preview
4429 k._soundsPreview = function(code) {
4430 var sound = code;
4431 if (code == 'AUTO') {
4432 sound = '_sound/defaultNotification';
4433
4434 var data = convertCodeToData(REALPONY);
4435 if (data.soundNotif) {
4436 sound = data.soundNotif;
4437 }
4438 }
4439 try {
4440 var ps = initPonySound('soundsTest', THEMEURL+sound+'.EXT');
4441 ps.respectSettings = false;
4442 ps.wait = 0;
4443 ps.play();
4444 } catch (e) {}
4445 };
4446
4447 k.bgError = null;
4448 k.bgMessage = null;
4449 k.bgTab = null;
4450 k.bgDrop = null;
4451 k.bgClearCustomBg = false;
4452 k.bgInitLoaded = false;
4453 k.bgSizeLimit = 1024 * 1024;
4454 k.bgSizeLimitDescription = '1 MB';
4455 k._isWebPSupported = false;
4456 k.bgInit = function() {
4457 if (k.bgInitLoaded) {
4458 return;
4459 }
4460
4461 k.bgError = $('ponyhoof_options_background_error');
4462 k.bgMessage = $('ponyhoof_options_background_message');
4463 k.bgTab = $('ponyhoof_options_tabs_background');
4464 k.bgDrop = $('ponyhoof_options_background_drop');
4465
4466 // Firefox 23 started enforcing a 1MB limit per preference
4467 // http://hg.mozilla.org/mozilla-central/rev/2e46cabb6a11
4468 if (ISFIREFOX && STORAGEMETHOD == 'greasemonkey') {
4469 k.bgSizeLimit = 1024 * 512;
4470 k.bgSizeLimitDescription = '512 KB';
4471 }
4472
4473 if (userSettings.customBg) {
4474 addClass(k.bgTab, 'hasCustom');
4475 addClass($('ponyhoof_options_background_custom'), 'active');
4476 } else if (userSettings.login_bg) {
4477 addClass($('ponyhoof_options_background_loginbg'), 'active');
4478 } else {
4479 addClass($('ponyhoof_options_background_cutie'), 'active');
4480 }
4481
4482 $$(k.bgTab, '.ponyhoof_options_fatradio a', function(ele) {
4483 ele.addEventListener('click', function() {
4484 $$(k.bgTab, '.ponyhoof_options_fatradio a', function(ele2) {
4485 removeClass(ele2.parentNode, 'active');
4486 });
4487
4488 var parent = this.parentNode;
4489 var attr = parent.getAttribute('data-ponyhoof-background');
4490 if (attr == 'custom') {
4491 userSettings.login_bg = false;
4492 changeCustomBg(userSettings.customBg);
4493 k.bgClearCustomBg = false;
4494 } else if (attr == 'loginbg') {
4495 userSettings.login_bg = true;
4496 changeCustomBg(null);
4497 addClass(d.documentElement, 'ponyhoof_settings_login_bg');
4498 k.bgClearCustomBg = true;
4499 } else {
4500 userSettings.login_bg = false;
4501 changeCustomBg(null);
4502 k.bgClearCustomBg = true;
4503 }
4504 addClass(parent, 'active');
4505 saveSettings();
4506
4507 k.needToSaveLabel = true;
4508 k.updateCloseButton();
4509
4510 return false;
4511 }, false);
4512 });
4513
4514 $('ponyhoof_options_background_select').addEventListener('change', function(e) {
4515 if (this.files && this.files[0]) {
4516 k.bgProcessFile(this.files[0]);
4517 }
4518 }, false);
4519
4520 isWebPSupported(function(result) {
4521 k._isWebPSupported = result;
4522
4523 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.';
4524 if (isCanvasSupported()) {
4525 var filetype = 'JPEG';
4526 if (k._isWebPSupported) {
4527 filetype = 'JPEG/WebP';
4528 }
4529
4530 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.';
4531 }
4532
4533 var uiHelpLink = k.bgDrop.getElementsByClassName('uiHelpLink');
4534 if (uiHelpLink.length) {
4535 uiHelpLink[0].setAttribute('aria-label', desc);
4536 }
4537 });
4538
4539 k.bgDropInit();
4540
4541 k.bgInitLoaded = true;
4542 };
4543
4544 k.bgDropInit = function() {
4545 if (typeof w.FileReader == 'undefined') {
4546 k.bgError.textContent = "Custom background pony pics are not supported on your browser. Please update your browser if possible.";
4547 removeClass(k.bgError, 'hidden_elem');
4548 addClass(k.bgDrop, 'hidden_elem');
4549 return;
4550 }
4551
4552 k.bgDrop.addEventListener('drop', function(e) {
4553 e.stopPropagation();
4554 e.preventDefault();
4555
4556 removeClass(this, 'ponyhoof_dropping');
4557
4558 if (e.dataTransfer.files && e.dataTransfer.files[0]) {
4559 k.bgProcessFile(e.dataTransfer.files[0]);
4560 }
4561 }, false);
4562
4563 k.bgDrop.addEventListener('dragover', function(e) {
4564 e.stopPropagation();
4565 e.preventDefault();
4566
4567 e.dataTransfer.dropEffect = 'copy';
4568 }, false);
4569
4570 k.bgDrop.addEventListener('dragenter', function(e) {
4571 addClass(k.bgDrop, 'ponyhoof_dropping');
4572 }, false);
4573
4574
4575 k.bgDrop.addEventListener('dragend', function(e) {
4576 removeClass(k.bgDrop, 'ponyhoof_dropping')
4577 }, false);
4578 }
4579
4580 k.bgReaderFile = null;
4581 k.bgReaderBg = null;
4582 k.bgProcessFile = function(file) {
4583 k.bgReaderFile = file;
4584 addClass(k.bgError, 'hidden_elem');
4585 addClass(k.bgMessage, 'hidden_elem');
4586
4587 if (!file.type.match(/image.*/)) {
4588 if (file.type) {
4589 k.bgError.textContent = "The file ("+file.name+") doesn't seem to be a pony pic ("+file.type+").";
4590 } else {
4591 k.bgError.textContent = "The file ("+file.name+") doesn't seem to be a pony pic.";
4592 }
4593 removeClass(k.bgError, 'hidden_elem');
4594 return;
4595 }
4596
4597 var reader = new w.FileReader();
4598 reader.onload = k.bgReaderLoad;
4599 reader.onerror = k.bgReaderError;
4600 reader.readAsDataURL(file);
4601 };
4602
4603 k.bgReaderLoad = function(e) {
4604 k.bgReaderBg = e.target.result;
4605 if (e.target.result.length > k.bgSizeLimit) {
4606 // base64 result is too big to fit, convertion required
4607 if (isCanvasSupported()) {
4608 k.bgPerformConvertion();
4609 } else {
4610 k.bgErrorTooBig();
4611 }
4612 } else {
4613 k.bgChangeSuccess();
4614 }
4615 };
4616
4617 k.bgReaderError = function(e) {
4618 k.bgError.textContent = "An error occurred reading the file. Please try again.";
4619 removeClass(k.bgError, 'hidden_elem');
4620 dir(e);
4621 };
4622
4623 k.bgErrorTooBig = function() {
4624 if (k.bgReaderFile.type && k.bgReaderFile.type != 'image/jpeg' && !isCanvasSupported()) {
4625 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.";
4626 } else {
4627 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.";
4628 }
4629 removeClass(k.bgError, 'hidden_elem');
4630 };
4631
4632 k.bgChangeSuccess = function() {
4633 addClass(k.bgError, 'hidden_elem');
4634 addClass(k.bgTab, 'hasCustom');
4635
4636 $$(k.bgTab, '.ponyhoof_options_fatradio a', function(ele) {
4637 removeClass(ele.parentNode, 'active');
4638 });
4639 addClass($('ponyhoof_options_background_custom'), 'active');
4640 k.bgClearCustomBg = false;
4641
4642 userSettings.login_bg = false;
4643 userSettings.customBg = k.bgReaderBg;
4644 saveSettings();
4645
4646 k.needToSaveLabel = true;
4647 k.updateCloseButton();
4648
4649 changeCustomBg(k.bgReaderBg);
4650 };
4651
4652 k.bgPerformConvertion = function() {
4653 var img = new w.Image();
4654 try {
4655 img.onload = function() {
4656 // First try converting to JPEG/WebP
4657 if (k.bgReaderFile.type != 'image/jpeg' || (k._isWebPSupported && k.bgReaderFile.type != 'image/webp')) {
4658 var transformed = k.bgCanvasTransform(img, img.width, img.height);
4659 if (transformed.length <= k.bgSizeLimit) {
4660 k.bgReaderBg = transformed;
4661 k.bgChangeSuccess();
4662
4663 img = null;
4664 transformed = null;
4665 return;
4666 }
4667 transformed = null;
4668 }
4669
4670 // Now try resizing to screen resolution
4671 var transformed = k.bgCanvasTransform(img, Math.min(w.screen.width, img.width), Math.min(w.screen.height, img.height));
4672 if (transformed.length <= k.bgSizeLimit) {
4673 k.bgMessage.textContent = "Automatically resized to screen resolution. For best results, we recommend using an image editor and resize/crop your pony pic.";
4674 removeClass(k.bgMessage, 'hidden_elem');
4675
4676 k.bgReaderBg = transformed;
4677 k.bgChangeSuccess();
4678
4679 img = null;
4680 transformed = null;
4681 return;
4682 }
4683 img = null;
4684 transformed = null;
4685
4686 // Fail :(
4687 k.bgErrorTooBig();
4688 };
4689 img.src = k.bgReaderBg;
4690 } catch (e) {
4691 k.bgErrorTooBig();
4692 }
4693 };
4694
4695 k.bgCanvasTransform = function(img, width, height) {
4696 var canvas = d.createElement('canvas');
4697 canvas.width = width;
4698 canvas.height = height;
4699 var ctx = canvas.getContext('2d');
4700 ctx.drawImage(img, 0, 0, width, height);
4701
4702 var type = 'image/jpeg';
4703 if (k._isWebPSupported) {
4704 type = 'image/webp';
4705 }
4706
4707 return canvas.toDataURL(type);
4708 };
4709
4710 k.disableDomNodeInserted = function() {
4711 k.soundsChanged(); // to set k.soundsSettingsWrap
4712
4713 var affectedOptions = ['sounds', 'debug_dominserted_console', 'debug_noMutationObserver', 'debug_mutationDebug', 'debug_betaFacebookLinks'];
4714 //'disableCommentBrohoofed','debug_mutationObserver'
4715 for (var i = 0, len = affectedOptions.length; i < len; i += 1) {
4716 var option = $('ponyhoof_options_'+affectedOptions[i]);
4717 var label = $('ponyhoof_options_label_'+affectedOptions[i]);
4718 if (userSettings.disableDomNodeInserted) {
4719 if (ranDOMNodeInserted) {
4720 k.needsToRefresh = true;
4721 k.updateCloseButton();
4722 }
4723
4724 option.disabled = true;
4725 option.checked = false;
4726
4727 addClass(label, 'ponyhoof_options_unavailable');
4728 label.setAttribute('data-hover', 'tooltip');
4729 label.setAttribute('aria-label', "This feature is not available because HTML detection is disabled, re-enable it at the Misc tab");
4730 } else {
4731 var option = $('ponyhoof_options_'+affectedOptions[i]);
4732 option.disabled = false;
4733 if (userSettings[affectedOptions[i]]) {
4734 option.checked = true;
4735 }
4736
4737 removeClass(label, 'ponyhoof_options_unavailable');
4738 label.removeAttribute('data-hover');
4739 label.removeAttribute('aria-label');
4740 label.removeAttribute('aria-owns');
4741 label.removeAttribute('aria-controls');
4742 label.removeAttribute('aria-haspopup');
4743 }
4744 }
4745 k._debugNoMutationObserver();
4746 };
4747
4748 k.disableDomNodeInsertedClicked = function() {
4749 if (!userSettings.disableDomNodeInserted) {
4750 runDOMNodeInserted();
4751 }
4752 k.disableDomNodeInserted();
4753 };
4754
4755 k.allowLoginScreenClicked = function() {
4756 if (globalSettings.allowLoginScreen) {
4757 globalSettings.lastUserId = USERID;
4758 } else {
4759 globalSettings.lastUserId = null;
4760 }
4761 saveGlobalSettings();
4762 };
4763
4764 k.debug_disablelog = function() {
4765 if ($('ponyhoof_options_debug_disablelog').checked) {
4766 CANLOG = false;
4767 } else {
4768 CANLOG = true;
4769 }
4770 };
4771
4772 k.disableDialog = null;
4773 k.disablePonyhoof = function() {
4774 if ($('ponyhoof_dialog_disable')) {
4775 $('ponyhoof_disable_allowLoginScreen').checked = !globalSettings.allowLoginScreen;
4776 $('ponyhoof_disable_runForNewUsers').checked = !globalSettings.runForNewUsers;
4777
4778 k.dialog.hide();
4779 k.disableDialog.show();
4780 $('ponyhoof_disable_ok').focus();
4781 return false;
4782 }
4783
4784 var c = '';
4785 c += "<strong>Are you sure you want to disable Ponyhoof for yourself?</strong><br><br>";
4786 c += "You can re-enable Ponyhoof for yourself at any time by going back to Ponyhoof Options and re-select a character.<br><br>";
4787 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>';
4788 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>';
4789
4790 var bottom = '';
4791 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_disable_ok"><span class="uiButtonText">Disable</span></a>';
4792 bottom += '<a href="#" class="uiButton uiButtonLarge" role="button" id="ponyhoof_disable_no"><span class="uiButtonText">Cancel</span></a>';
4793
4794 k.dialog.hide();
4795 k.disableDialog = new Dialog('disable');
4796 k.disableDialog.alwaysModal = true;
4797 k.disableDialog.create();
4798 k.disableDialog.changeTitle("Disable Ponyhoof");
4799 k.disableDialog.changeContent(c);
4800 k.disableDialog.changeBottom(bottom);
4801
4802 $('ponyhoof_disable_allowLoginScreen').checked = !globalSettings.allowLoginScreen;
4803 $('ponyhoof_disable_runForNewUsers').checked = !globalSettings.runForNewUsers;
4804
4805 k.disableDialog.show();
4806 k.disableDialog.onclose = function() {
4807 k.dialog.show();
4808 };
4809
4810 $('ponyhoof_disable_ok').focus();
4811 $('ponyhoof_disable_ok').addEventListener('click', function() {
4812 userSettings.theme = 'NONE';
4813 saveSettings();
4814
4815 globalSettings.allowLoginScreen = !$('ponyhoof_disable_allowLoginScreen').checked;
4816 globalSettings.runForNewUsers = !$('ponyhoof_disable_runForNewUsers').checked;
4817 saveGlobalSettings();
4818
4819 k.disableDialog.canCloseByEscapeKey = false;
4820 d.body.style.cursor = 'progress';
4821 $('ponyhoof_disable_allowLoginScreen').disabled = true;
4822 $('ponyhoof_disable_runForNewUsers').disabled = true;
4823 $('ponyhoof_disable_ok').className += ' uiButtonDisabled';
4824 $('ponyhoof_disable_no').className += ' uiButtonDisabled';
4825 w.location.reload();
4826
4827 return false;
4828 }, false);
4829
4830 $('ponyhoof_disable_no').addEventListener('click', function() {
4831 k.disableDialog.close();
4832 return false;
4833 }, false);
4834
4835 return false;
4836 };
4837
4838 k.browserPonies = null;
4839 k.runBrowserPonies = function() {
4840 var link = this;
4841 if (hasClass(link, 'ponyhoof_browserponies_loading')) {
4842 return false;
4843 }
4844
4845 var alreadyLoaded = !!k.browserPonies;
4846 addClass(link, 'ponyhoof_browserponies_loading');
4847
4848 if (!alreadyLoaded) {
4849 k.browserPonies = new BrowserPoniesHoof();
4850 }
4851 k.browserPonies.doneCallback = function() {
4852 k.dialog.close();
4853 removeClass(link, 'ponyhoof_browserponies_loading');
4854 if (!alreadyLoaded) {
4855 k.browserPonies.copyrightDialog();
4856 }
4857 k.browserPonies.createDialog();
4858 };
4859 k.browserPonies.errorCallback = function(error) {
4860 removeClass(link, 'ponyhoof_browserponies_loading');
4861 k.browserPonies.createErrorDialog(error);
4862 };
4863 k.browserPonies.run();
4864
4865 return false;
4866 }
4867
4868 k.checkboxStore = {};
4869 k.generateCheckbox = function(id, label, data) {
4870 data = data || {};
4871 var ex = '';
4872 var checkmark = '';
4873
4874 if ((!data.global && userSettings[id]) || (data.global && globalSettings[id])) {
4875 checkmark += ' CHECKED';
4876 }
4877 data.extraClass = data.extraClass || '';
4878 if (data.title) {
4879 label += ' <a href="#" class="uiHelpLink"></a>';
4880 ex += ' data-hover="tooltip" aria-label="'+data.title+'"';
4881 }
4882 if (data.tip) {
4883 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>';
4884 }
4885
4886 k.checkboxStore[id] = data;
4887
4888 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>';
4889 };
4890
4891 k.checkboxInit = function() {
4892 var extras = $('ponyhoof_dialog_options').querySelectorAll('input[type="checkbox"]');
4893 for (var i = 0, len = extras.length; i < len; i += 1) {
4894 var checkmark = extras[i].getAttribute('data-ponyhoof-checkmark');
4895 var data = {};
4896 if (k.checkboxStore[checkmark]) {
4897 data = k.checkboxStore[checkmark];
4898 }
4899 if (data.tooltipPosition) {
4900 extras[i].parentNode.setAttribute('data-tooltip-position', data.tooltipPosition);
4901 }
4902
4903 extras[i].addEventListener('click', function() {
4904 var checkmark = this.getAttribute('data-ponyhoof-checkmark');
4905 var data = {};
4906 if (k.checkboxStore[checkmark]) {
4907 data = k.checkboxStore[checkmark];
4908 }
4909
4910 if (!data.global) {
4911 userSettings[checkmark] = this.checked;
4912 saveSettings();
4913 } else {
4914 globalSettings[checkmark] = this.checked;
4915 saveGlobalSettings();
4916 }
4917
4918 if (this.checked) {
4919 addClass(d.documentElement, 'ponyhoof_settings_'+checkmark);
4920 } else {
4921 removeClass(d.documentElement, 'ponyhoof_settings_'+checkmark);
4922 }
4923 if (data.refresh) {
4924 k.needsToRefresh = true;
4925 }
4926 if (data.customFunc) {
4927 data.customFunc();
4928 }
4929
4930 k.needToSaveLabel = true;
4931 k.updateCloseButton();
4932 }, true);
4933 }
4934 };
4935
4936 k.tabsExposeDebug = 0;
4937 k.tabsInit = function() {
4938 var tabs = k.dialog.dialog.querySelectorAll('.ponyhoof_tabs a');
4939 for (var i = 0, len = tabs.length; i < len; i += 1) {
4940 tabs[i].addEventListener('click', function(e) {
4941 var tabName = this.getAttribute('data-ponyhoof-tab');
4942 if (tabName == 'extras') {
4943 if (!userSettings.debug_exposed && k.tabsExposeDebug < 5) {
4944 k.tabsExposeDebug += 1;
4945 if (k.tabsExposeDebug >= 5) {
4946 addClass(k.dialog.dialog, 'ponyhoof_options_debugExposed');
4947 k.switchTab('advanced');
4948 return;
4949 }
4950 }
4951 } else {
4952 k.tabsExposeDebug = 0;
4953 }
4954
4955 k.switchTab(tabName);
4956 e.preventDefault();
4957 }, false);
4958 }
4959 };
4960
4961 k.switchTab = function(tabName) {
4962 var tabActions = {
4963 'main': k.mainInit
4964 ,'background': k.bgInit
4965 ,'sounds': k.soundsInit
4966 ,'extras': k.extrasInit
4967 ,'advanced': k.debugInfo
4968 ,'about': k.loadDonate
4969 };
4970 removeClass(k.dialog.dialog.querySelector('.ponyhoof_tabs a.active'), 'active');
4971 addClass(k.dialog.dialog.querySelector('.ponyhoof_tabs a[data-ponyhoof-tab="'+tabName+'"]'), 'active');
4972
4973 try {
4974 if (tabActions[tabName]) {
4975 tabActions[tabName]();
4976 }
4977 } catch (e) {
4978 dir(e);
4979 ponyhoofError(e.toString());
4980 }
4981
4982 $$(k.dialog.dialog, '.ponyhoof_tabs_section', function(section) {
4983 section.style.display = 'none';
4984 });
4985 $('ponyhoof_options_tabs_'+tabName).style.display = 'block';
4986
4987 k.dialog.cardSpaceTick();
4988 };
4989
4990 k.saveButtonClick = function() {
4991 k.dialog.close();
4992 return false;
4993 };
4994
4995 k.dialogOnClose = function() {
4996 d.removeEventListener('keydown', k.kf, true);
4997
4998 if (k.debugLoaded) {
4999 if ($('ponyhoof_options_customcss').value == "Enter any custom CSS to load after Ponyhoof is loaded.") {
5000 userSettings.customcss = '';
5001 } else {
5002 userSettings.customcss = $('ponyhoof_options_customcss').value;
5003 }
5004 }
5005 if (k.canSaveSettings) {
5006 saveSettings();
5007 }
5008
5009 if (k.needsToRefresh) {
5010 w.location.reload();
5011 }
5012 };
5013
5014 k.dialogOnCloseFinish = function() {
5015 k.saveButton.getElementsByClassName('uiButtonText')[0].innerHTML = CURRENTLANG.close;
5016
5017 if (k.canSaveSettings) {
5018 if (k.bgClearCustomBg) {
5019 removeClass(k.bgTab, 'hasCustom');
5020 userSettings.customBg = null;
5021 saveSettings();
5022 }
5023 }
5024 };
5025
5026 k.updateCloseButton = function() {
5027 var button = k.saveButton.getElementsByClassName('uiButtonText')[0];
5028 var text = CURRENTLANG.close;
5029
5030 if (k.needToSaveLabel) {
5031 text = "Save & Close";
5032 }
5033
5034 if (k.needsToRefresh) {
5035 text = "Save & Reload";
5036 }
5037
5038 button.innerHTML = text;
5039 };
5040
5041 k.injectStyle = function() {
5042 var css = '';
5043 //css += '#ponyhoof_options_tabs_main .clearfix {margin-bottom:10px;}';
5044 css += '#ponyhoof_dialog_options .generic_dialog_popup, #ponyhoof_dialog_options .popup {width:480px;}';
5045 css += '#ponyhoof_options_likebox_div {height:80px;}';
5046 //css += 'html.ponyhoof_isusingpage #ponyhoof_options_likebox_div {display:none;}';
5047 css += '#ponyhoof_options_likebox {border:none;overflow:hidden;width:100%;height:80px;}';
5048 css += '#ponyhoof_options_pony {margin:8px 0 16px;}';
5049 css += '.ponyhoof_options_fatlink {display:block;margin-top:10px;}';
5050 css += '.ponyhoof_options_unavailable label {cursor:default;}';
5051 css += '#ponyhoof_dialog_options .usingPage, html.ponyhoof_isusingpage #ponyhoof_dialog_options .notPage {display:none;}';
5052 css += 'html.ponyhoof_isusingpage #ponyhoof_dialog_options .usingPage {display:block;}';
5053 css += 'html.ponyhoof_isusingbusiness #ponyhoof_dialog_options .notBusiness {display:none;}';
5054
5055 css += '#ponyhoof_dialog_options .uiHelpLink {margin-left:2px;}';
5056 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;}';
5057 css += '#ponyhoof_dialog_options textarea {resize:vertical;width:100%;height:60px;min-height:60px;line-height:normal;}';
5058 css += '#ponyhoof_dialog_options .ponyhoof_tabs > a[data-ponyhoof-tab="advanced"] {display:none;}';
5059 css += '#ponyhoof_dialog_options.ponyhoof_options_debugExposed .ponyhoof_tabs > a[data-ponyhoof-tab="advanced"] {display:block;}';
5060
5061 // 214px
5062 css += '.ponyhoof_options_fatradio {margin:10px 0;}';
5063 css += '.ponyhoof_options_fatradio li {width:222px;float:left;margin-left:12px;}';
5064 css += '#ponyhoof_options_tabs_background.hasCustom .ponyhoof_options_fatradio li {width:144px;}';
5065 css += '.ponyhoof_options_fatradio li:first-child {margin:0;}';
5066 css += '.ponyhoof_options_fatradio a {border:1px solid rgba(0,0,0,.3);display:block;text-align:center;width:100%;text-decoration:none;-moz-border-radius:3px;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;}';
5067 css += '.ponyhoof_options_fatradio a:hover {-moz-box-shadow:0 0 8px rgba(0,0,0,.3);box-shadow:0 0 8px rgba(0,0,0,.3);}';
5068 css += '.ponyhoof_options_fatradio a:active {background:#ECEFF5;-moz-box-shadow:0 0 8px rgba(0,0,0,.7);box-shadow:0 0 8px rgba(0,0,0,.7);}';
5069 css += '.ponyhoof_options_fatradio li.active a {background-color:#6D84B4;border-color:#3b5998;color:#fff;}';
5070 css += '.ponyhoof_options_fatradio span {padding:4px;display:block;}';
5071 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;}';
5072 css += '#ponyhoof_options_tabs_background.hasCustom .ponyhoof_options_fatradio .wrap i {height:144px;}';
5073 css += '#ponyhoof_options_background_cutie .wrap {padding:8px;}';
5074 css += '#ponyhoof_options_background_cutie .wrap i {width:206px;height:184px;}';
5075 css += '#ponyhoof_options_tabs_background.hasCustom #ponyhoof_options_background_cutie .wrap i {width:128px;height:128px;}';
5076 css += '#ponyhoof_options_background_custom {display:none;}';
5077 css += '#ponyhoof_options_tabs_background.hasCustom #ponyhoof_options_background_custom {display:block;}';
5078 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;}';
5079
5080 css += '#ponyhoof_options_background_error, #ponyhoof_options_background_message {margin-bottom:10px;}';
5081 css += '#ponyhoof_options_background_drop {background:#fff;border:2px dashed #75a3f5;padding:8px;position:relative;}'; //margin-bottom:8px;
5082 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;}';
5083 css += '#ponyhoof_options_background_drop.ponyhoof_dropping #ponyhoof_options_background_drop_dropping {display:block;}';
5084 css += '#ponyhoof_options_background_selectOuterWrap {position:relative;display:inline-block;top:-3px;}';
5085 css += '#ponyhoof_options_background_selectFileWrap {position:absolute;width:100%;height:100%;top:0;left:0;overflow:hidden;}';
5086 css += '#ponyhoof_options_background_select {font-size:1000px !important;opacity:0;padding:0;margin:0;position:absolute;bottom:0;right:0;cursor:pointer;}';
5087
5088 css += '#ponyhoof_options_tabs_main .ponyhoof_message {margin-top:10px;}';
5089 css += '#ponyhoof_browserponies .ponyhoof_loading {display:none;margin-top:0;vertical-align:text-bottom;}';
5090 css += '#ponyhoof_browserponies.ponyhoof_browserponies_loading .ponyhoof_loading {display:inline-block;}';
5091 css += '#ponyhoof_options_randomPonies .ponyhoof_loading {display:none !important;}';
5092 css += '#ponyhoof_options_randomPonies .ponyhoof_menuitem_checked {display:block;}';
5093 css += '#ponyhoof_options_tabs_sounds .ponyhoof_message.unavailable {margin-bottom:10px;}';
5094 css += '#ponyhoof_options_soundsSettingsWrap {margin-top:-14px;}';
5095 css += '#ponyhoof_options_soundsVolume {vertical-align:middle;width:50px;}';
5096 css += '#ponyhoof_options_soundsVolume[type="range"] {cursor:pointer;width:200px;}';
5097 css += '#ponyhoof_options_soundsVolumePreview {vertical-align:middle;}';
5098 css += '#ponyhoof_options_soundsVolumeValue {display:none;padding-left:3px;}';
5099 css += '#ponyhoof_options_soundsChatSoundWarning, #ponyhoof_options_soundsMessengerForWindowsWarning {margin-bottom:10px;}';
5100 css += '#ponyhoof_options_soundsChatSetting {margin:0;}';
5101 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;}';
5102 css += '#ponyhoof_options_tabs_advanced .ponyhoof_hide_if_injected.ponyhoof_message {margin-bottom:10px;}';
5103 css += '.ponyhoof_options_aboutsection {border-top:1px solid #ccc;margin:10px -10px 0;}';
5104 css += '.ponyhoof_options_aboutsection > .inner {border-top:1px solid #E9E9E9;padding:10px 10px 0;}';
5105 css += '#ponyhoof_options_devpic {display:block;}';
5106 css += '#ponyhoof_options_devpic img {width:50px !important;height:50px !important;}';
5107 css += '#ponyhoof_options_twitter {margin-top:10px;width:100%;height:20px;}';
5108 css += '#ponyhoof_options_plusone {margin-top:10px;height:23px;}';
5109
5110 css += '.ponyhoof_tip_wrapper {position:relative;z-index:10;}';
5111 css += '.ponyhoof_tip_trigger, .ponyhoof_tip_trigger:hover {text-decoration:none;}';
5112 css += '.ponyhoof_tip_trigger:hover .ponyhoof_tip {display:block;}';
5113 css += '.ponyhoof_options_unavailable .ponyhoof_tip_trigger {display:none !important;}';
5114 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;}';
5115 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;-moz-box-shadow:0 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 0 rgba(0,0,0,.1);}';
5116 css += '.ponyhoof_tip_arrow {position:absolute;top:0;right:10px;border:solid transparent;border-width:0 3px 5px 4px;border-bottom-color:#888;}';
5117
5118 css += '#ponyhoof_donate {background:#EDEFF4;border:1px solid #D2DBEA;color:#9CADCF;font-family:Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;}';
5119 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%;}';
5120 css += '#ponyhoof_donate a {display:block;width:100%;color:#9CADCF;text-decoration:none;}';
5121 css += '#ponyhoof_options_donatepaypal {border-right:1px solid #D2DBEA;}';
5122 //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;}';
5123 css += '#ponyhoof_donate_flattr_iframe {width:55px;height:62px;margin-top:6px;}';
5124 css += '#ponyhoof_donate a:hover {background-color:#DEDFE7;color:#3B5998;}';
5125
5126 injectManualStyle(css, 'options');
5127 };
5128
5129 k.show = function() {
5130 if (!k.created) {
5131 k.create();
5132 }
5133 k.dialog.show();
5134 };
5135
5136 k.kr = false;
5137 k.ks = [];
5138 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';
5139 k.kf = function(e) {
5140 if (k.kr) {
5141 return;
5142 }
5143
5144 k.ks.push(e.which);
5145 if (k.ks.join(',').indexOf(k.kc) > -1) {
5146 k.kr = true;
5147 k.dialog.close();
5148
5149 var width = 720;
5150 var height = 405;
5151
5152 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');
5153 var di = new Dialog('ky');
5154 di.alwaysModal = true;
5155 di.create();
5156 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");
5157 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>');
5158 di.addCloseButton();
5159 di.onclosefinish = function() {
5160 di.changeContent('');
5161 };
5162
5163 $('ponyhoof_kc_share').addEventListener('click', function() {
5164 var width = 626;
5165 var height = 436;
5166 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);
5167 return false;
5168 }, false);
5169 }
5170 };
5171
5172 k.ki = function() {
5173 d.addEventListener('keydown', k.kf, true);
5174 };
5175 };
5176
5177 var optionsGlobal = null;
5178 function optionsOpen() {
5179 log("Opening options...");
5180
5181 if (!optionsGlobal) {
5182 optionsGlobal = new Options();
5183 }
5184 optionsGlobal.create();
5185 optionsGlobal.show();
5186
5187 $$($('ponyhoof_dialog_options'), '#ponyhoof_options_pony .ponyhoof_button_menu', function(button) {
5188 try {
5189 button.focus();
5190 } catch (e) {}
5191 });
5192 }
5193
5194 // Welcome
5195 var WelcomeUI = function(param) {
5196 var k = this;
5197
5198 if (param) {
5199 k.param = param;
5200 } else {
5201 k.param = {};
5202 }
5203 k.dialogFirst = null;
5204 k.dialogPinkie = null;
5205 k.dialogFinish = null;
5206
5207 k._stack = '';
5208
5209 k.start = function() {
5210 k.injectStyle();
5211 k.createScenery();
5212 addClass(d.documentElement, 'ponyhoof_welcome_html');
5213 statTrack('welcomeUI');
5214
5215 k.showWelcome();
5216 };
5217
5218 k.showWelcome = function() {
5219 if ($('ponyhoof_dialog_welcome')) {
5220 return;
5221 }
5222
5223 addClass(d.documentElement, 'ponyhoof_welcome_html_scenery_loaded');
5224
5225 var co = '';
5226 co += '<div class="ponyhoof_message uiBoxYellow ponyhoof_updater_newVersion">';
5227 co += '<a href="#" class="uiButton uiButtonSpecial rfloat ponyhoof_updater_updateNow" role="button"><span class="uiButtonText">Update now</span></a>';
5228 co += '<span class="wrap">An update (v<span class="ponyhoof_updater_versionNum"></span>) for Ponyhoof is available.</span>';
5229 co += '</div>';
5230
5231 co += renderBrowserConfigWarning();
5232
5233 if (STORAGEMETHOD == 'chrome' && chrome.extension.inIncognitoContext) {
5234 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>';
5235 }
5236
5237 co += '<strong>Select your favorite character to get started:</strong>';
5238 co += '<div id="ponyhoof_welcome_pony"></div>';
5239 co += '<div id="ponyhoof_welcome_afterClose">You can re-select your character in Ponyhoof Options at the Account menu.</div>';
5240
5241 var bottom = '';
5242 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm uiButtonDisabled" role="button" id="ponyhoof_welcome_next"><span class="uiButtonText">Next</span></a>';
5243
5244 DIALOGCOUNT += 5;
5245
5246 k.dialogFirst = new Dialog('welcome');
5247 k.dialogFirst.canCardspace = false;
5248 k.dialogFirst.canCloseByEscapeKey = false;
5249 k.dialogFirst.create();
5250 k.dialogFirst.generic_dialogDiv.className += ' generic_dialog_fixed_overflow';
5251 if (BRONYNAME) {
5252 k.dialogFirst.changeTitle("Welcome to Ponyhoof, "+BRONYNAME+"!");
5253 } else {
5254 k.dialogFirst.changeTitle("Welcome to Ponyhoof!");
5255 }
5256 k.dialogFirst.changeContent(co);
5257 k.dialogFirst.changeBottom(bottom);
5258
5259 k.dialogFirst.dialog.className += ' ponyhoof_dialog_localstorageWarningEmbedded';
5260
5261 DIALOGCOUNT += 4;
5262
5263 var menuClosed = false;
5264 var ponySelector = new PonySelector($('ponyhoof_welcome_pony'), k.param);
5265 ponySelector.saveTheme = false;
5266 ponySelector.createSelector();
5267 w.setTimeout(function() {
5268 ponySelector.menu.open();
5269 }, 1);
5270 ponySelector.menu.afterClose = function() {
5271 if (!menuClosed) {
5272 menuClosed = true;
5273 addClass($('ponyhoof_welcome_afterClose'), 'show');
5274
5275 addClass(d.documentElement, 'ponyhoof_welcome_showmedemo');
5276 if ($('navAccount')) {
5277 addClass($('navAccount'), 'openToggler');
5278 }
5279 //addClass($('ponyhoof_account_options'), 'active');
5280
5281 w.setTimeout(function() {
5282 removeClass($('ponyhoof_welcome_next'), 'uiButtonDisabled');
5283 }, 200);
5284 }
5285 };
5286
5287 w.setTimeout(function() {
5288 changeThemeSmart(CURRENTPONY);
5289 }, 10);
5290 k._stack = CURRENTSTACK;
5291
5292 w.setTimeout(function() {
5293 var update = new Updater();
5294 update.checkForUpdates();
5295 }, 500);
5296
5297 // Detect if the Facebook's chat sound setting is turned off
5298 // We need to do this here as it is async
5299 try {
5300 if (typeof USW.requireLazy == 'function') {
5301 USW.requireLazy(['ChatOptions'], function(ChatOptions) {
5302 if (!ChatOptions.getSetting('sound')) {
5303 userSettings.chatSound = false;
5304 }
5305 });
5306 }
5307 } catch (e) {
5308 error("Unable to hook to ChatOptions");
5309 dir(e);
5310 }
5311
5312 $('ponyhoof_welcome_next').addEventListener('click', function(e) {
5313 e.preventDefault();
5314 if (hasClass(this, 'uiButtonDisabled')) {
5315 return false;
5316 }
5317
5318 k.dialogFirst.close();
5319 fadeOut($('ponyhoof_welcome_scenery'));
5320
5321 w.setTimeout(function() {
5322 removeClass(d.documentElement, 'ponyhoof_welcome_showmedemo');
5323 removeClass($('navAccount'), 'openToggler');
5324 removeClass($('ponyhoof_account_options'), 'active');
5325 }, 100);
5326
5327 userSettings.theme = CURRENTPONY;
5328 userSettings.chatSound1401 = true;
5329 saveSettings();
5330
5331 globalSettings.lastVersion = VERSION;
5332 if (globalSettings.allowLoginScreen) {
5333 globalSettings.lastUserId = USERID;
5334 }
5335 saveGlobalSettings();
5336
5337 if (CURRENTPONY == 'pinkie') {
5338 k.pinkieWelcome();
5339 } else {
5340 k.createFinalDialog();
5341 }
5342 }, false);
5343 };
5344
5345 k.pinkieWelcome = function() {
5346 removeClass(d.documentElement, 'ponyhoof_welcome_html_scenery_loaded');
5347
5348 var width = 720;
5349 var height = 405;
5350
5351 var bottom = '';
5352 bottom += '<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_welcome_pinkie_next"><span class="uiButtonText">Stop being silly, Pinkie</span></a>';
5353
5354 k.dialogPinkie = new Dialog('welcome_pinkie');
5355 k.dialogPinkie.alwaysModal = true;
5356 k.dialogPinkie.create();
5357 k.dialogPinkie.changeTitle("\x59\x4F\x55\x20\x43\x48\x4F\x4F\x53\x45\x20\x50\x49\x4E\x4B\x49\x45\x21\x3F\x21");
5358 k.dialogPinkie.changeContent('<iframe src="//hoof.little.my/files/aEPDsG6R4dY.htm" width="100%" height="405" scrolling="auto" frameborder="0" allowTransparency="true"></iframe>');
5359 k.dialogPinkie.changeBottom(bottom);
5360 k.dialogPinkie.onclose = function() {
5361 fadeOut($('ponyhoof_welcome_scenery'));
5362 k.createFinalDialog();
5363 };
5364 k.dialogPinkie.onclosefinish = function() {
5365 k.dialogPinkie.changeContent('');
5366 };
5367
5368 $('ponyhoof_welcome_pinkie_next').addEventListener('click', function(e) {
5369 k.dialogPinkie.close();
5370 e.preventDefault();
5371 }, false);
5372 };
5373
5374 k.createFinalDialog = function() {
5375 removeClass(d.documentElement, 'ponyhoof_welcome_html');
5376 removeClass(d.documentElement, 'ponyhoof_welcome_html_scenery_loaded');
5377
5378 var c = '';
5379
5380 var lang = getDefaultUiLang();
5381 if (lang != 'en_US' && lang != 'en_GB') {
5382 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>';
5383 }
5384
5385 if (!ISUSINGBUSINESS) {
5386 c += '<span class="ponyhoof_brohoof_button">'+capitaliseFirstLetter(CURRENTSTACK['like'])+'</span> us to receive news and help for Ponyhoof!';
5387 c += '<div id="ponyhoof_welcome_likeWrap"><iframe src="about:blank" id="ponyhoof_welcome_like" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div>';
5388 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>';
5389 } else {
5390 c += '<a href="'+w.location.protocol+PONYHOOF_URL+'" target="_top" id="ponyhoof_welcome_posttowall">Visit our Ponyhoof page for the latest news!</a>';
5391 }
5392
5393 var successText = '';
5394 var ponyData = convertCodeToData(REALPONY);
5395 if (ponyData.successText) {
5396 successText = ponyData.successText;
5397 } else {
5398 successText = "Yay!";
5399 }
5400
5401 k.dialogFinish = new Dialog('welcome_final');
5402 if (k._stack != CURRENTSTACK) {
5403 k.dialogFinish.alwaysModal = true;
5404 }
5405 k.dialogFinish.create();
5406 k.dialogFinish.changeTitle(successText);
5407 k.dialogFinish.changeContent(c);
5408 var buttonText = CURRENTLANG.done;
5409 if (k._stack != CURRENTSTACK) {
5410 buttonText = CURRENTLANG.finish;
5411 }
5412 k.dialogFinish.changeBottom('<a href="#" class="uiButton uiButtonLarge uiButtonConfirm" role="button" id="ponyhoof_welcomefinal_ok"><span class="uiButtonText">'+buttonText+'</span></a>');
5413 k.dialogFinish.onclose = function() {
5414 if (k._stack != CURRENTSTACK) {
5415 w.location.reload();
5416 }
5417 };
5418
5419 $('ponyhoof_welcomefinal_ok').addEventListener('click', k.dialogFinishOk, false);
5420 $('ponyhoof_welcomefinal_ok').focus();
5421
5422 if (!ISUSINGBUSINESS) {
5423 w.setTimeout(function() {
5424 $('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';
5425 }, 1);
5426 }
5427
5428 $('ponyhoof_welcome_posttowall').addEventListener('click', function(e) {
5429 k.dialogFinish.onclose = function() {};
5430 k.dialogFinish.close();
5431 }, false);
5432 };
5433
5434 k.dialogFinishOk = function(e) {
5435 if (k._stack != CURRENTSTACK) {
5436 if (hasClass(this, 'uiButtonDisabled')) {
5437 return false;
5438 }
5439
5440 this.className += ' uiButtonDisabled';
5441 w.location.reload();
5442 } else {
5443 k.dialogFinish.close();
5444 }
5445 e.preventDefault();
5446 };
5447
5448 k.createScenery = function() {
5449 if ($('ponyhoof_welcome_scenery')) {
5450 $('ponyhoof_welcome_scenery').style.display = 'block';
5451 return;
5452 }
5453
5454 var n = d.createElement('div');
5455 n.id = 'ponyhoof_welcome_scenery';
5456 d.body.appendChild(n);
5457
5458 return n;
5459 };
5460
5461 k.injectStyle = function() {
5462 var css = '';
5463 css += 'html.ponyhoof_welcome_html {overflow:hidden;}';
5464 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;}';
5465 css += 'html #ponyhoof_dialog_welcome .generic_dialog_fixed_overflow {background:transparent !important;}';
5466 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)+';}';
5467
5468 //css += '#ponyhoof_dialog_welcome .generic_dialog {z-index:401 !important;}';
5469 css += '#ponyhoof_dialog_welcome .generic_dialog_popup, #ponyhoof_dialog_welcome .popup {width:475px !important;}';
5470 //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;}';
5471 css += '#ponyhoof_dialog_welcome .ponyhoof_updater_newVersion {margin-bottom:10px;}';
5472
5473 css += '#ponyhoof_welcome_newVersion {display:none;margin:0 0 10px;}';
5474 css += '#ponyhoof_welcome_pony {margin:8px 0;}';
5475 css += '#ponyhoof_welcome_afterClose {visibility:hidden;opacity:0;}';
5476 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;}';
5477
5478 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;}';
5479 css += 'html.ponyhoof_welcome_showmedemo {cursor:not-allowed;}';
5480 css += 'html.ponyhoof_welcome_showmedemo .popup {cursor:default;}';
5481 css += 'html.ponyhoof_welcome_showmedemo #blueBar #pageHead {width:981px !important;padding-right:0 !important;}';
5482 css += 'html.sidebarMode.ponyhoof_welcome_showmedemo #pageHead, html.sidebarMode.ponyhoof_welcome_showmedemo .sidebarMode #globalContainer {left:0 !important;}';
5483 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;}';
5484
5485 css += '#ponyhoof_dialog_welcome_pinkie .generic_dialog_popup, #ponyhoof_dialog_welcome_pinkie .popup {width:720px;}';
5486 css += '#ponyhoof_dialog_welcome_pinkie .content {line-height:0;padding:0;}';
5487
5488 css += '#ponyhoof_welcome_likeWrap {margin:8px 0;}';
5489 css += '#ponyhoof_welcome_like {border:none;overflow:hidden;width:292px;height:62px;margin:0;}';
5490
5491 injectManualStyle(css, 'welcome');
5492 };
5493 };
5494
5495 var renderBrowserConfigWarning = function() {
5496 var c = '';
5497 if (STORAGEMETHOD == 'localstorage') {
5498 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>';
5499 } else if (ISMOBILE) {
5500 c += '<div class="ponyhoof_message uiBoxYellow">Mobile support for Ponyhoof is provided as a courtesy and is not officially supported.</div><br>';
5501 }
5502 return c;
5503 };
5504
5505 // Theme
5506 function getFaviconTag() {
5507 var l = d.getElementsByTagName('link');
5508 for (var i = 0, len = l.length; i < len; i += 1) {
5509 if (l[i].getAttribute('rel') == 'shortcut icon') {
5510 return l[i];
5511 }
5512 }
5513
5514 return false;
5515 }
5516
5517 function changeFavicon(character) {
5518 if (userSettings.noFavicon) {
5519 return;
5520 }
5521
5522 var favicon = getFaviconTag();
5523
5524 if (favicon) {
5525 // Don't change the favicon on apps.facebook.com
5526 if (w.location.hostname.indexOf('apps.') === 0) {
5527 if (favicon.href.indexOf('.ico') !== favicon.href.length-('.ico'.length)) {
5528 return;
5529 }
5530 }
5531
5532 var newIcon = favicon.cloneNode(true);
5533 } else {
5534 var newIcon = d.createElement('link');
5535 newIcon.rel = 'shortcut icon';
5536 }
5537
5538 if (character != 'NONE') {
5539 newIcon.type = 'image/png';
5540
5541 var data = convertCodeToData(character);
5542 if (data.icon16) {
5543 newIcon.href = THEMEURL+data.icon16;
5544 } else {
5545 newIcon.href = THEMEURL+character+'/icon16.png';
5546 }
5547 } else {
5548 newIcon.type = 'image/x-icon';
5549 newIcon.href = '//fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico';
5550 }
5551
5552 if (favicon) {
5553 favicon.parentNode.replaceChild(newIcon, favicon);
5554 } else {
5555 d.head.appendChild(newIcon);
5556 }
5557 }
5558
5559 function changeStack(character) {
5560 var pony = convertCodeToData(character);
5561 CURRENTSTACK = STACKS_LANG[0];
5562 if (pony.stack) {
5563 for (var i = 0, len = STACKS_LANG.length; i < len; i += 1) {
5564 if (STACKS_LANG[i].stack == pony.stack) {
5565 CURRENTSTACK = STACKS_LANG[i];
5566 break;
5567 }
5568 }
5569 }
5570
5571 if (UILANG == 'fb_LT') {
5572 if (CURRENTSTACK['people'] == 'ponies') {
5573 CURRENTSTACK['people'] = 'pwnies';
5574 }
5575 if (CURRENTSTACK['person'] == 'pony') {
5576 CURRENTSTACK['person'] = 'pwnie';
5577 }
5578 if (CURRENTSTACK['like'] == 'brohoof') {
5579 CURRENTSTACK['like'] = '/)';
5580 }
5581 if (CURRENTSTACK['likes'] == 'brohoofs') {
5582 CURRENTSTACK['likes'] = '/)';
5583 }
5584 //if (CURRENTSTACK['unlike'] == 'unbrohoof') {
5585 // CURRENTSTACK['unlike'] = '/)(\\';
5586 //}
5587 if (CURRENTSTACK['like_past'] == 'brohoof') {
5588 CURRENTSTACK['like_past'] = '/)';
5589 }
5590 if (CURRENTSTACK['likes_past'] == 'brohoofs') {
5591 CURRENTSTACK['likes_past'] = '/)';
5592 }
5593 if (CURRENTSTACK['liked'] == 'brohoof\'d') {
5594 CURRENTSTACK['liked'] = '/)';
5595 }
5596 if (CURRENTSTACK['liked_button'] == 'brohoof\'d') {
5597 CURRENTSTACK['liked_button'] = '/)';
5598 }
5599 if (CURRENTSTACK['liking'] == 'brohoofing') {
5600 CURRENTSTACK['liking'] = '/)';
5601 }
5602 }
5603 }
5604
5605 var changeThemeFuncQueue = [];
5606 function changeTheme(character) {
5607 addClass(d.documentElement, 'ponyhoof_injected');
5608
5609 REALPONY = character;
5610 d.documentElement.setAttribute('data-ponyhoof-character', character);
5611
5612 changeFavicon(character);
5613 changeStack(character);
5614 buildStackLang();
5615
5616 if (changeThemeFuncQueue) {
5617 for (var x in changeThemeFuncQueue) {
5618 if (changeThemeFuncQueue.hasOwnProperty(x) && changeThemeFuncQueue[x]) {
5619 changeThemeFuncQueue[x]();
5620 }
5621 }
5622 }
5623
5624 // Did we injected our theme already?
5625 if ($('ponyhoof_userscript_style')) {
5626 changeCostume(userSettings.costume);
5627 $('ponyhoof_userscript_style').href = THEMECSS+character+THEMECSS_EXT;
5628 return;
5629 }
5630
5631 addClass(d.documentElement, 'ponyhoof_initial');
5632 w.setTimeout(function() {
5633 removeClass(d.documentElement, 'ponyhoof_initial');
5634 }, 1000);
5635
5636 var n = d.createElement('link');
5637 n.href = THEMECSS+character+THEMECSS_EXT;
5638 n.type = 'text/css';
5639 n.rel = 'stylesheet';
5640 n.id = 'ponyhoof_userscript_style';
5641 d.head.appendChild(n);
5642
5643 changeCostume(userSettings.costume);
5644 }
5645
5646 function getRandomPony() {
5647 while (1) {
5648 var r = randNum(0, PONIES.length-1);
5649 if (!PONIES[r].hidden) {
5650 return PONIES[r].code;
5651 }
5652 }
5653 }
5654
5655 function getRandomMane6() {
5656 while (1) {
5657 var r = randNum(0, PONIES.length-1);
5658 if (PONIES[r].mane6) {
5659 return PONIES[r].code;
5660 }
5661 }
5662 }
5663
5664 function convertCodeToData(code) {
5665 for (var i = 0, len = PONIES.length; i < len; i += 1) {
5666 if (PONIES[i].code == code) {
5667 return PONIES[i];
5668 }
5669 }
5670
5671 return false;
5672 }
5673
5674 function changeThemeSmart(theme) {
5675 switch (theme) {
5676 case 'NONE':
5677 removeClass(d.documentElement, 'ponyhoof_injected');
5678 changeFavicon('NONE');
5679 changeCostume(null);
5680
5681 var style = $('ponyhoof_userscript_style');
5682 if (style) {
5683 style.parentNode.removeChild(style);
5684 }
5685 break;
5686
5687 case 'RANDOM':
5688 var current = [];
5689 if (userSettings.randomPonies) {
5690 current = userSettings.randomPonies.split('|');
5691 changeTheme(current[Math.floor(Math.random() * current.length)]);
5692 } else {
5693 changeTheme(getRandomPony());
5694 }
5695
5696 break;
5697
5698 default:
5699 if (theme == 'login' || convertCodeToData(theme)) {
5700 changeTheme(theme);
5701 } else {
5702 error("changeThemeSmart: "+theme+" is not a valid theme");
5703 userSettings.theme = null;
5704 CURRENTPONY = REALPONY = 'NONE';
5705 }
5706 break;
5707 }
5708 }
5709
5710 function changeCustomBg(base64) {
5711 if (!base64) {
5712 removeClass(d.documentElement, 'ponyhoof_settings_login_bg');
5713 removeClass(d.documentElement, 'ponyhoof_settings_customBg');
5714
5715 var style = $('ponyhoof_style_custombg');
5716 if (style) {
5717 style.parentNode.removeChild(style);
5718 }
5719 return;
5720 }
5721
5722 addClass(d.documentElement, 'ponyhoof_settings_login_bg');
5723 addClass(d.documentElement, 'ponyhoof_settings_customBg');
5724
5725 if (!$('ponyhoof_style_custombg')) {
5726 injectManualStyle('', 'custombg');
5727 }
5728 $('ponyhoof_style_custombg').textContent = '/* '+SIG+' */html,.fbIndex{background-position:center center !important;background-image:url("'+base64+'") !important;background-repeat:no-repeat;}';
5729 }
5730
5731 var changeCostume = function(costume) {
5732 // Make sure the costume exists
5733 if (!COSTUMESX[costume]) {
5734 removeCostume();
5735 return false;
5736 }
5737
5738 // Make sure the character has the costume
5739 if (!doesCharacterHaveCostume(REALPONY, costume)) {
5740 //removeCostume(); // leaving the costume alone wouldn't hurt...
5741 return false;
5742 }
5743
5744 d.documentElement.setAttribute('data-ponyhoof-costume', costume);
5745 };
5746
5747 var removeCostume = function() {
5748 d.documentElement.removeAttribute('data-ponyhoof-costume');
5749 };
5750
5751 var doesCharacterHaveCostume = function(character, costume) {
5752 return (COSTUMESX[costume] && COSTUMESX[costume].characters && COSTUMESX[costume].characters.indexOf(character) != -1);
5753 }
5754
5755 function getBronyName() {
5756 var name = d.querySelector('.headerTinymanName, #navTimeline > .navLink, .fbxWelcomeBoxName, ._521h ._4g5y, .-cx-PRIVATE-litestandSidebarBookmarks__profilewrapper .-cx-PRIVATE-litestandSidebarBookmarks__name');
5757 if (name) {
5758 BRONYNAME = name.textContent;
5759 }
5760
5761 return BRONYNAME;
5762 }
5763
5764 function getDefaultUiLang() {
5765 if (!d.body) {
5766 return false;
5767 }
5768 var classes = d.body.className.split(' ');
5769 for (var i = 0, len = classes.length; i < len; i += 1) {
5770 if (classes[i].indexOf('Locale_') == 0) {
5771 return classes[i].substring('Locale_'.length);
5772 }
5773 }
5774
5775 return false;
5776 }
5777
5778 // Screen saver
5779 var screenSaverTimer = null;
5780 var screenSaverActive = false;
5781 var screenSaverInactivity = function() {
5782 if (!screenSaverActive) {
5783 addClass(d.body, 'ponyhoof_screensaver');
5784 }
5785 screenSaverActive = true;
5786 };
5787 var screenSaverActivity = function() {
5788 if (screenSaverActive) {
5789 removeClass(d.body, 'ponyhoof_screensaver');
5790 }
5791 screenSaverActive = false;
5792
5793 w.clearTimeout(screenSaverTimer);
5794 screenSaverTimer = w.setTimeout(screenSaverInactivity, 30000);
5795 };
5796 var screenSaverActivate = function() {
5797 var mousemoveX = 0;
5798 var mousemoveY = 0;
5799
5800 d.addEventListener('click', screenSaverActivity, true);
5801 d.addEventListener('mousemove', function(e) {
5802 if (mousemoveX == e.clientX && mousemoveY == e.clientY) {
5803 return;
5804 }
5805 mousemoveX = e.clientX;
5806 mousemoveY = e.clientY;
5807
5808 screenSaverActivity();
5809 }, true);
5810 d.addEventListener('keydown', screenSaverActivity, true);
5811 d.addEventListener('contextmenu', screenSaverActivity, true);
5812 d.addEventListener('mousewheel', screenSaverActivity, true);
5813 d.addEventListener('touchstart', screenSaverActivity, true);
5814
5815 screenSaverActivity();
5816 };
5817
5818 // DOMNodeInserted
5819 var domReplaceText = function(ele, cn, deeper, regex, text) {
5820 var t = '';
5821 var id = ele.getAttribute('id');
5822 if ((cn == '' && deeper == '') || (cn && hasClass(ele, cn)) || (cn && id && id == nc)) {
5823 t = ele.innerHTML;
5824 t = t.replace(regex, text);
5825 if (ele.innerHTML != t) {
5826 ele.innerHTML = t;
5827 }
5828
5829 return;
5830 }
5831
5832 if (deeper) {
5833 var query = ele.querySelectorAll(deeper);
5834 if (query.length) {
5835 for (var i = 0, len = query.length; i < len; i += 1) {
5836 t = query[i].innerHTML;
5837 t = t.replace(regex, text);
5838 if (query[i].innerHTML != t) {
5839 query[i].innerHTML = t;
5840 }
5841 }
5842 }
5843 }
5844 };
5845
5846 var _fb_input_placeholderChanged = false;
5847 var domChangeTextbox = function(ele, cn, text) {
5848 var query = ele.querySelectorAll(cn);
5849 if (!query.length) {
5850 return;
5851 }
5852 if (!_fb_input_placeholderChanged) {
5853 contentEval(function(arg) {
5854 try {
5855 if (typeof window.requireLazy == 'function') {
5856 window.requireLazy(['Input'], function(Input) {
5857 var _setPlaceholder = Input.setPlaceholder;
5858 Input.setPlaceholder = function(textbox, t) {
5859 if (!textbox.getAttribute('data-ponyhoof-ponified-overridefb')) {
5860 if (textbox != document.activeElement) {
5861 _setPlaceholder(textbox, t);
5862 }
5863 textbox.setAttribute('data-ponyhoof-ponified-overridefb', 1);
5864 } else {
5865 // we already overridden, now FB wants to change the placeholder
5866 if (textbox.getAttribute('placeholder') == '' && t) {
5867 if (textbox.title) {
5868 // for composer
5869 _setPlaceholder(textbox, textbox.title);
5870 } else {
5871 // for typeahead (share dialog > private message)
5872 _setPlaceholder(textbox, t);
5873 }
5874 } else if (t == '') {
5875 // allow blanking placeholder (for typeahead)
5876 _setPlaceholder(textbox, t);
5877 }
5878 }
5879 };
5880 });
5881 }
5882 } catch (e) {
5883 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
5884 console.log("Unable to override Input.setPlaceholder()");
5885 console.dir(e);
5886 }
5887 }
5888 }, {"CANLOG":CANLOG});
5889 _fb_input_placeholderChanged = true;
5890 }
5891
5892 var placeholders = [];
5893 for (var i = 0, len = query.length; i < len; i += 1) {
5894 var textbox = query[i];
5895 if (textbox.getAttribute('data-ponyhoof-ponified')) {
5896 continue;
5897 }
5898 textbox.setAttribute('data-ponyhoof-ponified', 1);
5899
5900 if (typeof text == 'function') {
5901 placeholders[i] = text(textbox);
5902 } else {
5903 placeholders[i] = text;
5904 }
5905
5906 textbox.title = placeholders[i];
5907 textbox.setAttribute('aria-label', placeholders[i]);
5908 textbox.setAttribute('placeholder', placeholders[i]);
5909
5910 if (hasClass(textbox, 'DOMControl_placeholder')) {
5911 textbox.value = placeholders[i];
5912 }
5913
5914 }
5915
5916 /*try {
5917 if (typeof USW.requireLazy == 'function') {
5918 USW.requireLazy(['TextAreaControl'], function(TextAreaControl) {
5919 for (var i = 0; i < query.length; i++) {
5920 if (placeholders[i]) {
5921 //if (query[i] != d.activeElement) {
5922 TextAreaControl.getInstance(query[i]).setPlaceholderText(placeholders[i]);
5923 //}
5924 }
5925 }
5926 });
5927 } else {*/
5928 for (var i = 0, len = query.length; i < len; i += 1) {
5929 if (placeholders[i]) {
5930 var textbox = query[i];
5931 if (!textbox.getAttribute('data-ponyhoof-ponified-overridefb')) {
5932 textbox.setAttribute('aria-label', placeholders[i]);
5933 textbox.setAttribute('placeholder', placeholders[i]);
5934 textbox.setAttribute('data-ponyhoof-ponified-overridefb', 1);
5935 if (textbox == d.activeElement) {
5936 continue;
5937 }
5938 if (textbox.value == '' || hasClass(textbox, 'DOMControl_placeholder')) {
5939 if (placeholders[i]) {
5940 addClass(textbox, 'DOMControl_placeholder');
5941 } else {
5942 removeClass(textbox, 'DOMControl_placeholder');
5943 }
5944 textbox.value = placeholders[i] || '';
5945 }
5946 }
5947 }
5948 }
5949 /*}
5950 } catch (e) {
5951 error("Unable to hook to TextAreaControl");
5952 dir(e);
5953 }*/
5954 };
5955
5956 var domReplaceFunc = function(ele, cn, deeper, func) {
5957 if (!ele || (cn == '' && deeper == '')) {
5958 return;
5959 }
5960
5961 var id = ele.getAttribute('id');
5962 if ((cn && hasClass(ele, cn)) || (cn && id && id == cn)) {
5963 func(ele);
5964 return;
5965 }
5966
5967 if (deeper) {
5968 var query = ele.querySelectorAll(deeper);
5969 if (query.length) {
5970 for (var i = 0, len = query.length; i < len; i += 1) {
5971 func(query[i]);
5972 }
5973 }
5974 }
5975 };
5976
5977 var replaceText = function(arr, t) {
5978 var lowercase = t.toLowerCase();
5979 for (var i = 0, len = arr.length; i < len; i += 1) {
5980 if (arr[i][0] instanceof RegExp) {
5981 t = t.replace(arr[i][0], arr[i][1]);
5982 } else {
5983 if (arr[i][0].toLowerCase() == lowercase) {
5984 t = arr[i][1];
5985 }
5986 }
5987 }
5988
5989 return t;
5990 };
5991
5992 var loopChildText = function(ele, func) {
5993 if (!ele || !ele.childNodes) {
5994 return;
5995 }
5996 for (var i = 0, len = ele.childNodes.length; i < len; i += 1) {
5997 func(ele.childNodes[i]);
5998 }
5999 };
6000
6001 var buttonTitles = [];
6002 var dialogTitles = [];
6003 var tooltipTitles = [];
6004 var headerTitles = [];
6005 var menuTitles = [];
6006 var menuPrivacyOnlyTitles = [];
6007 var dialogDerpTitles = [];
6008 var headerInsightsTitles = [];
6009 var dialogDescriptionTitles = [];
6010 function buildStackLang() {
6011 var ponyData = convertCodeToData(REALPONY);
6012
6013 buttonTitles = [
6014 ["Done", "Eeyup"]
6015 ,["Okay", "Eeyup"]
6016 ,["Done Editing", "Eeyup"]
6017 ,["Save Changes", "Eeyup"]
6018 ,["OK", "Eeyup"]
6019
6020 ,[/everyone/i, "Everypony"] // for Everyone (Most Recent)
6021 ,["Everybody", "Everypony"]
6022 ,["Public", "Everypony"]
6023 ,["Anyone", "Anypony"]
6024 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6025 ,["Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6026 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Guests"]
6027 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Contributors"]
6028 ,["Only Me", "Alone"]
6029 ,["Only me", "Alone"]
6030 ,["Only Me (+)", "Alone (+)"]
6031 ,["Only me (+)", "Alone (+)"]
6032 ,["No One", "Alone"]
6033 ,["Nobody", "Nopony"]
6034
6035 ,["Add Friend", "Add "+capitaliseFirstLetter(CURRENTSTACK['friend'])]
6036 ,["Friend Request Sent", "Friendship Request Sent"]
6037 ,["Respond to Friend Request", "Respond to Friendship Request"]
6038 ,["Like", capitaliseFirstLetter(CURRENTSTACK['like'])]
6039 ,["Liked", capitaliseFirstLetter(CURRENTSTACK['liked_button'])]
6040 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK['unlike'])]
6041 ,["Like Page", capitaliseFirstLetter(CURRENTSTACK['like'])+" Page"]
6042 ,["Like This Page", capitaliseFirstLetter(CURRENTSTACK['like'])+" This Page"]
6043 ,["Suggest Friends", "Suggest "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6044 ,["Suggest Friend", "Suggest "+capitaliseFirstLetter(CURRENTSTACK['friend'])]
6045 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6046 ,["All friends", "All "+CURRENTSTACK['friends']]
6047 ,["Poke", "Nuzzle"]
6048 ,["Request Deleted", "Request Nuked"]
6049
6050 ,["Likes", capitaliseFirstLetter(CURRENTSTACK['likes'])]
6051 ,["Friends' Posts", capitaliseFirstLetter(CURRENTSTACK['friends'])+"' Posts"]
6052
6053 ,["Photos", "Pony Pics"]
6054 ,["People", capitaliseFirstLetter(CURRENTSTACK['people'])]
6055 ,["Banned", "Banished to Moon"]
6056 ,["Blocked", "Banished to Moon"]
6057 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK.people)+" that "+CURRENTSTACK.like_past+" this"]
6058 ,["Pages that like this", "Pages that "+CURRENTSTACK.like_past+" this"]
6059
6060 ,["Delete and Ban User", "Nuke and Banish to Moon"]
6061 ,["Remove from Friends", "Banish to Moon"]
6062 ,["Delete", "Nuke"]
6063 ,["Delete Photo", "Nuke Pony Pic"]
6064 ,["Delete Page", "Nuke Page"]
6065 ,["Delete All", "Nuke All"]
6066 ,["Delete Selected", "Nuke Selected"]
6067 ,["Delete Conversation", "Nuke Conversation"]
6068 ,["Delete Message", "Nuke Friendship Report"]
6069 ,["Delete Messages", "Nuke Friendship Reports"]
6070 ,["Delete Post", "Nuke Post"]
6071 ,["Remove", "Nuke"]
6072 ,["Delete Report", "Nuke This Whining"]
6073 ,["Report", "Whine"]
6074 ,["Report as Spam", "Whine as Spam"]
6075 ,["Clear Searches", "Nuke Searches"]
6076 ,["Report/Remove Tags", "Whine/Nuke Tags"]
6077 ,["Untag Photo", "Untag Pony Pic"]
6078 ,["Untag Photos", "Untag Pony Pics"]
6079 ,["Delete My Account", "Nuke My Account"]
6080 ,["Allowed on Timeline", "Allowed on Journal"]
6081 ,["Hidden from Timeline", "Hidden from Journal"]
6082 ,["Unban", "Unbanish"]
6083 ,["Delete Album", "Nuke Album"]
6084 ,["Cancel Report", "Cancel Whining"]
6085 ,["Unfriend", "Banish to Moon"]
6086 ,["Delete List", "Nuke List"]
6087
6088 ,["Messages", "Trough"]
6089 ,["New Message", "Write a Friendship Report"]
6090 ,["Other Messages", "Other Friendship Reports"]
6091 ,["Stay on Message", "Stay on Friendship Report"]
6092
6093 ,["Share Photo", "Share Pony Pic"]
6094 ,["Share Application", "Share Magic"]
6095 ,["Share Note", "Share Scroll"]
6096 ,["Share Question", "Share Query"]
6097 ,["Share Event", "Share Adventure"]
6098 ,["Share Group", "Share Herd"]
6099 ,["Send Message", "Send Friendship Letter"]
6100 ,["Share Photos", "Share Pony Pics"]
6101 ,["Share This Note", "Share This Scroll"] // entstream
6102 ,["Share This Photo", "Share This Pony Pic"]
6103
6104 ,["Add Friends", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6105 ,["Go to App", "Go to Magic"]
6106 ,["Back to Timeline", "Back to Journal"]
6107 ,["Add App", "Add Magic"]
6108 ,["Get More Likes", "Get More "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6109 ,["Advertise Your App", "Advertise Your Magic"]
6110 ,["Leave App", "Leave Magic"]
6111 ,["Find another app", "Find another magic"]
6112 ,["Post on your timeline", "Post on your journal"]
6113 ,["App Center", "Magic Center"]
6114 ,["View App Center", "View Magic Center"]
6115
6116 ,["Events", "Adventures"]
6117 ,["Page Events", "Page Adventures"]
6118 ,["Suggested Events", "Suggested Adventures"]
6119 ,["Past Events", "Past Adventures"]
6120 ,["Declined Events", "Declined Adventures"]
6121 ,["Create Event", "Plan an Adventure"]
6122 ,["Save Event", "Save Adventure"]
6123 ,["Back to Event", "Back to Adventure"]
6124 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK['friends_logic'])]
6125 ,["Page Event", "Page Adventures"]
6126 ,["Upcoming Events", "Upcoming Adventures"]
6127 ,["Group Events", "Herd Adventures"]
6128 ,["Change Event Photo", "Change Pony Pic for Adventure"]
6129 ,["Add Event Photo", "Add Pony Pic for Adventure"]
6130 ,["+ Create an Event", "+ Plan an Adventure"]
6131
6132 ,["Friend Activity", capitaliseFirstLetter(CURRENTSTACK['friend'])+" Activity"]
6133 ,["Activity Log", "Adventure Log"]
6134
6135 ,["Invite More Friends", "Invite More Pals"]
6136 ,["Find Friends", CURRENTSTACK['findFriendship']]
6137 //,["Pages I Like", "Pages I "+capitaliseFirstLetter(CURRENTSTACK['like_past'])]
6138 ,["Find My Friends", CURRENTSTACK['findFriendship']]
6139
6140 ,["Leave Group", "Leave Herd"]
6141 ,["Set Up Group Address", "Set Up Herd Address"]
6142 ,["Change Group Photo", "Change Herd Pony Pic"]
6143 ,["Notifications", "Sparks"]
6144 ,["Start Chat", "Start Whinny Chat"]
6145 ,["Create Group", "Create Herd"]
6146 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])]
6147 ,["Groups", "Herds"]
6148 ,["Join Group", "Join the Herd"]
6149 ,["View group", "View herd"]
6150 ,["Create New Group", "Create New Herd"]
6151 ,["Set Up Group", "Set Up Herd"] // tour
6152
6153 ,["Move photo", "Move pony pic"]
6154 ,["Delete Photos", "Nuke Pony Pics"]
6155 ,["Keep Photos", "Keep Pony Pics"]
6156 ,["Save Photo", "Save Pony Pic"]
6157 ,["Tag Photos", "Tag Pony Pics"]
6158 ,["Add Photos", "Add Pony Pics"]
6159 ,["Upload Photos", "Upload Pony Pics"]
6160 ,["Tag Photo", "Tag Pony Pic"]
6161 ,["Add More Photos", "Add More Pony Pics"]
6162 ,["Post Photos", "Post Pony Pics"]
6163 ,["Add Photos to Map", "Add Pony Pics to Map"]
6164 ,["Add Photo", "Add Pony Pic"]
6165
6166 ,["On your own timeline", "On your own journal"]
6167 ,["On a friend's timeline", "On a "+CURRENTSTACK['friend']+"'s journal"]
6168 ,["In a group", "In a herd"]
6169 ,["In a private message", "In a private friendship report"]
6170
6171 ,["Timeline", "Journal"]
6172 ,["Notes", "Scrolls"]
6173 ,["Comments", "Friendship Letters"]
6174 ,["Posts and Apps", "Posts and Magic"]
6175 ,["Timeline Review", "Journal Review"]
6176 ,["Pokes", "Nuzzles"]
6177 ,["Add to Timeline", "Add to Journal"]
6178
6179 ,["Photo", "Pony Pic"]
6180 ,["Question", "Query"]
6181
6182 //,["Create List", "Create Directory"]
6183 ,["See All Friends", "See All "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6184 //,["Manage List", "Manage Directory"]
6185 ,["Write a Note", "Write a Scroll"]
6186 ,["Add Note", "Add Scroll"]
6187 ,["Edit Featured Likes", "Edit Featured "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6188 ,["Add Featured Likes", "Add Featured "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6189 ,["Add profile picture", "Add journal pony pic"]
6190 ,["Edit Profile Picture", "Edit Journal Pony Pic"]
6191 //,["Create an Ad", "Buy a Cupcake"]
6192 //,["On This List", "On This Directory"]
6193 ,["Friend Requests", "Friendship Requests"]
6194 //,["Add Friends to List", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" to Directory"]
6195 ,["Add Friends to List", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" to List"]
6196
6197 ,[/^Pages I Like$/, "Pages I "+capitaliseFirstLetter(CURRENTSTACK['like_past'])]
6198 ,[/^Pages I like$/, "Pages I "+CURRENTSTACK['like_past']]
6199 ,["My Friends", "My "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6200 ,["Tell Friends", "Tell "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6201
6202 ,["Add to Profile", "Add to Journal"]
6203 ,["Add Likes", "Add "+capitaliseFirstLetter(CURRENTSTACK.likes)]
6204 ,["Set as Profile Picture", "Set as Journal Pony Pic"]
6205 ,["View Activity Log", "View Adventure Log"]
6206 ,["Invite Your Friends", "Invite Your "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6207 ,["Suggest Photo", "Suggest Pony Pic"]
6208 ,["All Apps", "All Magic"]
6209 ,["Link My Profile to Twitter", "Link My Journal to Twitter"]
6210 ,["Link profile to Twitter", "Link journal to Twitter"]
6211 ,["The app sends you a notification", "The magic sends you a spark"]
6212 ,["Upload a Photo", "Upload a Pony Pic"]
6213 ,["Take a Photo", "Take a Pony Pic"]
6214 ,["Take a Picture", "Take a Pony Pic"] // edit page
6215
6216 ,["Search All Friends", "Search All "+capitaliseFirstLetter(CURRENTSTACK.friends)] // invite friends
6217 ,["Top Comments", "Top Friendship Letters"] // comment resort
6218 ,["Go to Activity Log", "Go to Adventure Log"] // checkpoint
6219 ,["Upload Photo", "Upload Pony Pic"] // composer warning
6220 ,["Poke Back", "Nuzzle Back"] // newsfeed flyout
6221 ,["Friends to Invite", capitaliseFirstLetter(CURRENTSTACK['friends'])+" to Invite"] // app invite
6222 ,["Inbox", "Trough"] // page inbox
6223 ,["Save Profile Info", "Save Journal Info"] // welcome
6224 ,["Like Pages", capitaliseFirstLetter(CURRENTSTACK['like'])+" Pages"] // litestand Following
6225 ,["Visit App Center", "Visit Magic Center"] // litestand Games
6226 ,["Go to App Center", "Go to Magic Center"] // no https on app
6227
6228 // graph search
6229 ,["Likers", "Brohoofers"] // @todo likers
6230 ,["Liked by", capitaliseFirstLetter(CURRENTSTACK['liked'])+" by"] // @todo likers
6231
6232 ,["Create New App", "Create New Magic"]
6233 ,["Submit App Detail Page", "Submit Magic Detail Page"]
6234 ,["Edit App", "Edit Magic"]
6235 ,["Promote App", "Promote Magic"]
6236 ,["Make Friends", "Make "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6237 ,["Add to Other Apps", "Add to Other Magic"]
6238 ];
6239
6240 dialogTitles = [
6241 [/People who like /, capitaliseFirstLetter(CURRENTSTACK['people'])+" who "+CURRENTSTACK['like_past']+" "]
6242 ,[/People Who Like /, capitaliseFirstLetter(CURRENTSTACK['people'])+" Who "+capitaliseFirstLetter(CURRENTSTACK['like_past'])+" "]
6243 ,[/Friends who like /i, capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" who "+CURRENTSTACK['like_past']+" "]
6244 ,["People who voted for this option", capitaliseFirstLetter(CURRENTSTACK['people'])+" who voted for this option"]
6245 ,["People who are following this question", capitaliseFirstLetter(CURRENTSTACK['people'])+" who are following this question"]
6246 ,[/People Connected to /, capitaliseFirstLetter(CURRENTSTACK['people'])+" Connected to "]
6247 ,["People who saw this", capitaliseFirstLetter(CURRENTSTACK['people'])+" who saw this"]
6248 ,["Added Friends", "Added "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6249 ,["People who can repro this", capitaliseFirstLetter(CURRENTSTACK['people'])+" who can repro this"]
6250 ,["Friends that like this", capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" that "+CURRENTSTACK['like_past']+" this"]
6251 ,["People", capitaliseFirstLetter(CURRENTSTACK['people'])] // gifts
6252 ,["Choose friends to help translate", "Choose "+CURRENTSTACK['friends']+" to help translate"]
6253
6254 ,["Share this Profile", "Share this Journal"]
6255 ,["Share This Photo", "Share This Pony Pic"]
6256 //,["Share this Album", ""]
6257 ,["Share this Note", "Share this Scroll"]
6258 ,["Share this Group", "Share this Herd"]
6259 ,["Share this Event", "Share this Adventure"]
6260 //,["Share this Ad", ""]
6261 ,["Share this Application", "Share this Magic"]
6262 //,["Share this Video", ""]
6263 //,["Share this Page", "Share this Landmark"]
6264 //,["Share this Page", "You gotta share!"]
6265 //,["Share this Job", ""]
6266 //,["Share this Status", "You gotta share!"]
6267 ,["Share this Question", "Share this Query"]
6268 //,["Share this Link", "You gotta share!"]
6269 ,["Share", "You gotta share!"]
6270 //,["Share this Help Content", ""]
6271 ,["Send This Photo", "Send This Pony Pic"]
6272 ,["Share Photo", "Share Pony Pic"]
6273
6274 ,["Timeline and Tagging", "Journal and Tagging"]
6275 ,["Timeline Review", "Journal Review"]
6276 //,["Friends Can Check You Into Places", capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" Can Check You Into Landmarks"]
6277 //,["Limit The Audience for Old Posts on Your Timeline", "Limit The Audience for Old Posts on Your Journal"]
6278 //,["How people bring your info to apps they use", "How "+CURRENTSTACK['people']+" bring your info to magic they use"]
6279 //,["Turn off Apps, Plugins and Websites", "Turn off Magic, Plugins and Websites"]
6280
6281 ,["Likes", capitaliseFirstLetter(CURRENTSTACK['likes'])]
6282 ,["Edit Featured Likes", "Edit Featured "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6283 ,["Change Date", "Time Travel"]
6284 ,["Date Saved", "Time Traveled"]
6285
6286 ,["Delete", "Nuke"]
6287 ,["Delete Comment", "Nuke Friendship Letter"]
6288 ,["Delete Photo", "Nuke Pony Pic"]
6289 ,["Remove Picture?", "Nuke Pony Pic?"]
6290 ,["Delete Video?", "Nuke Video?"]
6291 ,["Delete Milestone", "Nuke Milestone"]
6292 ,["Delete Page?", "Nuke Page?"]
6293 ,["Delete This Message?", "Nuke This Friendship Report?"]
6294 ,["Delete This Entire Conversation?", "Nuke This Entire Conversation?"]
6295 ,["Delete These Messages?", "Nuke These Friendship Reports?"]
6296 ,["Delete Post", "Nuke Post"]
6297 ,["Delete Post?", "Nuke Post?"]
6298 ,["Delete Page Permanently?", "Nuke Page Permanently?"]
6299 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK['unlike'])]
6300 ,["Remove Search", "Nuke Search"]
6301 //,["Clear Searches", "Nuke Searches"]
6302 ,["Untag Photo", "Untag Pony Pic"]
6303 ,["Untag Photos", "Untag Pony Pics"]
6304 ,["Permanently Delete Account", "Permanently Nuke Account"]
6305 ,["Remove", "Nuke"]
6306 ,["Delete and Ban Member", "Nuke and Banish to Moon"]
6307 ,["Delete Album", "Nuke Album"]
6308 ,["Are you sure you want to clear all your searches?", "Are you sure you want to nuke all your searches?"]
6309 ,["Remove Photo?", "Nuke Pony Pic?"]
6310 ,["Removed Group Photo", "Nuked Herd Pony Pic"]
6311 ,["Post Deleted", "Post Nuked"]
6312 ,["Remove Event", "Nuke Adventure"]
6313 ,["Delete Entry?", "Nuke Entry?"]
6314 ,["Delete Video", "Nuke Video"]
6315 ,["Delete Event", "Nuke Adventure"] // for group admin
6316 ,["Remove Profile Picture", "Nuke Journal Pony Pic"]
6317 ,["Delete Photo?", "Nuke Pony Pic?"]
6318
6319 ,["Report and/or Block This Person", "Whine and/or Block This "+capitaliseFirstLetter(CURRENTSTACK['person'])] // 0
6320 ,["Report This Photo", "Whine About This Pony Pic"]
6321 ,["Report This Event", "Whine About This Adventure"]
6322 ,["Report Conversation", "Whine About Conversation"]
6323 ,["Report as Spam?", "Whine as Spam?"]
6324 ,["Invalid Report", "Invalid Whining"]
6325 ,["Report This Page", "Whine About This Page"]
6326 ,["Report This Doc Revision", "Whine About This Doc Revision"]
6327 ,["Confirm Report", "Confirm Whining"]
6328 ,["Report This Place", "Whine About This Place"] // 64
6329 ,["Thanks For This Report", "Thanks For Whining"]
6330 ,["Send Message", "Send Friendship Report"] // social report
6331 ,["Send Messages", "Send Friendship Reports"]
6332 ,["Why don't you like these photos?", "Why don't you like these pony pics?"]
6333 ,["Photos Untagged and Messages Sent", "Pony Pics Untagged and Friendship Reports Sent"]
6334 ,["Report This Post", "Whine About This Post"] // report lists as a page
6335 ,["Report This?", "Whine About This?"]
6336 ,["Report Recommendation", "Whine About Recommendation"] // 108
6337 ,["Why don't you like this photo?", "Why don't you like this pony pic?"]
6338 ,["Report Spam or Abuse", "Whine as Spam or Abuse"] // messages
6339 ,["Report Incorrect External Link", "Whine About Incorrect External Link"] // page vertex // 87
6340 ,["Post Reported", "Whined About Post"]
6341 ,[" Report a Problem ", "Whine About a Problem"]
6342 ,["Report a Problem", "Whine About a Problem"]
6343
6344 // report types: 5: links / 125: status / 70: group post / 86: og post
6345 ,["Is this post about you or a friend?", "Is this post about you or a "+CURRENTSTACK.friend+"?"]
6346 ,["Why are you reporting this Page?", "Why are you whining about this Page?"] // 23
6347 ,["Is this group about you or a friend?", "Is this herd about you or a "+CURRENTSTACK['friend']+"?"] // 1
6348 ,["Is this comment about you or a friend?", "Is this friendship letter about you or a "+CURRENTSTACK['friend']+"?"] // 71 / 74: page comment
6349 //,["Is this list about you or a friend?", "Is this directory about you a "+CURRENTSTACK.friend+"?"] // 92
6350 ,["Is this list about you or a friend?", "Is this list about you a "+CURRENTSTACK.friend+"?"] // 92
6351 ,["Is this photo about you or a friend?", "Is this pony pic about you or a "+CURRENTSTACK['friend']+"?"] // 2
6352 ,["Is this note about you or a friend?", "Is this scroll about you or a "+CURRENTSTACK['friend']+"?"] // 4
6353 ,["Is this video about you or a friend?", "Is this video about you or a "+CURRENTSTACK['friend']+"?"] // 13
6354 ,["Is this event about you or a friend?", "Is this adventure about you or a "+CURRENTSTACK['friend']+"?"] // 81
6355
6356 ,["How to Report Posts", "How to Whine About Posts"]
6357 ,["How to Report Posts on My Timeline", "How to Whine About Posts on My Journal"]
6358 ,["How to Report the Profile Picture", "How to Whine About the Journal Pony Pic"]
6359 ,["Why are you reporting this photo?", "Why are you whining about this pony pic?"]
6360 ,["How to Report the Cover", "How to Whine About the Cover"]
6361 ,["How to Report Messages", "How to Whine About Friendship Reports"]
6362 ,["How to Report a Page", "How to Whine About a Page"]
6363 ,["How to Report a Group", "How to Whine About a Herd"]
6364 ,["How to Report an Event", "How to Whine About an Adventure"]
6365 ,["How to Report Page Posts", "How to Whine About Page Posts"]
6366
6367 ,["New Message", "Write a Friendship Report"]
6368 ,["Forward Message", "Forward this Friendship Report"]
6369 ,["Delete This Message?", "Nuke This Friendship Report?"]
6370 ,["Message Not Sent", "Friendship Report Not Sent"]
6371 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])]
6372 ,["Add Photos", "Add Pony Pics"]
6373 ,["People in this message", capitaliseFirstLetter(CURRENTSTACK['people'])+" in this friendship report"]
6374 ,["Message Sent", "Friendship Report Sent"]
6375 ,["Message Filtering Preferences", "Friendship Report Filtering Preferences"]
6376 ,["Don't Send Message?", "Don't Send Friendship Report?"] // webmessenger
6377
6378 ,["Create New Group", "Create New Herd"]
6379 ,[/Create New Event/, "Plan an Adventure"]
6380 ,["Notification Settings", "Spark Settings"]
6381 ,["Create Group Email Address", "Create Herd Email Address"]
6382 ,["Set Up Group Web and Email Address", "Set Up Herd Web and Email Address"]
6383 ,["Mute Chat?", "Mute Whinny Chat?"]
6384 ,["Add Friends to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" to the Herd"]
6385 ,["Add People to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])+" to the Herd"]
6386 ,["Not a member of the group", "Not a member of the herd"]
6387 ,["Invite People to Group by Email", "Invite "+capitaliseFirstLetter(CURRENTSTACK.people)+" to Herd by Email"]
6388 ,["Remove Group Admin", "Remove Herd Admin"]
6389 ,["Add Group Admin", "Add Herd Admin"]
6390 ,["Group Admins", "Herd Admins"]
6391 ,["Change Group Privacy?", "Change Herd Privacy?"]
6392
6393 ,["Cancel Event?", "Cancel Adventure?"]
6394 ,["Change Event Photo", "Change Pony Pic for Adventure"]
6395 ,["Add Event Photo", "Add Adventure Pony Pic"]
6396 ,["Export Event", "Export Adventure"]
6397 ,["Edit Event Info", "Edit Adventure Info"]
6398 ,["Create Repeat Event", "Plan a Repeat Adventure"]
6399 ,["Event Invites", "Adventure Invites"]
6400
6401 ,["Hide all recent profile changes?", "Hide all recent journal changes?"]
6402 ,["Edit your profile story settings", "Edit your journal story settings"]
6403 ,["Edit your timeline recent activity settings", "Edit your journal recent activity settings"]
6404 ,["Hide all recent likes activity?", "Hide all recent "+CURRENTSTACK.likes+" activity?"]
6405 ,["Edit Privacy of Likes", "Edit Privacy of "+capitaliseFirstLetter(CURRENTSTACK.likes)]
6406
6407 ,["Edit News Feed Settings", "Edit Feed Bag Settings"]
6408 //,["Create New List", "Create New Directory"]
6409 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK['friends_logic'])]
6410 ,["Advanced Chat Settings", "Advanced Whinny Chat Settings"]
6411 ,["Notifications Updated", "Sparks Updated"]
6412 ,["Move photo to another album?", "Move pony pic to another album?"]
6413 ,["Group Muted", "Herd Muted"]
6414 ,["Block App?", "Block Magic?"]
6415 //,["List Notification Settings", "Directory Spark Settings"]
6416 ,["List Notification Settings", "List Spark Settings"]
6417 ,["Like This Photo?", capitaliseFirstLetter(CURRENTSTACK['like'])+" This Pony Pic?"]
6418 ,["Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6419 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6420 ,["Suggest Friend", "Suggest "+capitaliseFirstLetter(CURRENTSTACK.friend)]
6421 ,["Blocked People", "Blocked "+capitaliseFirstLetter(CURRENTSTACK.people)]
6422 ,["Block People", "Block "+capitaliseFirstLetter(CURRENTSTACK.people)]
6423 ,["Tag Friends", "Tag "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6424 ,["Unable to edit Group", "Unable to edit Herd"]
6425 ,["Thanks for Inviting Your Friends", "Thanks for Inviting Your "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6426 ,["Timeline Gift Preview", "Journal Gift Preview"]
6427 ,["Friend Request Setting", "Friendship Request Setting"]
6428 ,["Invalid Question", "Invalid Query"]
6429 //,["List Subscribers", "Directory Subscribers"]
6430 ,["People Who Shared This", capitaliseFirstLetter(CURRENTSTACK.people)+" Who Shared This"]
6431 //,["Edit List Settings", "Edit Directory Settings"]
6432 ,["Remove App", "Remove Magic"]
6433 ,["Turn Off Chat", "Turn Off Whinny Chat"]
6434 ,["Access Log", "Adventure Log"]
6435 ,["Post to Your Wall", "Post to Your Journal"]
6436 ,["About Adding Comments by Email", "About Adding Friendship Letters by Email"]
6437 ,["Find Your Friends", CURRENTSTACK['findFriendship']]
6438 ,["Upload a profile picture", "Upload a journal pony pic"]
6439 ,["Photo Upload Failed", "Pony Pic Upload Failed"] // chat photo upload
6440
6441 ,["Take a Profile Picture", "Take a Journal Pony Pic"]
6442 ,["Choosing Your Cover Photo", "Choosing Your Cover Pony Pic"]
6443 ,["Choose from Group Photos", "Choose from Herd Pony Pics"]
6444 ,["Group Albums", "Herd Albums"]
6445 ,["Choose From Your Photos", "Choose From Your Pony Pics"]
6446 ,["Choose from Photos", "Choose from Pony Pics"]
6447 ,["Choose Your Cover Photo", "Choose Your Cover Pony Pic"]
6448 ,["Choose from your synced photos", "Choose from your synced pony pics"]
6449 ,["Upload Your Profile Picture", "Upload Your Journal Pony Pic"] // welcome
6450
6451 ,["Create New App", "Create New Magic"]
6452 ,["Add Test Users to other Apps", "Add Test Users to other Magic"]
6453
6454 ,["Hidden in Groups", "Hidden in Herds"] // timeline
6455 ,["Add Friends as Contributors", "Add "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" as Contributors"] // shared albums
6456 ];
6457 if (ponyData.successText) {
6458 dialogTitles.push(["Success", ponyData.successText]);
6459 dialogTitles.push(["Success!", ponyData.successText]);
6460 }
6461
6462 tooltipTitles = [
6463 [/everyone/gi, "Everypony"]
6464 //,[/\bpublic\b/g, "everypony"]
6465 ,[/\bPublic\b/g, "Everypony"]
6466 ,["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."]
6467 //,["These people subscribe to the lists you're featured on", "These "+capitaliseFirstLetter(CURRENTSTACK['people'])+" subscribe to the directories you're featured on"]
6468 ,["These people subscribe to the lists you're featured on", "These "+capitaliseFirstLetter(CURRENTSTACK['people'])+" subscribe to the lists you're featured on"]
6469 ,["Friends of anyone going to this event", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of anypony going to this adventure"]
6470 ,["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"]
6471 ,["Anyone can see and join this event", "Anypony can see and join this adventure"]
6472 ,["Your friends will see your comment in News Feed.", "Your "+CURRENTSTACK['friends']+" will see your friendship letter in Feed Bag."]
6473 ,[/\bfriends in group\b/, CURRENTSTACK['friends']+" in herd"]
6474 ,["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']]
6475 ,["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."]
6476 ,["Friends and friends of anyone tagged", capitaliseFirstLetter(CURRENTSTACK['friends'])+" and "+CURRENTSTACK['friends']+" of anypony tagged"]
6477 ,["Guests of this event will see the comment you write below.", "Guests of this adventure will see the friendship letter you write below."]
6478 ,[/\bfriends of friends\b/g, CURRENTSTACK['friends']+" of "+CURRENTSTACK['friends']]
6479 ,[/\bFriends of Friends\b/g, capitaliseFirstLetter(CURRENTSTACK['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6480 ,[/\bfriends\b/g, CURRENTSTACK['friends']]
6481 ,[/\bFriends\b/g, capitaliseFirstLetter(CURRENTSTACK['friends'])]
6482 ,["Only Me", "Alone"]
6483 ,["Only me", "Alone"]
6484 ,["No One", "Alone"]
6485 ,["Only you", "Alone"]
6486 ,["Anyone tagged", "Anypony tagged"]
6487 //,[/cover photos are everypony/i, "Everypony can see your cover pony pics"]
6488 ,["Cover photos are public", "Everypony can see your cover pony pics"]
6489 ,[/any other information you made Everypony/i, "any other information that everypony can see"]
6490 ,["Anyone can see this Everypony comment", "Everypony can see this public friendship letter"]
6491 //,["Remember: all place ratings are Everypony.", "Remember: everypony can see all place ratings."]
6492 ,["Everypony can see posts on this Everypony page.", "Everypony can see posts on this public page."]
6493 ,["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"]
6494 //,["Name, profile picture, age range, gender, language, country and other Everypony info", "Name, profile picture, age range, gender, language, country and other public info"]
6495 ,["This will hide you from Everypony attribution", "This will hide you from public attribution"]
6496 ,["Remember: all place ratings are public.", "Remember: everypony can see all place ratings."]
6497 ,["Shared with: Anyone who can see this page", "Shared with: Anypony who can see this page"]
6498 ,["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."]
6499 ,["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)
6500 ,["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."]
6501 ,["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."]
6502 ,["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)
6503 ,["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"]
6504 ,["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."]
6505
6506 ,["Show comments", "Show friendship letters"]
6507 ,["Comment deleted", "Friendship letter nuked"]
6508 ,[/Comments/, "Friendship Letters"]
6509 ,[/Comment/, "Friendship Letter"]
6510
6511 ,["Remove", "Nuke"]
6512 ,["Edit or Delete", "Edit or Nuke"]
6513 ,["Edit or Remove", "Edit or Nuke"]
6514 ,["Delete Post", "Nuke Post"]
6515 ,["Remove or Report", "Nuke or Whine"]
6516 ,["Report", "Whine"]
6517 ,["Report/Mark as Spam", "Whine/Mark as Spam"]
6518 ,["Report as not relevant", "Whine as not relevant"]
6519 ,["Remove Invite", "Nuke Invite"]
6520 ,["Report/Remove Tag", "Whine/Nuke Tag"]
6521 ,["Delete", "Nuke"]
6522 ,["Delete and Ban", "Nuke and Banish"]
6523 ,["Report Place", "Whine About Place"]
6524 ,["Delete Album", "Nuke Album"]
6525
6526 ,["Shown on Timeline", "Shown on Journal"]
6527 ,["Allow on Timeline", "Allow on Journal"]
6528 ,["Highlighted on Timeline", "Highlighted on Journal"]
6529 ,["Allowed on Timeline", "Allowed on Journal"]
6530 ,["Hidden from Timeline", "Hidden from Journal"]
6531
6532 //,[/likes? this/g, "brohoof'd this"]
6533 ,["Sent from chat", "Sent from whinny chat"]
6534 ,["New Message", "Write a Friendship Report"]
6535
6536 //,[/\bpeople\b/gi, "ponies"]
6537 ,[/See who likes this/gi, "See who "+CURRENTSTACK['likes']+" this"]
6538 ,[/people like this\./gi, CURRENTSTACK['people']+" "+CURRENTSTACK['like_past']+" this."] // entstream
6539 ,[/like this\./gi, CURRENTSTACK['like_past']+" this."]
6540 ,[/likes this\./gi, CURRENTSTACK['likes_past']+" this."]
6541
6542 // top right pages
6543 ,["Status", "Take a Note"]
6544 ,["Photo / Video", "Add a Pic"]
6545 ,["Event, Milestone +", "Adventure, Milestone +"]
6546
6547 ,["Onsite Notifications", "Onsite Sparks"]
6548 ,["Create Event", "Plan an Adventure"]
6549 ,["Search messages in this conversation", "Search friendship reports in this conversation"]
6550 ,["Open photo viewer", "Open pony pic viewer"]
6551 ,["Choose a unique image for the cover of your timeline.", "Choose a unique pony pic for the cover of your journal."]
6552 ,["Remove from Dashboard", "Remove from Dashieboard"]
6553 ,["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."]
6554
6555 ,["Each photo has its own privacy setting", "Each pony pic has its own privacy setting"]
6556 ,["You can change the audience for each photo in this album", "You can change the audience for each pony pic in this album"]
6557
6558 ,["View Photo", "View Pony Pic"]
6559
6560 // litestand navigation when collapsed
6561 ,["News Feed", "Feed Bag"]
6562 ,["Messages", "Trough"]
6563 ,["Pokes", "Nuzzles"]
6564 ,["Manage Apps", "Manage Magic"]
6565 ,["Events", "Adventures"]
6566 ,["App Center", "Magic Center"]
6567 ,["Add Friend", "Add "+capitaliseFirstLetter(CURRENTSTACK['friend'])] // people you may know
6568
6569 // photo comments
6570 ,["Attach a Photo", "Attach a Pony Pic"]
6571 ,["Remove Photo", "Nuke Pony Pic"]
6572
6573 ,["Dismiss and go to most recent message", "Dismiss and go to most recent friendship letter"] // messages
6574 ,["To create an offer, your Page needs at least 100 likes.", "To create an offer, your Page needs at least 100 "+CURRENTSTACK['likes']+"."] // page composer
6575 ,["Verified profile", "Verified journal"] // verified
6576 ,["Tags help people find groups about certain topics.", "Tags help "+CURRENTSTACK['people']+" find herds about certain topics."] // verified
6577 ,["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
6578 ,["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."]
6579 ,["Like", capitaliseFirstLetter(CURRENTSTACK['like'])]
6580
6581 // developers
6582 ,["Enable the newsfeed ticker", "Enable the feedbag ticker"]
6583 ,["Add selected users to other apps you own.", "Add selected users to other magic you own."]
6584 ,["Remove selected users from this app.", "Remove selected users from this magic."]
6585
6586 // insights
6587 ,["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."]
6588 ,["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."]
6589 ,["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"]
6590
6591 ,["The week when the most people were talking about this Page.", "The week when the most "+CURRENTSTACK['people']+" were talking about this Page."]
6592 ,["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."]
6593 ,["The largest age group of the people talking about this Page.", "The largest age group of the "+CURRENTSTACK['people']+" talking about this Page."]
6594 ,["The number of photos that have this Page tagged.", "The number of pony pics that have this Page tagged."]
6595 ,["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."]
6596 ];
6597 if (ponyData.loadingText) {
6598 tooltipTitles.push(["Loading...", ponyData.loadingText]);
6599 }
6600
6601 headerTitles = [
6602 //["List Suggestions", "Directory Suggestions"]
6603 ["People You May Know", capitaliseFirstLetter(CURRENTSTACK.people)+" You May Know"]
6604 ,["Sponsored", "Cupcake Money"]
6605 ,["Pokes", "Nuzzles"]
6606 ,["People To Follow", capitaliseFirstLetter(CURRENTSTACK.people)+" To Follow"]
6607 ,["Poke Suggestions", "Nuzzle Suggestions"]
6608 ,["Suggested Groups", "Suggested Herds"]
6609 ,["Find More Friends", CURRENTSTACK['findFriendship']]
6610 ,["Rate Recently Used Apps", "Rate Recently Used Magic"]
6611 ,["Friends' Photos", "Pals' Pony Pics"]
6612 ,["Add a Location to Your Photos", "Add a Location to Your Pony Pics"]
6613 ,["Suggest Friends", "Suggest "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6614 ,["Other Pages You Like", "Other Pages You "+capitaliseFirstLetter(CURRENTSTACK.like)]
6615 ,["Entertainment Pages You Might Like", "Entertainment Pages You Might "+capitaliseFirstLetter(CURRENTSTACK.like)]
6616 ,["Music Pages You Might Like", "Music Pages You Might "+capitaliseFirstLetter(CURRENTSTACK.like)]
6617 ,["Add Personal Contacts as Friends", "Add Personal Contacts as "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6618 ,["Find Friends", CURRENTSTACK['findFriendship']]
6619 //,[/On This List/, "On This Directory"]
6620 //,["On this list", "On this directory"]
6621 //,["On This List", "On This Directory"]
6622 ,["Related Groups", "Related Herds"]
6623 ,["Entertainment Pages You May Like", "Entertainment Pages You May "+capitaliseFirstLetter(CURRENTSTACK['like'])]
6624 ,["Music Pages You May Like", "Music Pages You May "+capitaliseFirstLetter(CURRENTSTACK['like'])]
6625 ,["No New Friend Requests", "No New Friendship Requests"] // /friends/requests/
6626 ,["Games Your Friends Are Playing", "Games Your "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" Are Playing"]
6627 ,["Promote This Event", "Promote This Adventure"]
6628 ,["Respond to Your Friend Request", "Respond to Your Friendship Request"] // /friends/requests/
6629 ,[/^Respond to Your ([0-9]+?) Friend Requests$/, "Respond to Your $1 Friendship Requests"] // /friends/requests/
6630 ,["Add People You Know", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])+" You Know"]
6631
6632 ,["Notifications", "Sparks"]
6633 ,["New Likes", "New "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6634 ,["Invite Friends", "Invite "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6635 ,["Get More Likes", "Get More "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6636 ,["Added Apps", "Added Magic"]
6637 ,["Apps You May Like", "Magic You May "+capitaliseFirstLetter(CURRENTSTACK.like)]
6638 ,["Your Apps", "Your Magic"]
6639 ,["People Talking About This", capitaliseFirstLetter(CURRENTSTACK.people)+" Blabbering About This"]
6640 ,["Total Likes", "Total "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6641 ,["Games You May Like", "Games You May "+capitaliseFirstLetter(CURRENTSTACK.like)]
6642 ,["Add To News Feed", "Add To Feed Bag"]
6643
6644 ,["Messages", "Trough"]
6645 //,["Other Messages", "Other Friendship Reports"]
6646 //,["Unread Messages", "Unread Friendship Reports"]
6647 //,["Sent Messages", "Sent Friendship Reports"]
6648 //,["Archived Messages", "Archived Friendship Reports"]
6649 ,["Inbox", "Trough"]
6650
6651 ,["Groups", "Herds"]
6652 //,["Pages and Ads", "Landmarks and Ads"]
6653 ,["Apps", "Magic"]
6654 ,[/Friends who like /gi, capitaliseFirstLetter(CURRENTSTACK['friends_logic'])+" who "+CURRENTSTACK['like_past']+" "]
6655 ,["Favorites", capitaliseFirstLetter(CURRENTSTACK['likes'])]
6656 ,["Likes", capitaliseFirstLetter(CURRENTSTACK['likes'])]
6657 ,["Events", "Adventures"]
6658 ,["Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6659 ,["Ads", "Cupcakes"]
6660 ,["Mutual Likes", "Mutual "+capitaliseFirstLetter(CURRENTSTACK.likes)]
6661 ,[/Mutual Friends/, "Mutual "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6662
6663 ,["Notes", "Scrolls"]
6664 ,["My Notes", "My Scrolls"]
6665 ,["Notes About Me", "Scrolls About Me"]
6666 ,["Write a Note", "Write a Scroll"]
6667 ,["Edit Note", "Edit Scroll"]
6668
6669 ,["Timeline and Tagging", "Journal and Tagging"]
6670 ,["Ads, Apps and Websites", "Ads, Magic and Websites"]
6671 ,["Blocked People and Apps", "Banished "+capitaliseFirstLetter(CURRENTSTACK['people'])+" and Magic"]
6672 ,["Notifications Settings", "Sparks Settings"]
6673 ,["App Settings", "Magic Settings"]
6674 ,["Friend Requests", "Friendship Requests"]
6675 ,["People Who Shared This", capitaliseFirstLetter(CURRENTSTACK.people)+" Who Shared This"]
6676 ,["Your Notifications", "Your Sparks"]
6677 ,["Timeline and Tagging Settings", "Journal and Tagging Settings"]
6678 ,["Delete My Account", "Nuke My Account"]
6679
6680 ,["Posts in Groups", "Posts in Herds"]
6681 ,["People", capitaliseFirstLetter(CURRENTSTACK['people'])]
6682
6683 ,["Posts by Friends", "Posts by "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6684 ,["Support Dashboard", "Support Dashieboard"]
6685 ,["Event Invitations", "Adventure Invitations"]
6686 ,["Who Is in These Photos?", "Who Is in These Pony Pics?"]
6687 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK.people)+" that "+CURRENTSTACK.like_past+" this"]
6688 //,["List Subscribers", "Directory Subscribers"]
6689 ,["Upcoming Events", "Upcoming Adventures"]
6690 ,["Photos and Videos", "Pony Pics and Videos"]
6691 ,["People Who Are Going", capitaliseFirstLetter(CURRENTSTACK.people)+" Who Are Going"]
6692 ,["Would you like to opt out of this email notification?", "Would you like to opt out of this email spark?"]
6693 ,["Confirm Like", "Confirm "+capitaliseFirstLetter(CURRENTSTACK['like'])]
6694
6695 ,["Invite Friends You Email", "Invite "+capitaliseFirstLetter(CURRENTSTACK['friends'])+" You Email "]
6696 ,["Invite Your Friends", "Invite Your "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6697
6698 ,["Account Groups", "Account Herds"]
6699 ,["Ads Email Notifications", "Ads Email Soarks"]
6700 ,["Ads Notifications on Facebook", "Ads Sparks on Facebook"]
6701
6702 ,["App Restrictions", "Magic Restrictions"]
6703 ,["App Info", "Magic Info"]
6704
6705 ,["Tagged Photos", "Tagged Pony Pics"]
6706
6707 ,["Add Groups", "Add Herds"] // /addgroup
6708 ,["Photos", "Pony Pics"] // /media/video/
6709 ,["Post to Your Wall", "Post to Your Stall"]
6710 ];
6711
6712 menuTitles = [
6713 ["Everyone", "Everypony"]
6714 ,["Everybody", "Everypony"]
6715 ,["Public", "Everypony"]
6716 ,["Anyone", "Anypony"]
6717 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6718 ,["Friends except Acquaintances", capitaliseFirstLetter(CURRENTSTACK['friends'])+" except Acquaintances"]
6719 ,["Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6720 ,["Friends ", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6721 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Guests"]
6722 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Contributors"]
6723 ,["Only Me", "Alone"]
6724 ,["Only me", "Alone"]
6725 ,["No One", "Alone"]
6726 ,["Nobody", "Nopony"]
6727 //,["See all lists...", "See entire directory..."]
6728
6729 ,["Mutual Friends", "Mutual "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6730 ,["People You May Know", "Ponies You May Know"]
6731 ,["Poke...", "Nuzzle..."]
6732 ,["Poke", "Nuzzle"]
6733 ,["All Friends", "All "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6734 ,["All friends", "All "+CURRENTSTACK['friends']]
6735
6736 ,["On your own timeline", "On your own journal"]
6737 ,["On a friend's timeline", "On a "+CURRENTSTACK['friend']+"'s journal"]
6738 ,["In a group", "In a herd"]
6739 ,["In a private Message", "In a private Friendship Report"]
6740
6741 ,["Friends' Posts", capitaliseFirstLetter(CURRENTSTACK['friends'])+"' Posts"]
6742 ,["Friend Activity", capitaliseFirstLetter(CURRENTSTACK['friend'])+" Activity"]
6743
6744 ,["Change Date...", "Time Travel..."]
6745 ,["Reposition Photo...", "Reposition Pony Pic..."]
6746 ,["Manage Notifications", "Manage Sparks"]
6747 ,["Use Activity Log", "Use Adventure Log"]
6748 ,["See Banned Users...", "See Ponies who were Banished to the Moon..."]
6749 ,["Invite Friends...", "Invite "+capitaliseFirstLetter(CURRENTSTACK['friends'])+"..."]
6750 ,["Like As Your Page...", capitaliseFirstLetter(CURRENTSTACK.like)+" As Your Page..."]
6751 ,["Add App to Page", "Add Magic to Page"]
6752 ,["Change Primary Photo", "Change Primary Pony Pic"]
6753 ,["Change Date", "Time Travel"]
6754
6755 ,["People", capitaliseFirstLetter(CURRENTSTACK['people'])]
6756 //,["Pages", "Landmarks"]
6757 ,["Banned", "Banished to Moon"]
6758 ,["Blocked", "Banished to Moon"]
6759 ,["People who like this", capitaliseFirstLetter(CURRENTSTACK.people)+" who "+CURRENTSTACK.like_past+" this"]
6760 ,["Pages that like this", "Pages that "+CURRENTSTACK.like_past+" this"]
6761
6762 ,["Unlike", capitaliseFirstLetter(CURRENTSTACK['unlike'])]
6763 ,["Unlike...", capitaliseFirstLetter(CURRENTSTACK['unlike'])+"..."]
6764 ,["Show in News Feed", "Show in Feed Bag"]
6765 ,["Suggest Friends...", "Suggest "+capitaliseFirstLetter(CURRENTSTACK['friends'])+"..."]
6766 ,["Unfriend...", "Banish to Moon..."]
6767 ,["Unfriend", "Banish to Moon"]
6768 //,["New List...", "New Directory..."]
6769 ,["Get Notifications", "Get Sparks"]
6770 //,["Add to another list...", "Add to another directory..."]
6771
6772 ,["Create Event", "Plan an Adventure"]
6773 ,["Edit Group", "Edit Herd"]
6774 ,["Report Group", "Whine about Herd"]
6775 ,["Leave Group", "Leave Herd"]
6776 ,["Edit Group Settings", "Edit Herd Settings"]
6777 ,["Choose from Group Photos", "Choose from Herd Pony Pics"]
6778 ,["Upload a Photo", "Upload a Pony Pic"]
6779 ,["Remove from Group", "Banish to Moon"]
6780 ,["Share Group", "Share Herd"]
6781 ,["Create Group", "Create Herd"]
6782 ,["Change group settings", "Change herd settings"]
6783 ,["Add People to Group", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])+" to the Herd"]
6784 ,["Send Message", "Send Friendship Report"]
6785 ,["View Group", "View Herd"]
6786 ,["Add People", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])]
6787
6788 ,["Remove App", "Remove Magic"]
6789 ,["Uninstall App", "Uninstall Magic"]
6790 ,["Report App", "Whine about Magic"]
6791 ,["Block App", "Block Magic"]
6792 ,["Find More Apps", "Find More Magic"]
6793 ,["No more apps to add.", "No more magic to add."]
6794
6795 ,["Delete Post And Remove User", "Nuke Post And Banish to Moon"]
6796 ,["Delete Post And Ban User", "Nuke Post And Banish to Moon"]
6797 ,["Hide from Timeline", "Hide from Journal"]
6798 ,["Delete", "Nuke"]
6799 ,["Delete...", "Nuke..."]
6800 ,["Delete Photo", "Nuke Pony Pic..."]
6801 ,["Delete This Photo", "Nuke This Pony Pic"]
6802 ,["Delete Messages...", "Nuke Friendship Reports..."]
6803 ,["Delete Post", "Nuke Post"]
6804 ,["Delete Comment", "Nuke Friendship Letter..."]
6805 ,["Show on Timeline", "Show on Journal"]
6806 ,["Show on Profile", "Show on Journal"]
6807 ,["Shown on Timeline", "Shown on Journal"]
6808 ,["Allow on Timeline", "Allow on Journal"]
6809 ,["Highlighted on Timeline", "Highlighted on Journal"]
6810 ,["Allowed on Timeline", "Allowed on Journal"]
6811 ,["Hidden from Timeline", "Hidden from Journal"]
6812 ,["Remove", "Nuke"]
6813 ,["Delete Photo...", "Nuke Pony Pic..."]
6814 ,["Remove this photo", "Nuke this pony pic"]
6815 ,["Remove photo", "Nuke pony pic"]
6816 ,["Remove...", "Nuke..."]
6817 ,["Delete Conversation...", "Nuke Conversation..."]
6818 ,["Delete Album", "Nuke Album"]
6819 ,["Delete Comment...", "Nuke Friendship Letter..."]
6820 ,["Hide Comment...", "Hide Friendship Letter..."]
6821 ,["Hide Event", "Hide Adventure"]
6822 ,["Hide Comment", "Hide Friendship Letter"]
6823 ,["Delete Post...", "Nuke Post..."]
6824 ,["Delete Video", "Nuke Video"]
6825 ,["Delete Event", "Nuke Adventure"] // for group admin
6826
6827 ,["Report/Block...", "Whine/Block..."]
6828 ,["Report/Mark as Spam", "Whine/Mark as Spam"]
6829 ,["Report Page", "Whine about Page"]
6830 ,["Report Story or Spam", "Whine about Story or Spam"]
6831 ,["Report/Mark as Spam...", "Whine/Mark as Spam..."]
6832 ,["Report story...", "Whine about story..."]
6833 ,["Report as Spam or Abuse...", "Whine as Spam or Abuse..."]
6834 ,["Report Spam or Abuse...", "Whine as Spam or Abuse..."]
6835 ,["Report as Spam...", "Whine as Spam..."]
6836 ,["Report Conversation...", "Whine about Conversation..."]
6837 ,["Report This Photo", "Whine About This Pony Pic"]
6838 ,["Report/Remove Tag", "Whine/Nuke Tag"]
6839 ,["Mark as Spam", "Whine as Spam"]
6840 ,["Report/Remove Tag...", "Whine/Nuke Tag..."]
6841 ,["Report Content", "Whine about Content"]
6842 ,["Report Profile", "Whine about Journal"]
6843 ,["Report User", "Whine about This Pony"]
6844 ,["Report", "Whine"]
6845 ,["Report Place", "Whine about Place"]
6846 ,["Report App", "Whine about Magic"]
6847 //,["Report list", "Whine about directory"]
6848 ,["Report list", "Whine about list"]
6849 ,["Event at a place", "Adventure at a place"]
6850 ,["Report as Abuse", "Whine as Abuse"]
6851 ,["Report to Admin", "Whine to Admin"]
6852
6853 ,["Hide this recent activity story from Timeline", "Hide this recent activity story from Journal"]
6854 ,["Hide Similar Activity from Timeline...", "Hide Similar Activity from Journal..."]
6855 //,["Hide All Recent Lists from Timeline...", "Hide All Recent Directories from Journal..."]
6856 ,["Hide All Recent Lists from Timeline...", "Hide All Recent Lists from Journal..."]
6857 ,["Hide all Friend Highlights from Timeline", "Hide all "+capitaliseFirstLetter(CURRENTSTACK.friend)+" Highlights from Journal"]
6858 ,["Hide This Action from Profile...", "Hide This Action from Journal..."]
6859 ,["Hide All Recent profile changes from Profile...", "Hide All Recent journal changes from Journal..."]
6860 ,["Hide All Recent Pages from Timeline...", "Hide All Recent Pages from Journal..."]
6861 ,["See Photos Hidden From Timeline", "See Pony Pics Hidden From Journal"]
6862 ,["Hide Similar Activity from Timeline", "Hide Similar Activity from Journal"]
6863
6864 ,["Upcoming Events", "Upcoming Adventures"]
6865 ,["Suggested Events", "Suggested Adventures"]
6866 ,["Past Events", "Past Adventures"]
6867 ,["Past events", "Past adventures"]
6868 ,["Declined Events", "Declined Adventures"]
6869 ,["Export Events...", "Export Adventures..."]
6870 ,["Add Event Photo", "Add Adventure Pony Pic"]
6871 ,["Cancel Event", "Cancel Adventure"]
6872 ,["Export Event", "Export Adventure"]
6873 ,["Share Event", "Share Adventure"]
6874 ,["Turn Off Notifications", "Turn Off Sparks"]
6875 ,["Turn On Notifications", "Turn On Sparks"]
6876 ,["Promote Event", "Promote Adventure"]
6877 ,["Create Repeat Event", "Create Repeat Adventure"]
6878 ,["Message Guests", "Start Whinny Chat with Guests"]
6879 ,["Edit Event", "Edit Adventure"]
6880 ,["Publish Event on Timeline", "Publish Adventure on Journal"]
6881 ,["Leave Event", "Leave Adventure"]
6882
6883 ,["Add Friends to Chat...", "Add "+capitaliseFirstLetter(CURRENTSTACK.friends)+" to Whinny Chat..."]
6884 ,["Chat Sounds", "Whinny Chat Sounds"]
6885 ,["Add People...", "Add "+capitaliseFirstLetter(CURRENTSTACK['people'])+"..."]
6886 ,["Unread Messages", "Unread Friendship Reports"]
6887 ,["Archived Messages", "Archived Friendship Reports"]
6888 ,["Sent Messages", "Sent Friendship Reports"]
6889 ,["Forward Messages...", "Forward Friendship Reports..."]
6890 ,["Turn Off Chat", "Turn Off Whinny Chat"]
6891 ,["Open in Chat", "Open in Whinny Chat"]
6892 ,["Create Group...", "Create Herd..."]
6893 ,["Turn On Chat", "Turn On Whinny Chat"]
6894
6895 ,["Add/Remove Friends...", "Add/Remove "+capitaliseFirstLetter(CURRENTSTACK.friends)+"..."]
6896 ,["Comments and Likes", "Friendship Letters and Brohoofs"]
6897 //,["Archive List", "Archive Directory"]
6898 //,["On This List", "On This Directory"]
6899 //,["Restore List", "Restore Directory"]
6900
6901 //,["Rename List", "Rename Directory"]
6902 //,["Edit List", "Edit Directory"]
6903 ,["Notification Settings...", "Spark Settings..."]
6904 //,["Delete List", "Nuke Directory"]
6905 ,["Delete List", "Nuke List"]
6906
6907 ,["Likes", capitaliseFirstLetter(CURRENTSTACK['likes'])]
6908 ,["Photos", "Pony Pics"]
6909 ,["Comments", "Friendship Letters"]
6910 ,["Questions", "Queries"]
6911 ,["Events", "Adventures"]
6912 ,["Groups", "Herds"]
6913 ,["Timeline", "Journal"]
6914 ,["Notes", "Scrolls"]
6915 ,["Posts and Apps", "Posts and Magic"]
6916 ,["Recent Likes", "Recent "+capitaliseFirstLetter(CURRENTSTACK['likes'])]
6917 ,["Recent Comments", "Recent Friendship Letters"]
6918 ,["Timeline Review", "Journal Review"]
6919 ,["Pokes", "Nuzzles"]
6920 ,["Activity Log...", "Adventure Log..."]
6921 ,["Activity Log", "Adventure Log"]
6922 ,["Timeline Settings", "Journal Settings"]
6923 ,["Likers", "Brohoofers"] // @todo likers
6924 ,["Open Groups", "Open Herds"]
6925 ,["Cancel Friend Request", "Cancel Friendship Request"] // activity log
6926
6927 ,["Choose from Photos...", "Choose from Pony Pics..."]
6928 ,["Upload Photo...", "Upload Pony Pic..."]
6929 ,["Take Photo...", "Take Pony Pic..."]
6930 ,["Choose from my Photos", "Choose from my Pony Pics"]
6931 ,["Reposition Photo", "Reposition Pony Pic"]
6932 ,["Add Synced Photo...", "Add Synced Pony Pic..."]
6933 ,["Add Synced Photo", "Add Synced Pony Pic"]
6934 ,["Change Primary Photo...", "Change Primary Pony Pic..."]
6935 ,["Choose from Photo Albums...", "Choose from Pony Pic Albums..."]
6936 ,["Suggest this photo...", "Suggest this pony pic..."]
6937
6938 ,["Photo", "Pony Pic"]
6939 ,["Question", "Query"]
6940
6941 ,["Pages I like", "Pages I "+capitaliseFirstLetter(CURRENTSTACK.like)]
6942 ,["My Friends", "My "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6943 ,["All Notifications", "All Sparks"]
6944 ,["Search All Friends", "Search All "+capitaliseFirstLetter(CURRENTSTACK.friends)]
6945 ,["All Apps", "All Magic"]
6946 ,["Pages my friends like", "Pages my "+CURRENTSTACK['friends']+" "+CURRENTSTACK['like']]
6947
6948 ,["Page Likes", "Page "+capitaliseFirstLetter(CURRENTSTACK.likes)]
6949 ,["Mentions and Photo Tags", "Mentions and Pony Pic Tags"]
6950
6951 ,["Suggest photos", "Suggest pony pics"]
6952
6953 ,["Make Profile Picture", "Make Journal Pony Pic"]
6954 ,["Make Profile Picture for Page", "Make Journal Pony Pic for Page"]
6955 ,["Make Cover Photo", "Make Cover Pony Pic"]
6956
6957 ,["The app sends you a notification", "The magic sends you a spark"]
6958
6959 ,["Top Comments", "Top Friendship Letters"] // comment resort
6960 ,["See All Groups", "See All Herds"] // timeline
6961 ,["Friends to Invite", capitaliseFirstLetter(CURRENTSTACK['friends'])+" to Invite"] // app invite
6962 ,["Take a survey to improve News Feed", "Take a survey to improve Feed Bag"] // news feed
6963
6964 // insights
6965 ,["Post Clicks / Likes, Comments & Shares", "Post Clicks / "+capitaliseFirstLetter(CURRENTSTACK['likes'])+", Comments & Shares"]
6966 ,["Likes / Comments / Shares", capitaliseFirstLetter(CURRENTSTACK['likes'])+" / Comments / Shares"]
6967 ,["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
6968 ,["Likes, Comments & Shares", capitaliseFirstLetter(CURRENTSTACK['likes'])+", Comments & Shares"]
6969 ];
6970
6971 menuPrivacyOnlyTitles = [
6972 ["Everyone", "Everypony"]
6973 ,["Public", "Everypony"]
6974 ,["Anyone", "Anypony"]
6975 ,["Friends of Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of "+capitaliseFirstLetter(CURRENTSTACK['friends'])]
6976 ,["Friends except Acquaintances", capitaliseFirstLetter(CURRENTSTACK['friends'])+" except Acquaintances"]
6977 ,["Friends", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6978 ,["Friends ", capitaliseFirstLetter(CURRENTSTACK['friends'])]
6979 ,["Friends of Guests", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Guests"]
6980 ,["Friends of Contributors", capitaliseFirstLetter(CURRENTSTACK['friends'])+" of Contributors"]
6981 ,["Only Me", "Alone"]
6982 ,["Only me", "Alone"]
6983 //,["See all lists...", "See entire directory..."]
6984 ];
6985
6986 dialogDerpTitles = [
6987 "Insufficient send permissions"
6988 ,"Update Failed"
6989 ,"Failed to upload photo."
6990 ,"Hide Photo Failed"
6991 ,"Undo Mark Spam Failed"
6992 ,"Your Request Couldn't be Processed"
6993 ,"Sorry! The blocking system is overloaded"
6994 ,"Invalid Request"
6995 ,"Block! You are engaging in behavior that may be considered annoying or abusive by other users."
6996 ,"Already connected."
6997 ,"Cannot connect."
6998 ,"Database Down"
6999 ,"Failure to hide minifeed story."
7000 ,"Object cannot be liked"
7001 ,"Sorry, something went wrong"
7002 ,"Authentication Failure"
7003 ,"Unknown error"
7004 ,"Not Logged In"
7005 ,"No Permission to Add Comment or Trying to Comment on Deleted Post"
7006 ,"Could not determine coordinates of place"
7007 ,"Sorry, your account is temporarily unavailable."
7008 ,"Don't Have Permission"
7009 ,"Oops"
7010 ,"No Languages Provided ForUpdate"
7011 ,"Comment Does Not Exist"
7012 ,"Sorry, we got confused"
7013 ,"Database Write Failed"
7014 ,"Editing Bookmarks Failed"
7015 ,"Required Field Missing"
7016 ,"Could Not Load Story"
7017 ,"Invalid Name"
7018 ,"Cannot connect to yourself."
7019 ,"This content is no longer available"
7020 ,"Error" // poking someone who hasn't poked back yet
7021 ,"Please Try Again Later"
7022 ,"Submitting Documentation Feedback Failed"
7023 ,"Bad Request"
7024 ,"Internal Error"
7025 ,"Mark as Spam Failed"
7026 ,"Could not post to Wall"
7027 ,"No permissions"
7028 ,"Messages Unavailable"
7029 ,"Don't have Permission"
7030 ,"No file specified."
7031 ,"Storage Failure"
7032 ,"Invalid Date"
7033 ,"Vote submission failed."
7034 ,"Web Address is Invalid"
7035 ,"Oops!"
7036 ,"Invalid Recipients"
7037 ,"Add Fan Status Failed"
7038 ,"Adding Member Failed"
7039 ,"Post Has Been Removed"
7040 ,"Unable to edit Group"
7041 ,"Invalid Photo Selected"
7042 ,"Cannot backdate photo"
7043 ,"Invalid Search Query"
7044 ,"Unable to Add Friend"
7045 ,"Cannot Add Member"
7046 ,"Bad Image"
7047 ,"Missing Field"
7048 ,"Invalid Custom Privacy Setting"
7049 ,"Empty Friend List"
7050 ,"Unable to Add Attachment"
7051 ,"Unable to Change Date"
7052 ,"Invalid Whining"
7053 ,"Your Page Can't Be Promoted"
7054 ,"Cannot Send Gift"
7055 ,"An error occurred."
7056 ,"Image Resource Invalid"
7057 ,"Confirmation Required"
7058 ,"Error Uploading Video"
7059 ,"Upload Failed"
7060 ,"Photo Upload Failed"
7061 ,"Sticker Failed"
7062 ];
7063
7064 headerInsightsTitles = [
7065 ["People Who Like Your Page (Demographics and Location)", capitaliseFirstLetter(CURRENTSTACK.people)+" Who "+capitaliseFirstLetter(CURRENTSTACK.like)+" Your Page (Demographics and Location)"]
7066 ,["Where Your Likes Came From", "Where Your "+capitaliseFirstLetter(CURRENTSTACK.likes)+" Came From"]
7067 ,["How You Reached People (Reach and Frequency)", "How You Reached "+capitaliseFirstLetter(CURRENTSTACK.people)+" (Reach and Frequency)"]
7068 ,["How People Are Talking About Your Page", "How "+capitaliseFirstLetter(CURRENTSTACK.people)+" Are Talking About Your Page"]
7069 ];
7070
7071 dialogDescriptionTitles = [
7072 ["Are you sure you want to delete this?", "Are you sure you want to nuke this?"]
7073 ,["Are you sure you want to delete this video?", "Are you sure you want to nuke this video?"]
7074 ,["Are you sure you want to delete this photo?", "Are you sure you want to nuke this pony pic?"]
7075 ,["Are you sure you want to delete this comment?", "Are you sure you want to nuke this friendship letter?"]
7076 ,["Are you sure you want to delete this event?", "Are you sure you want to nuke this adventure?"]
7077 ,["Are you sure you want to delete this post?", "Are you sure you want to nuke this post?"]
7078 ,["Are you sure you want to remove this picture?", "Are you sure you want to nuke this pony pic?"]
7079 ,["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."]
7080 ,["Are you sure you want to remove this event?", "Are you sure you want to nuke this adventure?"]
7081 ,["Are you sure you want to unlike this?", "Are you sure you want to "+CURRENTSTACK['unlike']+" this?"]
7082 ,["Are you sure you want to remove this profile picture?", "Are you sure you want to nuke this journal pony pic?"]
7083
7084 ,["Report this if it's not relevant to your search results.", "Whine about this if it's not relevant to your search results."]
7085
7086 ,["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?"]
7087 ,["This post has been reported to the group admin.", "This post has been whined to the group admin."]
7088
7089 ,["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."]
7090 ,["You have not uploaded a picture.", "You have not uploaded a pony pic."]
7091 ,["Please try again. Make sure you are uploading a valid photo.", "Please try again. Make sure you are uploading a valid pony pic."]
7092 ,["There was a problem uploading the image file.", "There was a problem uploading the pony pic file."]
7093 ,["If you leave this page, your message won't be sent.", "If you leave this page, your friendship report won't be sent."]
7094 ];
7095 }
7096
7097 var DOMNodeInserted = function(dom) {
7098 domNodeHandlerMain.run(dom);
7099 };
7100
7101 var domNodeHandler = function() {
7102 var k = this;
7103 k.snowliftPinkieInjected = false;
7104
7105 k.run = function(dom) {
7106 if (INTERNALUPDATE) {
7107 return;
7108 }
7109
7110 if (k.shouldIgnore(dom)) {
7111 return;
7112 }
7113
7114 k.dumpConsole(dom);
7115
7116 // Start internal update
7117 var iu = INTERNALUPDATE;
7118 INTERNALUPDATE = true;
7119
7120 // Buttons
7121 if (dom.target.parentNode && dom.target.parentNode.parentNode) {
7122 var stop = true;
7123 var replacer = buttonTitles;
7124 if (hasClass(dom.target.parentNode, 'uiButtonText')) {
7125 var buttonText = dom.target.parentNode;
7126 var button = dom.target.parentNode.parentNode;
7127 stop = false;
7128
7129 if (button.parentNode && button.parentNode.parentNode && hasClass(button.parentNode.parentNode, 'audienceSelector')) {
7130 replacer = menuPrivacyOnlyTitles;
7131 }
7132 } else if (hasClass(dom.target.parentNode, '_42ft') || hasClass(dom.target.parentNode, '-cx-PRIVATE-abstractButton__root')) {
7133 // dropdown on close friends list dialog
7134 // <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>
7135 var buttonText = dom.target;
7136 var button = dom.target.parentNode;
7137 stop = false;
7138 } else if (hasClass(dom.target.parentNode.parentNode, '_42ft') || hasClass(dom.target.parentNode.parentNode, '-cx-PRIVATE-abstractButton__root')) {
7139 // hasClass(buttonText, '_55pe') || hasClass(buttonText, '-cx-PUBLIC-abstractPopoverButton__label')
7140 // "share to" dropdown on sharer dialog
7141 // comment resort on entstream
7142 var buttonText = dom.target;
7143 var button = dom.target.parentNode.parentNode;
7144 stop = false;
7145 }
7146
7147 if (!stop) {
7148 if (buttonText.nodeType == 3) {
7149 var orig = buttonText.textContent;
7150 } else {
7151 var orig = buttonText.innerHTML;
7152 }
7153 var replaced = replaceText(replacer, orig);
7154 if (hasClass(button, 'uiButton') || hasClass(button, '_42ft') || hasClass(button, '-cx-PRIVATE-abstractButton__root')) {
7155 // button text that didn't get ponified needs to be considered, e.g. share dialog's "On your Page"
7156 if (button.getAttribute('data-hover') != 'tooltip') {
7157 if (orig != replaced) {
7158 // ponified text
7159 if (button.title == '') {
7160 // tooltip is blank, so it would be OK to set our own
7161 button.title = orig;
7162 } else {
7163 // tooltip is NOT blank, this means (1) FB added their own tooltip or (2) we already added our own tooltip
7164 if (button.title == button.getAttribute('data-ponyhoof-button-orig')) {
7165 button.title = orig;
7166 }
7167 }
7168 } else {
7169 button.title = '';
7170 }
7171 }
7172 button.setAttribute('data-ponyhoof-button-orig', orig);
7173 button.setAttribute('data-ponyhoof-button-text', replaced);
7174 }
7175 if (orig != replaced) {
7176 if (buttonText.nodeType == 3) {
7177 buttonText.textContent = replaced;
7178 } else {
7179 buttonText.innerHTML = replaced;
7180 }
7181 }
7182 }
7183 }
7184
7185 // Text nodes
7186 if (dom.target.nodeType == 3) {
7187 //k.textNodes(dom);
7188 // firefox in mutationObserver goes to here when it should be characterData
7189 k.mutateCharacterData(dom);
7190 INTERNALUPDATE = iu;
7191 return;
7192 }
7193
7194 injectOptionsLink();
7195
7196 k.snowliftPinkie(dom);
7197 k.notificationsFlyoutSettings();
7198 k.findFriendsNav();
7199
7200 // .ufb-button-input => mutateAttributes
7201 // ._42fu, .-cx-PRIVATE-uiButton__root, ._4jy0, .-cx-PRIVATE-xuiButton__root
7202 domReplaceFunc(dom.target, '', '.uiButtonText, .uiButton input, ._42ft, .-cx-PRIVATE-abstractButton__root', function(ele) {
7203 // <a class="uiButton uiButtonConfirm uiButtonLarge" href="#" role="button"><span class="uiButtonText">Finish</span></a>
7204 // <label class="uiButton uiButtonConfirm"><input value="Okay" type="submit"></label>
7205
7206 // <button class="_42ft _42fu _11b selected _42g-" type="submit">Post</button>
7207 // <a class="_42ft _42fu" role="button" href="#"><i class="mrs img sp_8jfoef sx_d2d7c4"></i>Promote App</a>
7208
7209 // Skip close icons
7210 if (hasClass(ele, '_50zy') || hasClass(ele, '-cx-PRIVATE-xuiCloseButton__root')) {
7211 return;
7212 }
7213
7214 var button = ele;
7215 var replacer = buttonTitles;
7216 var tagName = ele.tagName.toUpperCase();
7217 if (tagName != 'A' && tagName != 'LABEL' && tagName != 'BUTTON') {
7218 button = ele.parentNode;
7219
7220 // new message
7221 var potentialLabel = button.querySelector('._6q-, .-cx-PUBLIC-mercuryComposer__button');
7222 if (potentialLabel) {
7223 ele = potentialLabel;
7224 }
7225 } else {
7226 var potentialLabel = button.querySelector('._55pe, .-cx-PUBLIC-abstractPopoverButton__label');
7227 if (potentialLabel) {
7228 ele = potentialLabel;
7229 } else {
7230 // Get More Likes button on page admin panel
7231 // <button value="1" class="_42ft _42fu selected _42g- _42gy" id="fanAcquisitionPanelPreviewBodyConfirmButton" type="submit"><span id="u_x_a">Get More Likes</span></button>
7232 }
7233 // Get More Likes (above)
7234 // comment resort on entstream
7235 if (ele.childNodes && ele.childNodes.length == 1 && ele.childNodes[0].tagName && ele.childNodes[0].tagName.toUpperCase() == 'SPAN') {
7236 ele = ele.childNodes[0];
7237 }
7238 }
7239 if (button &&
7240 (button.getAttribute('data-ponyhoof-button-orig') == null || (hasClass(button, '_for') || hasClass(button, '-cx-PRIVATE-fbVaultBadgedButton__button'))) && // vault buttons are crapped
7241 (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')*/)
7242 ) {
7243 if (button.parentNode && button.parentNode.parentNode && hasClass(button.parentNode.parentNode, 'audienceSelector')) {
7244 replacer = menuPrivacyOnlyTitles;
7245 }
7246
7247 if (tagName == 'INPUT') {
7248 var orig = ele.value;
7249 button.setAttribute('data-ponyhoof-button-orig', orig);
7250 var replaced = replaceText(replacer, orig);
7251
7252 k.changeButtonText(ele, replaced);
7253 } else {
7254 var orig = '';
7255 var replaced = '';
7256 loopChildText(ele, function(child) {
7257 if (child.nodeType == 3) {
7258 orig += child.textContent;
7259 replaced += replaceText(replacer, child.textContent);
7260 if (child.textContent != replaced) {
7261 child.textContent = replaced;
7262 }
7263 }
7264 });
7265 button.setAttribute('data-ponyhoof-button-orig', orig);
7266 }
7267
7268 if (orig != replaced) {
7269 if (button.getAttribute('data-hover') != 'tooltip') {
7270 if (button.title == '') {
7271 button.title = orig;
7272 }
7273 }
7274 }
7275 button.setAttribute('data-ponyhoof-button-text', replaced);
7276
7277 // Top-right "Join Group" and "Notifications" link on groups requires some treatment to avoid long group names from being crapped
7278 var ajaxify = button.getAttribute('ajaxify');
7279 if ((ajaxify && ajaxify.indexOf('/ajax/groups/membership/r2j.php?ref=group_jump_header') == 0) || (button.parentNode && button.parentNode.parentNode && hasClass(button.parentNode.parentNode, 'groupNotificationsSelector'))) {
7280 var groupsJumpTitle = $('groupsJumpTitle');
7281 if (!groupsJumpTitle) {
7282 return;
7283 }
7284
7285 var groupsJumpBarTop = dom.target.getElementsByClassName('groupsJumpBarTop');
7286 if (!groupsJumpBarTop.length) {
7287 return;
7288 }
7289 groupsJumpBarTop = groupsJumpBarTop[0];
7290
7291 var rfloat = groupsJumpBarTop.getElementsByClassName('rfloat');
7292 if (!rfloat.length) {
7293 return;
7294 }
7295 rfloat = rfloat[0];
7296
7297 var groupsCleanLinks = groupsJumpBarTop.getElementsByClassName('groupsCleanLinks');
7298 if (!groupsCleanLinks.length) {
7299 return;
7300 }
7301 groupsCleanLinks = groupsCleanLinks[0];
7302
7303 groupsJumpTitle.style.maxWidth = (800 - ((groupsCleanLinks.offsetWidth || 0) + (rfloat.offsetWidth || 0) - (groupsJumpTitle.offsetWidth || 0)) - 10) + 'px';
7304 }
7305 }
7306
7307 });
7308
7309 k.ufiPagerLink(dom);
7310
7311 if (k.reactRoot(dom)) {
7312 INTERNALUPDATE = iu;
7313 return;
7314 }
7315
7316 k.postLike(dom);
7317
7318 if (k.ticker(dom)) {
7319 INTERNALUPDATE = iu;
7320 return;
7321 }
7322
7323 if (k.pagesVoiceBarText(dom.target)) {
7324 INTERNALUPDATE = iu;
7325 return;
7326 }
7327
7328 if (k.endOfFeedPymlContainer(dom.target)) {
7329 INTERNALUPDATE = iu;
7330 return;
7331 }
7332
7333 if (k.pubcontentFeedChaining(dom.target)) {
7334 INTERNALUPDATE = iu;
7335 return;
7336 }
7337
7338 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', k.textBrohoof);
7339
7340 domReplaceFunc(dom.target, '', '.uiUfiViewAll, .uiUfiViewPrevious, .uiUfiViewMore', function(ele) {
7341 var button = ele.querySelector('input[type="submit"]');
7342 var t = button.value;
7343 t = t.replace(/comments/g, "friendship letters");
7344 t = t.replace(/comment/g, "friendship letter");
7345 if (button.value != t) {
7346 button.value = t;
7347 }
7348 });
7349
7350 k.tooltip(dom.target);
7351
7352 domReplaceFunc(dom.target, 'egoProfileTemplate', '.egoProfileTemplate', function(ele) {
7353 if (ele.getAttribute('data-ponyhoof-ponified')) {
7354 return;
7355 }
7356 var div = ele.getElementsByTagName('div');
7357 if (div.length) {
7358 for (var i = 0, len = div.length; i < len; i += 1) {
7359 var t = div[i].innerHTML;
7360 t = k.textStandard(t);
7361 if (div[i].innerHTML != t) {
7362 div[i].innerHTML = t;
7363 }
7364 }
7365 }
7366
7367 var action = ele.getElementsByClassName('uiIconText');
7368 if (action.length) {
7369 action = action[0];
7370 ele.setAttribute('data-ponyhoof-iconText', action.textContent);
7371
7372 var t = action.innerHTML;
7373 t = t.replace(/Like/g, capitaliseFirstLetter(CURRENTSTACK.like));
7374 t = t.replace(/Join Group/g, "Join the Herd");
7375 t = t.replace(/Add Friend/g, "Add "+capitaliseFirstLetter(CURRENTSTACK.friend));
7376 t = t.replace(/\bConfirm Friend\b/g, "Confirm Friendship");
7377 action.innerHTML = t;
7378 }
7379
7380 ele.setAttribute('data-ponyhoof-ponified', 1);
7381 });
7382
7383 domReplaceFunc(dom.target, 'uiInterstitial', '.uiInterstitial', function(ele) {
7384 if (ele.getAttribute('data-ponyhoof-ponified')) {
7385 return;
7386 }
7387 ele.setAttribute('data-ponyhoof-ponified', 1);
7388
7389 var title = ele.getElementsByClassName('uiHeaderTitle');
7390 if (title.length) {
7391 title = title[0];
7392 } else {
7393 title = ele.querySelector('.fsxl.fwb');
7394 if (!title) {
7395 return;
7396 }
7397 }
7398 ele.setAttribute('data-ponyhoof-inters-title', title.textContent);
7399 });
7400
7401 domReplaceFunc(dom.target, 'uiLayer', '.uiLayer', function(ele) {
7402 if (ele.getAttribute('data-ponyhoof-dialog-title')) {
7403 return;
7404 }
7405
7406 var titlebar = ele.querySelector('.-cx-PUBLIC-uiDialog__title, ._t ._1yw, ._4-i0, .-cx-PRIVATE-xuiDialog__title, .overlayTitle, .fbCalendarOverlayHeader');
7407 if (titlebar) {
7408 var titletext = ele.querySelector('._52c9, .-cx-PRIVATE-xuiDialog__titletext');
7409 if (!titletext) {
7410 titletext = titlebar;
7411 }
7412
7413 var orig = '';
7414 var replaced = '';
7415 loopChildText(titletext, function(child) {
7416 if (child.nodeType == 3) {
7417 orig += child.textContent;
7418 replaced += replaceText(dialogTitles, child.textContent);
7419 if (child.textContent != replaced) {
7420 child.textContent = replaced;
7421 }
7422 }
7423 });
7424 addClass(titlebar, 'ponyhoof_fbdialog_title');
7425 if (orig != replaced) {
7426 titlebar.title = orig;
7427 }
7428
7429 addClass(ele, 'ponyhoof_fbdialog');
7430 ele.setAttribute('data-ponyhoof-dialog-title', replaced);
7431 ele.setAttribute('data-ponyhoof-dialog-orig', orig);
7432
7433 var body = ele.querySelector('._t ._13, .-cx-PRIVATE-uiDialog__body, ._4-i2, .-cx-PRIVATE-xuiDialog__body, .uiLayerPageContent > .pvm');
7434 if (body) {
7435 addClass(body, 'ponyhoof_fbdialog_body');
7436
7437 var stop = false;
7438 loopChildText(body, function(child) {
7439 if (stop) {
7440 return;
7441 }
7442 if (child.nodeType == TEXT_NODE) {
7443 var replaced = replaceText(dialogDescriptionTitles, child.textContent);
7444 if (child.textContent != replaced) {
7445 child.textContent = replaced;
7446 stop = true;
7447 }
7448 }
7449 });
7450
7451 k._dialog_insertReadme(body);
7452 }
7453
7454 if (hasClass(dom.target, 'uiLayer')) {
7455 // dom.target is intentional
7456 // Detect rare cases when HTML detection just got turned on, and there is a dialog at the back
7457 k._dialog_playSound(replaced, ele);
7458 }
7459
7460 if (USINGMUTATION) {
7461 k.updateLayerPosition(ele);
7462 }
7463 }
7464
7465 domChangeTextbox(ele, '._5nw-, .groupsMemberFlyoutWelcomeTextarea', function(textbox) {
7466 var orig = textbox.getAttribute('placeholder');
7467 var t = orig.replace(/\bgroup\b/, 'herd');
7468 if (t != orig) {
7469 return t;
7470 }
7471 return "Welcome him/her to the herd...";
7472 });
7473 domChangeTextbox(ele, '.fbEventMemberComment', function(textbox) {
7474 var orig = textbox.getAttribute('placeholder');
7475 var t = orig.replace(/\bevent\b/, 'adventure');
7476 if (t != orig) {
7477 return t;
7478 }
7479 return orig; // for pages "Write something to let her know you're going too."
7480 });
7481
7482 // Hovercard
7483 $$(ele, '._7lo > .fcg, .-cx-PRIVATE-hovercard__footer > .fcg', function(footer) {
7484 loopChildText(footer, k.textBrohoof);
7485 });
7486 });
7487
7488 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) {
7489 if (CURRENTSTACK.stack == 'pony') {
7490 ele.setAttribute('data-hover', 'tooltip');
7491 ele.setAttribute('aria-label', CURRENTLANG.fb_share_tooltip);
7492 ele.setAttribute('title', '');
7493 }
7494 });
7495
7496 domReplaceFunc(dom.target, '', '.uiHeaderTitle, .legacyContextualDialogTitle, ._6dp, .-cx-PRIVATE-litestandRHC__titlename, ._34e', function(ele) {
7497 var imgwrap = ele.querySelector('._8m, .-cx-PRIVATE-uiImageBlock__content, .adsCategoryTitleLink');
7498 if (imgwrap) {
7499 ele = imgwrap;
7500 };
7501
7502 loopChildText(ele, function(child) {
7503 if (!child.children || !child.children.length) {
7504 var t = replaceText(headerTitles, child.textContent);
7505 if (child.textContent != t) {
7506 child.textContent = t;
7507 }
7508 }
7509 });
7510 });
7511
7512 /*domReplaceFunc(dom.target, '', '.insights-header .header-title > .ufb-text-content', function(ele) {
7513 var t = replaceText(headerInsightsTitles, ele.textContent);
7514 if (ele.textContent != t) {
7515 ele.textContent = t;
7516 }
7517 });*/
7518
7519 if (k.fbDockChatBuddylistNub(dom.target)) {
7520 INTERNALUPDATE = iu;
7521 return;
7522 }
7523
7524 if (k.pokesDashboard(dom.target)) {
7525 INTERNALUPDATE = iu;
7526 return;
7527 }
7528
7529 k.commentBrohoofed(dom);
7530
7531 k.changeCommentBox(dom);
7532 k.changeComposer(dom);
7533
7534 k.notification(dom);
7535 k.menuItems(dom);
7536 k.fbRemindersStory(dom.target);
7537 if (k.flyoutLikeForm(dom.target)) {
7538 INTERNALUPDATE = iu;
7539 return;
7540 }
7541 k.pluginButton(dom.target);
7542 //k.insightsCountry(dom.target);
7543 k.timelineMutualLikes(dom.target);
7544 k.videoStageContainer(dom.target);
7545 k.uiStreamShareLikePageBox(dom.target);
7546 k.fbTimelineUnit(dom.target);
7547 k.pageBrowserItem(dom.target);
7548
7549 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...");
7550 domChangeTextbox(dom.target, '.groupAddMemberTypeaheadBox .inputtext', "Add "+capitaliseFirstLetter(CURRENTSTACK.friends)+" to the Herd");
7551 //domChangeTextbox(dom.target, '.friendListAddTypeahead .inputtext', "Add "+CURRENTSTACK.friends+" to this directory");
7552 domChangeTextbox(dom.target, '.friendListFeed .friendListAddTypeahead .inputtext', "Add "+CURRENTSTACK['friends']+" to this list");
7553 domChangeTextbox(dom.target, '.groupsJumpHeaderSearch .inputtext', "Search this herd");
7554 domChangeTextbox(dom.target, '.MessagingSearchFilter .inputtext', "Search Friendship Reports");
7555 domChangeTextbox(dom.target, '#chatFriendsOnline .fbChatTypeahead .inputtext', "Pals on Whinny Chat");
7556
7557 //domChangeTextbox(dom.target, '.uiComposer textarea', "What lessons in friendship have you learned today?");
7558 //domChangeTextbox(dom.target, '.uiComposerMessageBox textarea', "Share your friendship stories...");
7559 //domChangeTextbox(dom.target, '.uiMetaComposerMessageBox textarea', "What lessons in friendship have you learned today?");
7560 domChangeTextbox(dom.target, '#q, ._585- ._586f, .-cx-PUBLIC-fbFacebar__root .-cx-PUBLIC-uiStructuredInput__text', function(searchbox) {
7561 if (CURRENTLANG.sniff_fb_search_boxAlt && searchbox.getAttribute('placeholder').indexOf(CURRENTLANG.sniff_fb_search_boxAlt) != -1) {
7562 return CURRENTLANG.fb_search_boxAlt;
7563 }
7564 return CURRENTLANG.fb_search_box;
7565 });
7566
7567 k.ponyhoofPageOptions(dom);
7568 if (userSettings.debug_betaFacebookLinks && w.location.hostname == 'beta.facebook.com') {
7569 k.debug_betaFacebookLinks(dom.target);
7570 }
7571
7572 INTERNALUPDATE = iu;
7573 };
7574
7575 k.photos_snowlift = null;
7576 k.snowliftPinkie = function(dom) {
7577 if (!k.snowliftPinkieInjected) {
7578 var id = dom.target.getAttribute('id');
7579 if ((id && id == 'photos_snowlift') || hasClass(dom.target, 'fbPhotoSnowlift')) {
7580 k.snowliftPinkieInjected = true;
7581 k.photos_snowlift = dom.target;
7582
7583 addClass(k.photos_snowlift, 'ponyhoof_snowlift_haspinkiediv');
7584 var n = d.createElement('div');
7585 n.id = 'ponyhoof_snowlift_pinkie';
7586 k.photos_snowlift.appendChild(n);
7587 }
7588 }
7589 };
7590
7591 k.notificationsFlyoutSettingsInjected = false;
7592 k.notificationsFlyoutSettings = function() {
7593 if (ISUSINGPAGE) {
7594 k.notificationsFlyoutSettingsInjected = true;
7595 return;
7596 }
7597 if (!k.notificationsFlyoutSettingsInjected) {
7598 var jewel = $('fbNotificationsJewel');
7599 if (jewel) {
7600 var header = jewel.getElementsByClassName('uiHeaderTop');
7601 if (!header.length || !header[0].childNodes || !header[0].childNodes.length) {
7602 return;
7603 }
7604 header = header[0];
7605
7606 var settingsLink = d.createElement('a');
7607 settingsLink.href = '#';
7608 settingsLink.textContent = 'Ponyhoof Sounds';
7609
7610 var actions = jewel.getElementsByClassName('uiHeaderActions');
7611 if (actions.length) {
7612 actions = actions[0];
7613 var span = d.createElement('span');
7614 span.innerHTML = ' &middot; ';
7615
7616 actions.appendChild(span);
7617 actions.appendChild(settingsLink);
7618 } else {
7619 var rfloat = d.createElement('div');
7620 rfloat.className = 'rfloat';
7621 rfloat.appendChild(settingsLink);
7622 header.insertBefore(rfloat, header.childNodes[0]);
7623 }
7624
7625 settingsLink.addEventListener('click', function(e) {
7626 e.preventDefault();
7627
7628 if (!optionsGlobal) {
7629 optionsGlobal = new Options();
7630 }
7631 optionsGlobal.create();
7632 optionsGlobal.switchTab('sounds');
7633 optionsGlobal.show();
7634
7635 try {
7636 clickLink(jewel.getElementsByClassName('jewelButton')[0]);
7637 } catch (e) {}
7638 }, false);
7639
7640 k.notificationsFlyoutSettingsInjected = true;
7641 }
7642 }
7643 };
7644
7645 // Change Find Friends link at the top-right to native text for reliability
7646 k.findFriendsNavInjected = false;
7647 k.findFriendsNav = function() {
7648 if (k.findFriendsNavInjected || ISUSINGPAGE || ISUSINGBUSINESS) {
7649 k.findFriendsNavInjected = true;
7650 return;
7651 }
7652 var findFriendsNav = $('findFriendsNav');
7653 if (!findFriendsNav || !findFriendsNav.childNodes || !findFriendsNav.childNodes.length) {
7654 return;
7655 }
7656 var text = findFriendsNav.childNodes[0]; // this should return the "Find Friends" node
7657 if (text.nodeType != TEXT_NODE) {
7658 text = findFriendsNav.childNodes[1]; // litestand
7659 if (text.nodeType != TEXT_NODE) {
7660 return;
7661 }
7662 }
7663
7664 text.textContent = CURRENTSTACK['findFriendship'];
7665 addClass(findFriendsNav, 'ponyhoof_findFriendsNav_native');
7666 k.findFriendsNavInjected = true;
7667 };
7668
7669 k.textNodes = function(dom) {
7670 try {
7671 if (!dom.target.parentNode || !dom.target.parentNode.parentNode || !hasClass(dom.target.parentNode.parentNode, 'dialog_title')) {
7672 return false;
7673 }
7674
7675 var title = dom.target.parentNode.parentNode;
7676 var orig = dom.target.textContent;
7677 var replaced = replaceText(dialogTitles, orig);
7678
7679 if (dom.target.textContent != replaced) {
7680 dom.target.textContent = replaced;
7681 }
7682 addClass(title, 'ponyhoof_fbdialog_title');
7683 if (orig != replaced) {
7684 title.title = orig;
7685 }
7686
7687 k.getParent(title, function(ele) {
7688 return hasClass(ele, 'generic_dialog');
7689 }, function(ele) {
7690 if (hasClass(ele, 'fbQuestionsPopup')) {
7691 return;
7692 }
7693
7694 addClass(ele, 'ponyhoof_fbdialog');
7695 ele.setAttribute('data-ponyhoof-dialog-title', replaced);
7696 ele.setAttribute('data-ponyhoof-dialog-orig', orig);
7697
7698 var body = ele.getElementsByClassName('dialog_body');
7699 if (body.length) {
7700 body = body[0];
7701 addClass(body, 'ponyhoof_fbdialog_body');
7702
7703 var confirmation_message = body.getElementsByClassName('confirmation_message');
7704 if (confirmation_message.length) {
7705 confirmation_message = confirmation_message[0];
7706
7707 var stop = false;
7708 loopChildText(confirmation_message, function(child) {
7709 if (stop) {
7710 return;
7711 }
7712 if (child.nodeType == TEXT_NODE) {
7713 var replaced = replaceText(dialogDescriptionTitles, child.textContent);
7714 if (child.textContent != replaced) {
7715 child.textContent = replaced;
7716 stop = true;
7717 }
7718 }
7719 });
7720 } else {
7721 var video_dialog_text = body.getElementsByClassName('video_dialog_text');
7722 if (video_dialog_text.length) {
7723 video_dialog_text = video_dialog_text[0];
7724 if (video_dialog_text.childNodes.length == 3) {
7725 var i = 0;
7726 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?"];
7727 loopChildText(video_dialog_text, function(child) {
7728 if (!texts[i]) {
7729 return;
7730 }
7731 child.textContent = texts[i];
7732 i += 1;
7733 });
7734 }
7735 } else {
7736 var stop = false;
7737 loopChildText(body, function(child) {
7738 if (stop) {
7739 return;
7740 }
7741 if (child.nodeType === TEXT_NODE) {
7742 var orig = child.textContent;
7743 var replaced = replaceText(dialogDescriptionTitles, orig);
7744 if (orig != replaced) {
7745 child.textContent = replaced;
7746 stop = true;
7747 }
7748 }
7749 });
7750 }
7751 }
7752 }
7753
7754 k._dialog_playSound(replaced, ele);
7755 });
7756
7757 return true;
7758 } catch (e) {}
7759
7760 return false;
7761 };
7762
7763 k.ufiPagerLink = function(dom) {
7764 domReplaceFunc(dom.target, '', '.UFIPagerLink', function(ele) {
7765 var t = ele.innerHTML;
7766 t = t.replace(/ comments/, " friendship letters");
7767 t = t.replace(/ comment/, " friendship letter");
7768 if (ele.innerHTML != t) {
7769 ele.innerHTML = t;
7770 }
7771 });
7772 };
7773
7774 k.postLike = function(dom) {
7775 if (hasClass(dom.target, 'uiUfiLike') || hasClass(dom.target, 'UFILikeSentence')) {
7776 k._likePostBox(dom.target);
7777 } else {
7778 /*if (dom.target.parentNode) {
7779 if (hasClass(dom.target.parentNode, 'UFILikeSentence')) {
7780 k._likePostBox(dom.target);
7781 return;
7782 }
7783 }*/
7784 domReplaceFunc(dom.target, '', '.uiUfiLike, .UFILikeSentence', k._likePostBox);
7785 }
7786 };
7787
7788 k._likePostBox = function(ele) {
7789 //var inner = ele.querySelector('._42ef, .-cx-PRIVATE-uiFlexibleBlock__flexiblecontent, .lfloat > span, .-cx-PRIVATE-uiImageBlockDeprecated__content, .-cx-PRIVATE-uiImageBlock__content, ._8m, .-cx-PRIVATE-uiFlexibleBlock__flexibleContent');
7790 //if (inner) {
7791
7792 var inner = ele.getElementsByClassName('UFILikeSentenceText');
7793 if (inner.length) {
7794 inner = inner[0];
7795 k._likePostBox_loop(inner);
7796 }
7797
7798 var reorder = ele.getElementsByClassName('UFIOrderingModeSelectorDownCaret');
7799 if (reorder.length) {
7800 reorder = reorder[0];
7801 if (reorder.previousSibling) {
7802 k.UFIOrderingMode(reorder.previousSibling);
7803 }
7804 }
7805 };
7806
7807 k._likePostBox_loop = function(ele) {
7808 // Change "**profile people test** likes this." -> "**profile people test** brohoofs this."
7809 // Previous versions would change it to "**profile ponies test** brohoofs this."
7810 for (var i = 0, len = ele.childNodes.length; i < len; i += 1) {
7811 if (ele.childNodes[i].nodeType === TEXT_NODE) {
7812 k._likePostBox_loop_text(ele.childNodes[i]);
7813 } else {
7814 /*var ajaxify = ele.childNodes[i].getAttribute('ajaxify');
7815 if (ajaxify && ajaxify.indexOf('/ajax/browser/dialog/likes') != -1) {
7816 k._likePostBox_loop_text(ele.childNodes[i]);
7817 } else {*/
7818 if (!hasClass(ele.childNodes[i], 'profileLink')) {
7819 k._likePostBox_loop(ele.childNodes[i]);
7820 }
7821 }
7822 }
7823 };
7824
7825 k._likePostBox_loop_text = function(ele) {
7826 var orig = ele.textContent;
7827 var t = k.likeSentence(orig);
7828 if (orig != t) {
7829 ele.textContent = t;
7830 }
7831 };
7832
7833 k.likeSentence = function(t) {
7834 //t = t.replace(/likes? this\./g, "brohoof'd this.");
7835 t = t.replace(/like this\./g, CURRENTSTACK['like_past']+" this.");
7836 t = t.replace(/likes this\./g, CURRENTSTACK['likes_past']+" this.");
7837 t = t.replace(/\bpeople\b/g, CURRENTSTACK['people']);
7838 t = t.replace(/\bperson\b/g, CURRENTSTACK['person']); // http://fb.com/647294431950845
7839 /*if (CURRENTSTACK == 'pony') {
7840 t = t.replace(/\<3 7h\!5/g, '/) 7h!5');
7841 t = t.replace(/\<3 7h15/g, '/) 7h!5');
7842 }*/
7843
7844 return t;
7845 };
7846
7847 k._likeCount = function(ufiitem) {
7848 var likecount = ufiitem.getElementsByClassName('comment_like_button');
7849 if (likecount.length) {
7850 likecount = likecount[0];
7851 var t = likecount.innerHTML;
7852 //t = t.replace(/likes? this\./g, "brohoof'd this.");
7853 t = t.replace(/like this/g, CURRENTSTACK['like_past']+" this");
7854 t = t.replace(/likes this/g, CURRENTSTACK['likes_past']+" this");
7855 if (likecount.innerHTML != t) {
7856 likecount.innerHTML = t;
7857 }
7858 }
7859 };
7860
7861 k.UFIOrderingMode = function(ele) {
7862 var t = ele.textContent;
7863 t = t.replace(/Top Comments/, "Top Friendship Letters");
7864 if (ele.textContent != t) {
7865 ele.textContent = t;
7866 }
7867 };
7868
7869 k._likeDesc = '';
7870 k._unlikeDesc = '';
7871 k._likeConditions = '';
7872 k._likeIsLikeConditions = '';
7873 k.FB_TN_LIKELINK = '>';
7874 k.FB_TN_UNLIKELINK = '?';
7875 k.commentBrohoofed = function(dom) {
7876 var targets = '.UFICommentActions a, .UFILikeLink';
7877 if (!USINGMUTATION) {
7878 targets += ', .UFILikeThumb';
7879 }
7880 domReplaceFunc(dom.target, '', targets, k._commentLikeLink);
7881 };
7882
7883 k.commentLikeDescInit = function() {
7884 if (k._likeDesc == '') {
7885 var locale = getDefaultUiLang();
7886 if (LANG[locale] && LANG[locale].sniff_comment_tooltip_like) {
7887 k._likeDesc = LANG[locale].sniff_comment_tooltip_like;
7888 } else {
7889 k._likeDesc = LANG['en_US'].sniff_comment_tooltip_like;
7890 }
7891 if (LANG[locale] && LANG[locale].sniff_comment_tooltip_unlike) {
7892 k._unlikeDesc = LANG[locale].sniff_comment_tooltip_unlike;
7893 } else {
7894 k._unlikeDesc = LANG['en_US'].sniff_comment_tooltip_unlike;
7895 }
7896
7897 k._likeConditions = [
7898 k._likeDesc, k._unlikeDesc,
7899 capitaliseFirstLetter(CURRENTSTACK.like)+" this friendship letter", capitaliseFirstLetter(CURRENTSTACK.unlike)+" this friendship letter"
7900 ];
7901 k._likeIsLikeConditions = [
7902 k._likeDesc,
7903 capitaliseFirstLetter(CURRENTSTACK.like)+" this friendship letter"
7904 ];
7905 }
7906 };
7907
7908 k._commentLikeLink = function(ele) {
7909 k.commentLikeDescInit();
7910
7911 var pass = false;
7912 var likeThumb = false;
7913 if (k._likeConditions.indexOf(ele.title) == -1) {
7914 // extreme sniffing
7915 var trackingNode = k.getTrackingNode(ele);
7916 if (trackingNode == k.FB_TN_LIKELINK || trackingNode == k.FB_TN_UNLIKELINK) {
7917 pass = true;
7918 } else if (!USINGMUTATION && hasClass(ele, 'UFILikeThumb')) {
7919 likeThumb = true;
7920 pass = true;
7921 }
7922 } else {
7923 pass = true;
7924 }
7925 if (!pass) {
7926 return;
7927 }
7928
7929 if (!hasClass(ele, 'ponyhoof_brohoof_button')) {
7930 if (!USINGMUTATION) {
7931 ele.addEventListener('click', function() {
7932 var ele = this;
7933 k.delayIU(function() {
7934 if (likeThumb) {
7935 // UFILikeThumb disappears after a post is brohoof'd
7936 k._likeBrohoofMagic(ele, false);
7937 } else {
7938 k._commentLikeLink(ele);
7939 }
7940 });
7941 }, false);
7942 }
7943 addClass(ele, 'ponyhoof_brohoof_button');
7944 }
7945
7946 var isLike = false;
7947 if (k.getTrackingNode(ele) == k.FB_TN_LIKELINK || likeThumb || k._likeIsLikeConditions.indexOf(ele.title) != -1) {
7948 isLike = true;
7949 }
7950
7951 k._likeBrohoofMagic(ele, isLike);
7952 };
7953
7954 k._likeBrohoofMagic = function(ele, isLike) {
7955 var comment = k.getReactComment(ele);
7956 var title = '';
7957 if (isLike) {
7958 removeClass(ele, 'ponyhoof_brohoof_button_unbrohoof');
7959 title = capitaliseFirstLetter(CURRENTSTACK.like)+" this";
7960 } else {
7961 addClass(ele, 'ponyhoof_brohoof_button_unbrohoof');
7962 title = capitaliseFirstLetter(CURRENTSTACK.unlike)+" this";
7963 }
7964 if (comment) {
7965 title += " friendship letter";
7966 }
7967 ele.setAttribute('data-ponyhoof-title', ele.title);
7968 ele.title = title;
7969 ele.setAttribute('data-ponyhoof-title-modified', title);
7970
7971 if (comment) {
7972 k._markCommentLiked(comment, isLike);
7973
7974 // Fix an edge case with jump to comment
7975 if (hasClass(comment, 'highlightComment')) {
7976 w.setTimeout(function() {
7977 k._markCommentLiked(comment, isLike);
7978 }, 1);
7979 }
7980 } else {
7981 k.delayIU(function() {
7982 if (!ele.parentNode) {
7983 var ufi = k.getReactUfi(ele);
7984 if (!ufi) {
7985 return;
7986 }
7987 ele = ufi;
7988 }
7989
7990 k.getParent(ele, function(form) {
7991 return (form.tagName.toUpperCase() == 'FORM' && hasClass(form, 'commentable_item'));
7992 }, function(form) {
7993 if (!form) {
7994 return;
7995 }
7996 var ufi = form.getElementsByClassName('UFIList');
7997 if (!ufi.length) {
7998 return;
7999 }
8000 ufi = ufi[0];
8001 if (!ufi.parentNode) {
8002 return;
8003 }
8004
8005 if (isLike) {
8006 removeClass(ufi.parentNode, 'ponyhoof_brohoofed');
8007 } else {
8008 addClass(ufi.parentNode, 'ponyhoof_brohoofed');
8009 }
8010 });
8011 });
8012 }
8013 };
8014
8015 k._markCommentLiked = function(ufiitem, isLike) {
8016 var child = null;
8017 if (ufiitem.childNodes && ufiitem.childNodes.length && ufiitem.childNodes[0]) {
8018 child = ufiitem.childNodes[0];
8019 }
8020 if (isLike) {
8021 removeClass(ufiitem, 'ponyhoof_comment_liked');
8022 if (child) {
8023 removeClass(child, 'ponyhoof_comment_liked');
8024 }
8025 } else {
8026 addClass(ufiitem, 'ponyhoof_comment_liked');
8027 if (child) {
8028 addClass(child, 'ponyhoof_comment_liked');
8029 }
8030 }
8031 };
8032
8033 k.REACTROOTID = '.r['; // https://github.com/facebook/react/commit/8bc2abd367232eca66e4d38ff63b335c8cf23c45
8034 k.REACTATTRNAME = 'data-reactid'; // https://github.com/facebook/react/commit/67cf44e7c18e068e3f39462b7ac7149eee58d3e5
8035 k.getReactId = function(ufiitem) {
8036 var id = ufiitem.getAttribute(k.REACTATTRNAME);
8037 if (!id) {
8038 return false;
8039 }
8040 return id.substring(k.REACTROOTID.length, id.indexOf(']'));
8041 };
8042
8043 k.reactRoot = function(dom) {
8044 var id = dom.target.getAttribute(k.REACTATTRNAME);
8045 if (id || hasClass(dom.target, 'UFILikeIcon')) {
8046 // beeperNotificaton
8047 if (hasClass(dom.target, '_3sod') || hasClass(dom.target, '-cx-PRIVATE-notificationBeeperItem__beeperitem')) {
8048 var info = dom.target.querySelector('._3sol > span, .-cx-PRIVATE-notificationBeeperItem__imageblockcontent > span');
8049 if (!info) {
8050 return false;
8051 }
8052 k._beepNotification_change(dom.target, info, k._beepNotification_condition_react);
8053
8054 return true;
8055 }
8056
8057 // Notifications
8058 if (k._notification_react(dom.target)) {
8059 return true;
8060 }
8061 var notificationReact = false;
8062 domReplaceFunc(dom.target, '', '.'+k.notification_itemClass[0]+', .'+k.notification_itemClass[1], function(ele) {
8063 k._notification_react(ele);
8064 notificationReact = true;
8065 });
8066 if (notificationReact) {
8067 return true;
8068 }
8069
8070 // Comments
8071 if (hasClass(dom.target, 'UFIComment')) {
8072 k.commentBrohoofed({target: dom.target});
8073 } else if (hasClass(dom.target, 'UFIReplyList')) {
8074 k.changeCommentBox({target: dom.target});
8075 k.commentBrohoofed({target: dom.target}); // only 1 reply
8076 } else if (hasClass(dom.target, 'UFIAddComment')) {
8077 domChangeTextbox(dom.target, 'textarea', k._changeCommentBox_change);
8078 } else if (hasClass(dom.target, 'UFILikeSentence')) {
8079 k._likePostBox(dom.target);
8080 } else if (hasClass(dom.target, 'UFIImageBlockContent')) {
8081 //if (hasClass(dom.target, '_42ef') || hasClass(dom.target, '-cx-PRIVATE-uiFlexibleBlock__flexiblecontent')) {
8082 // on groups with seen, clicking a photo will open in the viewer, but the original post on the group messes up
8083 k._likePostBox(dom.target.parentNode);
8084 //} else {
8085 // marking a comment as spam in another section, and then unmark
8086 k.commentBrohoofed({target: dom.target});
8087 //}
8088 } else if (hasClass(dom.target, 'UFILikeLink') || (!USINGMUTATION && hasClass(dom.target, 'UFILikeThumb'))) {
8089 k._commentLikeLink(dom.target);
8090 } else if (dom.target.parentNode) {
8091
8092 if (hasClass(dom.target.parentNode, 'UFIComment')) {
8093 // marking a comment as spam, and then immediately undo
8094 k.commentBrohoofed({target: dom.target.parentNode});
8095 } else if (hasClass(dom.target.parentNode, 'UFILikeSentence')) {
8096 // groups with seen, from no likes to liked
8097 k._likePostBox(dom.target.parentNode);
8098 } else if (dom.target.parentNode.parentNode) {
8099
8100 //if (hasClass(dom.target.parentNode.parentNode, 'UFIImageBlockContent') || hasClass(dom.target.parentNode.parentNode, 'lfloat')) {
8101 if (hasClass(dom.target.parentNode.parentNode, 'UFILikeSentenceText')) {
8102 // John Amebijeigeba Laverdetberg brohoof this.
8103 // You and John Amebijeigeba Laverdetberg like this.
8104 var ufi = k.getReactUfi(dom.target);
8105 if (ufi) {
8106 k.postLike({target: ufi});
8107 }
8108 } else if (dom.target.parentNode.parentNode.parentNode) {
8109
8110 //if (hasClass(dom.target.parentNode.parentNode.parentNode, 'UFIImageBlockContent')) {
8111 if (hasClass(dom.target.parentNode.parentNode.parentNode, 'UFILikeSentenceText')) {
8112 var ufi = k.getReactUfi(dom.target);
8113 if (ufi) {
8114 k.postLike({target: ufi});
8115 }
8116 }
8117 }
8118 }
8119 }
8120
8121 // Insights
8122 k.insightsCountry(dom.target);
8123
8124 return true;
8125 }
8126
8127 return false;
8128 };
8129
8130 k.changeCommentBox = function(dom) {
8131 domChangeTextbox(dom.target, '.commentArea textarea, .UFIAddComment textarea', k._changeCommentBox_change);
8132 };
8133 k._changeCommentBox_change = function(textbox) {
8134 try {
8135 var form = textbox;
8136 while (form) {
8137 if (form.tagName.toUpperCase() == 'FORM' && form.getAttribute('action') == '/ajax/ufi/modify.php') {
8138 break;
8139 }
8140 form = form.parentNode;
8141 }
8142 if (form) {
8143 var feedback_params = JSON.parse(form.querySelector('input[name="feedback_params"]').value);
8144 switch (feedback_params.assoc_obj_id) {
8145 case '140792002656140':
8146 case '346855322017980':
8147 return LANG['ms_MY'].fb_comment_box;
8148
8149 case '146225765511748':
8150 return CURRENTLANG.fb_composer_coolstory;
8151
8152 default:
8153 break;
8154 }
8155 switch (feedback_params.target_profile_id) {
8156 case '496282487062916':
8157 return CURRENTLANG.fb_composer_coolstory;
8158
8159 default:
8160 break;
8161 }
8162 }
8163 } catch (e) {}
8164
8165 return CURRENTLANG.fb_comment_box;
8166 };
8167
8168 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');
8169 k.composerExclude = new RegExp(['suck', 'shit', 'fuck', 'assho', 'crap', 'ponyfag', 'faggo', 'retard', 'dick'].join('|'), 'i');
8170 k.composerSpecialPages = null;
8171 k.composerSelectors = '.uiComposer textarea.mentionsTextarea, .composerTypeahead textarea';
8172 k.composerButtonSelectors = '.uiComposerMessageBoxControls .submitBtn input, .uiComposerMessageBoxControls .submitBtn .uiButtonText, ._11b input, .-cx-PRIVATE-fbComposerMessageBox__button input, button._11b, button.-cx-PRIVATE-fbComposerMessageBox__button';
8173 k.changeComposer = function(dom) {
8174 if (!k.composerSpecialPages) {
8175 k._changeComposer_initSpecialPages();
8176 }
8177
8178 var pageid = '';
8179
8180 // tagging people with "Who are you with?" and new feelings feature
8181 if (hasClass(dom.target, 'uiMentionsInput')) {
8182 // fix group composers, ugh
8183 if (dom.target.parentNode && dom.target.parentNode.parentNode && dom.target.parentNode.parentNode.parentNode) {
8184 // .uiMentionsInput -> #id -> .-cx-PUBLIC-fbComposerMessageBox__root -> form -> .-cx-PUBLIC-fbComposer__content
8185 k._changeComposer_fixGroup(dom.target.parentNode.parentNode.parentNode);
8186 }
8187
8188 contentEval(function(arg) {
8189 try {
8190 if (typeof window.requireLazy == 'function') {
8191 window.requireLazy(['MentionsInput'], function(MentionsInput) {
8192 var mentions = MentionsInput.getInstance(document.getElementById(arg.uiMentionsInput));
8193 mentions.setPlaceholder(mentions._input.title);
8194 });
8195 }
8196 } catch (e) {
8197 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
8198 console.log("Unable to hook to MentionsInput");
8199 console.dir(e);
8200 }
8201 }
8202 }, {"CANLOG":CANLOG, "uiMentionsInput":dom.target.id});
8203 return;
8204 }
8205
8206 domChangeTextbox(dom.target, k.composerSelectors, function(composer) {
8207 var placeholderText = CURRENTLANG.fb_composer_lessons;
8208
8209 try {
8210 var form = composer;
8211 var inputContainer = null;
8212 while (form) {
8213 if (hasClass(form, 'uiComposer') || hasClass(form, '_119' /*'_118'*/) || hasClass(form, '-cx-PRIVATE-fbComposer__root')) {
8214 break;
8215 }
8216 if (hasClass(form, 'inputContainer')) {
8217 inputContainer = form;
8218 }
8219 form = form.parentNode;
8220 }
8221
8222 if (!form) {
8223 return placeholderText;
8224 }
8225
8226 pageid = form.querySelector('input[name="xhpc_targetid"]');
8227 if (!pageid) {
8228 pageid = '';
8229 return placeholderText;
8230 }
8231 pageid = pageid.value;
8232 form.setAttribute('data-ponyhoof-xhpc_targetid', pageid);
8233 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].composer) {
8234 placeholderText = k.composerSpecialPages[pageid].composer;
8235 }
8236
8237 k._changeComposerAttachment(dom, pageid);
8238
8239 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8240 $$(form, k.composerButtonSelectors, function(submit) {
8241 k.changeButtonText(submit, "Kirim");
8242 });
8243 }
8244
8245 composer.addEventListener('input', function() {
8246 var malay = false;
8247 var lang = CURRENTLANG;
8248 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8249 malay = true;
8250 lang = LANG['ms_MY'];
8251 }
8252
8253 // we can't guarantee the button anymore, so we have to do this expensive JS :(
8254 // group composers are funky and teleport the textbox to a new <div> onclick
8255 $$(form, k.composerButtonSelectors, function(submit) {
8256 if (!k.composerExclude.test(composer.value) && k.composerPonies.test(composer.value)) {
8257 if (composer.value.toUpperCase() == composer.value) {
8258 k.changeButtonText(submit, lang.fb_composer_ponies_caps);
8259 } else {
8260 k.changeButtonText(submit, lang.fb_composer_ponies);
8261 }
8262 } else if (malay) {
8263 k.changeButtonText(submit, "Kirim");
8264 } else {
8265 var submitParent = submit;
8266 if (submit.tagName.toUpperCase() != 'BUTTON') {
8267 submitParent = submit.parentNode;
8268 }
8269 if (submitParent.getAttribute('data-ponyhoof-button-text')) {
8270 k.changeButtonText(submit, submitParent.getAttribute('data-ponyhoof-button-text'));
8271 }
8272 }
8273 });
8274 });
8275
8276 if (isPonyhoofPage(pageid)) {
8277 composer.addEventListener('focus', function() {
8278 if (inputContainer) {
8279 k._changeComposer_insertReadme(inputContainer.nextSibling);
8280 return;
8281 }
8282
8283 // pages have ComposerX and teleports the textbox here and there
8284 $$(form, '._2yg, .-cx-PUBLIC-fbComposerMessageBox__root', function(composer) {
8285 // exclude inactives
8286 if (!composer.parentNode || hasClass(composer.parentNode, 'hidden_elem')) {
8287 return;
8288 }
8289
8290 var temp = composer.getElementsByClassName('ponyhoof_page_readme');
8291 if (temp.length) {
8292 return;
8293 }
8294
8295 // status: before taggersPlaceholder
8296 // photos: after uploader
8297 // fallback: before bottom bar
8298 var insertBefore = composer.querySelector('._3-6, .-cx-PRIVATE-fbComposerBootloadStatus__taggersplaceholder');
8299 if (!insertBefore) {
8300 insertBefore = composer.querySelector('._93, .-cx-PRIVATE-fbComposerUploadMedia__root');
8301 if (insertBefore) {
8302 insertBefore = insertBefore.nextSibling;
8303 }
8304 }
8305 if (!insertBefore) {
8306 insertBefore = composer.querySelector('._1dsp, .-cx-PUBLIC-fbComposerMessageBox__bar');
8307 }
8308 // abort if no good insertion
8309 if (!insertBefore) {
8310 return;
8311 }
8312
8313 k._changeComposer_insertReadme(insertBefore);
8314 });
8315 }, true);
8316 return "Send feedback for Ponyhoof...";
8317 }
8318 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].composer) {
8319 return k.composerSpecialPages[pageid].composer;
8320 }
8321 } catch (e) {}
8322
8323 return placeholderText;
8324 });
8325
8326 // moved outside for timelineStickyHeader
8327 if (!pageid) {
8328 k._changeComposerAttachment(dom, null);
8329 }
8330
8331 // fix group composers, ugh
8332 //k._changeComposer_fixGroup(dom.target);
8333 };
8334
8335 k._changeComposerAttachment = function(dom, pageid) {
8336 $$(dom.target, '._4_ li a, ._9lb, .-cx-PUBLIC-fbComposerAttachment__link, .uiComposerAttachment', function(attachment) {
8337 if (attachment.getAttribute('data-ponyhoof-ponified')) {
8338 return;
8339 }
8340
8341 var switchit = false;
8342 switch (attachment.getAttribute('data-endpoint')) {
8343 case '/ajax/composerx/attachment/status/':
8344 case '/ajax/composerx/attachment/group/post/':
8345 case '/ajax/composerx/attachment/wallpost/':
8346 case '/ajax/metacomposer/attachment/timeline/status.php':
8347 case '/ajax/metacomposer/attachment/timeline/backdated_status.php':
8348 case '/ajax/metacomposer/attachment/timeline/wallpost.php':
8349 switchit = "Take a Note";
8350 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8351 switchit = "Tulis Kiriman";
8352 }
8353 break;
8354
8355 case '/ajax/composerx/attachment/media/chooser/':
8356 case '/ajax/composerx/attachment/media/chooser':
8357 case '/ajax/composerx/attachment/media/upload/':
8358 case '/ajax/metacomposer/attachment/timeline/photo/photo.php':
8359 case '/ajax/metacomposer/attachment/timeline/photo/backdated_upload.php':
8360 case '/ajax/metacomposer/attachment/timeline/backdated_vault.php?max_select=1':
8361 switchit = "Add a Pic";
8362 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8363 switchit = "Tambah Gambar / Video";
8364 }
8365 break;
8366
8367 case '/ajax/composerx/attachment/question/':
8368 switchit = "Query";
8369 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8370 switchit = "Tanya Soalan";
8371 }
8372 break;
8373
8374 case '/ajax/composerx/attachment/group/file/':
8375 case '/ajax/composerx/attachment/group/filedropbox/':
8376 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8377 switchit = "Muat Naik Fail";
8378 }
8379 break;
8380
8381 default:
8382 break;
8383 }
8384 if (!switchit) {
8385 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) {
8386 switchit = "Adventure, Milestone +";
8387 //if (attachment.id == 'offerEventAndOthersButton') {
8388 if (attachment.textContent.toLowerCase().indexOf('offer') != -1) {
8389 switchit = "Offer, Adventure +";
8390 }
8391 }
8392 }
8393
8394 if (switchit) {
8395 var done = false;
8396 var inner = attachment.querySelector('._2-s, .-cx-PUBLIC-fbTimelineComposerAttachment__label');
8397 if (!inner) {
8398 inner = attachment.querySelector('._51z7, .-cx-PUBLIC-fbComposerAttachment__linktext');
8399 if (!inner) {
8400 // page timelines use ".attachmentName" and are wacky, there are actually two copies of the <div> that show/hide
8401 $$(attachment, '.attachmentName', function(inner) {
8402 k._changeComposerAttachment_inner(inner, switchit);
8403 done = true;
8404 });
8405
8406 if (!done) {
8407 inner = attachment;
8408 }
8409 }
8410 }
8411
8412 if (!done) {
8413 k._changeComposerAttachment_inner(inner, switchit);
8414 }
8415 }
8416
8417 attachment.setAttribute('data-ponyhoof-ponified', 1);
8418 });
8419 };
8420
8421 k._changeComposerAttachment_inner = function(inner, switchit) {
8422 var stopit = false;
8423 loopChildText(inner, function(child) {
8424 if (stopit) {
8425 return;
8426 }
8427 if (child.nodeType == 3) {
8428 child.textContent = switchit;
8429 stopit = true;
8430 }
8431 });
8432 };
8433
8434 k._changeComposer_insertReadme = function(insertBefore) {
8435 var n = d.createElement('iframe');
8436 n.className = 'showOnceInteracted ponyhoof_page_readme _4- -cx-PRIVATE-fbComposer__showonceinteracted';
8437 n.scrolling = 'auto';
8438 n.frameborder = '0';
8439 n.allowtransparency = 'true';
8440 n.src = PONYHOOF_README;
8441 insertBefore.parentNode.insertBefore(n, insertBefore);
8442 };
8443
8444 k._changeComposer_fixGroup = function(target) {
8445 if (hasClass(target.parentNode, '_55d0') || hasClass(target.parentNode, '.-cx-PUBLIC-fbComposer__content')) {
8446 var pageid = target.querySelector('input[name="xhpc_targetid"]');
8447 if (!pageid) {
8448 return;
8449 }
8450 pageid = pageid.value;
8451
8452 // domChangeTextbox will not work as these <textarea>s already has "data-ponyhoof-ponified"
8453 var composer = target.querySelector(k.composerSelectors);
8454 if (!composer) {
8455 return;
8456 }
8457
8458 $$(target, k.composerButtonSelectors, function(submit) {
8459 var malay = false;
8460 var lang = CURRENTLANG;
8461 if (k.composerSpecialPages[pageid] && k.composerSpecialPages[pageid].malay) {
8462 malay = true;
8463 lang = LANG['ms_MY'];
8464 }
8465
8466 if (!k.composerExclude.test(composer.value) && k.composerPonies.test(composer.value)) {
8467 if (composer.value.toUpperCase() == composer.value) {
8468 k.changeButtonText(submit, lang.fb_composer_ponies_caps);
8469 } else {
8470 k.changeButtonText(submit, lang.fb_composer_ponies);
8471 }
8472 } else if (malay) {
8473 k.changeButtonText(submit, "Kirim");
8474 }
8475 });
8476 }
8477 };
8478
8479 k._changeComposer_initSpecialPages = function() {
8480 k.composerSpecialPages = {
8481 '140792002656140': {composer: LANG['ms_MY'].fb_composer_lessons, malay:true}
8482 ,'346855322017980': {composer: LANG['ms_MY'].fb_composer_lessons, malay:true}
8483 ,'366748370110998': {composer: LANG['ms_MY'].fb_composer_lessons, malay:true}
8484 ,'146225765511748': {composer: CURRENTLANG['fb_composer_coolstory']}
8485 ,'496282487062916': {composer: CURRENTLANG['fb_composer_coolstory']}
8486 };
8487 };
8488
8489 k.tooltip = function(outer) {
8490 domReplaceFunc(outer, '', '.tooltipContent', function(ele) {
8491 // <div class="tooltipContent"><div class="tooltipText"><span>Hide</span></div></div>
8492 // <div class="tooltipContent"><div>Ponyhoof brohoofs this.</div></div>
8493 // <div class="tooltipContent">xy</div>
8494 // <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>
8495
8496 // <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>
8497 var io = ele.getElementsByClassName('tooltipText');
8498 if (io.length) {
8499 var target = io[0];
8500 } else {
8501 var target = ele;
8502 }
8503 var potentialLabel = target.querySelector('._5bqd, .-cx-PRIVATE-HubbleInfoTip__content, ._5j1i');
8504 if (potentialLabel) {
8505 target = potentialLabel;
8506 }
8507 if (target.childNodes && target.childNodes.length && target.childNodes[0] && target.childNodes[0].tagName && target.childNodes[0].tagName.toUpperCase() == 'DIV') {
8508 target = target.childNodes[0];
8509 }
8510 if (target.childNodes && target.childNodes.length && target.childNodes[0] && target.childNodes[0].tagName && target.childNodes[0].tagName.toUpperCase() == 'SPAN') {
8511 target = target.childNodes[0];
8512 }
8513
8514 // Get the tooltip outer layer
8515 var layer = k._tooltipGetLayer(ele);
8516 if (!layer) {
8517 return;
8518 }
8519
8520 //removeClass(layer, 'ponyhoof_tooltip_flip');
8521
8522 // Replace text
8523 var orig = target.innerHTML;
8524 var origText = target.textContent;
8525 var t = orig;
8526 t = replaceText(tooltipTitles, t);
8527 if (orig != t) {
8528 //var oldWidth = ele.offsetWidth;
8529 target.innerHTML = t;
8530
8531 if (USINGMUTATION) {
8532 // Replace text at the parent that we are *really* certain
8533 if (orig === origText) {
8534 var owner = $(layer.getAttribute('data-ownerid'));
8535 if (owner) {
8536 owner.setAttribute('aria-label', t);
8537 }
8538 }
8539
8540 // fix horizontal scrollbar
8541 if (hasClass(layer.parentNode, 'fbPhotoSnowliftContainer')) {
8542 addClass(layer, 'ponyhoof_tooltip_widthFix');
8543 } else {
8544 removeClass(layer, 'ponyhoof_tooltip_widthFix');
8545 }
8546
8547 k.updateLayerPosition(layer);
8548 }
8549
8550 /*// Get the inner layer inside the outer layer (get it...?)
8551 var layerInner = layer.getElementsByClassName('uiContextualLayer');
8552 if (!layerInner.length) {
8553 return;
8554 }
8555 layerInner = layerInner[0];
8556
8557 if (layerInner.className.match(/Center/)) {
8558 /*var rect = ele.getBoundingClientRect();
8559 if (!rect) {
8560 return;
8561 }* /
8562
8563 layer.style.width = 'auto'; // fix horizontal scrollbar
8564 var left = parseInt(layer.style.left); // relative positioning at photo viewer
8565 var newWidth = ele.offsetWidth;
8566 //if ((rect.left + newWidth) < d.documentElement.clientWidth) {
8567 layer.style.left = (left - Math.round((newWidth - oldWidth) / 2))+'px';
8568 /*} else {
8569 Fix long "X, Y and 2 others like this." tooltips on photo viewer
8570 layer.style.left = (left - (oldWidth / 2) /*+ ((newWidth - oldWidth) / 2) - 18* / )+'px';
8571 addClass(layer, 'ponyhoof_tooltip_flip');
8572 }* /
8573 } else if (layerInner.className.match(/Left/)) {
8574 // Fix "Remember: all place ratings are public." tooltips that are being ponified and causing a horizontal page scrollbar
8575 //
8576 // This is complicated, Facebook caches the ContextualLayer <div>s for tooltips
8577 // If we directly change the classNames like this:
8578 // layerInner.className = layerInner.className.replace(/Left/, 'Right');
8579 // This would cause future tooltips to display incorrectly
8580 // So what we done is add our own "ponyhoof_tooltip_flip" class which flips the tooltip left to right
8581
8582 var rect = ele.getBoundingClientRect();
8583 if (!rect) {
8584 return;
8585 }
8586 if (rect.right >= d.documentElement.clientWidth) {
8587 layer.style.width = 'auto'; // bogus anyway
8588 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
8589 addClass(layer, 'ponyhoof_tooltip_flip');
8590 }
8591 }*/
8592 }
8593 });
8594 };
8595
8596 k._tooltipGetLayer = function(ele) {
8597 // <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>
8598 if (!ele.parentNode || !ele.parentNode.parentNode || !ele.parentNode.parentNode.parentNode) {
8599 return false;
8600 }
8601 var layer = ele.parentNode.parentNode.parentNode;
8602 if (!hasClass(layer, 'uiContextualLayerPositioner')) {
8603 return false;
8604 }
8605 return layer;
8606 };
8607
8608 k.fbDockChatBuddylistNub = function(target) {
8609 if (target.parentNode && target.parentNode.parentNode && target.parentNode.parentNode.getAttribute && target.parentNode.parentNode.getAttribute('id') == 'fbDockChatBuddylistNub' && hasClass(target, 'label')) {
8610 k._fbDockChatBuddylistNub_change(target);
8611 return true;
8612 }
8613 // first loading
8614 var nub = target.querySelector('#fbDockChatBuddylistNub .label');
8615 if (nub) {
8616 k._fbDockChatBuddylistNub_change(nub);
8617 }
8618 return false;
8619 };
8620
8621 k._fbDockChatBuddylistNub_change = function(target) {
8622 if (target.childNodes && target.childNodes.length && target.childNodes[0] && target.childNodes[0].nodeType == TEXT_NODE) {
8623 var replaced = target.childNodes[0].textContent.replace(/Chat/, "Whinny");
8624 if (target.childNodes[0].textContent != replaced) {
8625 addClass(target, 'ponyhoof_chatLabel_ponified');
8626 target.childNodes[0].textContent = replaced;
8627 }
8628 }
8629 };
8630
8631 k.pokesDashboard = function(target) {
8632 if (target.getAttribute && target.getAttribute('id') && target.getAttribute('id').indexOf('poke_') == 0) {
8633 k._pokesDashboard_item(target);
8634 return true;
8635 }
8636
8637 // (Sep 25) Include xuiCard
8638 //$$(target, '.pokesDashboard > .objectListItem', k._pokesDashboard_item);
8639 //$$(target, '.objectListItem[id^="poke_"], ._4-u2[id^="poke_"], .-cx-PRIVATE-xuiCard__root[id^="poke_"]', k._pokesDashboard_item);
8640 $$(target, '.objectListItem[id^="poke_"], ._5lbv, .-cx-PRIVATE-pokesDashboard__pokercontent', k._pokesDashboard_item);
8641
8642 if (hasClass(target, 'highlight')) {
8643 var t = target.textContent;
8644 t = t.replace(/You poked /, 'You nuzzled ');
8645 if (target.textContent != t) {
8646 target.textContent = t;
8647 }
8648 return true;
8649 }
8650
8651 k._pokesDashboard_pokeLink(target);
8652
8653 return false;
8654 };
8655
8656 k._pokesDashboard_item = function(item) {
8657 //var header = item.getElementsByClassName('pokeHeader');
8658 //if (!header || !header.length) {
8659 // return;
8660 //}
8661 //header = header[0];
8662
8663 // (Sep 25)
8664 var header = item.querySelector('._5lbt, .-cx-PRIVATE-pokesDashboard__pokername');
8665 if (header) {
8666 // <div class="-cx-PRIVATE-pokesDashboard__pokername _5lbt lfloat">&nbsp;<a href="" data-hovercard="">John</a> poked you.<br>&nbsp;<span class="-cx-PRIVATE-pokesDashboard__pokertime _5lbs"><abbr title="" data-utime="" class="timestamp">2 seconds ago</abbr></span></div>
8667 if (header.childNodes && header.childNodes.length) {
8668 if (header.childNodes[2] && header.childNodes[2].nodeType === TEXT_NODE) {
8669 var poke = header.childNodes[2];
8670 var t = poke.textContent;
8671 t = t.replace(/ poked you\./, ' nuzzled you.');
8672 if (poke.textContent != t) {
8673 poke.textContent = t;
8674 }
8675 } else if (header.childNodes[4] && header.childNodes[4].nodeType === ELEMENT_NODE) {
8676 var poke = header.childNodes[4];
8677 if (poke.textContent === "Suggested Poke") {
8678 poke.textContent = "Suggested Nuzzle";
8679 }
8680 }
8681 }
8682 } else {
8683 var header = item.querySelector('.uiProfileBlockContent > ._6a > ._6b > .fwb'); // .-cx-PRIVATE-uiInlineBlock__root > .-cx-PRIVATE-uiInlineBlock__middle
8684 if (header) {
8685 var t = header.innerHTML;
8686 t = t.replace(/ poked you\./, ' nuzzled you.');
8687 if (header.innerHTML != t) {
8688 header.innerHTML = t;
8689 }
8690
8691 k._pokesDashboard_pokeLink(item);
8692 }
8693 }
8694 };
8695
8696 k._pokesDashboard_pokeLink = function(target) {
8697 // (Sep 25) Skip buttons
8698 $$(target, 'a[ajaxify^="/pokes/inline/"]:not(._42ft)', function(poke) {
8699 var text = "Nuzzle";
8700 /*if (poke.getAttribute('ajaxify').indexOf('pokeback=1') != -1) { // http://fb.com/406911932763192
8701 text = "Nuzzle Back";
8702 }*/
8703
8704 if (poke.childNodes && poke.childNodes.length && poke.childNodes[1]) {
8705 poke.childNodes[1].textContent = text;
8706 return;
8707 }
8708
8709 var stop = false;
8710 loopChildText(poke, function(child) {
8711 if (stop) {
8712 return;
8713 }
8714 if (child.nodeType == TEXT_NODE) {
8715 child.textContent = text;
8716 stop = true;
8717 }
8718 });
8719 });
8720 };
8721
8722 k.notification = function(dom) {
8723 domReplaceFunc(dom.target, 'notification', '.notification', function(ele) {
8724 k._notification_change(ele, '.info', k._notification_general_metadata);
8725 });
8726
8727 if (ONPLUGINPAGE && hasClass(dom.target, 'notification-item')) {
8728 //.$$(dom.target, '.notification-item', function(ele) {
8729 k._notification_change(dom.target, '.notification-text > .message', k._notification_messenger_metadata);
8730 //});
8731 }
8732 };
8733
8734 k.notification_itemClass = ['_33c', '-cx-PRIVATE-fbNotificationJewelItem__item'];
8735 k.notification_textClass = ['_4l_v', '-cx-PRIVATE-fbNotificationJewelItem__text'];
8736 k.notification_metadataClass = ['_33f', '-cx-PRIVATE-fbNotificationJewelItem__metadata'];
8737 k._notification_react = function(ele) {
8738 for (var i = 0; i <= 1; i += 1) {
8739 if (hasClass(ele, k.notification_itemClass[i])) {
8740 k._notification_change(ele, '.'+k.notification_textClass[i]+' > span', k._notification_react_metadata);
8741 return true;
8742 }
8743 }
8744 return false;
8745 };
8746
8747 k._notification_general_metadata = function(node) {
8748 if (hasClass(node, 'metadata') || hasClass(node, 'blueName')) {
8749 return false;
8750 }
8751 return true;
8752 };
8753
8754 k._notification_messenger_metadata = function(node) {
8755 // <a href="">X</a> likes your <a href="">comment</a>: "Also, please use this group in the..."
8756 //if (node.nodeType != TEXT_NODE) {
8757 // return false;
8758 //}
8759 return true;
8760 };
8761
8762 k._notification_react_metadata = function(node) {
8763 if (hasClass(node, 'fwb')) {
8764 return false;
8765 }
8766 if (hasClass(node, k.notification_metadataClass[0]) || hasClass(node, k.notification_metadataClass[1])) {
8767 return false;
8768 }
8769 return true;
8770 };
8771
8772 k._notification_change = function(ele, info, metadataFunc) {
8773 var info = ele.querySelector(info);
8774 if (!info) {
8775 return;
8776 }
8777 if (!info.childNodes || !info.childNodes.length) {
8778 return;
8779 }
8780
8781 for (var i = 0, len = info.childNodes.length; i < len; i += 1) {
8782 var node = info.childNodes[i];
8783 if (!metadataFunc(node)) {
8784 continue;
8785 }
8786
8787 var text = node.textContent;
8788 if (text.indexOf('"') != -1) {
8789 var finalText = k.textNotification(text.substring(0, text.indexOf('"')));
8790 finalText += text.substring(text.indexOf('"'), text.length);
8791 } else {
8792 var finalText = k.textNotification(text);
8793 }
8794
8795 if (node.textContent != finalText) {
8796 node.textContent = finalText;
8797 }
8798
8799 if (text.indexOf('"') != -1) {
8800 break;
8801 }
8802 }
8803 };
8804
8805 k.menuPrivacyOnlyAjaxify = [
8806 // when posting
8807 '%22value%22%3A%2280%22' // Everyone
8808 ,'%22value%22%3A%2250%22' // Friends of Friends
8809 ,'%22value%22%3A%2240%22' // Friends
8810 ,'%22value%22%3A%22127%22' // Friends except Acquaintances
8811 ,'%22value%22%3A%2210%22' // Only Me
8812
8813 // https://www.facebook.com/settings?tab=timeline&section=posting&view
8814 ,'%22value%22%3A40'
8815 ,'%22value%22%3A10'
8816 ];
8817 k._processMenuXOldWidthDiff = 0;
8818 k.menuItems = function(dom) {
8819 var processMenuX = false;
8820 var hasScrollableArea = false;
8821 k._processMenuXOldWidthDiff = 0;
8822 domReplaceFunc(dom.target, 'uiMenuItem', '.uiMenuItem, ._54ni, .-cx-PUBLIC-abstractMenuItem__root, .ufb-menu-item', function(ele) {
8823 if (hasClass(ele, 'ponyhoof_fbmenuitem')) {
8824 return;
8825 }
8826 addClass(ele, 'ponyhoof_fbmenuitem');
8827
8828 // pages on share dialog
8829 if (hasClass(ele, '_90z') || hasClass(ele, '-cx-PRIVATE-fbShareModePage__smalliconcontainer')) {
8830 return;
8831 }
8832
8833 // lists/groups on Invite Friends dialogs
8834 var listendpoint = ele.getAttribute('data-listendpoint');
8835 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) {
8836 return;
8837 }
8838
8839 var replacer = menuTitles;
8840 if (hasClass(ele, 'fbPrivacyAudienceSelectorOption')) {
8841 replacer = menuPrivacyOnlyTitles;
8842
8843 // ensure that only FB-provided options get changed
8844 var itemAnchor = ele.getElementsByClassName('itemAnchor');
8845 if (itemAnchor.length) {
8846 var ajaxify = itemAnchor[0].getAttribute('ajaxify');
8847 // Sometimes ajaxify is missing (legacy edit video)
8848 if (ajaxify) {
8849 var _menuPrivacyOnlyOk = false;
8850 for (var i = 0, len = k.menuPrivacyOnlyAjaxify.length; i < len; i += 1) {
8851 if (ajaxify.indexOf(k.menuPrivacyOnlyAjaxify[i]) != -1) {
8852 _menuPrivacyOnlyOk = true;
8853 break;
8854 }
8855 }
8856 if (!_menuPrivacyOnlyOk) {
8857 return;
8858 }
8859 }
8860 }
8861 }
8862
8863 var label = ele.querySelector('.itemLabel, ._54nh, .-cx-PUBLIC-abstractMenuItem__label, .ufb-menu-item-label');
8864 if (label) {
8865 //if (label.childNodes.length == 1) {
8866 // timeline post has 2
8867 var io = label.getElementsByTagName('span');
8868 if (io.length) {
8869 if (!hasClass(io[0], 'hidden_elem')) {
8870 label = io[0];
8871 }
8872 }
8873
8874 var orig = '';
8875 var replaced = '';
8876 var oldLabelWidth = 0;
8877 ele.setAttribute('data-ponyhoof-menuitem-orig', ele.textContent);
8878 loopChildText(label, function(child) {
8879 if (child.nodeType == 3) {
8880 var t = child.textContent;
8881 orig += t+' ';
8882 t = replaceText(replacer, t);
8883 if (child.textContent != t) {
8884 if (!hasScrollableArea && (ele.parentNode && ele.parentNode.parentNode && hasClass(ele.parentNode.parentNode, 'uiScrollableAreaContent'))) {
8885 hasScrollableArea = true;
8886 }
8887 if (hasScrollableArea) {
8888 label.style.display = 'inline-block';
8889 if (!oldLabelWidth) {
8890 oldLabelWidth = label.offsetWidth;
8891 }
8892 }
8893 child.textContent = t;
8894 }
8895 replaced += t+' ';
8896 }
8897 });
8898
8899 orig = orig.substr(0, orig.length-1);
8900 replaced = replaced.substr(0, replaced.length-1);
8901 ele.setAttribute('data-ponyhoof-menuitem-text', replaced);
8902 ele.setAttribute('data-label', replaced); // technically, this is only used for .uiMenuItem
8903
8904 if (orig != replaced) {
8905 if (hasClass(ele, '_54ni') || hasClass(ele, '-cx-PUBLIC-abstractMenuItem__root')) {
8906 if (hasScrollableArea && oldLabelWidth) {
8907 var newWidth = label.offsetWidth;
8908 if (newWidth > oldLabelWidth) {
8909 k._processMenuXOldWidthDiff = Math.max(newWidth - oldLabelWidth, 0);
8910 processMenuX = true;
8911 }
8912 } else {
8913 processMenuX = true;
8914 }
8915 }
8916 }
8917 if (hasScrollableArea) {
8918 label.style.display = '';
8919 }
8920 }
8921 });
8922
8923 if (processMenuX) {
8924 if (hasClass(dom.target, 'uiContextualLayerPositioner')) {
8925 k._menuItems_processMenuX(dom.target);
8926 return;
8927 }
8928
8929 k.getParent(dom.target, function(parent) {
8930 return hasClass(parent, 'uiContextualLayerPositioner');
8931 }, k._menuItems_processMenuX);
8932 }
8933 };
8934 k._menuItems_processMenuX = function(layer) {
8935 if (!layer) {
8936 return;
8937 }
8938
8939 var ownerid = layer.getAttribute('data-ownerid');
8940 if (!ownerid) {
8941 return;
8942 }
8943 ownerid = $(ownerid);
8944 if (!ownerid) {
8945 return;
8946 }
8947
8948 var menu = layer.querySelector('._54nq, .-cx-PUBLIC-abstractMenu__wrapper');
8949 if (!menu) {
8950 return;
8951 }
8952
8953 if (k._processMenuXOldWidthDiff) {
8954 var uiScrollableArea = layer.getElementsByClassName('uiScrollableArea');
8955 var uiScrollableAreaBody = layer.getElementsByClassName('uiScrollableAreaBody');
8956 if (uiScrollableArea && uiScrollableAreaBody) {
8957 uiScrollableArea = uiScrollableArea[0];
8958 uiScrollableAreaBody = uiScrollableAreaBody[0];
8959
8960 uiScrollableArea.style.width = (parseInt(uiScrollableArea.style.width)+k._processMenuXOldWidthDiff)+'px';
8961 uiScrollableAreaBody.style.width = (parseInt(uiScrollableAreaBody.style.width)+k._processMenuXOldWidthDiff)+'px';
8962 }
8963 }
8964
8965 var border = layer.querySelector('._54hx, .-cx-PUBLIC-abstractMenu__shortborder');
8966 if (!border) {
8967 return;
8968 }
8969 border.style.width = (Math.max((menu.offsetWidth - ownerid.offsetWidth), 0))+'px';
8970 };
8971
8972 k.fbRemindersStory = function(target) {
8973 $$(target, '.fbRemindersStory', function(item) {
8974 var reminderType = '';
8975 if (item.querySelector('#pages_reminders_link')) {
8976 reminderType = 'page';
8977 }
8978
8979 var inner = item.querySelector('._42ef > .fcg, .-cx-PRIVATE-uiFlexibleBlock__flexiblecontent > .fcg');
8980 if (!inner) {
8981 return;
8982 }
8983
8984 loopChildText(inner, function(child) {
8985 if (child.nodeType == TEXT_NODE) {
8986 var t = child.textContent;
8987 if (reminderType === 'page') {
8988 t = t.replace(/\binvited you to like\b/, "invite you to "+CURRENTSTACK['like']);
8989 } else {
8990 t = t.replace(/\bpoked you\b/, "nuzzled you");
8991 }
8992 if (child.textContent != t) {
8993 child.textContent = t;
8994 }
8995 } else {
8996 if (hasClass(child, 'fbRemindersTitle')) {
8997 var t = child.innerHTML;
8998 t = t.replace(/([0-9]+?) events/, "$1 adventures")
8999 if (child.innerHTML != t) {
9000 child.innerHTML = t;
9001 }
9002 }
9003 }
9004 });
9005 });
9006 };
9007
9008 k.flyoutLikeForm = function(target) {
9009 //var result = k._flyoutLikeForm(target, 'groupsMemberFlyoutLikeForm', 'unlike');
9010 var result = k._flyoutLikeForm(target, '_5nx0', 'unlike');
9011 if (!result) {
9012 result = k._flyoutLikeForm(target, 'fbEventMemberLike', 'liked');
9013 }
9014 return result;
9015 };
9016
9017 k._flyoutLikeForm = function(target, className, forminput) {
9018 domReplaceFunc(target, className, '.'+className, function(ele) {
9019 if (!ele.elements[forminput]) {
9020 return;
9021 }
9022
9023 var isLike = true;
9024 if (ele.elements[forminput].value == 1) {
9025 isLike = false;
9026 }
9027
9028 var submit = ele.querySelector('input[type="submit"]');
9029 if (!submit) {
9030 return;
9031 }
9032 if (isLike) {
9033 submit.value = capitaliseFirstLetter(CURRENTSTACK['like']);
9034 } else {
9035 submit.value = capitaliseFirstLetter(CURRENTSTACK['unlike']);
9036 }
9037 });
9038
9039 if (hasClass(target, className)) {
9040 return true;
9041 }
9042 return false;
9043 };
9044
9045 k.pluginButton = function(target) {
9046 if (!ONPLUGINPAGE) {
9047 return;
9048 }
9049
9050 var root = target.getElementsByClassName('pluginConnectButtonLayoutRoot');
9051 if (!root.length) {
9052 var root = target.getElementsByClassName('pluginSkinLight');
9053 if (!root.length) {
9054 return;
9055 }
9056 }
9057 root = root[0];
9058
9059 domReplaceFunc(root, '', '.pluginButton', function(ele) {
9060 // oct 19
9061 var div = ele.getElementsByClassName('pluginButtonLabel');
9062 if (div.length) {
9063 div = div[0];
9064 if (div.innerHTML === "Like") {
9065 div.innerHTML = capitaliseFirstLetter(CURRENTSTACK['like']);
9066 return;
9067 }
9068 }
9069
9070 // old style
9071 var div = ele.getElementsByTagName('div');
9072 if (div.length) {
9073 ele = div[0];
9074 }
9075
9076 // <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>
9077 var stop = false;
9078 loopChildText(ele, function(child) {
9079 if (stop) {
9080 return;
9081 }
9082 if (child.tagName.toUpperCase() === 'SPAN') {
9083 if (child.innerHTML === "Like") {
9084 child.innerHTML = capitaliseFirstLetter(CURRENTSTACK['like']);
9085 stop = true;
9086 }
9087 }
9088 });
9089 });
9090
9091 domReplaceFunc(root, '', '.uiIconText', function(ele) {
9092 // <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>
9093 loopChildText(ele, function(child) {
9094 loopChildText(child, function(inner) {
9095 if (inner.nodeType === TEXT_NODE) {
9096 var t = k.likeSentence(inner.textContent);
9097 t = t.replace(/\bfriends\b/g, CURRENTSTACK['friends_logic']); // Be the first of your friends.
9098 if (inner.textContent != t) {
9099 inner.textContent = t;
9100 }
9101 }
9102 });
9103 });
9104 });
9105
9106 // likebox
9107 $$(root, '._51mx > .pls > div > span', function(ele) {
9108 var orig = ele.textContent;
9109 var t = k.likeSentence(orig);
9110 t = t.replace(/\bfriends\b/g, CURRENTSTACK['friends_logic']); // Be the first of your friends.
9111 if (orig != t) {
9112 ele.textContent = t;
9113 }
9114 });
9115 };
9116
9117 k.ticker = function(dom) {
9118 domReplaceFunc(dom.target, 'fbFeedTickerStory', '.fbFeedTickerStory', function(ele) {
9119 var div = ele.getElementsByClassName('uiStreamMessage');
9120 if (div.length) {
9121 div = div[0];
9122
9123 // Ticker messages are really inconsistent
9124 // <span class="passiveName">Friend</span> brohoofs <span class="token">Page</span>'s <span class="token">photo</span>.
9125 // <span class="passiveName">Friend</span> added a new pony pic.
9126 // <span class="passiveName">Friend</span> brohoofs <span class="token">Page</span>'s <span class="token">video</span> Title. // http://fb.com/10200537039965966
9127 var continueTextNodes = true;
9128 for (var i = 0, len = div.childNodes.length; i < len; i += 1) {
9129 var node = div.childNodes[i];
9130 if (node.nodeType == TEXT_NODE) {
9131 if (!continueTextNodes) {
9132 continue;
9133 }
9134
9135 var t = node.textContent;
9136
9137 var boundary = '';
9138 var haltOnBoundary = false;
9139 if (t.indexOf('"') != -1) {
9140 boundary = '"';
9141 haltOnBoundary = true;
9142 } else if (t.indexOf('\'s') != -1) {
9143 boundary = '\'s';
9144 continueTextNodes = false;
9145 }
9146
9147 if (boundary) {
9148 var finalText = k.textNotification(t.substring(0, t.indexOf(boundary)));
9149 finalText += t.substring(t.indexOf(boundary), t.length);
9150 } else {
9151 var finalText = k.textNotification(t);
9152 }
9153 //t = t.replace(/\blikes\b/, " "+CURRENTSTACK['likes_past']);
9154 //t = t.replace(/\blike\b/, " "+CURRENTSTACK['like_past']);
9155 if (node.textContent != finalText) {
9156 node.textContent = finalText;
9157 }
9158
9159 if (boundary && haltOnBoundary) {
9160 break;
9161 }
9162 } else {
9163 // It's too risky changing legit page names, so we are doing this in isolated cases
9164 if (hasClass(node, 'token')) {
9165 var list = [
9166 ['photo', 'pony pic']
9167 ,['a photo', 'a pony pic']
9168 ,['wall', 'journal']
9169 ];
9170 var t = replaceText(list, node.textContent);
9171 if (node.textContent != t) {
9172 node.textContent = t;
9173 }
9174 }
9175 }
9176 }
9177 }
9178 });
9179 if (hasClass(dom.target, 'fbFeedTickerStory')) {
9180 return true;
9181 }
9182 return false;
9183 };
9184
9185 k.pagesVoiceBarText = function(target) {
9186 if (hasClass(target, 'pagesVoiceBarText')) {
9187 if (target.childNodes && target.childNodes.length && target.childNodes[0]) {
9188 var textNode = target.childNodes[0];
9189 if (textNode.nodeType == TEXT_NODE) {
9190 var t = textNode.textContent;
9191 t = t.replace(/\bliking\b/, CURRENTSTACK['liking']);
9192 if (textNode.textContent != t) {
9193 textNode.textContent = t;
9194 }
9195 }
9196 }
9197 return true;
9198 }
9199 return false;
9200 };
9201
9202 k.endOfFeedPymlContainer = function(target) {
9203 if (target.getAttribute && target.getAttribute('id') === 'endOfFeedPymlContainer') {
9204 // _5jii - applicable table cell
9205 $$(target, '._5jii .fsm.fcg', function(ele) {
9206 var orig = ele.textContent;
9207 var t = orig;
9208 t = t.replace(/\bLikes\b/, capitaliseFirstLetter(CURRENTSTACK['likes']));
9209 t = t.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK['like']));
9210 t = t.replace(/\blikes\b/, CURRENTSTACK['likes']);
9211 t = t.replace(/\blike\b/, CURRENTSTACK['like']);
9212 if (t != orig) {
9213 ele.textContent = t;
9214 }
9215 });
9216 $$(target, '._5jii ._5f55', function(link) {
9217 if (link.childNodes && link.childNodes.length && link.childNodes[1] && link.childNodes[1].nodeType === TEXT_NODE) {
9218 var node = link.childNodes[1];
9219 var orig = node.textContent;
9220 var t = orig;
9221 t = t.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK['like']));
9222 if (t != orig) {
9223 node.textContent = t;
9224 }
9225 }
9226 });
9227
9228 return true;
9229 }
9230 return false;
9231 };
9232
9233 k.pubcontentFeedChaining = function(target) {
9234 if (hasClass(target, '_5j5u')) {
9235 $$(target, '._5j5w > .content > div > .fcg', function(fcg) {
9236 var orig = fcg.textContent;
9237 var t = orig;
9238 t = t.replace(/\blikes\b/, CURRENTSTACK['likes']);
9239 t = t.replace(/\blike\b/, CURRENTSTACK['like']);
9240 if (orig != t) {
9241 fcg.textContent = t;
9242 }
9243 });
9244
9245 return true;
9246 }
9247 return false;
9248 };
9249
9250 k._beepNotification_condition_react = function(node, gt) {
9251 // <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>
9252 // <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>
9253
9254 // **XYZ** posted on **Ponyhoof**'s **timeline**: "XYZ"
9255 // **profile people test** posted in **group people test**: "like test"
9256 if (hasClass(node, 'fwb')) {
9257 if (node.textContent === 'timeline') {
9258 return true;
9259 }
9260 return false;
9261 }
9262 return true;
9263 };
9264
9265 k._beepNotification_change = function(ele, info, condition) {
9266 if (!info) {
9267 return;
9268 }
9269
9270 var gt = JSON.parse(ele.getAttribute('data-gt'));
9271 ele.setAttribute('data-ponyhoof-beeper-orig', info.textContent);
9272 for (var i = 0, len = info.childNodes.length; i < len; i += 1) {
9273 var node = info.childNodes[i];
9274 if (condition(node, gt)) {
9275 var text = '';
9276 if (node.nodeType === TEXT_NODE) {
9277 text = node.textContent;
9278 k._beepNotification_change_text(node, text);
9279 } else {
9280 // emoticons are smacked together, so we need to run another loop
9281 for (var j = 0, jLen = node.childNodes.length; j < jLen; j += 1) {
9282 var textNode = node.childNodes[j];
9283 text = textNode.textContent;
9284 k._beepNotification_change_text(textNode, text);
9285 }
9286 }
9287
9288 if (text.indexOf('"') != -1) {
9289 break;
9290 }
9291 }
9292 }
9293 ele.setAttribute('data-ponyhoof-beeper-message', info.textContent);
9294
9295 if (userSettings.sounds) {
9296 var file = '';
9297 if (SOUNDS[userSettings.soundsFile]) {
9298 file = userSettings.soundsFile;
9299 }
9300
9301 if (!file || file == 'AUTO') {
9302 file = '_sound/defaultNotification';
9303
9304 var data = convertCodeToData(REALPONY);
9305 if (data.soundNotif) {
9306 file = data.soundNotif;
9307 }
9308 }
9309
9310 if (userSettings.soundsNotifTypeBlacklist) {
9311 var current = userSettings.soundsNotifTypeBlacklist.split('|');
9312
9313 if (current.indexOf(gt.notif_type) != -1) {
9314 return;
9315 }
9316 }
9317
9318 try {
9319 var finalfile = THEMEURL+file+'.EXT';
9320 if (gt.notif_type == 'poke' && CURRENTSTACK.stack == 'pony') {
9321 finalfile = THEMEURL+'_sound/pokeSound.EXT';
9322 }
9323
9324 var ps = initPonySound('notif', finalfile);
9325 ps.wait = 15;
9326 ps.play();
9327 } catch (e) {}
9328 }
9329 };
9330
9331 k._beepNotification_change_text = function(node, text) {
9332 if (!text) {
9333 return;
9334 }
9335 if (text.indexOf('"') != -1) {
9336 var finalText = k.textNotification(text.substring(0, text.indexOf('"')));
9337 finalText += text.substring(text.indexOf('"'), text.length);
9338 } else {
9339 var finalText = k.textNotification(text);
9340 }
9341
9342 if (text != finalText) {
9343 if (node.nodeType === TEXT_NODE) {
9344 node.textContent = finalText;
9345 } else {
9346 node.innerHTML = finalText;
9347 }
9348 }
9349 };
9350
9351 k.insightsCountryData = [
9352 ["United States of America", "United States of Amareica"]
9353 ,["Malaysia", "Marelaysia"]
9354 ,["Mexico", "Mexicolt"]
9355 ,["New Zealand", "Neigh Zealand"]
9356 ,["Philippines", "Fillypines"]
9357 ,["Singapore", "Singapony"]
9358 ,["Singapore, Singapore", "Singapony"]
9359 ];
9360 k.insightsCountry = function(target) {
9361 /*domReplaceFunc(dom.target, 'breakdown-list-table', '.breakdown-list-table', function(ele) {
9362 if (ele.getAttribute('data-ponyhoof-ponified')) {
9363 return;
9364 }
9365 ele.setAttribute('data-ponyhoof-ponified', 1);
9366 $$(ele, '.breakdown-key .ufb-text-content', function(country) {
9367 country.textContent = replaceText(k.insightsCountryData, country.textContent);
9368 });
9369 });*/
9370
9371 $$(target, '._5brx ._55jr', function(ele) {
9372 var orig = ele.textContent;
9373 var t = orig;
9374 t = replaceText(k.insightsCountryData, ele.textContent);
9375 if (orig != t) {
9376 ele.textContent = t;
9377 }
9378 });
9379 };
9380
9381 k.timelineMutualLikes = function(target) {
9382 $$(target, '.fbStreamTimelineFavStory', function(root) {
9383 $$(root, '.fbStreamTimelineFavInfoContainer', function(ele) {
9384 var done = false;
9385 loopChildText(ele, function(child) {
9386 if (done) {
9387 return;
9388 }
9389 if (child.nodeType == TEXT_NODE) {
9390 var t = k.textStandard(child.textContent);
9391 if (child.textContent != t) {
9392 child.textContent = t;
9393 done = true;
9394 }
9395 }
9396 });
9397 });
9398
9399 $$(root, '.fbStreamTimelineFavFriendContainer > .friendText > .fwn', function(ele) {
9400 loopChildText(ele, function(child) {
9401 if (child.nodeType == ELEMENT_NODE) {
9402 if (!child.href || child.href.indexOf('/browse/users/') == -1) {
9403 return;
9404 }
9405 }
9406 var t = k.textStandard(child.textContent);
9407 if (child.textContent != t) {
9408 child.textContent = t;
9409 }
9410 });
9411 });
9412 });
9413 };
9414
9415 // http://fb.com/406714556116263
9416 // http://fb.com/411361928984859
9417 k.videoStageContainer = function(target) {
9418 if (hasClass(target, 'videoStageContainer')) {
9419 addClass(k.photos_snowlift, 'ponyhoof_snowlift_video');
9420 } else if (hasClass(target, 'spotlight')) {
9421 removeClass(k.photos_snowlift, 'ponyhoof_snowlift_video');
9422 }
9423 };
9424
9425 k.uiStreamShareLikePageBox = function(target) {
9426 $$(target, '.uiStreamShareLikePageBox .uiPageLikeButton.rfloat + div > .fcg', function(ele) {
9427 var t = ele.textContent;
9428 t = t.replace(/likes/g, CURRENTSTACK['likes']);
9429 t = t.replace(/like/g, CURRENTSTACK['like']);
9430 if (ele.textContent != t) {
9431 ele.textContent = t;
9432 }
9433 });
9434 };
9435
9436 k.fbTimelineUnit = function(target) {
9437 if (!hasClass(target, 'fbTimelineUnit')) {
9438 return;
9439 }
9440 if (target.childNodes && target.childNodes.length) {
9441 if (hasClass(target.childNodes[1], 'pageFriendSummaryContainer')) {
9442 var headerText = target.childNodes[1].getElementsByClassName('headerText');
9443 if (!headerText.length) {
9444 return;
9445 }
9446 headerText = headerText[0];
9447
9448 // Friend(s)
9449 $$(headerText, '.fwb > a', function(link) {
9450 var t = link.textContent;
9451 t = t.replace(/\bFriends\b/, capitaliseFirstLetter(CURRENTSTACK['friends']));
9452 t = t.replace(/\bFriend\b/, capitaliseFirstLetter(CURRENTSTACK['friend']));
9453 if (link.textContent != t) {
9454 link.textContent = t;
9455 }
9456 });
9457
9458 // Like(s) PAGENAME
9459 $$(headerText, '.fcg', function(fcg) {
9460 var split = fcg.textContent.split(' ');
9461 var t = split[0];
9462 t = t.replace(/\bLikes\b/, capitaliseFirstLetter(CURRENTSTACK['likes']));
9463 t = t.replace(/\bLike\b/, capitaliseFirstLetter(CURRENTSTACK['like']));
9464 if (split[0] != t) {
9465 split[0] = t;
9466 fcg.textContent = split.join(' ');
9467 }
9468 });
9469
9470 return;
9471 }
9472
9473 // Brohoofs section at pages
9474 var liked_pages_timeline_unit_list = $('liked_pages_timeline_unit_list');
9475 if (liked_pages_timeline_unit_list) {
9476 $$(liked_pages_timeline_unit_list, '._42ef .fcg', function(fcg) {
9477 loopChildText(fcg, function(child) {
9478 // <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>
9479 // also like this.
9480 var t = child.textContent;
9481 t = k.textStandard(t);
9482 if (child.textContent != t) {
9483 child.textContent = t;
9484 }
9485 });
9486 });
9487 }
9488 }
9489 };
9490
9491 // https://www.facebook.com/pages
9492 k.pageBrowserItem = function(target) {
9493 // 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>
9494 if (hasClass(target, '_8qg') && hasClass(target, 'fcg')) {
9495 k._pageBrowserItem_item(target);
9496 return;
9497 }
9498
9499 $$(target, '._8qg.fcg', function(item) {
9500 // <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>
9501 k._pageBrowserItem_item(item);
9502 });
9503 };
9504
9505 k._pageBrowserItem_item = function(item) {
9506 loopChildText(item, function(child) {
9507 if (child.nodeType === TEXT_NODE || hasClass(child, 'fcg')) {
9508 k.textBrohoof(child);
9509 }
9510 });
9511 };
9512
9513 k._dialog_insertReadme = function(body) {
9514 var done = false;
9515 $$(body, '._22i .uiToken > input[type="hidden"]', function(input) { // @cx
9516 if (done) {
9517 return;
9518 }
9519 if (input.getAttribute('name') == 'undefined[]' && isPonyhoofPage(input.value)) { // undefined[] is intentional from FB, NOT A TYPO
9520 addClass(body, 'ponyhoof_composer_hasReadme');
9521
9522 var n = d.createElement('iframe');
9523 n.className = 'ponyhoof_page_readme';
9524 n.scrolling = 'auto';
9525 n.frameborder = '0';
9526 n.allowtransparency = 'true';
9527 n.src = PONYHOOF_README;
9528 body.appendChild(n);
9529
9530 done = true;
9531 }
9532 });
9533 };
9534
9535 k._dialog_playSound = function(title, outer) {
9536 if (!title) {
9537 return;
9538 }
9539 var lowercase = title.toLowerCase();
9540 for (var i = 0, len = dialogDerpTitles.length; i < len; i += 1) {
9541 if (dialogDerpTitles[i].toLowerCase() == lowercase) {
9542 if (outer) {
9543 addClass(outer, 'ponyhoof_fbdialog_derp');
9544 }
9545
9546 if (CURRENTSTACK.stack == 'pony' && userSettings.sounds && !isPageHidden()) {
9547 var ps = initPonySound('ijustdontknowwhatwentwrong', THEMEURL+'_sound/ijustdontknowwhatwentwrong.EXT');
9548 ps.wait = 5;
9549 ps.play();
9550 break;
9551 }
9552 }
9553 }
9554 };
9555
9556 k.ponyhoofPageOptions = function(dom) {
9557 if (!$('pagelet_timeline_page_actions')) {
9558 return;
9559 }
9560 if ($('ponyhoof_footer_options')) {
9561 return;
9562 }
9563
9564 var selector = dom.target.querySelector('#pagelet_timeline_page_actions .fbTimelineActionSelector');
9565 if (!selector) {
9566 return;
9567 }
9568 var menu = selector.getElementsByClassName('uiMenuInner');
9569 if (!menu.length) {
9570 return;
9571 }
9572 menu = menu[0];
9573 var whatpage = menu.querySelector('#fbpage_share_action a');
9574 if (!whatpage) {
9575 return;
9576 }
9577 if (whatpage.getAttribute('href').indexOf('p[]='+PONYHOOF_PAGE) != -1) {
9578 var button = selector.getElementsByClassName('fbTimelineActionSelectorButton');
9579 if (!button.length) {
9580 return;
9581 }
9582 button = button[0];
9583
9584 var sep = d.createElement('li');
9585 sep.className = 'uiMenuSeparator';
9586
9587 var a = d.createElement('a');
9588 a.className = 'itemAnchor';
9589 a.setAttribute('role', 'menuitem');
9590 a.setAttribute('tabindex', '0');
9591 a.href = '#';
9592 a.id = "ponyhoof_footer_options";
9593 a.innerHTML = '<span class="itemLabel fsm">'+CURRENTLANG.options_title+'</span>';
9594 a.addEventListener('click', function(e) {
9595 optionsOpen();
9596
9597 try {
9598 clickLink(button);
9599 } catch (ex) {}
9600
9601 e.preventDefault();
9602 }, false);
9603
9604 var li = d.createElement('li');
9605 li.className = 'uiMenuItem ponyhoof_fbmenuitem';
9606 li.setAttribute('data-label', CURRENTLANG.options_title);
9607 li.setAttribute('data-ponyhoof-menuitem-orig', CURRENTLANG.options_title);
9608 li.setAttribute('data-ponyhoof-menuitem-text', CURRENTLANG.options_title);
9609 li.appendChild(a);
9610
9611 menu.insertBefore(sep, menu.firstChild);
9612 menu.insertBefore(li, sep);
9613 }
9614 };
9615
9616 k.debug_betaFacebookBaseRewrote = false;
9617 k.debug_betaFacebookLinks = function(target) {
9618 if (!k.debug_betaFacebookBaseRewrote) {
9619 contentEval(function(arg) {
9620 try {
9621 if (typeof window.requireLazy == 'function') {
9622 window.requireLazy(['Env'], function(Env) {
9623 Env.www_base = window.location.protocol+'//'+window.location.hostname+'/';
9624 });
9625 }
9626 } catch (e) {
9627 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
9628 console.log("Unable to hook to Env");
9629 console.dir(e);
9630 }
9631 }
9632 }, {"CANLOG":CANLOG});
9633 k.debug_betaFacebookBaseRewrote = true;
9634 }
9635 var links = target.querySelectorAll('a[href^="http://www.facebook.com"], a[href^="https://www.facebook.com"]');
9636 for (var i = 0, len = links.length; i < len; i += 1) {
9637 var link = links[i];
9638 var href = link.href;
9639 href = href.replace(/http\:\/\/www.facebook.com\//, 'http://beta.facebook.com/');
9640 href = href.replace(/https\:\/\/www.facebook.com\//, 'https://beta.facebook.com/');
9641
9642 link.href = href;
9643 }
9644 };
9645
9646 // Mutation
9647 k.mutateCharacterData = function(mutation) {
9648 var parent = null;
9649 if (mutation.target && mutation.target.parentNode) {
9650 parent = mutation.target.parentNode;
9651 if (parent.tagName.toUpperCase() == 'ABBR') {
9652 return;
9653 }
9654 }
9655
9656 if (userSettings.debug_mutationDebug) {
9657 try {
9658 console.log('characterData:');
9659 if (!ISFIREFOX) {
9660 console.dir(mutation.target);
9661 }
9662 } catch (e) {}
9663 }
9664
9665 k.textNodes({target: mutation.target});
9666
9667 if (!parent) {
9668 return;
9669 }
9670 var id = parent.getAttribute(k.REACTATTRNAME);
9671 if (id) {
9672 if (parent.rel == 'dialog') {
9673 if (parent.getAttribute('ajaxify').indexOf('/ajax/browser/dialog/likes') == 0) {
9674 k.getParent(parent, function(likesentence) {
9675 return hasClass(likesentence, 'UFILikeSentence');
9676 }, function(likesentence) {
9677 if (likesentence) {
9678 k._likePostBox(likesentence);
9679 }
9680 });
9681 }
9682 } else if (hasClass(parent.parentNode, 'UFIPagerLink')) {
9683 k.ufiPagerLink({target: parent.parentNode.parentNode});
9684 } else if (hasClass(parent, 'ponyhoof_brohoof_button')) {
9685 k._commentLikeLink(parent);
9686 } else if (parent.nextSibling && hasClass(parent.nextSibling, 'UFIOrderingModeSelectorDownCaret')) {
9687 k.UFIOrderingMode(parent);
9688 } else {
9689 if (parent.parentNode && parent.parentNode.parentNode) {
9690 //if (hasClass(parent.parentNode.parentNode, 'UFIImageBlockContent') || (parent.parentNode.parentNode.parentNode && hasClass(parent.parentNode.parentNode.parentNode, 'UFIImageBlockContent'))) {
9691 if (hasClass(parent.parentNode.parentNode, 'UFILikeSentenceText') || (parent.parentNode.parentNode.parentNode && hasClass(parent.parentNode.parentNode.parentNode, 'UFILikeSentenceText'))) {
9692 // live commenting
9693 // You and John brohoof this.
9694 // You like this.
9695 var ufi = k.getReactUfi(parent);
9696 if (ufi) {
9697 k.postLike({target: ufi});
9698 }
9699 } else {
9700 if (hasClass(parent.parentNode.parentNode, k.notification_textClass[0]) || hasClass(parent.parentNode.parentNode, k.notification_textClass[1])) {
9701 // gosh, i dislike this...
9702 k.getParent(parent, function(notificationItem) {
9703 return hasClass(notificationItem, k.notification_itemClass[0]) || hasClass(notificationItem, k.notification_itemClass[1]);
9704 }, function(notificationItem) {
9705 if (!notificationItem) {
9706 return;
9707 }
9708
9709 var i = 0;
9710 if (hasClass(notificationItem, k.notification_itemClass[1])) {
9711 i = 1;
9712 }
9713
9714 k._notification_change(notificationItem, '.'+k.notification_textClass[i]+' > span', k._notification_react_metadata);
9715 });
9716 }
9717 }
9718 }
9719 }
9720 } else {
9721 // Nuzzles
9722 if (hasClass(parent, '_5lbu') || hasClass(parent, '-cx-PRIVATE-pokesDashboard__pokerbuttons')) {
9723 var t = mutation.target.textContent;
9724 t = t.replace(/\bPoke\b/, 'Nuzzle');
9725 if (mutation.target.textContent != t) {
9726 mutation.target.textContent = t;
9727 }
9728 }
9729 }
9730 };
9731
9732 k.mutateAttributes = function(mutation) {
9733 //if (mutation.attributeName.indexOf('data-ponyhoof-') == 0) {
9734 // return;
9735 //}
9736 var target = mutation.target;
9737 if (mutation.attributeName == 'title') {
9738 if (target.title == target.getAttribute('data-ponyhoof-title-modified')) {
9739 return;
9740 }
9741 }
9742 switch (mutation.attributeName) {
9743 case 'title':
9744 var id = target.getAttribute(k.REACTATTRNAME);
9745 if (id) {
9746 if (hasClass(target, 'UFILikeLink')) {
9747 if (target.title == '' && mutation.oldValue != '') { // thanks a lot Hover Zoom
9748 target.setAttribute('data-ponyhoof-title', mutation.oldValue);
9749 target.setAttribute('data-ponyhoof-title-modified', mutation.oldValue);
9750 } else {
9751 var orig = target.title;
9752 var t = orig;
9753 t = t.replace(/\bcomment\b/, "friendship letter");
9754 t = t.replace(/\bLike this \b/, capitaliseFirstLetter(CURRENTSTACK.like)+' this ');
9755 t = t.replace(/\bUnlike this \b/, capitaliseFirstLetter(CURRENTSTACK.unlike)+' this ');
9756 t = t.replace(/\bunlike this \b/, CURRENTSTACK.unlike+' this ');
9757 t = t.replace(/\bliking this \b/, CURRENTSTACK.liking+' this ');
9758
9759 if (orig != t) {
9760 target.title = t;
9761 }
9762 target.setAttribute('data-ponyhoof-title', orig);
9763 target.setAttribute('data-ponyhoof-title-modified', t);
9764 }
9765 }
9766 }
9767 break;
9768
9769 /*case 'value':
9770 if (/*(target.parentNode && hasClass(target.parentNode, 'uiButton')) || * /hasClass(target, 'ufb-button-input')) {
9771 var button = target.parentNode;
9772 if (button) {
9773 var orig = target.value;
9774 var replaced = replaceText(buttonTitles, orig);
9775 if (/*hasClass(button, 'uiButton') || * /hasClass(button, 'ufb-button')) {
9776 if (button.getAttribute('data-hover') != 'tooltip') {
9777 if (orig != replaced) {
9778 if (button.title == '') {
9779 button.title = orig;
9780 } else {
9781 if (button.title == button.getAttribute('data-ponyhoof-button-orig')) {
9782 button.title = orig;
9783 }
9784 }
9785 } else {
9786 button.title = '';
9787 }
9788 }
9789 button.setAttribute('data-ponyhoof-button-orig', orig);
9790 button.setAttribute('data-ponyhoof-button-text', replaced);
9791 }
9792 if (orig != replaced) {
9793 target.value = replaced;
9794 }
9795 }
9796 }
9797 break;*/
9798
9799 default:
9800 break;
9801 }
9802 };
9803
9804 // Utilities
9805 k.getParent = function(ele, iffunc, func) {
9806 var outer = ele.parentNode;
9807 while (outer) {
9808 if (iffunc(outer)) {
9809 break;
9810 }
9811 outer = outer.parentNode;
9812 }
9813
9814 func(outer);
9815 };
9816
9817 k.changeButtonText = function(button, t) {
9818 if (button.tagName.toUpperCase() == 'INPUT') {
9819 button.value = t;
9820 } else {
9821 button.innerHTML = t;
9822 }
9823 };
9824
9825 // Delays and let Facebook finish changing the DOM
9826 // Note that this shouldn't be a problem when MutationObserver is used full-time
9827 k.delayIU = function(func, delay) {
9828 var delay = delay || 10;
9829
9830 if (USINGMUTATION) {
9831 func();
9832 return;
9833 }
9834
9835 w.setTimeout(function() {
9836 var iu = INTERNALUPDATE;
9837 INTERNALUPDATE = true;
9838 func();
9839 INTERNALUPDATE = iu;
9840 }, delay);
9841 };
9842
9843 k.getReactUfi = function(ele) {
9844 // .reactRoot[3].[1][0].0.[1].0.0.[2]
9845 var finalid = k.getReactId(ele);
9846
9847 var ufi = d.querySelector('div['+k.REACTATTRNAME+'=".r['+finalid+']"]');
9848 if (ufi && hasClass(ufi, 'UFIList')) {
9849 return ufi;
9850 }
9851
9852 // Rollback to old method
9853 k.getParent(ele, function(ufiitem) {
9854 return hasClass(ufiitem, 'UFIList');
9855 }, function(ufiitem) {
9856 ufi = ufiitem;
9857 });
9858 return ufi;
9859 };
9860
9861 k.getReactCommentComponent = function(ele) {
9862 // .reactRoot[3].[1][2][1]{comment105273202993369_7901}.0.[1].0.[1].0.[1].[2]
9863 // .reactRoot[1].:1:1:1:comment558202387555478_1973546.:0.:1.:0.:1.:0
9864 var id = ele.getAttribute(k.REACTATTRNAME);
9865 if (!id) {
9866 return false;
9867 }
9868 var open = id.indexOf('{comment');
9869 var close = '}';
9870 var closeCount = 1;
9871 if (open == -1) {
9872 open = id.indexOf(':comment');
9873 if (open == -1) {
9874 return false;
9875 }
9876 close = '.:';
9877 closeCount = 0;
9878 }
9879 var subEnd = id.substring(open, id.length).indexOf(close);
9880 var component = id.substring(0, open+subEnd+closeCount);
9881
9882 return component;
9883 };
9884
9885 k.getReactComment = function(ele) {
9886 var component = k.getReactCommentComponent(ele);
9887
9888 var comment = d.querySelector('div['+k.REACTATTRNAME+'="'+component+'"]');
9889 if (comment && hasClass(comment, 'UFIComment')) {
9890 return comment;
9891 }
9892
9893 // Rollback to old method
9894 k.getParent(ele, function(ufiitem) {
9895 return hasClass(ufiitem, 'UFIComment');
9896 }, function(ufiitem) {
9897 comment = ufiitem;
9898 });
9899 return comment;
9900 };
9901
9902 k.getTrackingNode = function(ele) {
9903 var trackingNode = ele.getAttribute('data-ft');
9904 if (trackingNode) {
9905 try {
9906 trackingNode = JSON.parse(trackingNode);
9907 return trackingNode.tn;
9908 } catch (e) {}
9909 }
9910 return false;
9911 };
9912
9913 k.updateLayerPosition = function(layer) {
9914 var tempClass = 'ponyhoof_temp_'+(+new Date());
9915 addClass(layer, tempClass);
9916
9917 contentEval(function(arg) {
9918 try {
9919 if (typeof window.requireLazy == 'function') {
9920 window.requireLazy(['DataStore'], function(DataStore) {
9921 var layer = document.getElementsByClassName(arg.tempClass);
9922 if (!layer || !layer.length) {
9923 return;
9924 }
9925 layer = layer[0];
9926
9927 var layerClass = DataStore.get(layer, 'layer');
9928 layerClass.updatePosition();
9929 layerClass = null;
9930
9931 if (layer.classList) {
9932 layer.classList.remove(arg.tempClass);
9933 }
9934 });
9935 }
9936 } catch (e) {
9937 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
9938 console.log("Unable to hook to DataStore");
9939 console.dir(e);
9940 }
9941 }
9942 }, {'CANLOG':CANLOG, 'tempClass':tempClass});
9943
9944 if (!layer.classList) {
9945 w.setTimeout(function() {
9946 removeClass(layer, tempClass);
9947 }, 500);
9948 }
9949 };
9950
9951 // Ignore irrelevant tags and some classes
9952 k.shouldIgnore = function(dom) {
9953 if (dom.target.nodeType == 8) { // comments
9954 return true;
9955 }
9956
9957 if (dom.target.nodeType != 3) {
9958 var tn = dom.target.tagName.toUpperCase();
9959 if (tn == 'SCRIPT' || tn == 'STYLE' || tn == 'LINK' || tn == 'INPUT' || tn == 'BR' || tn == 'META') {
9960 return true;
9961 }
9962 }
9963
9964 if (dom.target.parentNode && /(DOMControl_shadow|highlighterContent|textMetrics)/.test(dom.target.parentNode.className)) {
9965 return true;
9966 }
9967
9968 return false;
9969 };
9970
9971 k.dumpConsole = function(dom) {
9972 if (!userSettings.debug_dominserted_console) {
9973 return;
9974 }
9975
9976 if (dom.target.nodeType == 8) { // comments
9977 return;
9978 }
9979
9980 if (dom.target.nodeType == 3) {
9981 if (dom.target.parentNode && dom.target.parentNode.tagName.toUpperCase() != 'ABBR') {
9982 if (typeof console !== 'undefined' && console.dir) {
9983 console.dir(dom.target);
9984 }
9985 }
9986 return;
9987 }
9988
9989 var id = dom.target.getAttribute('id');
9990 if (id && (id.indexOf('bfb_') == 0 || id.indexOf('sfx_') == 0)) {
9991 return;
9992 }
9993
9994 var className = dom.target.className;
9995 if (className.indexOf('bfb_') == 0 || className.indexOf('sfx_') == 0) {
9996 return;
9997 }
9998
9999 var tagName = dom.target.tagName.toUpperCase();
10000 if (tagName != 'BODY') {
10001 if (typeof console !== 'undefined' && console.log) {
10002 console.log(dom.target.outerHTML);
10003 }
10004 }
10005 };
10006
10007 k.textBrohoof = function(ele) {
10008 var orig = '';
10009 var t = '';
10010 if (ele.nodeType === TEXT_NODE) {
10011 orig = ele.textContent;
10012 } else {
10013 orig = ele.innerHTML;
10014 }
10015 t = orig;
10016 t = t.replace(/\bpeople\b/g, " "+CURRENTSTACK['people']);
10017 t = t.replace(/\bperson\b/g, " "+CURRENTSTACK['person']);
10018 t = t.replace(/likes this/g, CURRENTSTACK['likes']+" this");
10019 t = t.replace(/like this/g, CURRENTSTACK['like']+" this");
10020 t = t.replace(/Likes/g, capitaliseFirstLetter(CURRENTSTACK['likes'])); // new news feed page likes
10021 t = t.replace(/likes/g, CURRENTSTACK['likes']);
10022 t = t.replace(/like/g, CURRENTSTACK['like']);
10023 t = t.replace(/\btalking about this\b/g, "blabbering about this");
10024 t = t.replace(/\bfriends\b/g, CURRENTSTACK['friends_logic']);
10025 t = t.replace(/\bfriend\b/g, CURRENTSTACK['friend_logic']);
10026 if (orig != t) {
10027 if (ele.nodeType === TEXT_NODE) {
10028 ele.textContent = t;
10029 } else {
10030 ele.innerHTML = t;
10031 }
10032 }
10033 };
10034
10035 k.textStandard = function(t) {
10036 t = t.replace(/\bpeople\b/g, " "+CURRENTSTACK['people']);
10037 t = t.replace(/\bfriends\b/g, " "+CURRENTSTACK['friends_logic']);
10038 t = t.replace(/\bfriend\b/g, " "+CURRENTSTACK['friend_logic']);
10039 t = t.replace(/\blikes\b/g, " "+CURRENTSTACK['likes_past']);
10040 t = t.replace(/\blike\b/g, " "+CURRENTSTACK['like_past']);
10041 return t;
10042 };
10043
10044 k.textNotification = function(t) {
10045 t = t.replace(/\bpeople\b/g, " "+CURRENTSTACK['people']);
10046 t = t.replace(/\(friends\b/g, "("+CURRENTSTACK['friends_logic']);
10047 t = t.replace(/\bfriends\b/g, " "+CURRENTSTACK['friends_logic']);
10048 t = t.replace(/\binvited you to like\b/g, " invited you to "+CURRENTSTACK.like);
10049 t = t.replace(/\blikes\b/g, " "+CURRENTSTACK['likes_past']);
10050 t = t.replace(/\blike\b/g, " "+CURRENTSTACK['like_past']);
10051
10052 t = t.replace(/\bcomment\b/g, "friendship letter");
10053 t = t.replace(/\bphoto\b/g, "pony pic");
10054 t = t.replace(/\bphotos\b/g, "pony pics");
10055 t = t.replace(/\bgroup\b/g, "herd");
10056 t = t.replace(/\bevent\b/g, "adventure");
10057 t = t.replace(/\btimeline\b/g, "journal");
10058 t = t.replace(/\bTimeline Review\b/g, "Journal Review");
10059 t = t.replace(/\bTimeline\b/g, "Journal"); // English UK
10060 t = t.replace(/\bnew messages\b/, "new friendship reports");
10061 t = t.replace(/\bnew message\b/, "new friendship report");
10062 t = t.replace(/\bprofile picture\b/g, "journal pony pic");
10063 t = t.replace(/\bfriend request\b/g, "friendship request");
10064 t = t.replace(/\bpoked you/g, " nuzzled you");
10065 return t;
10066 };
10067 };
10068 var _optionsLinkInjected = false;
10069 var injectOptionsLink = function() {
10070 if (_optionsLinkInjected) {
10071 return;
10072 }
10073
10074 if ($('logout_form')) {
10075 _optionsLinkInjected = true;
10076
10077 var optionsLink = d.createElement('a');
10078 optionsLink.href = '#';
10079 optionsLink.id = 'ponyhoof_account_options';
10080 optionsLink.className = 'navSubmenu submenuNav'; // submenuNav is for developers.facebook.com
10081 optionsLink.innerHTML = CURRENTLANG.options_title+" <span class='ponyhoof_hide_if_injected inline'>(Disabled)</span>";
10082 optionsLink.addEventListener('click', function(e) {
10083 optionsOpen();
10084
10085 try {
10086 clickLink($('navAccountLink'));
10087 } catch (e) {}
10088 try {
10089 clickLink($('accountNavArrow'));
10090 } catch (e) {}
10091
10092 e.preventDefault();
10093 }, false);
10094
10095 var optionsLinkLi = d.createElement('li');
10096 optionsLinkLi.setAttribute('role', 'menuitem');
10097 optionsLinkLi.appendChild(optionsLink);
10098
10099 var logout = $('logout_form');
10100 logout.parentNode.parentNode.insertBefore(optionsLinkLi, logout.parentNode);
10101 } else {
10102 var pageNav = $('pageNav');
10103 if (!pageNav) {
10104 return;
10105 }
10106
10107 var isBusiness = pageNav.querySelector('.navLink[href*="logout.php?h="]');
10108 if (!isBusiness) {
10109 return;
10110 }
10111
10112 _optionsLinkInjected = true;
10113
10114 var optionsLink = d.createElement('a');
10115 optionsLink.href = '#';
10116 optionsLink.id = 'ponyhoof_account_options';
10117 optionsLink.className = 'navLink';
10118 optionsLink.innerHTML = CURRENTLANG.options_title+" <span class='ponyhoof_hide_if_injected inline'>(Disabled)</span>";
10119 optionsLink.addEventListener('click', function(e) {
10120 optionsOpen();
10121 e.preventDefault();
10122 }, false);
10123
10124 var optionsLinkLi = d.createElement('li');
10125 optionsLinkLi.className = 'navItem middleItem';
10126 optionsLinkLi.appendChild(optionsLink);
10127
10128 pageNav.insertBefore(optionsLinkLi, pageNav.childNodes[0]);
10129 }
10130 };
10131
10132 var domNodeHandlerMain = new domNodeHandler();
10133 var mutationObserverMain = null;
10134
10135 var ranDOMNodeInserted = false;
10136 var runDOMNodeInserted = function() {
10137 if (ranDOMNodeInserted) {
10138 return false;
10139 }
10140
10141 ranDOMNodeInserted = true;
10142
10143 onPageReady(function() {
10144 if (d.body) {
10145 DOMNodeInserted({target: d.body});
10146 }
10147 });
10148
10149 if (!userSettings.debug_noMutationObserver) {
10150 try {
10151 var mutationObserver = w.WebKitMutationObserver || w.MutationObserver || false;
10152 if (mutationObserver) {
10153 var observerOptions = {attributes:true, childList:true, characterData:true, subtree:true, attributeOldValue:true, attributeFilter:['title'/*, 'class', 'value'*/]};
10154 mutationObserverMain = new mutationObserver(function(mutations) {
10155 if (INTERNALUPDATE) {
10156 return;
10157 }
10158 mutationObserverMain.disconnect();
10159
10160 for (var i = 0, len = mutations.length; i < len; i += 1) {
10161 switch (mutations[i].type) {
10162 case 'characterData':
10163 var iu = INTERNALUPDATE;
10164 INTERNALUPDATE = true;
10165
10166 domNodeHandlerMain.mutateCharacterData(mutations[i]);
10167
10168 INTERNALUPDATE = iu;
10169 break;
10170
10171 case 'childList':
10172 for (var j = 0, jlen = mutations[i].addedNodes.length; j < jlen; j += 1) {
10173 if (userSettings.debug_mutationDebug) {
10174 if (mutations[i].addedNodes[j].parentNode && mutations[i].addedNodes[j].parentNode.tagName != 'ABBR') {
10175 try {
10176 console.log('childList:');
10177 if (!ISFIREFOX) {
10178 console.dir(mutations[i].addedNodes[j]);
10179 } else {
10180 if (typeof mutations[i].addedNodes[j].className == 'undefined') {
10181 console.dir(mutations[i].addedNodes[j]);
10182 } else {
10183 //console.log(' '+mutations[i].addedNodes[j].className);
10184 //console.log(' '+mutations[i].addedNodes[j].innerHTML);
10185 }
10186 }
10187 } catch (e) {}
10188 }
10189 }
10190 DOMNodeInserted({target: mutations[i].addedNodes[j]});
10191 }
10192 break;
10193
10194 case 'attributes':
10195 var iu = INTERNALUPDATE;
10196 INTERNALUPDATE = true;
10197
10198 domNodeHandlerMain.mutateAttributes(mutations[i]);
10199
10200 INTERNALUPDATE = iu;
10201 break;
10202
10203 default:
10204 break;
10205 }
10206 }
10207 if (userSettings.debug_mutationDebug) {
10208 console.log('=========================================');
10209 }
10210 mutationObserverMain.observe(d.documentElement, observerOptions);
10211 });
10212 mutationObserverMain.observe(d.documentElement, observerOptions);
10213 USINGMUTATION = true;
10214 }
10215 } catch (e) {
10216 warn("MutationObserver threw an exception, fallback to DOMNodeInserted");
10217 dir(e);
10218 }
10219 }
10220 if (!USINGMUTATION) {
10221 d.addEventListener('DOMNodeInserted', DOMNodeInserted, true);
10222 }
10223
10224 if (d.body) {
10225 DOMNodeInserted({target: d.body});
10226 }
10227 };
10228
10229 var turnOffFbNotificationSound = function() {
10230 contentEval(function(arg) {
10231 try {
10232 if (typeof window.requireLazy == 'function') {
10233 window.requireLazy(['NotificationSound'], function(NotificationSound) {
10234 NotificationSound.prototype.play = function() {};
10235 });
10236 }
10237 } catch (e) {
10238 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
10239 console.log("Unable to hook to NotificationSound");
10240 console.dir(e);
10241 }
10242 }
10243 }, {"CANLOG":CANLOG});
10244 };
10245
10246 var changeChatSound = function(code) {
10247 onPageReady(function() {
10248 contentEval(function(arg) {
10249 try {
10250 if (typeof window.requireLazy == 'function') {
10251 window.requireLazy(['ChatConfig'], function(ChatConfig) {
10252 ChatConfig.set('sound.notif_ogg_url', arg.THEMEURL+arg.code+'.ogg');
10253 ChatConfig.set('sound.notif_mp3_url', arg.THEMEURL+arg.code+'.mp3');
10254 });
10255 }
10256 } catch (e) {
10257 if (arg.CANLOG && typeof console != 'undefined' && console.log && console.dir) {
10258 console.log("Unable to hook to ChatConfig");
10259 console.dir(e);
10260 }
10261 }
10262 }, {"CANLOG":CANLOG, "THEMEURL":THEMEURL, 'code':code});
10263 });
10264 };
10265
10266 var ranExtraInjection = false;
10267 var extraInjection = function() {
10268 if (ranExtraInjection) {
10269 return false;
10270 }
10271 ranExtraInjection = true;
10272
10273 for (var x in HTMLCLASS_SETTINGS) {
10274 if (userSettings[HTMLCLASS_SETTINGS[x]]) {
10275 addClass(d.documentElement, 'ponyhoof_settings_'+HTMLCLASS_SETTINGS[x]);
10276 }
10277 }
10278
10279 var globalcss = '';
10280 globalcss += '.ponyhoof_page_readme {width:100%;height:300px;border:solid #B4BBCD;border-width:1px 0;-moz-box-sizing:border-box;box-sizing:border-box;}';
10281 globalcss += '#fbIndex_swf {position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;}';
10282 globalcss += '.ponyhoof_image_shadow {-moz-box-shadow:0 3px 8px rgba(0,0,0,.3);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;}';
10283 globalcss += '.ponyhoof_image_shadow.noshadow {-moz-box-shadow:none;box-shadow:none;}';
10284 globalcss += '.ponyhoof_tooltip_widthFix {width:auto !important;}';
10285
10286 injectManualStyle(globalcss, 'global');
10287
10288 if (userSettings.customcss) {
10289 injectManualStyle(userSettings.customcss, 'customcss');
10290 }
10291
10292 INTERNALUPDATE = true;
10293 for (var i = 0; i < 10; i += 1) {
10294 var n = d.createElement('div');
10295 n.id = 'ponyhoof_extra_'+i;
10296 d.body.appendChild(n);
10297 }
10298
10299 var timeShift = function() {
10300 var now = new Date();
10301
10302 d.documentElement.setAttribute('data-ponyhoof-year', now.getFullYear());
10303 d.documentElement.setAttribute('data-ponyhoof-month', now.getMonth());
10304 d.documentElement.setAttribute('data-ponyhoof-date', now.getDate());
10305 d.documentElement.setAttribute('data-ponyhoof-hour', now.getHours());
10306 d.documentElement.setAttribute('data-ponyhoof-minute', now.getMinutes());
10307 };
10308 timeShift();
10309 w.setInterval(timeShift, 60*1000);
10310
10311 if (userSettings.chatSound) {
10312 if (!SOUNDS_CHAT[userSettings.chatSoundFile] || !SOUNDS_CHAT[userSettings.chatSoundFile].name) {
10313 userSettings.chatSoundFile = '_sound/grin2';
10314 }
10315 if (typeof w.Audio != 'undefined') {
10316 changeChatSound(userSettings.chatSoundFile);
10317 }
10318 }
10319
10320 if (userSettings.customBg && !ONPLUGINPAGE) {
10321 changeCustomBg(userSettings.customBg);
10322 }
10323
10324 // Turn off Facebook's own notification sound
10325 if (userSettings.sounds) {
10326 turnOffFbNotificationSound();
10327 }
10328
10329 INTERNALUPDATE = false;
10330 };
10331
10332 var detectBrokenFbStyle = function() {
10333 var test = d.createElement('div');
10334 test.className = 'hidden_elem';
10335 d.documentElement.appendChild(test);
10336
10337 var style = w.getComputedStyle(test, null);
10338 if (style && style.display != 'none') {
10339 d.documentElement.removeChild(test);
10340
10341
10342 return true;
10343 }
10344 d.documentElement.removeChild(test);
10345 return false;
10346 };
10347
10348 // Wait for the current page to complete
10349 var scriptStarted = false;
10350 function startScript() {
10351 if (scriptStarted) {
10352 return;
10353 }
10354 scriptStarted = true;
10355
10356 // Don't run on exclusions
10357 if (w.location.hostname.indexOf('.facebook.com') == w.location.hostname.length-'.facebook.com'.length) {
10358 var excludes = ['/l.php', '/ai.php', '/ajax/'];
10359 for (var i = 0, len = excludes.length; i < len; i += 1) {
10360 if (w.location.pathname.indexOf(excludes[i]) == 0) {
10361 return;
10362 }
10363 }
10364 }
10365
10366 // Don't run on ajaxpipe
10367 if (w.location.search && w.location.search.indexOf('ajaxpipe=1') != -1) {
10368 return;
10369 }
10370
10371 // Don't run on Browser Ponies
10372 if (w.location.hostname == 'hoof.little.my') {
10373 var excludes = ['.gif', '.png'];
10374 for (var i = 0, len = excludes.length; i < len; i += 1) {
10375 if (w.location.pathname.indexOf(excludes[i]) != -1) {
10376 return;
10377 }
10378 }
10379 }
10380
10381 // Don't run on Open Graph Debugger
10382 if (w.location.hostname.indexOf('developers.') != -1 && w.location.hostname.indexOf('.facebook.com') != -1 && w.location.pathname == '/tools/debug/og/echo') {
10383 return;
10384 }
10385
10386 if (w.location.hostname == '0.facebook.com') {
10387 return;
10388 }
10389
10390 if (!d.head) {
10391 d.head = d.getElementsByTagName('head')[0];
10392 }
10393
10394 // Are we running in a special Ponyhoof page?
10395 if (d.documentElement.id == 'ponyhoof_page') {
10396 // Modify the <html> tag
10397 addClass(d.documentElement, 'ponyhoof_userscript');
10398 d.documentElement.setAttribute('data-ponyhoof-userscript-version', VERSION);
10399
10400 var changeVersion = function() {
10401 var v = d.getElementsByClassName('ponyhoof_VERSION');
10402 for (var i = 0, len = v.length; i < len; i += 1) {
10403 v[i].textContent = VERSION;
10404 }
10405 };
10406 changeVersion();
10407 onPageReady(changeVersion);
10408
10409 try {
10410 if (d.documentElement.getAttribute('data-ponyhoof-update-current') > VERSION) {
10411 addClass(d.documentElement, 'ponyhoof_update_outdated');
10412 } else {
10413 addClass(d.documentElement, 'ponyhoof_update_newest');
10414 }
10415 } catch (e) {}
10416 }
10417
10418 // Determine what storage method to use
10419 STORAGEMETHOD = 'none';
10420 try {
10421 if (typeof GM_getValue === 'function' && typeof GM_setValue === 'function') {
10422 // Chrome lies about GM_getValue support
10423 GM_setValue("ponyhoof_test", "ponies");
10424 if (GM_getValue("ponyhoof_test") === "ponies") {
10425 STORAGEMETHOD = 'greasemonkey';
10426 }
10427 }
10428 } catch (e) {}
10429
10430 if (STORAGEMETHOD == 'none') {
10431 try {
10432 if (typeof chrome != 'undefined' && chrome && chrome.extension && typeof GM_getValue == 'undefined') {
10433 STORAGEMETHOD = 'chrome';
10434 }
10435 } catch (e) {}
10436 }
10437
10438 if (STORAGEMETHOD == 'none') {
10439 try {
10440 if (typeof opera != 'undefined' && opera && opera.extension) {
10441 STORAGEMETHOD = 'opera';
10442 }
10443 } catch (e) {}
10444 }
10445
10446 if (STORAGEMETHOD == 'none') {
10447 try {
10448 if (typeof safari != 'undefined') {
10449 STORAGEMETHOD = 'safari';
10450 }
10451 } catch (e) {}
10452 }
10453
10454 if (STORAGEMETHOD == 'none') {
10455 if (DISTRIBUTION == 'xpi') {
10456 STORAGEMETHOD = 'xpi';
10457 }
10458 }
10459
10460 if (STORAGEMETHOD == 'none') {
10461 if (DISTRIBUTION == 'mxaddon') {
10462 STORAGEMETHOD = 'mxaddon';
10463 }
10464 }
10465
10466 if (STORAGEMETHOD == 'none') {
10467 STORAGEMETHOD = 'localstorage';
10468 }
10469
10470 if (d.documentElement.id == 'ponyhoof_page') {
10471 addClass(d.documentElement, 'ponyhoof_distribution_'+DISTRIBUTION);
10472 addClass(d.documentElement, 'ponyhoof_storagemethod_'+STORAGEMETHOD);
10473 return;
10474 }
10475
10476 // Inject the system style so we can do any error trapping
10477 injectSystemStyle();
10478
10479 // Grab the user
10480 USERID = cookie('c_user');
10481 if (!USERID) {
10482 USERID = 0;
10483 } else {
10484 SETTINGSPREFIX = USERID+'_';
10485 }
10486
10487 loadSettings(function(s) {
10488 userSettings = s;
10489
10490 loadSettings(function(s) {
10491 globalSettings = s;
10492
10493 if (userSettings.debug_slow_load) {
10494 onPageReady(settingsLoaded);
10495 return;
10496 }
10497 settingsLoaded();
10498 }, {prefix:'global_', defaultSettings:GLOBALDEFAULTSETTINGS});
10499 });
10500 };
10501
10502 // Check for legacy settings through message passing
10503 var migrateSettingsChromeDone = false;
10504 var migrateSettingsChrome = function(callback) {
10505 if (STORAGEMETHOD == 'chrome') {
10506 if (chrome.storage) {
10507 try {
10508 chrome_sendMessage({'command':'getValue', 'name':SETTINGSPREFIX+'settings'}, function(response) {
10509 if (response && typeof response.val != 'undefined') {
10510 var _settings = JSON.parse(response.val);
10511 if (_settings) {
10512 userSettings = _settings;
10513 saveSettings();
10514
10515 chrome_sendMessage({'command':'clearStorage'}, function() {});
10516 }
10517
10518 migrateSettingsChromeDone = true;
10519 callback();
10520 }
10521 });
10522 } catch (e) {
10523 error("Failed to read previous settings through message passing");
10524 dir(e);
10525 migrateSettingsChromeDone = true;
10526 callback();
10527 }
10528 return;
10529 }
10530 }
10531 migrateSettingsChromeDone = true;
10532 callback();
10533 };
10534
10535 // Check for previous settings from unprefixed settings
10536 var migrateSettingsUnprefixedDone = false;
10537 var migrateSettingsUnprefixed = function(callback) {
10538 loadSettings(function(s) {
10539 if (s.lastVersion) { // only existed in previous versions
10540 userSettings = s;
10541 saveSettings();
10542 saveValue('settings', JSON.stringify(null));
10543 }
10544
10545 migrateSettingsUnprefixedDone = true;
10546 callback();
10547 }, {prefix:''});
10548 };
10549
10550 var globalSettingsTryLastUserDone = false;
10551 var globalSettingsTryLastUser = function(callback) {
10552 if (!globalSettings.lastUserId) {
10553 globalSettingsTryLastUserDone = true;
10554 callback();
10555 return;
10556 }
10557
10558 SETTINGSPREFIX = globalSettings.lastUserId+'_';
10559 loadSettings(function(s) {
10560 if (s) {
10561 userSettings = s;
10562 }
10563
10564 globalSettingsTryLastUserDone = true;
10565 callback();
10566 });
10567 };
10568
10569 function settingsLoaded() {
10570 if (!userSettings.theme && !migrateSettingsChromeDone) {
10571 migrateSettingsChrome(settingsLoaded);
10572 return;
10573 }
10574
10575 // Migrate for multi-user
10576 if (!userSettings.theme && !migrateSettingsUnprefixedDone) {
10577 migrateSettingsUnprefixed(settingsLoaded);
10578 return;
10579 }
10580
10581 if (!globalSettings.globalSettingsMigrated) {
10582 if (!userSettings.lastVersion) {
10583 // New user
10584 statTrack('install');
10585 }
10586
10587 for (var i in GLOBALDEFAULTSETTINGS) {
10588 if (userSettings.hasOwnProperty(i)) {
10589 globalSettings[i] = userSettings[i];
10590 }
10591 }
10592 globalSettings.globalSettingsMigrated = true;
10593 saveGlobalSettings();
10594 }
10595
10596 if (!USERID && !globalSettingsTryLastUserDone) {
10597 // Try loading the last user
10598 globalSettingsTryLastUser(settingsLoaded);
10599 return;
10600 }
10601
10602 // If we haven't set up Ponyhoof, don't log
10603 if (!userSettings.theme || userSettings.debug_disablelog) {
10604 CANLOG = false;
10605 }
10606
10607 // Run ONLY on #facebook
10608 if (!(d.documentElement.id == 'facebook' && w.location.hostname.indexOf('.facebook.com') == w.location.hostname.length-'.facebook.com'.length) && d.documentElement.id != 'ponyhoof_page') {
10609 info("Ponyhoof does not run on "+w.location.href+" (html id is not #facebook)");
10610 return;
10611 }
10612
10613 // Did we already run our script?
10614 if (hasClass(d.documentElement, 'ponyhoof_userscript')) {
10615 info("Style already injected at "+w.location.href);
10616 return;
10617 }
10618
10619 // Don't run in frames
10620 var forceWhiteBackground = false;
10621 try {
10622 var href = w.location.href.toLowerCase();
10623
10624 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))) {
10625 // Allow like boxes for the Ponyhoof page (yeah, a bit cheating)
10626 } else if (hasClass(d.body, 'chrmxt')) {
10627 // Allow for Facebook Notifications for Chrome
10628 } else {
10629 // Allow for some frames
10630 var allowedFrames = ['/ads/manage/powereditor/funding', '/ads/manage/powereditor/convtrack', '/mobile/iframe_emails.php'];
10631 var allowedFramesOk = false;
10632 for (var i = 0, len = allowedFrames.length; i < len; i += 1) {
10633 if (w.location.pathname.indexOf(allowedFrames[i]) == 0) {
10634 allowedFramesOk = true;
10635 forceWhiteBackground = true;
10636 }
10637 }
10638
10639 // Allow for comment boxes owned by Ponyhoof
10640 // (in theory, we could still be run by http://example/?api_key=231958156911371 but this isn't a big deal)
10641 if (w.location.pathname === '/plugins/comments.php') {
10642 if (w.location.search.indexOf('api_key=231958156911371') != -1 || w.location.search.indexOf('api_key=376261472405891') != -1) {
10643 allowedFramesOk = true;
10644 }
10645 }
10646
10647 if (!allowedFramesOk) {
10648 if (USW.self != USW.top) {
10649 throw 1;
10650 }
10651 }
10652 }
10653 } catch (e) {
10654 info("Framed");
10655 return;
10656 }
10657
10658 // Special instructions for browsers that needs localStorage
10659 runMe = true;
10660 if (STORAGEMETHOD == 'localstorage') {
10661 // Don't run on non-www :(
10662 if (userSettings.force_run) {
10663 log("Force running on "+w.location.href);
10664 } else {
10665 if (w.location.hostname != 'www.facebook.com') {
10666 info("w.location.hostname = "+w.location.hostname);
10667 runMe = false;
10668 }
10669 }
10670 }
10671
10672 if (!runMe) {
10673 info("Ponyhoof style is not injected on "+w.location.href);
10674 //return;
10675 }
10676
10677 CURRENTPONY = userSettings.theme;
10678
10679 if (!USERID && !globalSettings.allowLoginScreen) {
10680 info("Ponyhoof will not run when logged out because of a setting.");
10681 return;
10682 }
10683
10684 // Ban parasprites
10685 // 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
10686 if (USERID && ['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) {
10687 if (globalSettings.allowLoginScreen) {
10688 globalSettings.allowLoginScreen = false;
10689 saveGlobalSettings();
10690 }
10691 return;
10692 }
10693
10694 // If we don't have an old setting...
10695 if (userSettings.theme == null) {
10696 // ... and not logged in, DON'T show the welcome screen
10697 if (!USERID) {
10698 // Special exception at home page, we want that cool login background
10699 if (!hasClass(d.body, 'fbIndex')) {
10700 info("Ponyhoof does not run for logged out users.");
10701 return;
10702 }
10703 }
10704
10705 // Don't run on dialogs
10706 if (w.location.pathname.indexOf('/dialog/') == 0) {
10707 info("Ponyhoof does not run when there is no theme selected and running on dialogs.");
10708 return;
10709 }
10710 }
10711
10712 // v1.581: Detect broken Facebook styles and abort if derped
10713 if (userSettings.theme && detectBrokenFbStyle()) {
10714 error("Broken Facebook style: hidden_elem is not expected");
10715 return;
10716 }
10717
10718 // Modify the <html> tag
10719 addClass(d.documentElement, 'ponyhoof_userscript');
10720 addClass(d.documentElement, 'ponyhoof_storagemethod_'+STORAGEMETHOD);
10721 addClass(d.documentElement, 'ponyhoof_distribution_'+DISTRIBUTION);
10722 d.documentElement.setAttribute('data-ponyhoof-userscript-version', VERSION);
10723
10724 // CANLOG previously could be disabled before
10725 if (!userSettings.debug_disablelog) {
10726 CANLOG = true;
10727 }
10728
10729 // Load the language for the options link
10730 CURRENTLANG = LANG['en_US'];
10731 if (!userSettings.forceEnglish) {
10732 UILANG = getDefaultUiLang();
10733 if (!UILANG) {
10734 UILANG = 'en_US';
10735 } else {
10736 for (var i in LANG[UILANG]) {
10737 CURRENTLANG[i] = LANG[UILANG][i];
10738 }
10739 }
10740 }
10741
10742 // Inject Ponyhoof Options in the Account dropdown even when DOMNodeInserted is disabled
10743 onPageReady(function() {
10744 injectOptionsLink();
10745 domNodeHandlerMain.ponyhoofPageOptions({target: d.body});
10746 });
10747
10748 if (!runMe) {
10749 return;
10750 }
10751
10752 var luckyGuess = -1;
10753 if (!CURRENTPONY && globalSettings.runForNewUsers) {
10754 // If we have a "special" name, load the peferred theme for that character if we're in one
10755 try {
10756 getBronyName();
10757 for (var i = 0, len = PONIES.length; i < len; i += 1) {
10758 if (PONIES[i].users) {
10759 var lowercase = BRONYNAME.toLowerCase();
10760 for (var j = 0, jlen = PONIES[i].users.length; j < jlen; j += 1) {
10761 if (lowercase.indexOf(PONIES[i].users[j]) != -1) {
10762 // We got a match!
10763 CURRENTPONY = PONIES[i].code;
10764 luckyGuess = i;
10765 }
10766 }
10767 }
10768 }
10769 } catch (e) {
10770 error("Failed to get brony name");
10771 }
10772 }
10773
10774 // If we still don't have one, then assume none
10775 if (!CURRENTPONY) {
10776 CURRENTPONY = 'NONE';
10777 }
10778
10779 if ($('jewelFansTitle')) {
10780 ISUSINGPAGE = true;
10781 addClass(d.documentElement, 'ponyhoof_isusingpage');
10782 }
10783
10784 if (d.querySelector('#pageLogo > a[href*="/business/dashboard/"]')) {
10785 ISUSINGBUSINESS = true;
10786 addClass(d.documentElement, 'ponyhoof_isusingbusiness');
10787 }
10788
10789 // v1.401: Turn on new chat sound by default
10790 if (!userSettings.chatSound1401 && !userSettings.chatSound) {
10791 userSettings.chatSound = true;
10792 userSettings.chatSound1401 = true;
10793 saveSettings();
10794 }
10795
10796 // v1.501: Migrate previous randomSetting
10797 if (userSettings.randomSetting && !userSettings.randomSettingMigrated) {
10798 if (userSettings.randomSetting == 'mane6') {
10799 userSettings.randomPonies = 'twilight|dash|pinkie|applej|flutter|rarity';
10800 }
10801 userSettings.randomSettingMigrated = true;
10802 saveSettings();
10803 }
10804
10805 // v1.571
10806 userSettings.soundsVolume = Math.max(0, Math.min(parseFloat(userSettings.soundsVolume), 1));
10807
10808 // v1.601
10809 if (globalSettings.lastVersion < 1.6) {
10810 if (userSettings.customcss || userSettings.debug_dominserted_console || userSettings.debug_slow_load || userSettings.debug_disablelog || userSettings.debug_noMutationObserver || userSettings.debug_mutationDebug) {
10811 userSettings.debug_exposed = true;
10812 saveSettings();
10813 }
10814 }
10815
10816 // v1.511: Track updates
10817 if (userSettings.theme && globalSettings.lastVersion < VERSION) {
10818 statTrack('updated');
10819 globalSettings.lastVersion = VERSION;
10820 saveGlobalSettings();
10821 }
10822
10823 if (forceWhiteBackground || hasClass(d.body, 'plugin') || hasClass(d.body, 'transparent_widget') || hasClass(d.body, '_1_vn')) {
10824 ONPLUGINPAGE = true;
10825 addClass(d.documentElement, 'ponyhoof_fbplugin');
10826 changeThemeSmart(CURRENTPONY);
10827 } else {
10828 // Are we on homepage?
10829 if (hasClass(d.body, 'fbIndex') && globalSettings.allowLoginScreen) {
10830 // Activate screen saver
10831 screenSaverActivate();
10832
10833 $$(d.body, '#blueBar .loggedout_menubar > .rfloat, ._50dz > .ptl[style*="#3B5998"] .rfloat > #login_form, ._50dz > div[style*="#3B5998"] td > div[style*="float"] #login_form', function() {
10834 addClass(d.documentElement, 'ponyhoof_fbIndex_topRightLogin');
10835 });
10836 }
10837
10838 // No theme?
10839 if (userSettings.theme == null) {
10840 // No theme AND logged out
10841 if (!USERID) {
10842 changeTheme('login');
10843 log("Homepage is default to login.");
10844 extraInjection();
10845 if (!userSettings.disableDomNodeInserted) {
10846 runDOMNodeInserted();
10847 }
10848 return;
10849 }
10850
10851 if (globalSettings.runForNewUsers) {
10852 if (luckyGuess == -1) {
10853 CURRENTPONY = getRandomMane6();
10854 }
10855
10856 var welcome = new WelcomeUI({feature: luckyGuess});
10857 welcome.start();
10858 }
10859 } else {
10860 if (hasClass(d.body, 'fbIndex')) {
10861 if (CURRENTPONY == 'RANDOM' && !userSettings.randomPonies) {
10862 log("On login page and theme is RANDOM, choosing 'login'");
10863 changeThemeSmart('login');
10864 } else {
10865 changeThemeSmart(CURRENTPONY);
10866 }
10867
10868 if (canPlayFlash()) {
10869 var dat = convertCodeToData(REALPONY);
10870 if (dat.fbIndex_swf && !userSettings.disable_animation) {
10871 addClass(d.documentElement, 'ponyhoof_fbIndex_hasswf');
10872
10873 var swf = d.createElement('div');
10874 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>';
10875 d.body.appendChild(swf);
10876 }
10877 }
10878 } else {
10879 changeThemeSmart(CURRENTPONY);
10880 }
10881 }
10882 }
10883
10884 if (CURRENTPONY != 'NONE' && !userSettings.disableDomNodeInserted) {
10885 runDOMNodeInserted();
10886 }
10887
10888 if (CURRENTPONY != 'NONE') {
10889 extraInjection();
10890 }
10891
10892 // Record the last user to figure out what theme to load at login screen
10893 // This is low priority, if all else fails, we would just load the default Equestria 'login' anyway
10894 if (CURRENTPONY != 'NONE' && userSettings.theme != null) { // Make sure we have a pony set
10895 if (USERID && globalSettings.lastUserId != USERID && globalSettings.allowLoginScreen) {
10896 globalSettings.lastUserId = USERID;
10897 saveGlobalSettings();
10898 }
10899 }
10900 }
10901
10902 onPageReady(startScript);
10903 d.addEventListener('DOMContentLoaded', startScript, true);
10904
10905 var _loop = function() {
10906 if (d.body) {
10907 startScript();
10908 return;
10909 } else {
10910 w.setTimeout(_loop, 100);
10911 }
10912 };
10913 _loop();
10914 })();
10915
10916 /* ALL YOUR PONIES ARE BELONG TO US */
10917 /*eof*/