- Fixed a bunch of bugs for existing paginations
[FlickrHacks.git] / _greasemonkey_ / flickrcheckbuddyactivity.user.js
blob2b9790151b6c959ce7b116b96256f6563bc83df9
1 // ==UserScript==
2 // @name        Flickr Check Buddy Activity
3 // @namespace   http://6v8.gamboni.org/
4 // @description Check when a particular user commented/faved a photo of your for the last time
5 // @version        0.5
6 // @identifier  http://6v8.gamboni.org/IMG/js/flickrcheckbuddyactivity.user.js
7 // @date           2007-07-02
8 // @creator        Pierre Andrews (mortimer.pa@free.fr)
9 // @include http://www.flickr.com*
10 // @include http://flickr.com*
11 // ==/UserScript==
13 // --------------------------------------------------------------------
15 // This is a Greasemonkey user script.
17 // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
18 // Then restart Firefox and revisit this script.
19 // Under Tools, there will be a new menu item to "Install User Script".
20 // Accept the default configuration and install.
22 // --------------------------------------------------------------------
23 // Copyright (C) 2007 Pierre Andrews
24 // 
25 // This program is free software; you can redistribute it and/or
26 // modify it under the terms of the GNU General Public License
27 // as published by the Free Software Foundation; either version 2
28 // of the License, or (at your option) any later version.
29 // 
30 // This program is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33 // GNU General Public License for more details.
34 // 
35 // The GNU General Public License is available by visiting
36 //   http://www.gnu.org/copyleft/gpl.html
37 // or by writing to
38 //   Free Software Foundation, Inc.
39 //   51 Franklin Street, Fifth Floor
40 //   Boston, MA  02110-1301
41 //   USA
44 (function () {
46         var DEBUG=true;
48         //update information
49         var SCRIPT = {
50                 name: "Flickr Check Buddy Activity",
51                 namespace: "http://6v8.gamboni.org/",
52                 description: "Check when a particular user commented/faved a photo of your for the last time",
53                 identifier: "http://6v8.gamboni.org/IMG/js/flickrcheckbuddyactivity.user.js",
54                 version: "0.5",                                                         // version
55                 date: (new Date("2007-07-02"))          // update date
56                 .valueOf()
57         };
58         
59         
60         function M8_log() {
61                 if(unsafeWindow.console)
62                         unsafeWindow.console.log(arguments);
63                 else
64                         GM_log(arguments);
65         }
67         /*
68           Xpath trickery, from:
69           http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
70          */
71         function $x( xpath, root )
72                 {
73                         var doc = root ? root.evaluate?root:root.ownerDocument : document;
74                         var got = doc.evaluate( xpath, root||doc, null, 0, null ), next;
75                         var result = [];
76                         while( next = got.iterateNext() )
77                                 result.push( next );
78                         return result;
79                 }
82         function $x1(xpath) {
83                 return document.evaluate(
84                                                                  xpath,
85                                                                  document,
86                                                                  null,
87                                                                  XPathResult.FIRST_ORDERED_NODE_TYPE, null
88                                                                  ).singleNodeValue;
89         }
91         function foreach( xpath, cb, root )
92         {
93                 var nodes = $x( xpath, root ), e = 0;
94                 for( var i=0; i<nodes.length; i++ )
95                         e += cb( nodes[i], i ) || 0;
96                 return e;
97         }
101         function getObjectMethodClosure(object, method) {
102                 return function(arg) {
103                         return object[method](arg); 
104                 }
105         }
107         /***********************************************************************
108          * Flickr Localisation
109          **********************************************************************/
111         var FlickrLocaliser = function(locals) {
112                 this.init(locals);
113         }
114         FlickrLocaliser.prototype = {
115                 selectedLang: undefined,
116                 localisations: undefined,
117                 getLanguage: function() {
118                         if(!this.selectedLang) {
119                                 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
120                                 if(langA) {
121                                         var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
122                                         if(matches && matches[1]) {
123                                                 this.selectedLang = matches[1];
124                                                 return this.selectedLang;
125                                         }
126                                 }
127                                 return false;
128                         } else return this.selectedLang;
129                 },
131                 init: function(locals) {
132                         this.localisations = locals;
133                 },
135                 localise: function(string, params) {
136                         if(this.localisations && this.getLanguage()) {
137                                 var currentLang = this.localisations[this.selectedLang];
138                                 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
139                                 var local = currentLang[string];
140                                 if(!local) {
141                                         local = this.localisations[this.localisations.defaultLang][string];
142                                 } 
143                                 if(!local) return string;
144                                 var toRet = local;
145                                 while(matches = /@([^@]+)@/g.exec(local)) {
146                                         if(matches[1]) {
147                                                 var arg = matches[1];
148                                                 var rep = new RegExp('@'+arg+'@','g');
149                                                 if(params[arg])
150                                                         toRet = toRet.replace(rep,params[arg]);
151                                                 else
152                                                         toRet = toRet.replace(rep,'');
153                                         }
154                                 }
155                                 return toRet;
156                         } else return undefined;
157                 }
159         }
161         /*****************************Flickr Localisation**********************/
163         
165         /*
166           LightWeightBox - Thom Shannon
167           http://www.ts0.com
168           V 1.0 2006
169           BSD License
170         */
172         var LightWeightBoxOn=false;
173         var LightWeightBox = function(ele){
174                 this.ele = ele;
175                 this.backgroundColor = '#CCC';
176                 this.opacity = 0.5;
177         }
178         with (LightWeightBox){
179                 prototype.Render = function(){
180                         if (!LightWeightBoxOn){
181                                 bgDiv = document.createElement('div');
182                                 bgDiv.innerHTML = ''
183                                 bgDiv.style.backgroundColor = this.backgroundColor;
184                                 bgDiv.style.position='fixed';
185                                 bgDiv.style.height='100%';
186                                 bgDiv.style.width='100%';
187                                 bgDiv.style.top=0;
188                                 bgDiv.style.left='0';
189                                 bgDiv.style.opacity=this.opacity;
190                                 this.ele.style.position='fixed';
191                                 this.bgDiv=bgDiv;
192                                 document.body.appendChild(this.bgDiv);
193                                 document.body.appendChild(this.ele);
194                                 this.CheckSize();
195                                 LightWeightBoxOn = true;
196                                 var oSelf=this;
197                                 this.sizeCheck = setInterval(function(){oSelf.CheckSize();},20);
198                         }
199                 }
200                 prototype.CheckSize = function(){
201                         if (this.ele.offsetHeight!=this.currentHeight) {
202                                 this.offsetTop = (self.innerHeight/2)-(this.ele.offsetHeight/2);
203                                 this.ele.style.top = this.offsetTop+'px';
204                                 this.currentHeight=this.ele.offsetHeight;
205                         }
206                         if (this.ele.offsetWidth!=this.currentWidth) {
207                                 this.offsetLeft = (self.innerWidth/2)-(this.ele.offsetWidth/2);
208                                 this.ele.style.left = this.offsetLeft+'px';
209                                 this.currentWidth=this.ele.offsetWidth;
210                         }
211                 }
213                 prototype.Close=function(oSelf){
214                         document.body.removeChild(oSelf.bgDiv);
215                         document.body.removeChild(oSelf.ele);
216                         LightWeightBoxOn = false;
217                 }
218         }
222         var flickrcheckbuddyactivity = function() {this.init();}
223         
224         flickrcheckbuddyactivity.prototype = {
225                 localiser: new FlickrLocaliser({
226                         'en-us' : {
227                                 'check_activity' : 'Check Buddy Activity',
228                                         'close' : 'Close',
229                                         'no_activity' : "no activity in the last @timeframe@.",
230                                         '31d' : 'month',
231                                         'comment' : '@username@ commented @photo@ on the @date@.',
232                                         'fave' : '@username@ faved @photo@ on the @date@.',
233                                         'tag' : '@username@ tagged @photo@ on the @date@.',
234                                         'note' : '@username@ added a note to @photo@ on the @date@.',
235                                         'activity_title' : 'Last Activity',
236                                         'please_wait' : 'Please Wait',
237                                         'menu_item' : 'CheckBuddyActivity: Set the timeframe',
238                                         'prompt_timeframe' : 'What timeframe should the script check (enter value in hours (e.g. 24h) or days (e.g. 31d).',
239                                         'additional_count' : 'During this @timeframe@, this user left: @comment_cnt@ comment(s), @fave_link@ , @tag_cnt@ tag(s) and @note_cnt@ note(s).',
240                                         'fave_cnt' : '@fave_cnt@ favorite(s)',
241                                         'tag_note_cnt' : 'During this @timeframe@, @username@ left @tag_cnt@ tag(s) and @note_cnt@ note(s).',
242                                         'tag_cnt' : 'During this @timeframe@, @username@ left @tag_cnt@ tag(s).',
243                                         'note_cnt' : 'During this @timeframe@, @username@ left @tag_cnt@ tag(s).',
244                                         },
245                                 'fr-fr': {
246                                         // 3
247                                         '31d' : 'moi',
248                                                 // A
249                                                 'activity_title' : 'Derni&egrave;re Activit&eacute;',
250                                                 'additional_count' : 'Pendant ce @timeframe@,cet utilisateur a laiss&eacute;: @comment_cnt@ commentaire(s), @fave_link@ , @tag_cnt@ tag(s) et @note_cnt@ note(s).',
251                                                 // C
252                                                 'check_activity' : 'Verrifier l\'Activit&eacute;',
253                                                 'close' : 'Fermer',
254                                                 'comment' : '@username@ a comment&eacute; @photo@ le @date@',
255                                                 // F
256                                                 'fave' : '@username@ a ajout&eacute; @photo@ comme favorit le @date@',
257                                                 'fave_cnt' : '@fave_cnt@ favorit(s)',
258                                                 // M
259                                                 'menu_item' : 'CheckBuddyActivity: Ajuster l\'intervale de temps',
260                                                 // N
261                                                 'no_activity' : 'Aucune activit&eacute; dans le dernier @timeframe@.',
262                                                 'note' : '@username@ a ajout&eacute; une note &agrave; @photo@ le @date@',
263                                                 'note_cnt' : 'Pendant ce @timeframe@, @username@ a laiss&eacute; @tag_cnt@ tag(s).',
264                                                 // P
265                                                 'please_wait' : 'Patienter',
266                                                 'prompt_timeframe' : 'Quelle intervale de temps v&eacute;rifier (donner une valeur en heures (e.g. 24h) ou jours (e.g. 31d).',
267                                                 // T
268                                                 'tag' : '@username@ a tagg&eacute;  @photo@ le @date@',
269                                                 'tag_cnt' : 'Pendant ce @timeframe@, @username@ a laiss&eacute; @tag_cnt@ tag(s).',
270                                                 'tag_note_cnt' : 'Pendant ce @timeframe@, @username@ a laiss&eacute; @tag_cnt@ tag(s) et @note_cnt@ note(s).'
271                                                 },
272                                         'pt-br': {
273                                                 // A
274                                                 'activity_title' : '&Uacute;ltima atividade',
275                                                         // C
276                                                         'check_activity' : 'Checar atividade do camarada',
277                                                         'close' : 'Fechar',
278                                                         'comment' : '@username@ comentado @photo@ na @date@',
279                                         // F
280                                         'fave' : '@username@ favorito @photo@ na @date@',
281                                         // N
282                                         'no_activity' : 'Sem atividade no &uacute;ltimo @timeframe@.',
283                                         '31d' : 'm&ecirc;s',
284                                         // P
285                                         'please_wait' : 'Por favor, aguarde'
286                                 },
287                                 defaultLang: 'en-us'
288                         }),
289                 boxEle: undefined,
290                 timeframe: 0,
291                 init: function() {
292                         var menu = document.getElementById('personmenu_contacts_link');
293                         if(menu) {                      
294                                 this.timeframe = GM_getValue('timeframe');
295                                 if(!this.timeframe) {
296                                         this.timeframe = '31d';
297                                         GM_setValue('timeframe','31d');
298                                 }
300                                 var link =document.createElement('a');
301                                 link.setAttribute('class','block');
302                                 link.setAttribute('id','tag_person_link');
303                                 link.setAttribute('href','javascript:;');
304                                 link.addEventListener('click',getObjectMethodClosure(this,'showDialogue'),true);
305                                 link.innerHTML = this.localiser.localise('check_activity');
306                           
307                                 menu.parentNode.insertBefore(link,menu.nextSibling);
308                         }
309                         var self = this;
310                         GM_registerMenuCommand( this.localiser.localise("menu_item"), function() {self.timeframe = prompt(self.localiser.localise('prompt_timeframe'),self.timeframe);GM_setValue('timeframe',self.timeframe)});
311                 },
312                 count_tag:0,
313                 count_note:0,
314                 count_fave:0,
315                 count_comment:0,
316                 foundActivity: 0,
317                 foundEvent: undefined,
319                 processRSP: function(rsp,page,user_id) {
320                         for(var i=0;i<rsp.items.item.length;i++) {
321                                 for(var j=0;j<rsp.items.item[i].activity.event.length;j++) {
322                                         if(rsp.items.item[i].activity.event[j].user == user_id) {       
323                                                 this.username = rsp.items.item[i].activity.event[j].username;
324                                                 var period = 0;
325                                                 if((this.timeframe.indexOf('D') >= 0) || (this.timeframe.indexOf('d') >= 0)) {
326                                                         if(DEBUG) M8_log('counting in days for user_id: '+user_id);
327                                                         period = (Date.now() - rsp.items.item[i].activity.event[j].dateadded*1000)/(3600*24*1000);
328                                                 } else {
329                                                         if(DEUBG) M8_log('counting in hours for user_id: '+user_id);
330                                                         period = (Date.now() - rsp.items.item[i].activity.event[j].dateadded*1000)/(3600*1000);
331                                                 }
332                                                 if(DEBUG) M8_log(rsp.items.item[i].activity.event[j].type+':'+period+':'+parseInt(this.timeframe));
333                                                 if(period <= parseInt(this.timeframe)) {
334                                                         if(DEBUG) M8_log('this event is in the timeframe.');
335                                                         this['count_'+rsp.items.item[i].activity.event[j].type]++;
336                                                         if((rsp.items.item[i].activity.event[j].type == 'comment' ||
337                                                                 rsp.items.item[i].activity.event[j].type == 'fave') &&
338                                                            (rsp.items.item[i].activity.event[j].dateadded > this.foundActivity)) {
339                                                                 this.foundEvent = {event: rsp.items.item[i].activity.event[j],
340                                                                                                    first: rsp.items.item[i]};
341                                                                 this.foundActivity = rsp.items.item[i].activity.event[j].dateadded;
342                                                         }
343                                                 }
344                                         }
345                                 }
346                                 
347                         }
348                         
349                         if(page < rsp.items.pages) {
350                                 this.checkPage(page+1,user_id);
351                         } else {
352                                 this.boxEle.removeChild(this.dial);
353                                 var dial = this.boxEle.appendChild(document.createElement('div'));
354                                 dial.setAttribute('style',"clear:both; width:70%;overflow:auto;margin-left:15%;");
355                                 if(this.foundEvent && this.foundEvent.event && this.foundEvent.first) {
356                                         var first = this.foundEvent.first;
357                                         var event = this.foundEvent.event;
358                                         var id = first.id;
359                                         if(first.type == 'photoset')
360                                                 id = first.primary;
361                                         dial.innerHTML = this.localiser.localise(event.type,
362                                                                                                                          {
363                                                                                                                                  'username' : '<a href="http://www.flickr.com/photos/'+encodeURIComponent(event.user)+'" >'+event.username+'</a>',
364                                                                                                                                  'photo' : '<br/><a href="http://www.flickr.com/photos/'+encodeURIComponent(unsafeWindow.global_nsid)+'/'+first.id+'"><img src="http://farm'+first.farm+'.static.flickr.com/'+first.server+'/'+id+'_'+first.secret+'_m.jpg"/></a><br/>',
365                                                                                                                                  'date' : "<br/>"+(new Date(event.dateadded*1000)).toUTCString()
366                                                                                                                          });
367                                         dial.innerHTML += '<br/>'+this.localiser.localise('additional_count',{
368                                                         'tag_cnt':this.count_tag+0+' ', 
369                                                                 'note_cnt':this.count_note+0+' ',
370                                                                 'fave_link':((this.count_fave > 0)?('<a title="Favorite Finder" href="http://bighugelabs.com/flickr/favorites.php?user1='+encodeURIComponent(unsafeWindow.global_nsid)+'&user2='+encodeURIComponent(user_id)+'&button=Go">'+this.localiser.localise('fave_cnt',{'fave_cnt':this.count_fave+0+''})+'</a>'):(this.localiser.localise('fave_cnt',{'fave_cnt':this.count_fave+0+''}))),
371                                                                 'fave_cnt':this.count_fave+0+' ',
372                                                                 'comment_cnt':this.count_comment+0+' ',
373                                                                 'timeframe':this.localiser.localise(this.timeframe)
374                                                                 });
375                                 } else if(this.countTag > 0 && this.countNote > 0) {
376                                         dial.innerHTML = this.localiser.localise('tag_note_cnt',{'username' : '<a href="http://www.flickr.com/photos/'+encodeURIComponent(user_id)+'" >'+this.username+'</a>','tag_cnt':this.count_tag, 'note_cnt':this.count_note, 'timeframe':this.localiser.localise(this.timeframe)});
377                                 } else if(this.count_tag > 0) {
378                                         dial.innerHTML = this.localiser.localise('tag_cnt',{'username' : '<a href="http://www.flickr.com/photos/'+encodeURIComponent(user_id)+'" >'+this.username+'</a>','tag_cnt':this.count_tag, 'timeframe':this.localiser.localise(this.timeframe)});
379                                 } else if(this.count_note > 0) {
380                                         dial.innerHTML = this.localiser.localise('note_cnt',{'username' : '<a href="http://www.flickr.com/photos/'+encodeURIComponent(user_id)+'" >'+this.username+'</a>','note_cnt':this.count_note, 'timeframe':this.localiser.localise(this.timeframe)});
381                                 } else {
382                                         dial.innerHTML = this.localiser.localise('no_activity',{'timeframe':this.localiser.localise(this.timeframe)});
383                                 }
384                         }
385                 },
387                 checkPage: function(page,user_id) {
388                         var self = this;
389                         var lastCheck = eval(GM_getValue('cached_page_'+page));
390                         var when;
391                         if(lastCheck) {
392                                 var when = Date.now() - lastCheck.timestamp;
393                                 when = when / (3600*1000);
394                         } else when = 2;
395                         if(when > 1) {
396                                 var listener = {
397                                         flickr_activity_userPhotos_onLoad: function(success, responseXML, responseText, params){
398                                                 try{
399                                                         var rsp = responseText.replace(/jsonFlickrApi\(/,'');
400                                                         rsp = eval('('+rsp);
401                                                         if(rsp.stat == 'ok') {
402                                                                 GM_setValue('cached_page_'+page,uneval({timestamp: Date.now(),
403                                                                                                 rsp: rsp}));
404                                                                 self.processRSP(rsp,page,user_id);
405                                                         } else
406                                                                 M8_log("Error2 "+responseText);                                                 
407                                                 } catch (e) {
408                                                         M8_log("Error1 "+responseText);
409                                                         M8_log(e);
410                                                 }
411                                         }
412                                 };
413                                 
414                                 unsafeWindow.F.API.callMethod('flickr.activity.userPhotos', {
415                                                 timeframe: this.timeframe,
416                                                         page:page,
417                                                         per_page: 25,
418                                                         format: 'json'
419                                                         }, listener);
420                         } else {
421                                 this.processRSP(lastCheck.rsp,page,user_id);
422                         }       
423                 },
424                 showDialogue: function(ev) {
425                         var block = ev.target.parentNode;
426                         var matches = /messages_write\.gne\?to=([^"]*)"/.exec(block.innerHTML);
427                         if(matches && matches[1]) {
428                                 var user_id=matches[1]
429                                 // create a block element of some kind
430                                 this.boxEle = document.createElement('div');
431                                 // style it up with a class or inline
432                                 this.boxEle.className = 'popup';
433                                 // create something to act as a close button
434                                 btnClose = document.createElement('a');
435                                 btnClose.href='javascript:;';
436                                 btnClose.innerHTML='<img style="margin: 0; padding: 0; border:0px !important; vertical-align: top;" src="http://flickr.com/images/window_close_grey.gif" alt="'+this.localiser.localise('close')+'"/>';
437                                 btnClose.title = this.localiser.localise('close');
439                                 // add close button to block element
440                                 this.boxEle.appendChild(btnClose);
441                                 // create box with block element
442                                 var lwBox = new LightWeightBox(this.boxEle);
443                                 // optional bg color and opacity
444                                 this.boxEle.style.paddingTop= '10px';
445                                 this.boxEle.style.width= '350px';
446                                 this.boxEle.style.paddingBottom = '10px';
447                                 this.boxEle.style.backgroundColor = '#fff';
448                                 this.boxEle.style.border = '1px solid black';
449                                 // attach close event and add your own code
450                                 btnClose.addEventListener('click',function(){
451                                                 // you have to pass box object into event
452                                                 // because of the js event scoping
453                                                 lwBox.Close(lwBox);
454                                                 // false to cancel link
455                                                 return false;
456                                         },true);
457                                 btnClose.setAttribute('style','float:right;margin-bottom:10px;margin-right:5px;');
458                                 
459                                 var title = this.boxEle.appendChild(document.createElement('div'));
460                                 title.setAttribute('style',"padding:12px;background-color: #EEEEEE;clear:both;font-size: 14px;margin-bottom:10px");
461                                 title.innerHTML = '<h3 style="margin:0;">'+this.localiser.localise('activity_title')+'</h3>';
463                                 this.dial = this.boxEle.appendChild(document.createElement('div'));
464                                 this.dial.setAttribute('style',"clear:both; width:70%;overflow:auto;margin-left:15%;");
466                                 
467                                 this.count_tag=0;
468                                 this.count_note=0;
469                                 this.count_fave=0;
470                                 this.count_comment=0;
471                                 this.foundActivity=0;
472                                 this.foundEvent=undefined;
473                                 
474                                 this.checkPage(1,user_id);
476                                 this.dial.innerHTML = this.localiser.localise('please_wait')+' <img height="24" width="24" src="data:image/gif,GIF89a%10%00%10%00%D5%3D%00%D3%D3%D3%F7%F7%F7%D1%D1%D1%D7%D7%D7%C9%C9%C9%CA%CA%CA%C6%C6%C6%FC%FC%FC%F0%F0%F0%E8%E8%E8%D5%D5%D5%FB%FB%FB%F8%F8%F8%CF%CF%CF%C5%C5%C5%C4%C4%C4%E2%E2%E2%D9%D9%D9%EF%EF%EF%F3%F3%F3%D4%D4%D4%C8%C8%C8%F4%F4%F4%E6%E6%E6%E3%E3%E3%DA%DA%DA%F5%F5%F5%F1%F1%F1%D2%D2%D2%F9%F9%F9%E4%E4%E4%E1%E1%E1%F6%F6%F6%EB%EB%EB%CB%CB%CB%EC%EC%EC%C3%C3%C3%D0%D0%D0%E7%E7%E7%CC%CC%CC%E9%E9%E9%DC%DC%DC%E5%E5%E5%D8%D8%D8%CE%CE%CE%C1%C1%C1%DB%DB%DB%EA%EA%EA%EE%EE%EE%DD%DD%DD%DF%DF%DF%DE%DE%DE%D6%D6%D6%F2%F2%F2%ED%ED%ED%FA%FA%FA%E0%E0%E0%FE%FE%FE%FD%FD%FD%C7%C7%C7%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00!%FF%0BNETSCAPE2.0%03%01%00%00%00!%F9%04%05%00%00%3D%00%2C%00%00%00%00%10%00%10%00%00%06%C3%40%9EP%B7%C9%F1%04%14J%26w%10%3A%3B%1F%C2%84%17%D9%3D%00%07%86%C6%C9%C8%ECv%1F%5Ebg%B0%F1B%91%80%F0%96z8%04%3C%C6%23%A3%5B%B0%0C%B8Cs%01%2B%19%8C%00%1B%3C8_%3B%08%18%177%3C%3A)F%1D%07%08%22%1C%18%16%3C%14%24%0A%2F%0B9%3AN7FN%00%06%0E\'.N%A7%20%26%03%0D%02%03%26%20B%A0%3C%07%0A%15%24%3B%1C%A79%16%8A%3C99%01%1F%2C-%B9%16%18%14s%0BN%17B%1313%13%15_%22%B0%10B%22%03%95u%3A%10%B6%D6%13%22%5B%A2%04%89B%0C.%00%01%3A%03%0E%1E%3C*%06%06%11%1D%5C%23g%F1%0A%3C%01%058%F4%A7%CA*((h%20dC\'!A%00%00!%F9%04%05%00%00%3D%00%2C%00%00%00%00%10%00%10%00%00%06l%40%9E%90%87%C0%01%84%00%1Cb%C8%84%14v%3B!%B4%80c%0A%25%04%A8%14%9A%60%5En%3Cl%94%C7%E5%E9P%C4%82%00%8C%95vu%83B%11%BA%0E%0B%DF%03%A8%11%BA%AB%0F%E1%7CGV%83%84%85V%00%7C%3B%5DCbPI%7CoBlY%3BJOxBuXr%3C8xc%7Dl%10L%80%A0%A1%83(O%A6%05%17%84E%82IKCA%00!%F9%04%05%00%00%3D%00%2C%00%00%00%00%10%00%10%00%00%06%BE%40%9E%90%B7%C0Q%14%0D%E1F7%14%06%02%BC%D4c%A7%E0%05%0A8%C6%90%11%F1%F0%2C%84%9DW%B5%A32u%90%5DE%93%8384%3C%85%83%C4%81N*%E5%15%8FQ%D5UN%18PP%16%18%00%15(97%3C7%2Bl%3C!%5EC%89M%1D%3A5%19%3B%0D%02%03%26%20MC%1E%0D%0E%0E%02%00%3BS%25%13%9F%3C%20%17%03%0D4-%05%11%1BM%0779M8%0A!%B9%23C%3A8%0F%14%18%16%3C%13P%0B2\'%B98%3C%07%25e%3B%0899%2F%0D%99%7B%04%BF%23S8%07%3C9%11%0E%06%1F%3C%09%06%0D%07%07%19%11PB%0B%1F%04%AA%11%3B%0E%179%1A%EF%C0%1B%B9%02%14%1C%20%2Ch%12%04%00%3B" alt="'+this.localiser.localise('please_wait')+'" />';
477                                 lwBox.Render();
478                         }
479                 } 
480                 
481         }
483         //======================================================================
484         // launch
485         try {
486                 window.addEventListener("load", function () {
487                                                                         try {
488                                                                                 
489                                                                                 // update automatically (http://userscripts.org/scripts/show/2296)
490                                                                                 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
491                                                                         } catch (ex) {} 
492                                                                         
493                                                                         var flickrgp = new flickrcheckbuddyactivity();
494                 }, false);
495         } catch (ex) {}
496 })();