From ca99f4688fc70fb74bb2510a0aaaf4914a2c7aa9 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Sep 2008 15:31:02 -0700 Subject: Adding notes about the INTERNAL_IPS setting for this to work. --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index 44aba49..2857fe9 100644 --- a/README.rst +++ b/README.rst @@ -36,6 +36,11 @@ Installation must come after any other middleware that encodes the response's content (such as GZipMiddleware). +#. Make sure your IP is listed in the `INTERNAL_IPS` setting. If you are + working locally this will be: + + INTERNAL_IPS = ('127.0.0.1',) + #. Add a tuple called `DEBUG_TOOLBAR_PANELS` to your ``settings.py`` file that specifies the full Python path to the panel that you want included in the Toolbar. This setting looks very much like the `MIDDLEWARE_CLASSES` setting. -- cgit v1.2.3 From 414368b6ec0ed856752dce752afad140a03c97f6 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Sep 2008 21:49:49 -0700 Subject: Patch submitted by Ned Batchelder to fix panel path slashes on Windows. --- debug_toolbar/templates/debug_toolbar/panels/templates.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index 58904be..f9f03b5 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -12,8 +12,8 @@ {% if templates %}
{% for template in templates %} -
{{ template.0 }}
-
{{ template.1 }}
+
{{ template.0|addslashes }}
+
{{ template.1|addslashes }}
{% endfor %}
{% else %} -- cgit v1.2.3 From 4ef51f1c912d49c7650126398c4ac38fef0f795c Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Sep 2008 23:18:14 -0700 Subject: Moving reformat sql so we can pull this in elsewhere. --- debug_toolbar/panels/sql.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index f23e317..8edfce9 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -36,13 +36,6 @@ class SQLDebugPanel(DebugPanel): self._offset = len(connection.queries) self._sql_time = 0 - def _reformat_sql(self, sql): - sql = sql.replace('`,`', '`, `') - sql = sql.replace('` FROM `', '` \n FROM `') - sql = sql.replace('` WHERE ', '` \n WHERE ') - sql = sql.replace(' ORDER BY ', ' \n ORDER BY ') - return sql - def title(self): self._sql_time = sum(map(lambda q: float(q['time']) * 1000, connection.queries)) return '%d SQL Queries (%.2fms)' % (len(connection.queries), self._sql_time) @@ -53,10 +46,19 @@ class SQLDebugPanel(DebugPanel): def content(self): sql_queries = connection.queries[self._offset:] for query in sql_queries: - query['sql'] = self._reformat_sql(query['sql']) + query['sql'] = reformat_sql(query['sql']) context = { 'queries': sql_queries, 'sql_time': self._sql_time, } return render_to_string('debug_toolbar/panels/sql.html', context) + +def reformat_sql(sql): + sql = sql.replace('`,`', '`, `') + sql = sql.replace('` FROM `', '` \n FROM `') + sql = sql.replace('` WHERE ', '` \n WHERE ') + sql = sql.replace('` INNER JOIN ', '` \n INNER JOIN ') + sql = sql.replace('` OUTER JOIN ', '` \n OUTER JOIN ') + sql = sql.replace(' ORDER BY ', ' \n ORDER BY ') + return sql -- cgit v1.2.3 From 8377ea179568c1fbf8f46db1234e85d689daae0a Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Sep 2008 23:19:27 -0700 Subject: Adding JSON params to pass to view and adding link for explain. --- debug_toolbar/panels/sql.py | 3 ++- debug_toolbar/templates/debug_toolbar/panels/sql.html | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 8edfce9..757505a 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -1,3 +1,4 @@ +import simplejson import time from debug_toolbar.panels import DebugPanel from django.db import connection @@ -20,7 +21,7 @@ class DatabaseStatTracker(util.CursorDebugWrapper): 'sql': self.db.ops.last_executed_query(self.cursor, sql, params), 'time': stop - start, 'raw_sql': sql, - 'params': params, + 'params': simplejson.dumps(params), }) util.CursorDebugWrapper = DatabaseStatTracker diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 046be7f..9a6638b 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -4,13 +4,15 @@ Time (ms) Query + Action {% for query in queries %} {{ query.time|floatformat:"4" }} -
{{ query.sql|escape }}
+
{{ query.sql|wordwrap:80|escape }}
+ EXPLAIN {% endfor %} -- cgit v1.2.3 From 4591e34f0140c43e68e4ecd97eae7f3ea05878f6 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Sep 2008 23:21:12 -0700 Subject: Adding view to explain SQL passed in via query string. Hopefully this is database backend agnostic. Next up is connecting this with the SQL panel via AJAX. --- .../debug_toolbar/panels/sql_explain.html | 25 ++++++++++++++++++ debug_toolbar/urls.py | 6 +++++ debug_toolbar/views.py | 30 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 debug_toolbar/templates/debug_toolbar/panels/sql_explain.html create mode 100644 debug_toolbar/urls.py create mode 100644 debug_toolbar/views.py diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html new file mode 100644 index 0000000..757d43f --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html @@ -0,0 +1,25 @@ +

SQL Explained

+
+
Executed SQL
+
{{ sql|wordwrap:80 }}
+
Time
+
{{ time }} ms
+
+ + + + {% for h in headers %} + + {% endfor %} + + + + {% for row in result %} + + {% for column in row %} + + {% endfor %} + + {% endfor %} + +
{{ h|upper }}
{{ column|escape }}
diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py new file mode 100644 index 0000000..24d4b12 --- /dev/null +++ b/debug_toolbar/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + # EXPLAIN SQL via AJAX + url(r'explain/$', 'debug_toolbar.views.explain', name='explain_sql'), +) diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py new file mode 100644 index 0000000..5bdf450 --- /dev/null +++ b/debug_toolbar/views.py @@ -0,0 +1,30 @@ +import simplejson +from django.db import connection +from django.shortcuts import render_to_response +from debug_toolbar.panels.sql import reformat_sql + +def explain(request): + """ + Returns the output of the SQL EXPLAIN on the given query. + + Expected GET variables: + sql: urlencoded sql with position arguments + params: JSON encoded parameter values + time: time for SQL to execute passed in from toolbar just for redisplay + """ + sql = request.GET.get('sql', '') + if sql.lower().startswith('select'): + params = simplejson.loads(request.GET.get('params', '')) + cursor = connection.cursor() + cursor.execute("EXPLAIN %s" % (sql,), params) + headers = [d[0] for d in cursor.description] + result = cursor.fetchall() + cursor.close() + context = { + 'result': result, + 'sql': reformat_sql(cursor.db.ops.last_executed_query(cursor, sql, params)), + 'time': request.GET.get('time', 0.0), + 'headers': headers, + } + return render_to_response('debug_toolbar/panels/sql_explain.html', context) + \ No newline at end of file -- cgit v1.2.3 From 4056bf7fa4049190f103602d071be99a53846952 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 12 Sep 2008 10:49:45 -0700 Subject: Updating README to follow a name refactoring that happened a few commits back with the request_vars panel. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 2857fe9..a6f2d56 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ Installation 'debug_toolbar.panels.version.VersionDebugPanel', 'debug_toolbar.panels.timer.TimerDebugPanel', 'debug_toolbar.panels.headers.HeaderDebugPanel', - 'debug_toolbar.panels.http_vars.HttpVarsDebugPanel', + 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', 'debug_toolbar.panels.sql.SQLDebugPanel', 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', -- cgit v1.2.3 From ec38c74d20606182d9b9462977e185f0c37e99b2 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 12 Sep 2008 13:34:39 -0700 Subject: Moving default list of panels into the loader to skip an install step. Panel list can still be overridden with a setting if desired. Updated README as well. --- README.rst | 17 +++++++++-------- debug_toolbar/toolbar/loader.py | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index a6f2d56..791fa79 100644 --- a/README.rst +++ b/README.rst @@ -41,10 +41,13 @@ Installation INTERNAL_IPS = ('127.0.0.1',) -#. Add a tuple called `DEBUG_TOOLBAR_PANELS` to your ``settings.py`` file that - specifies the full Python path to the panel that you want included in the - Toolbar. This setting looks very much like the `MIDDLEWARE_CLASSES` setting. - For example:: +#. Add `debug_toolbar` to your `INSTALLED_APPS` setting so Django can find the + the template files associated with the Debug Toolbar. + +#. Optional: Add a tuple called `DEBUG_TOOLBAR_PANELS` to your ``settings.py`` + file that specifies the full Python path to the panel that you want included + in the Toolbar. This setting looks very much like the `MIDDLEWARE_CLASSES` + setting. For example:: DEBUG_TOOLBAR_PANELS = ( 'debug_toolbar.panels.version.VersionDebugPanel', @@ -57,10 +60,8 @@ Installation ) You can change the ordering of this tuple to customize the order of the - panels you want to display. - -#. Add `debug_toolbar` to your `INSTALLED_APPS` setting so Django can find the - the template files associated with the Debug Toolbar. + panels you want to display. And you can include panels that you have created + or that are specific to your project. TODO ==== diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 815c7f3..67dcc3e 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -10,15 +10,29 @@ class DebugToolbar(object): self.panels = [] self.panel_list = [] self.content_list = [] + # Override this tuple by copying to settings.py as `DEBUG_TOOLBAR_PANELS` + self.default_panels = ( + 'debug_toolbar.panels.version.VersionDebugPanel', + 'debug_toolbar.panels.timer.TimerDebugPanel', + 'debug_toolbar.panels.headers.HeaderDebugPanel', + 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', + 'debug_toolbar.panels.sql.SQLDebugPanel', + 'debug_toolbar.panels.cache.CacheDebugPanel', + 'debug_toolbar.panels.template.TemplateDebugPanel', + ) def load_panels(self): """ - Populate debug panel lists from settings.DEBUG_TOOLBAR_PANELS. + Populate debug panels """ from django.conf import settings from django.core import exceptions - for panel_path in settings.DEBUG_TOOLBAR_PANELS: + # Check if settings has a DEBUG_TOOLBAR_PANELS, otherwise use default + if hasattr(settings, 'DEBUG_TOOLBAR_PANELS'): + self.default_panels = settings.DEBUG_TOOLBAR_PANELS + + for panel_path in self.default_panels: try: dot = panel_path.rindex('.') except ValueError: -- cgit v1.2.3 From 351081586846468c6c8b849e1d4ca5a35d05cd9d Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 15 Sep 2008 17:06:13 +0100 Subject: Updated README to indicate a different (better?) method of getting the debug templates loaded. --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 791fa79..2bd8b87 100644 --- a/README.rst +++ b/README.rst @@ -43,6 +43,9 @@ Installation #. Add `debug_toolbar` to your `INSTALLED_APPS` setting so Django can find the the template files associated with the Debug Toolbar. + + Alternatively, add the path to the debug toolbar templates + (``'path/to/debug_toolbar/templates'`` to your ``TEMPLATE_DIRS`` setting.) #. Optional: Add a tuple called `DEBUG_TOOLBAR_PANELS` to your ``settings.py`` file that specifies the full Python path to the panel that you want included -- cgit v1.2.3 From a77ee9cee43ec01f43bebc71ad64702fa110b475 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 15 Sep 2008 17:43:10 +0100 Subject: Added a mechanism for monkeypatching in debug views, and also added jquery as both a test case and a place to get started making some js improvements. I'm not totally thrilled with this approach -- it feels *very* hackish. The alternative might be to simply require installers to add a line to their ROOT_URLCONF, which wouldn't be *bad*, but I like the "load automatically" part of this thing. --- debug_toolbar/media/jquery.js | 11 +++++++++++ debug_toolbar/middleware.py | 14 ++++++++++++++ debug_toolbar/urls.py | 13 +++++++++++++ debug_toolbar/views.py | 16 ++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 debug_toolbar/media/jquery.js create mode 100644 debug_toolbar/urls.py create mode 100644 debug_toolbar/views.py diff --git a/debug_toolbar/media/jquery.js b/debug_toolbar/media/jquery.js new file mode 100644 index 0000000..0404307 --- /dev/null +++ b/debug_toolbar/media/jquery.js @@ -0,0 +1,11 @@ +/* + * jQuery 1.2.5 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-20 23:14:54 -0400 (Tue, 20 May 2008) $ + * $Rev: 5651 $ + */ +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){I w=19.4G,3k$=19.$;I D=19.4G=19.$=G(a,b){H 2t D.16.5r(a,b)};I u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,61=/^.[^:#\\[\\.]*$/,11;D.16=D.4d={5r:G(d,b){d=d||R;7(d.12){6[0]=d;6.J=1;H 6}7(1i d=="21"){I c=u.2K(d);7(c&&(c[1]||!b)){7(c[1])d=D.4g([c[1]],b);N{I a=R.5X(c[3]);7(a){7(a.2w!=c[3])H D().2x(d);H D(a)}d=[]}}N H D(b).2x(d)}N 7(D.1E(d))H D(R)[D.16.28?"28":"40"](d);H 6.6W(D.2d(d))},5u:"1.2.5",8F:G(){H 6.J},J:0,3o:G(a){H a==11?D.2d(6):6[a]},2C:G(b){I a=D(b);a.5j=6;H a},6W:G(a){6.J=0;2p.4d.1o.1y(6,a);H 6},O:G(a,b){H D.O(6,a,b)},5f:G(b){I a=-1;H D.2E(b&&b.5u?b[0]:b,6)},1J:G(c,a,b){I d=c;7(c.1u==54)7(a===11)H 6[0]&&D[b||"1J"](6[0],c);N{d={};d[c]=a}H 6.O(G(i){Q(c 1m d)D.1J(b?6.T:6,c,D.1h(6,d[c],b,i,c))})},1f:G(b,a){7((b==\'2g\'||b==\'1S\')&&2Y(a)<0)a=11;H 6.1J(b,a,"2a")},1q:G(b){7(1i b!="3V"&&b!=U)H 6.4E().3v((6[0]&&6[0].2y||R).5F(b));I a="";D.O(b||6,G(){D.O(6.3t,G(){7(6.12!=8)a+=6.12!=1?6.74:D.16.1q([6])})});H a},5y:G(b){7(6[0])D(b,6[0].2y).5S().38(6[0]).2j(G(){I a=6;1H(a.1z)a=a.1z;H a}).3v(6);H 6},8X:G(a){H 6.O(G(){D(6).6Q().5y(a)})},8Q:G(a){H 6.O(G(){D(6).5y(a)})},3v:G(){H 6.3S(17,L,P,G(a){7(6.12==1)6.3R(a)})},6F:G(){H 6.3S(17,L,L,G(a){7(6.12==1)6.38(a,6.1z)})},6E:G(){H 6.3S(17,P,P,G(a){6.1b.38(a,6)})},5k:G(){H 6.3S(17,P,L,G(a){6.1b.38(a,6.2F)})},3m:G(){H 6.5j||D([])},2x:G(b){I c=D.2j(6,G(a){H D.2x(b,a)});H 6.2C(/[^+>] [^+>]/.Y(b)||b.1g("..")>-1?D.4q(c):c)},5S:G(e){I f=6.2j(G(){7(D.15.1e&&!D.4m(6)){I a=6.6m(L),5e=R.3h("1t");5e.3R(a);H D.4g([5e.4I])[0]}N H 6.6m(L)});I d=f.2x("*").5H().O(G(){7(6[E]!=11)6[E]=U});7(e===L)6.2x("*").5H().O(G(i){7(6.12==3)H;I c=D.K(6,"3w");Q(I a 1m c)Q(I b 1m c[a])D.V.1d(d[i],a,c[a][b],c[a][b].K)});H f},1C:G(b){H 6.2C(D.1E(b)&&D.3C(6,G(a,i){H b.1j(a,i)})||D.3f(b,6))},4V:G(b){7(b.1u==54)7(61.Y(b))H 6.2C(D.3f(b,6,L));N b=D.3f(b,6);I a=b.J&&b[b.J-1]!==11&&!b.12;H 6.1C(G(){H a?D.2E(6,b)<0:6!=b})},1d:G(a){H 6.2C(D.4q(D.2O(6.3o(),1i a==\'21\'?D(a):D.2d(a))))},3A:G(a){H!!a&&D.3f(a,6).J>0},7S:G(a){H 6.3A("."+a)},6e:G(b){7(b==11){7(6.J){I c=6[0];7(D.W(c,"2A")){I e=c.63,60=[],14=c.14,2W=c.M=="2A-2W";7(e<0)H U;Q(I i=2W?e:0,2c=2W?e+1:14.J;i<2c;i++){I d=14[i];7(d.3a){b=D.15.1e&&!d.ap.2u.al?d.1q:d.2u;7(2W)H b;60.1o(b)}}H 60}N H(6[0].2u||"").1n(/\\r/g,"")}H 11}H 6.O(G(){7(6.12!=1)H;7(b.1u==2p&&/5O|5L/.Y(6.M))6.4D=(D.2E(6.2u,b)>=0||D.2E(6.37,b)>=0);N 7(D.W(6,"2A")){I a=D.2d(b);D("9S",6).O(G(){6.3a=(D.2E(6.2u,a)>=0||D.2E(6.1q,a)>=0)});7(!a.J)6.63=-1}N 6.2u=b})},2I:G(a){H a==11?(6.J?6[0].4I:U):6.4E().3v(a)},7c:G(a){H 6.5k(a).1Y()},77:G(i){H 6.3s(i,i+1)},3s:G(){H 6.2C(2p.4d.3s.1y(6,17))},2j:G(b){H 6.2C(D.2j(6,G(a,i){H b.1j(a,i,a)}))},5H:G(){H 6.1d(6.5j)},K:G(d,b){I a=d.1P(".");a[1]=a[1]?"."+a[1]:"";7(b===11){I c=6.5C("9z"+a[1]+"!",[a[0]]);7(c===11&&6.J)c=D.K(6[0],d);H c===11&&a[1]?6.K(a[0]):c}N H 6.1R("9u"+a[1]+"!",[a[0],b]).O(G(){D.K(6,d,b)})},2V:G(a){H 6.O(G(){D.2V(6,a)})},3S:G(g,f,h,d){I e=6.J>1,3p;H 6.O(G(){7(!3p){3p=D.4g(g,6.2y);7(h)3p.9n()}I b=6;7(f&&D.W(6,"1U")&&D.W(3p[0],"4N"))b=6.3F("1W")[0]||6.3R(6.2y.3h("1W"));I c=D([]);D.O(3p,G(){I a=e?D(6).5S(L)[0]:6;7(D.W(a,"1k")){c=c.1d(a)}N{7(a.12==1)c=c.1d(D("1k",a).1Y());d.1j(b,a)}});c.O(6S)})}};D.16.5r.4d=D.16;G 6S(i,a){7(a.3X)D.3T({1a:a.3X,3c:P,1K:"1k"});N D.5s(a.1q||a.6O||a.4I||"");7(a.1b)a.1b.2Z(a)}G 1x(){H+2t 8J}D.1l=D.16.1l=G(){I b=17[0]||{},i=1,J=17.J,4z=P,14;7(b.1u==8H){4z=b;b=17[1]||{};i=2}7(1i b!="3V"&&1i b!="G")b={};7(J==i){b=6;--i}Q(;i-1}},6p:G(b,c,a){I e={};Q(I d 1m c){e[d]=b.T[d];b.T[d]=c[d]}a.1j(b);Q(I d 1m c)b.T[d]=e[d]},1f:G(d,e,c){7(e=="2g"||e=="1S"){I b,3I={30:"64",5d:"1B",18:"3G"},2Q=e=="2g"?["5c","6j"]:["5a","6h"];G 59(){b=e=="2g"?d.8e:d.8b;I a=0,2m=0;D.O(2Q,G(){a+=2Y(D.2a(d,"55"+6,L))||0;2m+=2Y(D.2a(d,"2m"+6+"49",L))||0});b-=26.83(a+2m)}7(D(d).3A(":4i"))59();N D.6p(d,3I,59);H 26.2c(0,b)}H D.2a(d,e,c)},2a:G(f,l,k){I e,T=f.T;G 3D(b){7(!D.15.2k)H P;I a=3N.51(b,U);H!a||a.50("3D")==""}7(l=="1r"&&D.15.1e){e=D.1J(T,"1r");H e==""?"1":e}7(D.15.2J&&l=="18"){I d=T.4W;T.4W="0 7X 7W";T.4W=d}7(l.1A(/4h/i))l=y;7(!k&&T&&T[l])e=T[l];N 7(3N.51){7(l.1A(/4h/i))l="4h";l=l.1n(/([A-Z])/g,"-$1").3g();I c=3N.51(f,U);7(c&&!3D(f))e=c.50(l);N{I g=[],2D=[],a=f,i=0;Q(;a&&3D(a);a=a.1b)2D.6g(a);Q(;i<2D.J;i++)7(3D(2D[i])){g[i]=2D[i].T.18;2D[i].T.18="3G"}e=l=="18"&&g[2D.J-1]!=U?"2L":(c&&c.50(l))||"";Q(i=0;i]*?)\\/>/g,G(b,a,c){H c.1A(/^(aG|3H|7C|aD|4S|7z|ay|3y|ax|av|as)$/i)?b:a+">"});I f=D.3l(d).3g(),1t=h.3h("1t");I e=!f.1g("",""]||!f.1g("",""]||f.1A(/^<(an|1W|ak|ai|af)/)&&[1,"<1U>",""]||!f.1g("<4N")&&[2,"<1U><1W>",""]||(!f.1g("<1W><4N>",""]||!f.1g("<7C")&&[2,"<1U><1W><7n>",""]||D.15.1e&&[1,"1t<1t>",""]||[0,"",""];1t.4I=e[1]+d+e[2];1H(e[0]--)1t=1t.5R;7(D.15.1e){I g=!f.1g("<1U")&&f.1g("<1W")<0?1t.1z&&1t.1z.3t:e[1]=="<1U>"&&f.1g("<1W")<0?1t.3t:[];Q(I j=g.J-1;j>=0;--j)7(D.W(g[j],"1W")&&!g[j].3t.J)g[j].1b.2Z(g[j]);7(/^\\s/.Y(d))1t.38(h.5F(d.1A(/^\\s*/)[0]),1t.1z)}d=D.2d(1t.3t)}7(d.J===0&&(!D.W(d,"3W")&&!D.W(d,"2A")))H;7(d[0]==11||D.W(d,"3W")||d.14)k.1o(d);N k=D.2O(k,d)});H k},1J:G(d,f,c){7(!d||d.12==3||d.12==8)H 11;I e=!D.4m(d),41=c!==11,1e=D.15.1e;f=e&&D.3I[f]||f;7(d.2e){I g=/5N|3X|T/.Y(f);7(f=="3a"&&D.15.2k)d.1b.63;7(e&&!g&&f 1m d){7(41){7(f=="M"&&D.W(d,"4S")&&d.1b)7l"M a1 9Y\'t 9U 9T";d[f]=c}7(D.W(d,"3W")&&d.7e(f))H d.7e(f).74;H d[f]}7(1e&&e&&f=="T")H D.1J(d.T,"9Q",c);7(41)d.9P(f,""+c);7(1e&&g&&e)H d.4J(f,2);H d.4J(f)}7(1e&&f=="1r"){7(41){d.6B=1;d.1C=(d.1C||"").1n(/7b\\([^)]*\\)/,"")+(3r(c)+\'\'=="9K"?"":"7b(1r="+c*79+")")}H d.1C&&d.1C.1g("1r=")>=0?(2Y(d.1C.1A(/1r=([^)]*)/)[1])/79)+\'\':""}f=f.1n(/-([a-z])/9G,G(a,b){H b.2o()});7(41)d[f]=c;H d[f]},3l:G(a){H(a||"").1n(/^\\s+|\\s+$/g,"")},2d:G(b){I a=[];7(b!=U){I i=b.J;7(i==U||b.1P||b.4H||b.1j)a[0]=b;N 1H(i)a[--i]=b[i]}H a},2E:G(b,a){Q(I i=0,J=a.J;i*",6).1Y();1H(6.1z)6.2Z(6.1z)}},G(a,b){D.16[a]=G(){H 6.O(b,17)}});D.O(["6N","49"],G(i,c){I b=c.3g();D.16[b]=G(a){H 6[0]==19?D.15.2J&&R.1c["5q"+c]||D.15.2k&&19["5p"+c]||R.6X=="7r"&&R.1F["5q"+c]||R.1c["5q"+c]:6[0]==R?26.2c(26.2c(R.1c["4y"+c],R.1F["4y"+c]),26.2c(R.1c["2i"+c],R.1F["2i"+c])):a==11?(6.J?D.1f(6[0],b):U):6.1f(b,a.1u==54?a:a+"2U")}});G 25(a,b){H a[0]&&3r(D.2a(a[0],b,L),10)||0}I C=D.15.2k&&3r(D.15.5B)<8G?"(?:[\\\\w*3k-]|\\\\\\\\.)":"(?:[\\\\w\\8E-\\8D*3k-]|\\\\\\\\.)",6K=2t 4w("^>\\\\s*("+C+"+)"),6J=2t 4w("^("+C+"+)(#)("+C+"+)"),6I=2t 4w("^([#.]?)("+C+"*)");D.1l({6G:{"":G(a,i,m){H m[2]=="*"||D.W(a,m[2])},"#":G(a,i,m){H a.4J("2w")==m[2]},":":{8C:G(a,i,m){H im[3]-0},34:G(a,i,m){H m[3]-0==i},77:G(a,i,m){H m[3]-0==i},3n:G(a,i){H i==0},3Q:G(a,i,m,r){H i==r.J-1},6D:G(a,i){H i%2==0},6C:G(a,i){H i%2},"3n-4u":G(a){H a.1b.3F("*")[0]==a},"3Q-4u":G(a){H D.34(a.1b.5R,1,"4R")==a},"8y-4u":G(a){H!D.34(a.1b.5R,2,"4R")},6U:G(a){H a.1z},4E:G(a){H!a.1z},8x:G(a,i,m){H(a.6O||a.8w||D(a).1q()||"").1g(m[3])>=0},4i:G(a){H"1B"!=a.M&&D.1f(a,"18")!="2L"&&D.1f(a,"5d")!="1B"},1B:G(a){H"1B"==a.M||D.1f(a,"18")=="2L"||D.1f(a,"5d")=="1B"},8u:G(a){H!a.3O},3O:G(a){H a.3O},4D:G(a){H a.4D},3a:G(a){H a.3a||D.1J(a,"3a")},1q:G(a){H"1q"==a.M},5O:G(a){H"5O"==a.M},5L:G(a){H"5L"==a.M},5m:G(a){H"5m"==a.M},3E:G(a){H"3E"==a.M},5l:G(a){H"5l"==a.M},6A:G(a){H"6A"==a.M},6y:G(a){H"6y"==a.M},2q:G(a){H"2q"==a.M||D.W(a,"2q")},4S:G(a){H/4S|2A|6x|2q/i.Y(a.W)},3J:G(a,i,m){H D.2x(m[3],a).J},8s:G(a){H/h\\d/i.Y(a.W)},8r:G(a){H D.3C(D.3M,G(b){H a==b.S}).J}}},6w:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2t 4w("^([:.#]*)("+C+"+)")],3f:G(a,c,b){I d,1s=[];1H(a&&a!=d){d=a;I f=D.1C(a,c,b);a=f.t.1n(/^\\s*,\\s*/,"");1s=b?c=f.r:D.2O(1s,f.r)}H 1s},2x:G(t,o){7(1i t!="21")H[t];7(o&&o.12!=1&&o.12!=9)H[];o=o||R;I d=[o],2z=[],3Q,W;1H(t&&3Q!=t){I r=[];3Q=t;t=D.3l(t);I l=P,3j=6K,m=3j.2K(t);7(m){W=m[1].2o();Q(I i=0;d[i];i++)Q(I c=d[i].1z;c;c=c.2F)7(c.12==1&&(W=="*"||c.W.2o()==W))r.1o(c);d=r;t=t.1n(3j,"");7(t.1g(" ")==0)6M;l=L}N{3j=/^([>+~])\\s*(\\w*)/i;7((m=3j.2K(t))!=U){r=[];I k={};W=m[2].2o();m=m[1];Q(I j=0,3i=d.J;j<3i;j++){I n=m=="~"||m=="+"?d[j].2F:d[j].1z;Q(;n;n=n.2F)7(n.12==1){I g=D.K(n);7(m=="~"&&k[g])1T;7(!W||n.W.2o()==W){7(m=="~")k[g]=L;r.1o(n)}7(m=="+")1T}}d=r;t=D.3l(t.1n(3j,""));l=L}}7(t&&!l){7(!t.1g(",")){7(o==d[0])d.4r();2z=D.2O(2z,d);r=d=[o];t=" "+t.6u(1,t.J)}N{I h=6J;I m=h.2K(t);7(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2K(t)}m[2]=m[2].1n(/\\\\/g,"");I f=d[d.J-1];7(m[1]=="#"&&f&&f.5X&&!D.4m(f)){I p=f.5X(m[2]);7((D.15.1e||D.15.2J)&&p&&1i p.2w=="21"&&p.2w!=m[2])p=D(\'[@2w="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.W(p,m[3]))?[p]:[]}N{Q(I i=0;d[i];i++){I a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];7(a=="*"&&d[i].W.3g()=="3V")a="3y";r=D.2O(r,d[i].3F(a))}7(m[1]==".")r=D.5i(r,m[2]);7(m[1]=="#"){I e=[];Q(I i=0;r[i];i++)7(r[i].4J("2w")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1n(h,"")}}7(t){I b=D.1C(t,r);d=r=b.r;t=D.3l(b.t)}}7(t)d=[];7(d&&o==d[0])d.4r();2z=D.2O(2z,d);H 2z},5i:G(r,m,a){m=" "+m+" ";I c=[];Q(I i=0;r[i];i++){I b=(" "+r[i].1G+" ").1g(m)>=0;7(!a&&b||a&&!b)c.1o(r[i])}H c},1C:G(t,r,h){I d;1H(t&&t!=d){d=t;I p=D.6w,m;Q(I i=0;p[i];i++){m=p[i].2K(t);7(m){t=t.8q(m[0].J);m[2]=m[2].1n(/\\\\/g,"");1T}}7(!m)1T;7(m[1]==":"&&m[2]=="4V")r=61.Y(m[3])?D.1C(m[3],r,L).r:D(r).4V(m[3]);N 7(m[1]==".")r=D.5i(r,m[2],h);N 7(m[1]=="["){I g=[],M=m[3];Q(I i=0,3i=r.J;i<3i;i++){I a=r[i],z=a[D.3I[m[2]]||m[2]];7(z==U||/5N|3X|3a/.Y(m[2]))z=D.1J(a,m[2])||\'\';7((M==""&&!!z||M=="="&&z==m[5]||M=="!="&&z!=m[5]||M=="^="&&z&&!z.1g(m[5])||M=="$="&&z.6u(z.J-m[5].J)==m[5]||(M=="*="||M=="~=")&&z.1g(m[5])>=0)^h)g.1o(a)}r=g}N 7(m[1]==":"&&m[2]=="34-4u"){I e={},g=[],Y=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2K(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.Y(m[3])&&"8p+"+m[3]||m[3]),3n=(Y[1]+(Y[2]||1))-0,d=Y[3]-0;Q(I i=0,3i=r.J;i<3i;i++){I j=r[i],1b=j.1b,2w=D.K(1b);7(!e[2w]){I c=1;Q(I n=1b.1z;n;n=n.2F)7(n.12==1)n.4p=c++;e[2w]=L}I b=P;7(3n==0){7(j.4p==d)b=L}N 7((j.4p-d)%3n==0&&(j.4p-d)/3n>=0)b=L;7(b^h)g.1o(j)}r=g}N{I f=D.6G[m[1]];7(1i f=="3V")f=f[m[2]];7(1i f=="21")f=6t("P||G(a,i){H "+f+";}");r=D.3C(r,G(a,i){H f(a,i,m,r)},h)}}H{r:r,t:t}},4T:G(b,c){I a=[],1s=b[c];1H(1s&&1s!=R){7(1s.12==1)a.1o(1s);1s=1s[c]}H a},34:G(a,e,c,b){e=e||1;I d=0;Q(;a;a=a[c])7(a.12==1&&++d==e)1T;H a},5t:G(n,a){I r=[];Q(;n;n=n.2F){7(n.12==1&&n!=a)r.1o(n)}H r}});D.V={1d:G(f,i,g,e){7(f.12==3||f.12==8)H;7(D.15.1e&&f.4H)f=19;7(!g.23)g.23=6.23++;7(e!=11){I h=g;g=6.3L(h,G(){H h.1y(6,17)});g.K=e}I j=D.K(f,"3w")||D.K(f,"3w",{}),1D=D.K(f,"1D")||D.K(f,"1D",G(){7(1i D!="11"&&!D.V.5n)H D.V.1D.1y(17.3P.S,17)});1D.S=f;D.O(i.1P(/\\s+/),G(c,b){I a=b.1P(".");b=a[0];g.M=a[1];I d=j[b];7(!d){d=j[b]={};7(!D.V.2s[b]||D.V.2s[b].4o.1j(f)===P){7(f.3K)f.3K(b,1D,P);N 7(f.6s)f.6s("4n"+b,1D)}}d[g.23]=g;D.V.24[b]=L});f=U},23:1,24:{},1Y:G(e,h,f){7(e.12==3||e.12==8)H;I i=D.K(e,"3w"),1I,5f;7(i){7(h==11||(1i h=="21"&&h.8o(0)=="."))Q(I g 1m i)6.1Y(e,g+(h||""));N{7(h.M){f=h.2v;h=h.M}D.O(h.1P(/\\s+/),G(b,a){I c=a.1P(".");a=c[0];7(i[a]){7(f)2X i[a][f.23];N Q(f 1m i[a])7(!c[1]||i[a][f].M==c[1])2X i[a][f];Q(1I 1m i[a])1T;7(!1I){7(!D.V.2s[a]||D.V.2s[a].4A.1j(e)===P){7(e.6o)e.6o(a,D.K(e,"1D"),P);N 7(e.6n)e.6n("4n"+a,D.K(e,"1D"))}1I=U;2X i[a]}}})}Q(1I 1m i)1T;7(!1I){I d=D.K(e,"1D");7(d)d.S=U;D.2V(e,"3w");D.2V(e,"1D")}}},1R:G(h,c,f,g,i){c=D.2d(c);7(h.1g("!")>=0){h=h.3s(0,-1);I a=L}7(!f){7(6.24[h])D("*").1d([19,R]).1R(h,c)}N{7(f.12==3||f.12==8)H 11;I b,1I,16=D.1E(f[h]||U),V=!c[0]||!c[0].31;7(V){c.6g({M:h,2G:f,31:G(){},3Y:G(){},4l:1x()});c[0][E]=L}c[0].M=h;7(a)c[0].6l=L;I d=D.K(f,"1D");7(d)b=d.1y(f,c);7((!16||(D.W(f,\'a\')&&h=="4K"))&&f["4n"+h]&&f["4n"+h].1y(f,c)===P)b=P;7(V)c.4r();7(i&&D.1E(i)){1I=i.1y(f,b==U?c:c.78(b));7(1I!==11)b=1I}7(16&&g!==P&&b!==P&&!(D.W(f,\'a\')&&h=="4K")){6.5n=L;1Z{f[h]()}1X(e){}}6.5n=P}H b},1D:G(b){I a,1I,36,5A,4k;b=17[0]=D.V.6k(b||19.V);36=b.M.1P(".");b.M=36[0];36=36[1];5A=!36&&!b.6l;4k=(D.K(6,"3w")||{})[b.M];Q(I j 1m 4k){I c=4k[j];7(5A||c.M==36){b.2v=c;b.K=c.K;1I=c.1y(6,17);7(a!==P)a=1I;7(1I===P){b.31();b.3Y()}}}H a},6k:G(b){7(b[E]==L)H b;I d=b;b={8n:d};I c="8m 8l 8k 8j 2q 8i 45 5D 6i 5b 8h K 8g 8f 4j 2v 58 57 8d 8c 56 6f 8a 89 4L 87 86 85 6c 2G 4l 6b M 82 81 2Q".1P(" ");Q(I i=c.J;i;i--)b[c[i]]=d[c[i]];b[E]=L;b.31=G(){7(d.31)d.31();d.80=P};b.3Y=G(){7(d.3Y)d.3Y();d.7Z=L};b.4l=b.4l||1x();7(!b.2G)b.2G=b.6c||R;7(b.2G.12==3)b.2G=b.2G.1b;7(!b.4L&&b.4j)b.4L=b.4j==b.2G?b.6b:b.4j;7(b.56==U&&b.5D!=U){I a=R.1F,1c=R.1c;b.56=b.5D+(a&&a.2h||1c&&1c.2h||0)-(a.6a||0);b.6f=b.6i+(a&&a.2b||1c&&1c.2b||0)-(a.69||0)}7(!b.2Q&&((b.45||b.45===0)?b.45:b.58))b.2Q=b.45||b.58;7(!b.57&&b.5b)b.57=b.5b;7(!b.2Q&&b.2q)b.2Q=(b.2q&1?1:(b.2q&2?3:(b.2q&4?2:0)));H b},3L:G(a,b){b.23=a.23=a.23||b.23||6.23++;H b},2s:{28:{4o:G(){53();H},4A:G(){H}},4b:{4o:G(){7(D.15.1e)H P;D(6).2N("52",D.V.2s.4b.2v);H L},4A:G(){7(D.15.1e)H P;D(6).4c("52",D.V.2s.4b.2v);H L},2v:G(a){7(F(a,6))H L;a.M="4b";H D.V.1D.1y(6,17)}},4e:{4o:G(){7(D.15.1e)H P;D(6).2N("4Z",D.V.2s.4e.2v);H L},4A:G(){7(D.15.1e)H P;D(6).4c("4Z",D.V.2s.4e.2v);H L},2v:G(a){7(F(a,6))H L;a.M="4e";H D.V.1D.1y(6,17)}}}};D.16.1l({2N:G(c,a,b){H c=="4Y"?6.2W(c,a,b):6.O(G(){D.V.1d(6,c,b||a,b&&a)})},2W:G(d,b,c){I e=D.V.3L(c||b,G(a){D(6).4c(a,e);H(c||b).1y(6,17)});H 6.O(G(){D.V.1d(6,d,e,c&&b)})},4c:G(a,b){H 6.O(G(){D.V.1Y(6,a,b)})},1R:G(c,a,b){H 6.O(G(){D.V.1R(c,a,6,L,b)})},5C:G(c,a,b){H 6[0]&&D.V.1R(c,a,6[0],P,b)},2l:G(b){I c=17,i=1;1H(i=0){I i=g.3s(e,g.J);g=g.3s(0,e)}c=c||G(){};I f="2S";7(d)7(D.1E(d)){c=d;d=U}N{d=D.3y(d);f="66"}I h=6;D.3T({1a:g,M:f,1K:"2I",K:d,1N:G(a,b){7(b=="22"||b=="6z")h.2I(i?D("<1t/>").3v(a.4C.1n(/<1k(.|\\s)*?\\/1k>/g,"")).2x(i):a.4C);h.O(c,[a.4C,b,a])}});H 6},aL:G(){H D.3y(6.7H())},7H:G(){H 6.2j(G(){H D.W(6,"3W")?D.2d(6.aH):6}).1C(G(){H 6.37&&!6.3O&&(6.4D||/2A|6x/i.Y(6.W)||/1q|1B|3E/i.Y(6.M))}).2j(G(i,c){I b=D(6).6e();H b==U?U:b.1u==2p?D.2j(b,G(a,i){H{37:c.37,2u:a}}):{37:c.37,2u:b}}).3o()}});D.O("7G,7F,7E,7D,7B,7A".1P(","),G(i,o){D.16[o]=G(f){H 6.2N(o,f)}});I B=1x();D.1l({3o:G(d,b,a,c){7(D.1E(b)){a=b;b=U}H D.3T({M:"2S",1a:d,K:b,22:a,1K:c})},aC:G(b,a){H D.3o(b,U,a,"1k")},aB:G(c,b,a){H D.3o(c,b,a,"3u")},aA:G(d,b,a,c){7(D.1E(b)){a=b;b={}}H D.3T({M:"66",1a:d,K:b,22:a,1K:c})},az:G(a){D.1l(D.5Z,a)},5Z:{1a:5Y.5N,24:L,M:"2S",2T:0,7y:"4t/x-aw-3W-au",7w:L,3c:L,K:U,5V:U,3E:U,4v:{2M:"4t/2M, 1q/2M",2I:"1q/2I",1k:"1q/4s, 4t/4s",3u:"4t/3u, 1q/4s",1q:"1q/aq",4Q:"*/*"}},4x:{},3T:G(s){s=D.1l(L,s,D.1l(L,{},D.5Z,s));I g,33=/=\\?(&|$)/g,1v,K,M=s.M.2o();7(s.K&&s.7w&&1i s.K!="21")s.K=D.3y(s.K);7(s.1K=="4P"){7(M=="2S"){7(!s.1a.1A(33))s.1a+=(s.1a.1A(/\\?/)?"&":"?")+(s.4P||"7t")+"=?"}N 7(!s.K||!s.K.1A(33))s.K=(s.K?s.K+"&":"")+(s.4P||"7t")+"=?";s.1K="3u"}7(s.1K=="3u"&&(s.K&&s.K.1A(33)||s.1a.1A(33))){g="4P"+B++;7(s.K)s.K=(s.K+"").1n(33,"="+g+"$1");s.1a=s.1a.1n(33,"="+g+"$1");s.1K="1k";19[g]=G(a){K=a;22();1N();19[g]=11;1Z{2X 19[g]}1X(e){}7(i)i.2Z(h)}}7(s.1K=="1k"&&s.1V==U)s.1V=P;7(s.1V===P&&M=="2S"){I j=1x();I k=s.1a.1n(/(\\?|&)3k=.*?(&|$)/,"$am="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1A(/\\?/)?"&":"?")+"3k="+j:"")}7(s.K&&M=="2S"){s.1a+=(s.1a.1A(/\\?/)?"&":"?")+s.K;s.K=U}7(s.24&&!D.4O++)D.V.1R("7G");I n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;7(s.1K=="1k"&&M=="2S"&&n.Y(s.1a)&&n.2K(s.1a)[1]!=5Y.aj){I i=R.3F("6v")[0];I h=R.3h("1k");h.3X=s.1a;7(s.7s)h.ah=s.7s;7(!g){I l=P;h.ag=h.ae=G(){7(!l&&(!6.3e||6.3e=="67"||6.3e=="1N")){l=L;22();1N();i.2Z(h)}}}i.3R(h);H 11}I m=P;I c=19.7q?2t 7q("ac.ab"):2t 7p();7(s.5V)c.7o(M,s.1a,s.3c,s.5V,s.3E);N c.7o(M,s.1a,s.3c);1Z{7(s.K)c.4B("a9-a8",s.7y);7(s.5Q)c.4B("a7-5P-a6",D.4x[s.1a]||"a5, a4 a3 a2 5x:5x:5x a0");c.4B("X-9X-9W","7p");c.4B("9V",s.1K&&s.4v[s.1K]?s.4v[s.1K]+", */*":s.4v.4Q)}1X(e){}7(s.7k&&s.7k(c,s)===P){s.24&&D.4O--;c.7j();H P}7(s.24)D.V.1R("7A",[c,s]);I d=G(a){7(!m&&c&&(c.3e==4||a=="2T")){m=L;7(f){7i(f);f=U}1v=a=="2T"&&"2T"||!D.7h(c)&&"3d"||s.5Q&&D.7g(c,s.1a)&&"6z"||"22";7(1v=="22"){1Z{K=D.7f(c,s.1K,s.9R)}1X(e){1v="5I"}}7(1v=="22"){I b;1Z{b=c.5z("7d-5P")}1X(e){}7(s.5Q&&b)D.4x[s.1a]=b;7(!g)22()}N D.5G(s,c,1v);1N();7(s.3c)c=U}};7(s.3c){I f=4H(d,13);7(s.2T>0)3z(G(){7(c){c.7j();7(!m)d("2T")}},s.2T)}1Z{c.9O(s.K)}1X(e){D.5G(s,c,U,e)}7(!s.3c)d();G 22(){7(s.22)s.22(K,1v);7(s.24)D.V.1R("7B",[c,s])}G 1N(){7(s.1N)s.1N(c,1v);7(s.24)D.V.1R("7E",[c,s]);7(s.24&&!--D.4O)D.V.1R("7F")}H c},5G:G(s,a,b,e){7(s.3d)s.3d(a,b,e);7(s.24)D.V.1R("7D",[a,s,e])},4O:0,7h:G(a){1Z{H!a.1v&&5Y.9N=="5m:"||(a.1v>=70&&a.1v<9L)||a.1v==7a||a.1v==9J||D.15.2k&&a.1v==11}1X(e){}H P},7g:G(a,c){1Z{I b=a.5z("7d-5P");H a.1v==7a||b==D.4x[c]||D.15.2k&&a.1v==11}1X(e){}H P},7f:G(a,c,b){I d=a.5z("9I-M"),2M=c=="2M"||!c&&d&&d.1g("2M")>=0,K=2M?a.9H:a.4C;7(2M&&K.1F.2e=="5I")7l"5I";7(b)K=b(K,c);7(c=="1k")D.5s(K);7(c=="3u")K=6t("("+K+")");H K},3y:G(a){I s=[];7(a.1u==2p||a.5u)D.O(a,G(){s.1o(3q(6.37)+"="+3q(6.2u))});N Q(I j 1m a)7(a[j]&&a[j].1u==2p)D.O(a[j],G(){s.1o(3q(j)+"="+3q(6))});N s.1o(3q(j)+"="+3q(D.1E(a[j])?a[j]():a[j]));H s.6r("&").1n(/%20/g,"+")}});D.16.1l({1M:G(c,b){H c?6.2f({1S:"1M",2g:"1M",1r:"1M"},c,b):6.1C(":1B").O(G(){6.T.18=6.5E||"";7(D.1f(6,"18")=="2L"){I a=D("<"+6.2e+" />").6P("1c");6.T.18=a.1f("18");7(6.T.18=="2L")6.T.18="3G";a.1Y()}}).3m()},1L:G(b,a){H b?6.2f({1S:"1L",2g:"1L",1r:"1L"},b,a):6.1C(":4i").O(G(){6.5E=6.5E||D.1f(6,"18");6.T.18="2L"}).3m()},76:D.16.2l,2l:G(a,b){H D.1E(a)&&D.1E(b)?6.76.1y(6,17):a?6.2f({1S:"2l",2g:"2l",1r:"2l"},a,b):6.O(G(){D(6)[D(6).3A(":1B")?"1M":"1L"]()})},9F:G(b,a){H 6.2f({1S:"1M"},b,a)},9E:G(b,a){H 6.2f({1S:"1L"},b,a)},9D:G(b,a){H 6.2f({1S:"2l"},b,a)},9C:G(b,a){H 6.2f({1r:"1M"},b,a)},9B:G(b,a){H 6.2f({1r:"1L"},b,a)},9M:G(c,a,b){H 6.2f({1r:a},c,b)},2f:G(k,j,i,g){I h=D.75(j,i,g);H 6[h.35===P?"O":"35"](G(){7(6.12!=1)H P;I f=D.1l({},h),p,1B=D(6).3A(":1B"),46=6;Q(p 1m k){7(k[p]=="1L"&&1B||k[p]=="1M"&&!1B)H f.1N.1j(6);7(p=="1S"||p=="2g"){f.18=D.1f(6,"18");f.32=6.T.32}}7(f.32!=U)6.T.32="1B";f.44=D.1l({},k);D.O(k,G(c,a){I e=2t D.29(46,f,c);7(/2l|1M|1L/.Y(a))e[a=="2l"?1B?"1M":"1L":a](k);N{I b=a.6q().1A(/^([+-]=)?([\\d+-.]+)(.*)$/),27=e.1s(L)||0;7(b){I d=2Y(b[2]),2H=b[3]||"2U";7(2H!="2U"){46.T[c]=(d||1)+2H;27=((d||1)/e.1s(L))*27;46.T[c]=27+2H}7(b[1])d=((b[1]=="-="?-1:1)*d)+27;e.47(27,d,2H)}N e.47(27,a,"")}});H L})},35:G(a,b){7(D.1E(a)||(a&&a.1u==2p)){b=a;a="29"}7(!a||(1i a=="21"&&!b))H A(6[0],a);H 6.O(G(){7(b.1u==2p)A(6,a,b);N{A(6,a).1o(b);7(A(6,a).J==1)b.1j(6)}})},9w:G(b,c){I a=D.3M;7(b)6.35([]);6.O(G(){Q(I i=a.J-1;i>=0;i--)7(a[i].S==6){7(c)a[i](L);a.7I(i,1)}});7(!c)6.5T();H 6}});I A=G(b,c,a){7(b){c=c||"29";I q=D.K(b,c+"35");7(!q||a)q=D.K(b,c+"35",D.2d(a))}H q};D.16.5T=G(a){a=a||"29";H 6.O(G(){I q=A(6,a);q.4r();7(q.J)q[0].1j(6)})};D.1l({75:G(b,a,c){I d=b&&b.1u==9Z?b:{1N:c||!c&&a||D.1E(b)&&b,2r:b,48:c&&a||a&&a.1u!=9r&&a};d.2r=(d.2r&&d.2r.1u==5g?d.2r:D.29.5J[d.2r])||D.29.5J.72;d.5M=d.1N;d.1N=G(){7(d.35!==P)D(6).5T();7(D.1E(d.5M))d.5M.1j(6)};H d},48:{71:G(p,n,b,a){H b+a*p},5K:G(p,n,b,a){H((-26.9p(p*26.9o)/2)+0.5)*a+b}},3M:[],43:U,29:G(b,c,a){6.14=c;6.S=b;6.1h=a;7(!c.3Z)c.3Z={}}});D.29.4d={4M:G(){7(6.14.39)6.14.39.1j(6.S,6.1x,6);(D.29.39[6.1h]||D.29.39.4Q)(6);7(6.1h=="1S"||6.1h=="2g")6.S.T.18="3G"},1s:G(a){7(6.S[6.1h]!=U&&6.S.T[6.1h]==U)H 6.S[6.1h];I r=2Y(D.1f(6.S,6.1h,a));H r&&r>-9m?r:2Y(D.2a(6.S,6.1h))||0},47:G(c,b,d){6.5v=1x();6.27=c;6.3m=b;6.2H=d||6.2H||"2U";6.1x=6.27;6.2R=6.4F=0;6.4M();I e=6;G t(a){H e.39(a)}t.S=6.S;D.3M.1o(t);7(D.43==U){D.43=4H(G(){I a=D.3M;Q(I i=0;i6.14.2r+6.5v){6.1x=6.3m;6.2R=6.4F=1;6.4M();6.14.44[6.1h]=L;I b=L;Q(I i 1m 6.14.44)7(6.14.44[i]!==L)b=P;7(b){7(6.14.18!=U){6.S.T.32=6.14.32;6.S.T.18=6.14.18;7(D.1f(6.S,"18")=="2L")6.S.T.18="3G"}7(6.14.1L)6.S.T.18="2L";7(6.14.1L||6.14.1M)Q(I p 1m 6.14.44)D.1J(6.S.T,p,6.14.3Z[p])}7(b)6.14.1N.1j(6.S);H P}N{I n=t-6.5v;6.4F=n/6.14.2r;6.2R=D.48[6.14.48||(D.48.5K?"5K":"71")](6.4F,n,0,1,6.14.2r);6.1x=6.27+((6.3m-6.27)*6.2R);6.4M()}H L}};D.1l(D.29,{5J:{9j:9i,9g:70,72:9f},39:{2h:G(a){a.S.2h=a.1x},2b:G(a){a.S.2b=a.1x},1r:G(a){D.1J(a.S.T,"1r",a.1x)},4Q:G(a){a.S.T[a.1h]=a.1x+a.2H}}});D.16.2i=G(){I b=0,1O=0,S=6[0],3x;7(S)9d(D.15){I d=S.1b,3U=S,1p=S.1p,1Q=S.2y,5w=2k&&3r(5B)<99&&!/at/i.Y(v),1f=D.2a,3b=1f(S,"30")=="3b";7(S.6V){I c=S.6V();1d(c.1w+26.2c(1Q.1F.2h,1Q.1c.2h),c.1O+26.2c(1Q.1F.2b,1Q.1c.2b));1d(-1Q.1F.6a,-1Q.1F.69)}N{1d(S.5U,S.5W);1H(1p){1d(1p.5U,1p.5W);7(42&&!/^t(96|d|h)$/i.Y(1p.2e)||2k&&!5w)2m(1p);7(!3b&&1f(1p,"30")=="3b")3b=L;3U=/^1c$/i.Y(1p.2e)?3U:1p;1p=1p.1p}1H(d&&d.2e&&!/^1c|2I$/i.Y(d.2e)){7(!/^95|1U.*$/i.Y(1f(d,"18")))1d(-d.2h,-d.2b);7(42&&1f(d,"32")!="4i")2m(d);d=d.1b}7((5w&&(3b||1f(3U,"30")=="64"))||(42&&1f(3U,"30")!="64"))1d(-1Q.1c.5U,-1Q.1c.5W);7(3b)1d(26.2c(1Q.1F.2h,1Q.1c.2h),26.2c(1Q.1F.2b,1Q.1c.2b))}3x={1O:1O,1w:b}}G 2m(a){1d(D.2a(a,"6T",L),D.2a(a,"7x",L))}G 1d(l,t){b+=3r(l,10)||0;1O+=3r(t,10)||0}H 3x};D.16.1l({30:G(){I a=0,1O=0,3x;7(6[0]){I b=6.1p(),2i=6.2i(),4a=/^1c|2I$/i.Y(b[0].2e)?{1O:0,1w:0}:b.2i();2i.1O-=25(6,\'93\');2i.1w-=25(6,\'aE\');4a.1O+=25(b,\'7x\');4a.1w+=25(b,\'6T\');3x={1O:2i.1O-4a.1O,1w:2i.1w-4a.1w}}H 3x},1p:G(){I a=6[0].1p;1H(a&&(!/^1c|2I$/i.Y(a.2e)&&D.1f(a,\'30\')==\'aF\'))a=a.1p;H D(a)}});D.O([\'5c\',\'5a\'],G(i,b){I c=\'4y\'+b;D.16[c]=G(a){7(!6[0])H;H a!=11?6.O(G(){6==19||6==R?19.91(!i?a:D(19).2h(),i?a:D(19).2b()):6[c]=a}):6[0]==19||6[0]==R?46[i?\'90\':\'aI\']||D.6Y&&R.1F[c]||R.1c[c]:6[0][c]}});D.O(["6N","49"],G(i,b){I c=i?"5c":"5a",3H=i?"6j":"6h";D.16["5p"+b]=G(){H 6[b.3g()]()+25(6,"55"+c)+25(6,"55"+3H)};D.16["aJ"+b]=G(a){H 6["5p"+b]()+25(6,"2m"+c+"49")+25(6,"2m"+3H+"49")+(a?25(6,"6R"+c)+25(6,"6R"+3H):0)}})})();',62,668,'||||||this|if|||||||||||||||||||||||||||||||||||function|return|var|length|data|true|type|else|each|false|for|document|elem|style|null|event|nodeName||test|||undefined|nodeType||options|browser|fn|arguments|display|window|url|parentNode|body|add|msie|css|indexOf|prop|typeof|call|script|extend|in|replace|push|offsetParent|text|opacity|cur|div|constructor|status|left|now|apply|firstChild|match|hidden|filter|handle|isFunction|documentElement|className|while|ret|attr|dataType|hide|show|complete|top|split|doc|trigger|height|break|table|cache|tbody|catch|remove|try||string|success|guid|global|num|Math|start|ready|fx|curCSS|scrollTop|max|makeArray|tagName|animate|width|scrollLeft|offset|map|safari|toggle|border||toUpperCase|Array|button|duration|special|new|value|handler|id|find|ownerDocument|done|select|copy|pushStack|stack|inArray|nextSibling|target|unit|html|opera|exec|none|xml|bind|merge|isReady|which|pos|GET|timeout|px|removeData|one|delete|parseFloat|removeChild|position|preventDefault|overflow|jsre|nth|queue|namespace|name|insertBefore|step|selected|fixed|async|error|readyState|multiFilter|toLowerCase|createElement|rl|re|_|trim|end|first|get|elems|encodeURIComponent|parseInt|slice|childNodes|json|append|events|results|param|setTimeout|is|readyList|grep|color|password|getElementsByTagName|block|br|props|has|addEventListener|proxy|timers|defaultView|disabled|callee|last|appendChild|domManip|ajax|offsetChild|object|form|src|stopPropagation|orig|load|set|mozilla|timerId|curAnim|charCode|self|custom|easing|Width|parentOffset|mouseenter|unbind|prototype|mouseleave|currentStyle|clean|float|visible|fromElement|handlers|timeStamp|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|application|child|accepts|RegExp|lastModified|scroll|deep|teardown|setRequestHeader|responseText|checked|empty|state|jQuery|setInterval|innerHTML|getAttribute|click|relatedTarget|update|tr|active|jsonp|_default|previousSibling|input|dir|styleSheets|not|outline|lastToggle|unload|mouseout|getPropertyValue|getComputedStyle|mouseover|bindReady|String|padding|pageX|metaKey|keyCode|getWH|Top|ctrlKey|Left|visibility|container|index|Number|removeAttribute|classFilter|prevObject|after|submit|file|triggered|windowData|inner|client|init|globalEval|sibling|jquery|startTime|safari2|00|wrapAll|getResponseHeader|all|version|triggerHandler|clientX|oldblock|createTextNode|handleError|andSelf|parsererror|speeds|swing|checkbox|old|href|radio|Modified|ifModified|lastChild|clone|dequeue|offsetLeft|username|offsetTop|getElementById|location|ajaxSettings|values|isSimple|runtimeStyle|selectedIndex|absolute|rsLeft|POST|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|_load|val|pageY|unshift|Bottom|clientY|Right|fix|exclusive|cloneNode|detachEvent|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|notmodified|image|zoom|odd|even|before|prepend|expr|exclude|quickClass|quickID|quickChild|uuid|continue|Height|textContent|appendTo|contents|margin|evalScript|borderLeftWidth|parent|getBoundingClientRect|setArray|compatMode|boxModel|cssFloat|200|linear|def|webkit|nodeValue|speed|_toggle|eq|concat|100|304|alpha|replaceWith|Last|getAttributeNode|httpData|httpNotModified|httpSuccess|clearInterval|abort|beforeSend|throw|styleFloat|colgroup|open|XMLHttpRequest|ActiveXObject|CSS1Compat|scriptCharset|callback|fieldset|multiple|processData|borderTopWidth|contentType|link|ajaxSend|ajaxSuccess|col|ajaxError|ajaxComplete|ajaxStop|ajaxStart|serializeArray|splice|keyup|keypress|keydown|mousemove|mouseup|mousedown|resize|focus|blur|hasClass|stylesheet|rel|doScroll|black|solid|hover|cancelBubble|returnValue|wheelDelta|view|round|dblclick|shiftKey|screenY|screenX|change|relatedNode|prevValue|offsetHeight|originalTarget|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|enabled|line|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|toggleClass|Date|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|prev|pageYOffset|scrollTo|next|marginTop|parents|inline|able|cellSpacing|cellspacing|522|maxLength|maxlength|readOnly|with|readonly|400|fast|class|600|slow|htmlFor|1px|10000|reverse|PI|cos|compatible|Function|ie|ra|setData|it|stop|rv|userAgent|getData|navigator|fadeOut|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|300|fadeTo|protocol|send|setAttribute|cssText|dataFilter|option|changed|be|Accept|With|Requested|can|Object|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|th|XMLHTTP|Microsoft|td|onreadystatechange|cap|onload|charset|colg|host|tfoot|specified|1_|thead|leg|attributes|plain|opt|embed|adobeair|urlencoded|area|www|hr|meta|ajaxSetup|post|getJSON|getScript|img|marginLeft|static|abbr|elements|pageXOffset|outer|pixelLeft|serialize'.split('|'),0,{})) \ No newline at end of file diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index ee00448..a7e5655 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -4,6 +4,8 @@ Debug Toolbar middleware import re from django.conf import settings from django.utils.encoding import smart_str +from django.conf.urls.defaults import include, patterns +import debug_toolbar.urls from debug_toolbar.toolbar.loader import DebugToolbar _HTML_TYPES = ('text/html', 'application/xhtml+xml') @@ -31,6 +33,18 @@ class DebugToolbarMiddleware(object): if self.show_toolbar(request): self.debug_toolbar = DebugToolbar(request) self.debug_toolbar.load_panels() + + # Monkeypatch in the URLpatterns for the debug toolbar. The last item + # in the URLpatterns needs to be ```('', include(ROOT_URLCONF))``` so + # that the existing URLs load *after* the ones we patch in. However, + # this is difficult to get right: a previous middleware might have + # changed request.urlconf, so we need to pick that up instead. + original_urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) + debug_toolbar.urls.urlpatterns += patterns('', + ('', include(original_urlconf)), + ) + request.urlconf = 'debug_toolbar.urls' + return None def process_response(self, request, response): diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py new file mode 100644 index 0000000..c8ec7cd --- /dev/null +++ b/debug_toolbar/urls.py @@ -0,0 +1,13 @@ +""" +URLpatterns for the debug toolbar. + +These should not be loaded explicitly; the debug toolbar middleware will patch +this into the urlconf for the request. +""" + +from django.conf.urls.defaults import * +from django.conf import settings + +urlpatterns = patterns('', + url('^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media', name='debug_toolbar_media'), +) \ No newline at end of file diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py new file mode 100644 index 0000000..40cc7b1 --- /dev/null +++ b/debug_toolbar/views.py @@ -0,0 +1,16 @@ +""" +Helper views for the debug toolbar. These are dynamically installed when the +debug toolbar is displayed, and typically can do Bad Things, so hooking up these +views in any other way is generally not advised. +""" + +import os +import django.views.static +from django.conf import settings + +def debug_media(request, path): + root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None) + if root is None: + parent = os.path.abspath(os.path.dirname(__file__)) + root = os.path.join(parent, 'media') + return django.views.static.serve(request, path, root) \ No newline at end of file -- cgit v1.2.3 From 5fd534e68dbd191c5d6062a39ae512b109cccbdb Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 15 Sep 2008 18:02:17 +0100 Subject: Modified scripts to use jQuery, and moved 'em to a better place. --- debug_toolbar/media/toolbar.css | 14 +++++++++ debug_toolbar/media/toolbar.js | 15 +++++++++ debug_toolbar/templates/debug_toolbar/base.html | 42 +++---------------------- debug_toolbar/urls.py | 2 +- 4 files changed, 35 insertions(+), 38 deletions(-) create mode 100644 debug_toolbar/media/toolbar.css create mode 100644 debug_toolbar/media/toolbar.js diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css new file mode 100644 index 0000000..11dd978 --- /dev/null +++ b/debug_toolbar/media/toolbar.css @@ -0,0 +1,14 @@ +#djDebugToolbar {height:30px; background:orange; color:#000; z-index:100000000; border:1px solid #06171D; border-width:1px 0;} +#djDebugToolbar ul {margin:0; padding:0 10px; list-style:none;} +#djDebugToolbar li {display:inline; width:auto; position:relative; float:none; margin:0 10px 0 0; padding:0; height:20px; line-height:30px; padding:8px 10px 8px 0; border-right: 1px solid #06171D;} +#djDebugToolbar #djDebugButton {color:red; font-weight:bold;} +#djDebug * {margin:0; padding:0; float:none; position:static; } +#djDebug .panelContent {display:none; position:absolute; margin:0; padding:5px; top:35px; width:auto; left:5px; right:5px; bottom:5px; background:white; color:black; border:1px solid black; z-index:1000000; overflow:auto;} +#djDebug .panelContent p {padding: 0 5px;} +#djDebug .panelContent p, #djDebug .panelContent table, #djDebug .panelContent ul, #djDebug .panelContent dl {margin:5px 0;} +#djDebug .close {float:right; font-weight:bold;} +#djDebug .panelContent dt, #djDebug .panelContent dd {display: block;} +#djDebug .panelContent dd {margin-left:10px;} +#djDebug th, #djDebug td {padding: 5px;} +#djDebug .row1 td {background:#fff;} +#djDebug .row2 td {background:#ddd;} diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js new file mode 100644 index 0000000..8c0a86d --- /dev/null +++ b/debug_toolbar/media/toolbar.js @@ -0,0 +1,15 @@ +jQuery.noConflict(); +jQuery(document).ready(function() { + var current = null; + jQuery('#djDebugPanelList li a').click(function() { + if (current) { current.hide(); } + current = jQuery('#djDebug #' + this.className); + current.show(); + return false; + }); + jQuery('#djDebug a.close').click(function() { + if (current) { current.hide(); } + current = null; + return false; + }) +}); diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 637e04d..8ee29d2 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,39 +1,7 @@ - + +
@@ -42,7 +10,7 @@ {% for panel in panels %}
  • {% if panel.has_content %} - {{ panel.title }} + {{ panel.title }} {% else %} {{ panel.title }} {% endif %} @@ -54,7 +22,7 @@ {% if panel.has_content %}
    - Close + Close
    {{ panel.content|safe }}
    diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py index c8ec7cd..26a5ca2 100644 --- a/debug_toolbar/urls.py +++ b/debug_toolbar/urls.py @@ -9,5 +9,5 @@ from django.conf.urls.defaults import * from django.conf import settings urlpatterns = patterns('', - url('^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media', name='debug_toolbar_media'), + url('^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media'), ) \ No newline at end of file -- cgit v1.2.3 From db62fbe4af73297698d0e716e4478f9662c813ce Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 16 Sep 2008 07:37:07 -0700 Subject: Updating toolbar.js to close panel on 2nd click. --- debug_toolbar/media/toolbar.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 8c0a86d..7e974d2 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -2,7 +2,11 @@ jQuery.noConflict(); jQuery(document).ready(function() { var current = null; jQuery('#djDebugPanelList li a').click(function() { - if (current) { current.hide(); } + if (current) { + current.hide(); + current = null; + return false; + } current = jQuery('#djDebug #' + this.className); current.show(); return false; -- cgit v1.2.3 From 7e27e62a690e98150f2294ff8f3aa7e43fc83e9c Mon Sep 17 00:00:00 2001 From: nbstrite Date: Tue, 16 Sep 2008 21:53:44 -0400 Subject: Fixed bug where django application was assumed to installed at / url. --- debug_toolbar/templates/debug_toolbar/base.html | 6 +++--- debug_toolbar/toolbar/loader.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 8ee29d2..58f4820 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,7 +1,7 @@ - - + +
    diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 67dcc3e..b2de90e 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -58,4 +58,4 @@ class DebugToolbar(object): """ Renders the overall Toolbar with panels inside. """ - return render_to_string('debug_toolbar/base.html', {'panels': self.panels}) + return render_to_string('debug_toolbar/base.html', {'panels': self.panels, 'base_url': self.request.META.get('SCRIPT_NAME', '')}) -- cgit v1.2.3 From 455aacf49b03e9d4c5edd8e3843999cfafada563 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 16 Sep 2008 21:41:13 -0700 Subject: Minor stylistic changes. --- debug_toolbar/templates/debug_toolbar/base.html | 6 +++--- debug_toolbar/toolbar/loader.py | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 58f4820..4cc028c 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,7 +1,7 @@ - - + +
    diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index b2de90e..935f45c 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -58,4 +58,7 @@ class DebugToolbar(object): """ Renders the overall Toolbar with panels inside. """ - return render_to_string('debug_toolbar/base.html', {'panels': self.panels, 'base_url': self.request.META.get('SCRIPT_NAME', '')}) + return render_to_string('debug_toolbar/base.html', { + 'panels': self.panels, + 'BASE_URL': self.request.META.get('SCRIPT_NAME', '') + }) -- cgit v1.2.3 From 816889b61cdd8bd1380009cfc755f9f655406e5c Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 16 Sep 2008 22:55:43 -0700 Subject: We now have a jQuery.djDebug object to extend. This might be overkill but it fixes a few issues with open/closing panels and adds a keybinding on the ESC key to close any panels that are open. --- debug_toolbar/media/toolbar.js | 57 ++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 7e974d2..e4e1ab3 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,19 +1,44 @@ jQuery.noConflict(); +(function(jQuery) { + jQuery.djDebug = function(data, klass) { + jQuery.djDebug.init(); + } + jQuery.extend(jQuery.djDebug, { + init: function() { + var current = null; + jQuery('#djDebugPanelList li a').click(function() { + current = jQuery('#djDebug #' + this.className); + if (current.is(':visible')) { + jQuery(document).trigger('close.djDebug'); + } else { + jQuery('.panelContent').hide(); + current.show(); + jQuery.djDebug.open(); + } + return false; + }); + jQuery('#djDebug a.close').click(function() { + jQuery(document).trigger('close.djDebug'); + return false; + }); + }, + open: function() { + jQuery(document).bind('keydown.djDebug', function(e) { + if (e.keyCode == 27) { + jQuery.djDebug.close(); + } + }); + }, + close: function() { + jQuery(document).trigger('close.djDebug'); + return false; + } + }); + jQuery(document).bind('close.djDebug', function() { + jQuery(document).unbind('keydown.djDebug'); + jQuery('.panelContent').hide(); + }); +})(jQuery); jQuery(document).ready(function() { - var current = null; - jQuery('#djDebugPanelList li a').click(function() { - if (current) { - current.hide(); - current = null; - return false; - } - current = jQuery('#djDebug #' + this.className); - current.show(); - return false; - }); - jQuery('#djDebug a.close').click(function() { - if (current) { current.hide(); } - current = null; - return false; - }) + jQuery.djDebug(); }); -- cgit v1.2.3 From e40b2c0fbdbd932be5f9d0550a16b6652de0d38d Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 18 Sep 2008 13:43:13 -0700 Subject: I noticed the template_rendered signal from the test suite also passed context, so I'm including the context with each template in the Template panel. This should make the designers happy. --- debug_toolbar/media/toolbar.js | 10 ++++++++ debug_toolbar/panels/template.py | 28 +++++++++++++++------- .../templates/debug_toolbar/panels/templates.html | 8 +++++-- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index e4e1ab3..21994a9 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -17,6 +17,9 @@ jQuery.noConflict(); } return false; }); + jQuery('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { + jQuery.djDebug.toggle_content(jQuery(this).parent().next()); + }); jQuery('#djDebug a.close').click(function() { jQuery(document).trigger('close.djDebug'); return false; @@ -29,6 +32,13 @@ jQuery.noConflict(); } }); }, + toggle_content: function(elem) { + if (elem.is(':visible')) { + elem.hide(); + } else { + elem.show(); + } + }, close: function() { jQuery(document).trigger('close.djDebug'); return false; diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index f1cf65b..f02b673 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -32,11 +32,11 @@ class TemplateDebugPanel(DebugPanel): def __init__(self, request): super(TemplateDebugPanel, self).__init__(request) - self.templates_used = [] - template_rendered.connect(self._storeRenderedTemplates) + self.templates = [] + template_rendered.connect(self._storeTemplateInfo) - def _storeRenderedTemplates(self, sender, **kwargs): - self.templates_used.append(kwargs['template']) + def _storeTemplateInfo(self, sender, **kwargs): + self.templates.append(kwargs) def title(self): return 'Templates' @@ -45,12 +45,22 @@ class TemplateDebugPanel(DebugPanel): return '' def content(self): - templates = [ - (t.name, t.origin and t.origin.name or 'No origin') - for t in self.templates_used - ] + template_context = [] + for i, d in enumerate(self.templates): + info = {} + # Clean up some info about templates + t = d.get('template', None) + if t.origin and t.origin.name: + t.origin_name = t.origin.name + else: + t.origin_name = 'No origin' + info['template'] = t + # Clean up context for better readability + c = d.get('context', None) + info['context'] = '\n'.join([_d.__repr__() for _d in c.dicts]) + template_context.append(info) context = { - 'templates': templates, + 'templates': template_context, 'template_dirs': settings.TEMPLATE_DIRS, } return render_to_string('debug_toolbar/panels/templates.html', context) diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index f9f03b5..ee93708 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -12,8 +12,12 @@ {% if templates %}
    {% for template in templates %} -
    {{ template.0|addslashes }}
    -
    {{ template.1|addslashes }}
    +
    {{ template.template.name|addslashes }}
    +
    {{ template.template.origin_name|addslashes }}
    +
    + + +
    {% endfor %}
    {% else %} -- cgit v1.2.3 From 43bb25c874f765800076285e76b2b0ba1460a597 Mon Sep 17 00:00:00 2001 From: Nowell Strite Date: Fri, 19 Sep 2008 01:17:16 -0400 Subject: Fixed template panel to skip over debug_toolbar templates. Fixed a bug in template context output where rendering would hang while trying to autoescape the context variable output. --- debug_toolbar/panels/template.py | 3 +++ debug_toolbar/templates/debug_toolbar/panels/templates.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index f02b673..bda6630 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -50,6 +50,9 @@ class TemplateDebugPanel(DebugPanel): info = {} # Clean up some info about templates t = d.get('template', None) + # Skip templates that we are generating through the debug toolbar. + if t.name.startswith('debug_toolbar/'): + continue if t.origin and t.origin.name: t.origin_name = t.origin.name else: diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index ee93708..0c47c5c 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -16,7 +16,7 @@
    {{ template.template.origin_name|addslashes }}
    - +
    {% endfor %} -- cgit v1.2.3 From 5a711759e75bfef4788498d9cfaa9fe019bcd15d Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 19 Sep 2008 10:47:16 -0700 Subject: Remove the safe filter from template context so objects don't turn into HTML tags (e.g. ) --- debug_toolbar/templates/debug_toolbar/panels/templates.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index 0c47c5c..575d507 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -16,10 +16,10 @@
    {{ template.template.origin_name|addslashes }}
    - +
    {% endfor %} {% else %} None -{% endif %} \ No newline at end of file +{% endif %} -- cgit v1.2.3 From 0c2c0ab82d6f848b6083a176f301d72d8bb798d8 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 11:51:58 -0700 Subject: jQuery patch from Alex Gaynor. --- debug_toolbar/media/toolbar.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 21994a9..3da65d2 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,5 +1,5 @@ jQuery.noConflict(); -(function(jQuery) { +jQuery(function() { jQuery.djDebug = function(data, klass) { jQuery.djDebug.init(); } @@ -48,7 +48,8 @@ jQuery.noConflict(); jQuery(document).unbind('keydown.djDebug'); jQuery('.panelContent').hide(); }); -})(jQuery); -jQuery(document).ready(function() { +}); + +jQuery(function() { jQuery.djDebug(); }); -- cgit v1.2.3 From af4f7a99dc346bb6b844564370fd6d479d6c36e7 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sat, 20 Sep 2008 20:18:41 +0100 Subject: Use $ shortcut for jQuery without conflicting with other libraries --- debug_toolbar/media/toolbar.js | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 3da65d2..b163000 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,34 +1,36 @@ jQuery.noConflict(); -jQuery(function() { - jQuery.djDebug = function(data, klass) { - jQuery.djDebug.init(); +jQuery(function($) { + $.djDebug = function(data, klass) { + $.djDebug.init(); } - jQuery.extend(jQuery.djDebug, { + $.extend($.djDebug, { init: function() { var current = null; - jQuery('#djDebugPanelList li a').click(function() { - current = jQuery('#djDebug #' + this.className); + $('#djDebugPanelList li a').click(function() { + current = $('#djDebug #' + this.className); if (current.is(':visible')) { - jQuery(document).trigger('close.djDebug'); + $(document).trigger('close.djDebug'); } else { - jQuery('.panelContent').hide(); + $('.panelContent').hide(); current.show(); - jQuery.djDebug.open(); + $.djDebug.open(); } return false; }); - jQuery('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { - jQuery.djDebug.toggle_content(jQuery(this).parent().next()); - }); - jQuery('#djDebug a.close').click(function() { - jQuery(document).trigger('close.djDebug'); + $('#djDebugTemplatePanel a.djTemplateShowContext').click( + function() { + $.djDebug.toggle_content($(this).parent().next()); + } + ); + $('#djDebug a.close').click(function() { + $(document).trigger('close.djDebug'); return false; }); }, open: function() { - jQuery(document).bind('keydown.djDebug', function(e) { + $(document).bind('keydown.djDebug', function(e) { if (e.keyCode == 27) { - jQuery.djDebug.close(); + $.djDebug.close(); } }); }, @@ -40,16 +42,15 @@ jQuery(function() { } }, close: function() { - jQuery(document).trigger('close.djDebug'); + $(document).trigger('close.djDebug'); return false; } }); - jQuery(document).bind('close.djDebug', function() { - jQuery(document).unbind('keydown.djDebug'); - jQuery('.panelContent').hide(); + $(document).bind('close.djDebug', function() { + $(document).unbind('keydown.djDebug'); + $('.panelContent').hide(); }); }); - jQuery(function() { jQuery.djDebug(); }); -- cgit v1.2.3 From 8e124b0a129ab351ec6cae30d8358709d4c1430b Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sat, 20 Sep 2008 20:30:45 +0100 Subject: Use pformat for template contexts, which makes it more readable --- debug_toolbar/panels/template.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index bda6630..e08f220 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -5,6 +5,8 @@ from django.template.loader import render_to_string from django.test.signals import template_rendered from debug_toolbar.panels import DebugPanel +from pprint import pformat + # Code taken and adapted from Simon Willison and Django Snippets: # http://www.djangosnippets.org/snippets/766/ @@ -60,7 +62,7 @@ class TemplateDebugPanel(DebugPanel): info['template'] = t # Clean up context for better readability c = d.get('context', None) - info['context'] = '\n'.join([_d.__repr__() for _d in c.dicts]) + info['context'] = '\n'.join([pformat(_d) for _d in c.dicts]) template_context.append(info) context = { 'templates': template_context, -- cgit v1.2.3 From 6bd25be6b8345f0a08c99acc35877faafd2a08ee Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 13:44:09 -0700 Subject: partly done with ajax support and js --- debug_toolbar/media/toolbar.css | 2 ++ debug_toolbar/media/toolbar.js | 19 ++++++++++++++++--- debug_toolbar/middleware.py | 4 ++-- debug_toolbar/templates/debug_toolbar/base.html | 5 ++--- debug_toolbar/templates/debug_toolbar/panels/sql.html | 2 +- .../templates/debug_toolbar/panels/sql_explain.html | 1 + 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 11dd978..7d2ad82 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -12,3 +12,5 @@ #djDebug th, #djDebug td {padding: 5px;} #djDebug .row1 td {background:#fff;} #djDebug .row2 td {background:#ddd;} +#djDebugWindow {z-index:2000000;} +#djDebugWindow .back {float:right; font-weight:bold;} diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 3da65d2..7d2f6b5 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -17,13 +17,22 @@ jQuery(function() { } return false; }); - jQuery('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { - jQuery.djDebug.toggle_content(jQuery(this).parent().next()); - }); jQuery('#djDebug a.close').click(function() { jQuery(document).trigger('close.djDebug'); return false; }); + jQuery('#djDebugWindow a.back').click(function() { + console.dir(jQuery(this).parent()); + jQuery(this).parent().hide(); + return false; + }); + jQuery('#djDebug a.remoteCall').click(function() { + jQuery.djDebug.remote_call(this); + return false; + }); + jQuery('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { + jQuery.djDebug.toggle_content(jQuery(this).parent().next()); + }); }, open: function() { jQuery(document).bind('keydown.djDebug', function(e) { @@ -39,6 +48,10 @@ jQuery(function() { elem.show(); } }, + remote_call: function(obj) { + jQuery('#djDebugWindow').load(obj.href).show(); + + }, close: function() { jQuery(document).trigger('close.djDebug'); return false; diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index a7e5655..eebd5a2 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -23,8 +23,8 @@ class DebugToolbarMiddleware(object): def show_toolbar(self, request): if not settings.DEBUG: return False - if request.is_ajax(): - return False + #if request.is_ajax(): + # return False if not request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS: return False return True diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 4cc028c..e654219 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -21,11 +21,10 @@ {% for panel in panels %} {% if panel.has_content %}
    -
    - Close -
    + Close {{ panel.content|safe }}
    {% endif %} {% endfor %} +
    diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 246fa74..bd167bc 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -12,7 +12,7 @@ {{ query.time|floatformat:"4" }}
    {{ query.sql|wordwrap:80|escape }}
    - EXPLAIN + EXPLAIN {% endfor %} diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html index 757d43f..8219205 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html @@ -1,3 +1,4 @@ +« Back

    SQL Explained

    Executed SQL
    -- cgit v1.2.3 From 251a7f4eb5efaf6339edd57021e5ce3d53a679b3 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 13:46:44 -0700 Subject: Import simplejson from django rather than an external dependency. --- debug_toolbar/panels/sql.py | 2 +- debug_toolbar/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 757505a..cdcbd1b 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -1,9 +1,9 @@ -import simplejson import time from debug_toolbar.panels import DebugPanel from django.db import connection from django.db.backends import util from django.template.loader import render_to_string +from django.utils import simplejson class DatabaseStatTracker(util.CursorDebugWrapper): """ diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index 1b44ed1..97739e6 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -5,11 +5,11 @@ views in any other way is generally not advised. """ import os -import simplejson import django.views.static from django.conf import settings from django.db import connection from django.shortcuts import render_to_response +from django.utils import simplejson def debug_media(request, path): root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None) -- cgit v1.2.3 From d85426c65e906d721e6b656ea9d7d53052c8a6bc Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 15:37:19 -0700 Subject: From Simon Willison but cleaned up tabbing: Use $ shortcut for jQuery without conflicting with other libraries --- debug_toolbar/media/toolbar.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 3da65d2..0b3624b 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,34 +1,34 @@ jQuery.noConflict(); -jQuery(function() { - jQuery.djDebug = function(data, klass) { - jQuery.djDebug.init(); +jQuery(function($) { + $.djDebug = function(data, klass) { + $.djDebug.init(); } - jQuery.extend(jQuery.djDebug, { + $.extend($.djDebug, { init: function() { var current = null; - jQuery('#djDebugPanelList li a').click(function() { - current = jQuery('#djDebug #' + this.className); + $('#djDebugPanelList li a').click(function() { + current = $('#djDebug #' + this.className); if (current.is(':visible')) { - jQuery(document).trigger('close.djDebug'); + $(document).trigger('close.djDebug'); } else { - jQuery('.panelContent').hide(); + $('.panelContent').hide(); current.show(); - jQuery.djDebug.open(); + $.djDebug.open(); } return false; }); - jQuery('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { - jQuery.djDebug.toggle_content(jQuery(this).parent().next()); + $('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { + $.djDebug.toggle_content($(this).parent().next()); }); - jQuery('#djDebug a.close').click(function() { - jQuery(document).trigger('close.djDebug'); + $('#djDebug a.close').click(function() { + $(document).trigger('close.djDebug'); return false; }); }, open: function() { - jQuery(document).bind('keydown.djDebug', function(e) { + $(document).bind('keydown.djDebug', function(e) { if (e.keyCode == 27) { - jQuery.djDebug.close(); + $.djDebug.close(); } }); }, @@ -40,13 +40,13 @@ jQuery(function() { } }, close: function() { - jQuery(document).trigger('close.djDebug'); + $(document).trigger('close.djDebug'); return false; } }); - jQuery(document).bind('close.djDebug', function() { - jQuery(document).unbind('keydown.djDebug'); - jQuery('.panelContent').hide(); + $(document).bind('close.djDebug', function() { + $(document).unbind('keydown.djDebug'); + $('.panelContent').hide(); }); }); -- cgit v1.2.3 From 344c60d81eb265088e58efd07fff51983232cde4 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 15:59:40 -0700 Subject: Upgrading jquery.js to v1.2.6 and including the minified version vs the packed version for faster processing time (vs faster transmit times). --- debug_toolbar/media/jquery.js | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/media/jquery.js b/debug_toolbar/media/jquery.js index 0404307..82b98e1 100644 --- a/debug_toolbar/media/jquery.js +++ b/debug_toolbar/media/jquery.js @@ -1,11 +1,32 @@ /* - * jQuery 1.2.5 - New Wave Javascript + * jQuery 1.2.6 - New Wave Javascript * * Copyright (c) 2008 John Resig (jquery.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * - * $Date: 2008-05-20 23:14:54 -0400 (Tue, 20 May 2008) $ - * $Rev: 5651 $ + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ */ -eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){I w=19.4G,3k$=19.$;I D=19.4G=19.$=G(a,b){H 2t D.16.5r(a,b)};I u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,61=/^.[^:#\\[\\.]*$/,11;D.16=D.4d={5r:G(d,b){d=d||R;7(d.12){6[0]=d;6.J=1;H 6}7(1i d=="21"){I c=u.2K(d);7(c&&(c[1]||!b)){7(c[1])d=D.4g([c[1]],b);N{I a=R.5X(c[3]);7(a){7(a.2w!=c[3])H D().2x(d);H D(a)}d=[]}}N H D(b).2x(d)}N 7(D.1E(d))H D(R)[D.16.28?"28":"40"](d);H 6.6W(D.2d(d))},5u:"1.2.5",8F:G(){H 6.J},J:0,3o:G(a){H a==11?D.2d(6):6[a]},2C:G(b){I a=D(b);a.5j=6;H a},6W:G(a){6.J=0;2p.4d.1o.1y(6,a);H 6},O:G(a,b){H D.O(6,a,b)},5f:G(b){I a=-1;H D.2E(b&&b.5u?b[0]:b,6)},1J:G(c,a,b){I d=c;7(c.1u==54)7(a===11)H 6[0]&&D[b||"1J"](6[0],c);N{d={};d[c]=a}H 6.O(G(i){Q(c 1m d)D.1J(b?6.T:6,c,D.1h(6,d[c],b,i,c))})},1f:G(b,a){7((b==\'2g\'||b==\'1S\')&&2Y(a)<0)a=11;H 6.1J(b,a,"2a")},1q:G(b){7(1i b!="3V"&&b!=U)H 6.4E().3v((6[0]&&6[0].2y||R).5F(b));I a="";D.O(b||6,G(){D.O(6.3t,G(){7(6.12!=8)a+=6.12!=1?6.74:D.16.1q([6])})});H a},5y:G(b){7(6[0])D(b,6[0].2y).5S().38(6[0]).2j(G(){I a=6;1H(a.1z)a=a.1z;H a}).3v(6);H 6},8X:G(a){H 6.O(G(){D(6).6Q().5y(a)})},8Q:G(a){H 6.O(G(){D(6).5y(a)})},3v:G(){H 6.3S(17,L,P,G(a){7(6.12==1)6.3R(a)})},6F:G(){H 6.3S(17,L,L,G(a){7(6.12==1)6.38(a,6.1z)})},6E:G(){H 6.3S(17,P,P,G(a){6.1b.38(a,6)})},5k:G(){H 6.3S(17,P,L,G(a){6.1b.38(a,6.2F)})},3m:G(){H 6.5j||D([])},2x:G(b){I c=D.2j(6,G(a){H D.2x(b,a)});H 6.2C(/[^+>] [^+>]/.Y(b)||b.1g("..")>-1?D.4q(c):c)},5S:G(e){I f=6.2j(G(){7(D.15.1e&&!D.4m(6)){I a=6.6m(L),5e=R.3h("1t");5e.3R(a);H D.4g([5e.4I])[0]}N H 6.6m(L)});I d=f.2x("*").5H().O(G(){7(6[E]!=11)6[E]=U});7(e===L)6.2x("*").5H().O(G(i){7(6.12==3)H;I c=D.K(6,"3w");Q(I a 1m c)Q(I b 1m c[a])D.V.1d(d[i],a,c[a][b],c[a][b].K)});H f},1C:G(b){H 6.2C(D.1E(b)&&D.3C(6,G(a,i){H b.1j(a,i)})||D.3f(b,6))},4V:G(b){7(b.1u==54)7(61.Y(b))H 6.2C(D.3f(b,6,L));N b=D.3f(b,6);I a=b.J&&b[b.J-1]!==11&&!b.12;H 6.1C(G(){H a?D.2E(6,b)<0:6!=b})},1d:G(a){H 6.2C(D.4q(D.2O(6.3o(),1i a==\'21\'?D(a):D.2d(a))))},3A:G(a){H!!a&&D.3f(a,6).J>0},7S:G(a){H 6.3A("."+a)},6e:G(b){7(b==11){7(6.J){I c=6[0];7(D.W(c,"2A")){I e=c.63,60=[],14=c.14,2W=c.M=="2A-2W";7(e<0)H U;Q(I i=2W?e:0,2c=2W?e+1:14.J;i<2c;i++){I d=14[i];7(d.3a){b=D.15.1e&&!d.ap.2u.al?d.1q:d.2u;7(2W)H b;60.1o(b)}}H 60}N H(6[0].2u||"").1n(/\\r/g,"")}H 11}H 6.O(G(){7(6.12!=1)H;7(b.1u==2p&&/5O|5L/.Y(6.M))6.4D=(D.2E(6.2u,b)>=0||D.2E(6.37,b)>=0);N 7(D.W(6,"2A")){I a=D.2d(b);D("9S",6).O(G(){6.3a=(D.2E(6.2u,a)>=0||D.2E(6.1q,a)>=0)});7(!a.J)6.63=-1}N 6.2u=b})},2I:G(a){H a==11?(6.J?6[0].4I:U):6.4E().3v(a)},7c:G(a){H 6.5k(a).1Y()},77:G(i){H 6.3s(i,i+1)},3s:G(){H 6.2C(2p.4d.3s.1y(6,17))},2j:G(b){H 6.2C(D.2j(6,G(a,i){H b.1j(a,i,a)}))},5H:G(){H 6.1d(6.5j)},K:G(d,b){I a=d.1P(".");a[1]=a[1]?"."+a[1]:"";7(b===11){I c=6.5C("9z"+a[1]+"!",[a[0]]);7(c===11&&6.J)c=D.K(6[0],d);H c===11&&a[1]?6.K(a[0]):c}N H 6.1R("9u"+a[1]+"!",[a[0],b]).O(G(){D.K(6,d,b)})},2V:G(a){H 6.O(G(){D.2V(6,a)})},3S:G(g,f,h,d){I e=6.J>1,3p;H 6.O(G(){7(!3p){3p=D.4g(g,6.2y);7(h)3p.9n()}I b=6;7(f&&D.W(6,"1U")&&D.W(3p[0],"4N"))b=6.3F("1W")[0]||6.3R(6.2y.3h("1W"));I c=D([]);D.O(3p,G(){I a=e?D(6).5S(L)[0]:6;7(D.W(a,"1k")){c=c.1d(a)}N{7(a.12==1)c=c.1d(D("1k",a).1Y());d.1j(b,a)}});c.O(6S)})}};D.16.5r.4d=D.16;G 6S(i,a){7(a.3X)D.3T({1a:a.3X,3c:P,1K:"1k"});N D.5s(a.1q||a.6O||a.4I||"");7(a.1b)a.1b.2Z(a)}G 1x(){H+2t 8J}D.1l=D.16.1l=G(){I b=17[0]||{},i=1,J=17.J,4z=P,14;7(b.1u==8H){4z=b;b=17[1]||{};i=2}7(1i b!="3V"&&1i b!="G")b={};7(J==i){b=6;--i}Q(;i-1}},6p:G(b,c,a){I e={};Q(I d 1m c){e[d]=b.T[d];b.T[d]=c[d]}a.1j(b);Q(I d 1m c)b.T[d]=e[d]},1f:G(d,e,c){7(e=="2g"||e=="1S"){I b,3I={30:"64",5d:"1B",18:"3G"},2Q=e=="2g"?["5c","6j"]:["5a","6h"];G 59(){b=e=="2g"?d.8e:d.8b;I a=0,2m=0;D.O(2Q,G(){a+=2Y(D.2a(d,"55"+6,L))||0;2m+=2Y(D.2a(d,"2m"+6+"49",L))||0});b-=26.83(a+2m)}7(D(d).3A(":4i"))59();N D.6p(d,3I,59);H 26.2c(0,b)}H D.2a(d,e,c)},2a:G(f,l,k){I e,T=f.T;G 3D(b){7(!D.15.2k)H P;I a=3N.51(b,U);H!a||a.50("3D")==""}7(l=="1r"&&D.15.1e){e=D.1J(T,"1r");H e==""?"1":e}7(D.15.2J&&l=="18"){I d=T.4W;T.4W="0 7X 7W";T.4W=d}7(l.1A(/4h/i))l=y;7(!k&&T&&T[l])e=T[l];N 7(3N.51){7(l.1A(/4h/i))l="4h";l=l.1n(/([A-Z])/g,"-$1").3g();I c=3N.51(f,U);7(c&&!3D(f))e=c.50(l);N{I g=[],2D=[],a=f,i=0;Q(;a&&3D(a);a=a.1b)2D.6g(a);Q(;i<2D.J;i++)7(3D(2D[i])){g[i]=2D[i].T.18;2D[i].T.18="3G"}e=l=="18"&&g[2D.J-1]!=U?"2L":(c&&c.50(l))||"";Q(i=0;i]*?)\\/>/g,G(b,a,c){H c.1A(/^(aG|3H|7C|aD|4S|7z|ay|3y|ax|av|as)$/i)?b:a+">"});I f=D.3l(d).3g(),1t=h.3h("1t");I e=!f.1g("",""]||!f.1g("",""]||f.1A(/^<(an|1W|ak|ai|af)/)&&[1,"<1U>",""]||!f.1g("<4N")&&[2,"<1U><1W>",""]||(!f.1g("<1W><4N>",""]||!f.1g("<7C")&&[2,"<1U><1W><7n>",""]||D.15.1e&&[1,"1t<1t>",""]||[0,"",""];1t.4I=e[1]+d+e[2];1H(e[0]--)1t=1t.5R;7(D.15.1e){I g=!f.1g("<1U")&&f.1g("<1W")<0?1t.1z&&1t.1z.3t:e[1]=="<1U>"&&f.1g("<1W")<0?1t.3t:[];Q(I j=g.J-1;j>=0;--j)7(D.W(g[j],"1W")&&!g[j].3t.J)g[j].1b.2Z(g[j]);7(/^\\s/.Y(d))1t.38(h.5F(d.1A(/^\\s*/)[0]),1t.1z)}d=D.2d(1t.3t)}7(d.J===0&&(!D.W(d,"3W")&&!D.W(d,"2A")))H;7(d[0]==11||D.W(d,"3W")||d.14)k.1o(d);N k=D.2O(k,d)});H k},1J:G(d,f,c){7(!d||d.12==3||d.12==8)H 11;I e=!D.4m(d),41=c!==11,1e=D.15.1e;f=e&&D.3I[f]||f;7(d.2e){I g=/5N|3X|T/.Y(f);7(f=="3a"&&D.15.2k)d.1b.63;7(e&&!g&&f 1m d){7(41){7(f=="M"&&D.W(d,"4S")&&d.1b)7l"M a1 9Y\'t 9U 9T";d[f]=c}7(D.W(d,"3W")&&d.7e(f))H d.7e(f).74;H d[f]}7(1e&&e&&f=="T")H D.1J(d.T,"9Q",c);7(41)d.9P(f,""+c);7(1e&&g&&e)H d.4J(f,2);H d.4J(f)}7(1e&&f=="1r"){7(41){d.6B=1;d.1C=(d.1C||"").1n(/7b\\([^)]*\\)/,"")+(3r(c)+\'\'=="9K"?"":"7b(1r="+c*79+")")}H d.1C&&d.1C.1g("1r=")>=0?(2Y(d.1C.1A(/1r=([^)]*)/)[1])/79)+\'\':""}f=f.1n(/-([a-z])/9G,G(a,b){H b.2o()});7(41)d[f]=c;H d[f]},3l:G(a){H(a||"").1n(/^\\s+|\\s+$/g,"")},2d:G(b){I a=[];7(b!=U){I i=b.J;7(i==U||b.1P||b.4H||b.1j)a[0]=b;N 1H(i)a[--i]=b[i]}H a},2E:G(b,a){Q(I i=0,J=a.J;i*",6).1Y();1H(6.1z)6.2Z(6.1z)}},G(a,b){D.16[a]=G(){H 6.O(b,17)}});D.O(["6N","49"],G(i,c){I b=c.3g();D.16[b]=G(a){H 6[0]==19?D.15.2J&&R.1c["5q"+c]||D.15.2k&&19["5p"+c]||R.6X=="7r"&&R.1F["5q"+c]||R.1c["5q"+c]:6[0]==R?26.2c(26.2c(R.1c["4y"+c],R.1F["4y"+c]),26.2c(R.1c["2i"+c],R.1F["2i"+c])):a==11?(6.J?D.1f(6[0],b):U):6.1f(b,a.1u==54?a:a+"2U")}});G 25(a,b){H a[0]&&3r(D.2a(a[0],b,L),10)||0}I C=D.15.2k&&3r(D.15.5B)<8G?"(?:[\\\\w*3k-]|\\\\\\\\.)":"(?:[\\\\w\\8E-\\8D*3k-]|\\\\\\\\.)",6K=2t 4w("^>\\\\s*("+C+"+)"),6J=2t 4w("^("+C+"+)(#)("+C+"+)"),6I=2t 4w("^([#.]?)("+C+"*)");D.1l({6G:{"":G(a,i,m){H m[2]=="*"||D.W(a,m[2])},"#":G(a,i,m){H a.4J("2w")==m[2]},":":{8C:G(a,i,m){H im[3]-0},34:G(a,i,m){H m[3]-0==i},77:G(a,i,m){H m[3]-0==i},3n:G(a,i){H i==0},3Q:G(a,i,m,r){H i==r.J-1},6D:G(a,i){H i%2==0},6C:G(a,i){H i%2},"3n-4u":G(a){H a.1b.3F("*")[0]==a},"3Q-4u":G(a){H D.34(a.1b.5R,1,"4R")==a},"8y-4u":G(a){H!D.34(a.1b.5R,2,"4R")},6U:G(a){H a.1z},4E:G(a){H!a.1z},8x:G(a,i,m){H(a.6O||a.8w||D(a).1q()||"").1g(m[3])>=0},4i:G(a){H"1B"!=a.M&&D.1f(a,"18")!="2L"&&D.1f(a,"5d")!="1B"},1B:G(a){H"1B"==a.M||D.1f(a,"18")=="2L"||D.1f(a,"5d")=="1B"},8u:G(a){H!a.3O},3O:G(a){H a.3O},4D:G(a){H a.4D},3a:G(a){H a.3a||D.1J(a,"3a")},1q:G(a){H"1q"==a.M},5O:G(a){H"5O"==a.M},5L:G(a){H"5L"==a.M},5m:G(a){H"5m"==a.M},3E:G(a){H"3E"==a.M},5l:G(a){H"5l"==a.M},6A:G(a){H"6A"==a.M},6y:G(a){H"6y"==a.M},2q:G(a){H"2q"==a.M||D.W(a,"2q")},4S:G(a){H/4S|2A|6x|2q/i.Y(a.W)},3J:G(a,i,m){H D.2x(m[3],a).J},8s:G(a){H/h\\d/i.Y(a.W)},8r:G(a){H D.3C(D.3M,G(b){H a==b.S}).J}}},6w:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2t 4w("^([:.#]*)("+C+"+)")],3f:G(a,c,b){I d,1s=[];1H(a&&a!=d){d=a;I f=D.1C(a,c,b);a=f.t.1n(/^\\s*,\\s*/,"");1s=b?c=f.r:D.2O(1s,f.r)}H 1s},2x:G(t,o){7(1i t!="21")H[t];7(o&&o.12!=1&&o.12!=9)H[];o=o||R;I d=[o],2z=[],3Q,W;1H(t&&3Q!=t){I r=[];3Q=t;t=D.3l(t);I l=P,3j=6K,m=3j.2K(t);7(m){W=m[1].2o();Q(I i=0;d[i];i++)Q(I c=d[i].1z;c;c=c.2F)7(c.12==1&&(W=="*"||c.W.2o()==W))r.1o(c);d=r;t=t.1n(3j,"");7(t.1g(" ")==0)6M;l=L}N{3j=/^([>+~])\\s*(\\w*)/i;7((m=3j.2K(t))!=U){r=[];I k={};W=m[2].2o();m=m[1];Q(I j=0,3i=d.J;j<3i;j++){I n=m=="~"||m=="+"?d[j].2F:d[j].1z;Q(;n;n=n.2F)7(n.12==1){I g=D.K(n);7(m=="~"&&k[g])1T;7(!W||n.W.2o()==W){7(m=="~")k[g]=L;r.1o(n)}7(m=="+")1T}}d=r;t=D.3l(t.1n(3j,""));l=L}}7(t&&!l){7(!t.1g(",")){7(o==d[0])d.4r();2z=D.2O(2z,d);r=d=[o];t=" "+t.6u(1,t.J)}N{I h=6J;I m=h.2K(t);7(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2K(t)}m[2]=m[2].1n(/\\\\/g,"");I f=d[d.J-1];7(m[1]=="#"&&f&&f.5X&&!D.4m(f)){I p=f.5X(m[2]);7((D.15.1e||D.15.2J)&&p&&1i p.2w=="21"&&p.2w!=m[2])p=D(\'[@2w="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.W(p,m[3]))?[p]:[]}N{Q(I i=0;d[i];i++){I a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];7(a=="*"&&d[i].W.3g()=="3V")a="3y";r=D.2O(r,d[i].3F(a))}7(m[1]==".")r=D.5i(r,m[2]);7(m[1]=="#"){I e=[];Q(I i=0;r[i];i++)7(r[i].4J("2w")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1n(h,"")}}7(t){I b=D.1C(t,r);d=r=b.r;t=D.3l(b.t)}}7(t)d=[];7(d&&o==d[0])d.4r();2z=D.2O(2z,d);H 2z},5i:G(r,m,a){m=" "+m+" ";I c=[];Q(I i=0;r[i];i++){I b=(" "+r[i].1G+" ").1g(m)>=0;7(!a&&b||a&&!b)c.1o(r[i])}H c},1C:G(t,r,h){I d;1H(t&&t!=d){d=t;I p=D.6w,m;Q(I i=0;p[i];i++){m=p[i].2K(t);7(m){t=t.8q(m[0].J);m[2]=m[2].1n(/\\\\/g,"");1T}}7(!m)1T;7(m[1]==":"&&m[2]=="4V")r=61.Y(m[3])?D.1C(m[3],r,L).r:D(r).4V(m[3]);N 7(m[1]==".")r=D.5i(r,m[2],h);N 7(m[1]=="["){I g=[],M=m[3];Q(I i=0,3i=r.J;i<3i;i++){I a=r[i],z=a[D.3I[m[2]]||m[2]];7(z==U||/5N|3X|3a/.Y(m[2]))z=D.1J(a,m[2])||\'\';7((M==""&&!!z||M=="="&&z==m[5]||M=="!="&&z!=m[5]||M=="^="&&z&&!z.1g(m[5])||M=="$="&&z.6u(z.J-m[5].J)==m[5]||(M=="*="||M=="~=")&&z.1g(m[5])>=0)^h)g.1o(a)}r=g}N 7(m[1]==":"&&m[2]=="34-4u"){I e={},g=[],Y=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2K(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.Y(m[3])&&"8p+"+m[3]||m[3]),3n=(Y[1]+(Y[2]||1))-0,d=Y[3]-0;Q(I i=0,3i=r.J;i<3i;i++){I j=r[i],1b=j.1b,2w=D.K(1b);7(!e[2w]){I c=1;Q(I n=1b.1z;n;n=n.2F)7(n.12==1)n.4p=c++;e[2w]=L}I b=P;7(3n==0){7(j.4p==d)b=L}N 7((j.4p-d)%3n==0&&(j.4p-d)/3n>=0)b=L;7(b^h)g.1o(j)}r=g}N{I f=D.6G[m[1]];7(1i f=="3V")f=f[m[2]];7(1i f=="21")f=6t("P||G(a,i){H "+f+";}");r=D.3C(r,G(a,i){H f(a,i,m,r)},h)}}H{r:r,t:t}},4T:G(b,c){I a=[],1s=b[c];1H(1s&&1s!=R){7(1s.12==1)a.1o(1s);1s=1s[c]}H a},34:G(a,e,c,b){e=e||1;I d=0;Q(;a;a=a[c])7(a.12==1&&++d==e)1T;H a},5t:G(n,a){I r=[];Q(;n;n=n.2F){7(n.12==1&&n!=a)r.1o(n)}H r}});D.V={1d:G(f,i,g,e){7(f.12==3||f.12==8)H;7(D.15.1e&&f.4H)f=19;7(!g.23)g.23=6.23++;7(e!=11){I h=g;g=6.3L(h,G(){H h.1y(6,17)});g.K=e}I j=D.K(f,"3w")||D.K(f,"3w",{}),1D=D.K(f,"1D")||D.K(f,"1D",G(){7(1i D!="11"&&!D.V.5n)H D.V.1D.1y(17.3P.S,17)});1D.S=f;D.O(i.1P(/\\s+/),G(c,b){I a=b.1P(".");b=a[0];g.M=a[1];I d=j[b];7(!d){d=j[b]={};7(!D.V.2s[b]||D.V.2s[b].4o.1j(f)===P){7(f.3K)f.3K(b,1D,P);N 7(f.6s)f.6s("4n"+b,1D)}}d[g.23]=g;D.V.24[b]=L});f=U},23:1,24:{},1Y:G(e,h,f){7(e.12==3||e.12==8)H;I i=D.K(e,"3w"),1I,5f;7(i){7(h==11||(1i h=="21"&&h.8o(0)=="."))Q(I g 1m i)6.1Y(e,g+(h||""));N{7(h.M){f=h.2v;h=h.M}D.O(h.1P(/\\s+/),G(b,a){I c=a.1P(".");a=c[0];7(i[a]){7(f)2X i[a][f.23];N Q(f 1m i[a])7(!c[1]||i[a][f].M==c[1])2X i[a][f];Q(1I 1m i[a])1T;7(!1I){7(!D.V.2s[a]||D.V.2s[a].4A.1j(e)===P){7(e.6o)e.6o(a,D.K(e,"1D"),P);N 7(e.6n)e.6n("4n"+a,D.K(e,"1D"))}1I=U;2X i[a]}}})}Q(1I 1m i)1T;7(!1I){I d=D.K(e,"1D");7(d)d.S=U;D.2V(e,"3w");D.2V(e,"1D")}}},1R:G(h,c,f,g,i){c=D.2d(c);7(h.1g("!")>=0){h=h.3s(0,-1);I a=L}7(!f){7(6.24[h])D("*").1d([19,R]).1R(h,c)}N{7(f.12==3||f.12==8)H 11;I b,1I,16=D.1E(f[h]||U),V=!c[0]||!c[0].31;7(V){c.6g({M:h,2G:f,31:G(){},3Y:G(){},4l:1x()});c[0][E]=L}c[0].M=h;7(a)c[0].6l=L;I d=D.K(f,"1D");7(d)b=d.1y(f,c);7((!16||(D.W(f,\'a\')&&h=="4K"))&&f["4n"+h]&&f["4n"+h].1y(f,c)===P)b=P;7(V)c.4r();7(i&&D.1E(i)){1I=i.1y(f,b==U?c:c.78(b));7(1I!==11)b=1I}7(16&&g!==P&&b!==P&&!(D.W(f,\'a\')&&h=="4K")){6.5n=L;1Z{f[h]()}1X(e){}}6.5n=P}H b},1D:G(b){I a,1I,36,5A,4k;b=17[0]=D.V.6k(b||19.V);36=b.M.1P(".");b.M=36[0];36=36[1];5A=!36&&!b.6l;4k=(D.K(6,"3w")||{})[b.M];Q(I j 1m 4k){I c=4k[j];7(5A||c.M==36){b.2v=c;b.K=c.K;1I=c.1y(6,17);7(a!==P)a=1I;7(1I===P){b.31();b.3Y()}}}H a},6k:G(b){7(b[E]==L)H b;I d=b;b={8n:d};I c="8m 8l 8k 8j 2q 8i 45 5D 6i 5b 8h K 8g 8f 4j 2v 58 57 8d 8c 56 6f 8a 89 4L 87 86 85 6c 2G 4l 6b M 82 81 2Q".1P(" ");Q(I i=c.J;i;i--)b[c[i]]=d[c[i]];b[E]=L;b.31=G(){7(d.31)d.31();d.80=P};b.3Y=G(){7(d.3Y)d.3Y();d.7Z=L};b.4l=b.4l||1x();7(!b.2G)b.2G=b.6c||R;7(b.2G.12==3)b.2G=b.2G.1b;7(!b.4L&&b.4j)b.4L=b.4j==b.2G?b.6b:b.4j;7(b.56==U&&b.5D!=U){I a=R.1F,1c=R.1c;b.56=b.5D+(a&&a.2h||1c&&1c.2h||0)-(a.6a||0);b.6f=b.6i+(a&&a.2b||1c&&1c.2b||0)-(a.69||0)}7(!b.2Q&&((b.45||b.45===0)?b.45:b.58))b.2Q=b.45||b.58;7(!b.57&&b.5b)b.57=b.5b;7(!b.2Q&&b.2q)b.2Q=(b.2q&1?1:(b.2q&2?3:(b.2q&4?2:0)));H b},3L:G(a,b){b.23=a.23=a.23||b.23||6.23++;H b},2s:{28:{4o:G(){53();H},4A:G(){H}},4b:{4o:G(){7(D.15.1e)H P;D(6).2N("52",D.V.2s.4b.2v);H L},4A:G(){7(D.15.1e)H P;D(6).4c("52",D.V.2s.4b.2v);H L},2v:G(a){7(F(a,6))H L;a.M="4b";H D.V.1D.1y(6,17)}},4e:{4o:G(){7(D.15.1e)H P;D(6).2N("4Z",D.V.2s.4e.2v);H L},4A:G(){7(D.15.1e)H P;D(6).4c("4Z",D.V.2s.4e.2v);H L},2v:G(a){7(F(a,6))H L;a.M="4e";H D.V.1D.1y(6,17)}}}};D.16.1l({2N:G(c,a,b){H c=="4Y"?6.2W(c,a,b):6.O(G(){D.V.1d(6,c,b||a,b&&a)})},2W:G(d,b,c){I e=D.V.3L(c||b,G(a){D(6).4c(a,e);H(c||b).1y(6,17)});H 6.O(G(){D.V.1d(6,d,e,c&&b)})},4c:G(a,b){H 6.O(G(){D.V.1Y(6,a,b)})},1R:G(c,a,b){H 6.O(G(){D.V.1R(c,a,6,L,b)})},5C:G(c,a,b){H 6[0]&&D.V.1R(c,a,6[0],P,b)},2l:G(b){I c=17,i=1;1H(i=0){I i=g.3s(e,g.J);g=g.3s(0,e)}c=c||G(){};I f="2S";7(d)7(D.1E(d)){c=d;d=U}N{d=D.3y(d);f="66"}I h=6;D.3T({1a:g,M:f,1K:"2I",K:d,1N:G(a,b){7(b=="22"||b=="6z")h.2I(i?D("<1t/>").3v(a.4C.1n(/<1k(.|\\s)*?\\/1k>/g,"")).2x(i):a.4C);h.O(c,[a.4C,b,a])}});H 6},aL:G(){H D.3y(6.7H())},7H:G(){H 6.2j(G(){H D.W(6,"3W")?D.2d(6.aH):6}).1C(G(){H 6.37&&!6.3O&&(6.4D||/2A|6x/i.Y(6.W)||/1q|1B|3E/i.Y(6.M))}).2j(G(i,c){I b=D(6).6e();H b==U?U:b.1u==2p?D.2j(b,G(a,i){H{37:c.37,2u:a}}):{37:c.37,2u:b}}).3o()}});D.O("7G,7F,7E,7D,7B,7A".1P(","),G(i,o){D.16[o]=G(f){H 6.2N(o,f)}});I B=1x();D.1l({3o:G(d,b,a,c){7(D.1E(b)){a=b;b=U}H D.3T({M:"2S",1a:d,K:b,22:a,1K:c})},aC:G(b,a){H D.3o(b,U,a,"1k")},aB:G(c,b,a){H D.3o(c,b,a,"3u")},aA:G(d,b,a,c){7(D.1E(b)){a=b;b={}}H D.3T({M:"66",1a:d,K:b,22:a,1K:c})},az:G(a){D.1l(D.5Z,a)},5Z:{1a:5Y.5N,24:L,M:"2S",2T:0,7y:"4t/x-aw-3W-au",7w:L,3c:L,K:U,5V:U,3E:U,4v:{2M:"4t/2M, 1q/2M",2I:"1q/2I",1k:"1q/4s, 4t/4s",3u:"4t/3u, 1q/4s",1q:"1q/aq",4Q:"*/*"}},4x:{},3T:G(s){s=D.1l(L,s,D.1l(L,{},D.5Z,s));I g,33=/=\\?(&|$)/g,1v,K,M=s.M.2o();7(s.K&&s.7w&&1i s.K!="21")s.K=D.3y(s.K);7(s.1K=="4P"){7(M=="2S"){7(!s.1a.1A(33))s.1a+=(s.1a.1A(/\\?/)?"&":"?")+(s.4P||"7t")+"=?"}N 7(!s.K||!s.K.1A(33))s.K=(s.K?s.K+"&":"")+(s.4P||"7t")+"=?";s.1K="3u"}7(s.1K=="3u"&&(s.K&&s.K.1A(33)||s.1a.1A(33))){g="4P"+B++;7(s.K)s.K=(s.K+"").1n(33,"="+g+"$1");s.1a=s.1a.1n(33,"="+g+"$1");s.1K="1k";19[g]=G(a){K=a;22();1N();19[g]=11;1Z{2X 19[g]}1X(e){}7(i)i.2Z(h)}}7(s.1K=="1k"&&s.1V==U)s.1V=P;7(s.1V===P&&M=="2S"){I j=1x();I k=s.1a.1n(/(\\?|&)3k=.*?(&|$)/,"$am="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1A(/\\?/)?"&":"?")+"3k="+j:"")}7(s.K&&M=="2S"){s.1a+=(s.1a.1A(/\\?/)?"&":"?")+s.K;s.K=U}7(s.24&&!D.4O++)D.V.1R("7G");I n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;7(s.1K=="1k"&&M=="2S"&&n.Y(s.1a)&&n.2K(s.1a)[1]!=5Y.aj){I i=R.3F("6v")[0];I h=R.3h("1k");h.3X=s.1a;7(s.7s)h.ah=s.7s;7(!g){I l=P;h.ag=h.ae=G(){7(!l&&(!6.3e||6.3e=="67"||6.3e=="1N")){l=L;22();1N();i.2Z(h)}}}i.3R(h);H 11}I m=P;I c=19.7q?2t 7q("ac.ab"):2t 7p();7(s.5V)c.7o(M,s.1a,s.3c,s.5V,s.3E);N c.7o(M,s.1a,s.3c);1Z{7(s.K)c.4B("a9-a8",s.7y);7(s.5Q)c.4B("a7-5P-a6",D.4x[s.1a]||"a5, a4 a3 a2 5x:5x:5x a0");c.4B("X-9X-9W","7p");c.4B("9V",s.1K&&s.4v[s.1K]?s.4v[s.1K]+", */*":s.4v.4Q)}1X(e){}7(s.7k&&s.7k(c,s)===P){s.24&&D.4O--;c.7j();H P}7(s.24)D.V.1R("7A",[c,s]);I d=G(a){7(!m&&c&&(c.3e==4||a=="2T")){m=L;7(f){7i(f);f=U}1v=a=="2T"&&"2T"||!D.7h(c)&&"3d"||s.5Q&&D.7g(c,s.1a)&&"6z"||"22";7(1v=="22"){1Z{K=D.7f(c,s.1K,s.9R)}1X(e){1v="5I"}}7(1v=="22"){I b;1Z{b=c.5z("7d-5P")}1X(e){}7(s.5Q&&b)D.4x[s.1a]=b;7(!g)22()}N D.5G(s,c,1v);1N();7(s.3c)c=U}};7(s.3c){I f=4H(d,13);7(s.2T>0)3z(G(){7(c){c.7j();7(!m)d("2T")}},s.2T)}1Z{c.9O(s.K)}1X(e){D.5G(s,c,U,e)}7(!s.3c)d();G 22(){7(s.22)s.22(K,1v);7(s.24)D.V.1R("7B",[c,s])}G 1N(){7(s.1N)s.1N(c,1v);7(s.24)D.V.1R("7E",[c,s]);7(s.24&&!--D.4O)D.V.1R("7F")}H c},5G:G(s,a,b,e){7(s.3d)s.3d(a,b,e);7(s.24)D.V.1R("7D",[a,s,e])},4O:0,7h:G(a){1Z{H!a.1v&&5Y.9N=="5m:"||(a.1v>=70&&a.1v<9L)||a.1v==7a||a.1v==9J||D.15.2k&&a.1v==11}1X(e){}H P},7g:G(a,c){1Z{I b=a.5z("7d-5P");H a.1v==7a||b==D.4x[c]||D.15.2k&&a.1v==11}1X(e){}H P},7f:G(a,c,b){I d=a.5z("9I-M"),2M=c=="2M"||!c&&d&&d.1g("2M")>=0,K=2M?a.9H:a.4C;7(2M&&K.1F.2e=="5I")7l"5I";7(b)K=b(K,c);7(c=="1k")D.5s(K);7(c=="3u")K=6t("("+K+")");H K},3y:G(a){I s=[];7(a.1u==2p||a.5u)D.O(a,G(){s.1o(3q(6.37)+"="+3q(6.2u))});N Q(I j 1m a)7(a[j]&&a[j].1u==2p)D.O(a[j],G(){s.1o(3q(j)+"="+3q(6))});N s.1o(3q(j)+"="+3q(D.1E(a[j])?a[j]():a[j]));H s.6r("&").1n(/%20/g,"+")}});D.16.1l({1M:G(c,b){H c?6.2f({1S:"1M",2g:"1M",1r:"1M"},c,b):6.1C(":1B").O(G(){6.T.18=6.5E||"";7(D.1f(6,"18")=="2L"){I a=D("<"+6.2e+" />").6P("1c");6.T.18=a.1f("18");7(6.T.18=="2L")6.T.18="3G";a.1Y()}}).3m()},1L:G(b,a){H b?6.2f({1S:"1L",2g:"1L",1r:"1L"},b,a):6.1C(":4i").O(G(){6.5E=6.5E||D.1f(6,"18");6.T.18="2L"}).3m()},76:D.16.2l,2l:G(a,b){H D.1E(a)&&D.1E(b)?6.76.1y(6,17):a?6.2f({1S:"2l",2g:"2l",1r:"2l"},a,b):6.O(G(){D(6)[D(6).3A(":1B")?"1M":"1L"]()})},9F:G(b,a){H 6.2f({1S:"1M"},b,a)},9E:G(b,a){H 6.2f({1S:"1L"},b,a)},9D:G(b,a){H 6.2f({1S:"2l"},b,a)},9C:G(b,a){H 6.2f({1r:"1M"},b,a)},9B:G(b,a){H 6.2f({1r:"1L"},b,a)},9M:G(c,a,b){H 6.2f({1r:a},c,b)},2f:G(k,j,i,g){I h=D.75(j,i,g);H 6[h.35===P?"O":"35"](G(){7(6.12!=1)H P;I f=D.1l({},h),p,1B=D(6).3A(":1B"),46=6;Q(p 1m k){7(k[p]=="1L"&&1B||k[p]=="1M"&&!1B)H f.1N.1j(6);7(p=="1S"||p=="2g"){f.18=D.1f(6,"18");f.32=6.T.32}}7(f.32!=U)6.T.32="1B";f.44=D.1l({},k);D.O(k,G(c,a){I e=2t D.29(46,f,c);7(/2l|1M|1L/.Y(a))e[a=="2l"?1B?"1M":"1L":a](k);N{I b=a.6q().1A(/^([+-]=)?([\\d+-.]+)(.*)$/),27=e.1s(L)||0;7(b){I d=2Y(b[2]),2H=b[3]||"2U";7(2H!="2U"){46.T[c]=(d||1)+2H;27=((d||1)/e.1s(L))*27;46.T[c]=27+2H}7(b[1])d=((b[1]=="-="?-1:1)*d)+27;e.47(27,d,2H)}N e.47(27,a,"")}});H L})},35:G(a,b){7(D.1E(a)||(a&&a.1u==2p)){b=a;a="29"}7(!a||(1i a=="21"&&!b))H A(6[0],a);H 6.O(G(){7(b.1u==2p)A(6,a,b);N{A(6,a).1o(b);7(A(6,a).J==1)b.1j(6)}})},9w:G(b,c){I a=D.3M;7(b)6.35([]);6.O(G(){Q(I i=a.J-1;i>=0;i--)7(a[i].S==6){7(c)a[i](L);a.7I(i,1)}});7(!c)6.5T();H 6}});I A=G(b,c,a){7(b){c=c||"29";I q=D.K(b,c+"35");7(!q||a)q=D.K(b,c+"35",D.2d(a))}H q};D.16.5T=G(a){a=a||"29";H 6.O(G(){I q=A(6,a);q.4r();7(q.J)q[0].1j(6)})};D.1l({75:G(b,a,c){I d=b&&b.1u==9Z?b:{1N:c||!c&&a||D.1E(b)&&b,2r:b,48:c&&a||a&&a.1u!=9r&&a};d.2r=(d.2r&&d.2r.1u==5g?d.2r:D.29.5J[d.2r])||D.29.5J.72;d.5M=d.1N;d.1N=G(){7(d.35!==P)D(6).5T();7(D.1E(d.5M))d.5M.1j(6)};H d},48:{71:G(p,n,b,a){H b+a*p},5K:G(p,n,b,a){H((-26.9p(p*26.9o)/2)+0.5)*a+b}},3M:[],43:U,29:G(b,c,a){6.14=c;6.S=b;6.1h=a;7(!c.3Z)c.3Z={}}});D.29.4d={4M:G(){7(6.14.39)6.14.39.1j(6.S,6.1x,6);(D.29.39[6.1h]||D.29.39.4Q)(6);7(6.1h=="1S"||6.1h=="2g")6.S.T.18="3G"},1s:G(a){7(6.S[6.1h]!=U&&6.S.T[6.1h]==U)H 6.S[6.1h];I r=2Y(D.1f(6.S,6.1h,a));H r&&r>-9m?r:2Y(D.2a(6.S,6.1h))||0},47:G(c,b,d){6.5v=1x();6.27=c;6.3m=b;6.2H=d||6.2H||"2U";6.1x=6.27;6.2R=6.4F=0;6.4M();I e=6;G t(a){H e.39(a)}t.S=6.S;D.3M.1o(t);7(D.43==U){D.43=4H(G(){I a=D.3M;Q(I i=0;i6.14.2r+6.5v){6.1x=6.3m;6.2R=6.4F=1;6.4M();6.14.44[6.1h]=L;I b=L;Q(I i 1m 6.14.44)7(6.14.44[i]!==L)b=P;7(b){7(6.14.18!=U){6.S.T.32=6.14.32;6.S.T.18=6.14.18;7(D.1f(6.S,"18")=="2L")6.S.T.18="3G"}7(6.14.1L)6.S.T.18="2L";7(6.14.1L||6.14.1M)Q(I p 1m 6.14.44)D.1J(6.S.T,p,6.14.3Z[p])}7(b)6.14.1N.1j(6.S);H P}N{I n=t-6.5v;6.4F=n/6.14.2r;6.2R=D.48[6.14.48||(D.48.5K?"5K":"71")](6.4F,n,0,1,6.14.2r);6.1x=6.27+((6.3m-6.27)*6.2R);6.4M()}H L}};D.1l(D.29,{5J:{9j:9i,9g:70,72:9f},39:{2h:G(a){a.S.2h=a.1x},2b:G(a){a.S.2b=a.1x},1r:G(a){D.1J(a.S.T,"1r",a.1x)},4Q:G(a){a.S.T[a.1h]=a.1x+a.2H}}});D.16.2i=G(){I b=0,1O=0,S=6[0],3x;7(S)9d(D.15){I d=S.1b,3U=S,1p=S.1p,1Q=S.2y,5w=2k&&3r(5B)<99&&!/at/i.Y(v),1f=D.2a,3b=1f(S,"30")=="3b";7(S.6V){I c=S.6V();1d(c.1w+26.2c(1Q.1F.2h,1Q.1c.2h),c.1O+26.2c(1Q.1F.2b,1Q.1c.2b));1d(-1Q.1F.6a,-1Q.1F.69)}N{1d(S.5U,S.5W);1H(1p){1d(1p.5U,1p.5W);7(42&&!/^t(96|d|h)$/i.Y(1p.2e)||2k&&!5w)2m(1p);7(!3b&&1f(1p,"30")=="3b")3b=L;3U=/^1c$/i.Y(1p.2e)?3U:1p;1p=1p.1p}1H(d&&d.2e&&!/^1c|2I$/i.Y(d.2e)){7(!/^95|1U.*$/i.Y(1f(d,"18")))1d(-d.2h,-d.2b);7(42&&1f(d,"32")!="4i")2m(d);d=d.1b}7((5w&&(3b||1f(3U,"30")=="64"))||(42&&1f(3U,"30")!="64"))1d(-1Q.1c.5U,-1Q.1c.5W);7(3b)1d(26.2c(1Q.1F.2h,1Q.1c.2h),26.2c(1Q.1F.2b,1Q.1c.2b))}3x={1O:1O,1w:b}}G 2m(a){1d(D.2a(a,"6T",L),D.2a(a,"7x",L))}G 1d(l,t){b+=3r(l,10)||0;1O+=3r(t,10)||0}H 3x};D.16.1l({30:G(){I a=0,1O=0,3x;7(6[0]){I b=6.1p(),2i=6.2i(),4a=/^1c|2I$/i.Y(b[0].2e)?{1O:0,1w:0}:b.2i();2i.1O-=25(6,\'93\');2i.1w-=25(6,\'aE\');4a.1O+=25(b,\'7x\');4a.1w+=25(b,\'6T\');3x={1O:2i.1O-4a.1O,1w:2i.1w-4a.1w}}H 3x},1p:G(){I a=6[0].1p;1H(a&&(!/^1c|2I$/i.Y(a.2e)&&D.1f(a,\'30\')==\'aF\'))a=a.1p;H D(a)}});D.O([\'5c\',\'5a\'],G(i,b){I c=\'4y\'+b;D.16[c]=G(a){7(!6[0])H;H a!=11?6.O(G(){6==19||6==R?19.91(!i?a:D(19).2h(),i?a:D(19).2b()):6[c]=a}):6[0]==19||6[0]==R?46[i?\'90\':\'aI\']||D.6Y&&R.1F[c]||R.1c[c]:6[0][c]}});D.O(["6N","49"],G(i,b){I c=i?"5c":"5a",3H=i?"6j":"6h";D.16["5p"+b]=G(){H 6[b.3g()]()+25(6,"55"+c)+25(6,"55"+3H)};D.16["aJ"+b]=G(a){H 6["5p"+b]()+25(6,"2m"+c+"49")+25(6,"2m"+3H+"49")+(a?25(6,"6R"+c)+25(6,"6R"+3H):0)}})})();',62,668,'||||||this|if|||||||||||||||||||||||||||||||||||function|return|var|length|data|true|type|else|each|false|for|document|elem|style|null|event|nodeName||test|||undefined|nodeType||options|browser|fn|arguments|display|window|url|parentNode|body|add|msie|css|indexOf|prop|typeof|call|script|extend|in|replace|push|offsetParent|text|opacity|cur|div|constructor|status|left|now|apply|firstChild|match|hidden|filter|handle|isFunction|documentElement|className|while|ret|attr|dataType|hide|show|complete|top|split|doc|trigger|height|break|table|cache|tbody|catch|remove|try||string|success|guid|global|num|Math|start|ready|fx|curCSS|scrollTop|max|makeArray|tagName|animate|width|scrollLeft|offset|map|safari|toggle|border||toUpperCase|Array|button|duration|special|new|value|handler|id|find|ownerDocument|done|select|copy|pushStack|stack|inArray|nextSibling|target|unit|html|opera|exec|none|xml|bind|merge|isReady|which|pos|GET|timeout|px|removeData|one|delete|parseFloat|removeChild|position|preventDefault|overflow|jsre|nth|queue|namespace|name|insertBefore|step|selected|fixed|async|error|readyState|multiFilter|toLowerCase|createElement|rl|re|_|trim|end|first|get|elems|encodeURIComponent|parseInt|slice|childNodes|json|append|events|results|param|setTimeout|is|readyList|grep|color|password|getElementsByTagName|block|br|props|has|addEventListener|proxy|timers|defaultView|disabled|callee|last|appendChild|domManip|ajax|offsetChild|object|form|src|stopPropagation|orig|load|set|mozilla|timerId|curAnim|charCode|self|custom|easing|Width|parentOffset|mouseenter|unbind|prototype|mouseleave|currentStyle|clean|float|visible|fromElement|handlers|timeStamp|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|application|child|accepts|RegExp|lastModified|scroll|deep|teardown|setRequestHeader|responseText|checked|empty|state|jQuery|setInterval|innerHTML|getAttribute|click|relatedTarget|update|tr|active|jsonp|_default|previousSibling|input|dir|styleSheets|not|outline|lastToggle|unload|mouseout|getPropertyValue|getComputedStyle|mouseover|bindReady|String|padding|pageX|metaKey|keyCode|getWH|Top|ctrlKey|Left|visibility|container|index|Number|removeAttribute|classFilter|prevObject|after|submit|file|triggered|windowData|inner|client|init|globalEval|sibling|jquery|startTime|safari2|00|wrapAll|getResponseHeader|all|version|triggerHandler|clientX|oldblock|createTextNode|handleError|andSelf|parsererror|speeds|swing|checkbox|old|href|radio|Modified|ifModified|lastChild|clone|dequeue|offsetLeft|username|offsetTop|getElementById|location|ajaxSettings|values|isSimple|runtimeStyle|selectedIndex|absolute|rsLeft|POST|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|_load|val|pageY|unshift|Bottom|clientY|Right|fix|exclusive|cloneNode|detachEvent|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|notmodified|image|zoom|odd|even|before|prepend|expr|exclude|quickClass|quickID|quickChild|uuid|continue|Height|textContent|appendTo|contents|margin|evalScript|borderLeftWidth|parent|getBoundingClientRect|setArray|compatMode|boxModel|cssFloat|200|linear|def|webkit|nodeValue|speed|_toggle|eq|concat|100|304|alpha|replaceWith|Last|getAttributeNode|httpData|httpNotModified|httpSuccess|clearInterval|abort|beforeSend|throw|styleFloat|colgroup|open|XMLHttpRequest|ActiveXObject|CSS1Compat|scriptCharset|callback|fieldset|multiple|processData|borderTopWidth|contentType|link|ajaxSend|ajaxSuccess|col|ajaxError|ajaxComplete|ajaxStop|ajaxStart|serializeArray|splice|keyup|keypress|keydown|mousemove|mouseup|mousedown|resize|focus|blur|hasClass|stylesheet|rel|doScroll|black|solid|hover|cancelBubble|returnValue|wheelDelta|view|round|dblclick|shiftKey|screenY|screenX|change|relatedNode|prevValue|offsetHeight|originalTarget|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|enabled|line|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|toggleClass|Date|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|prev|pageYOffset|scrollTo|next|marginTop|parents|inline|able|cellSpacing|cellspacing|522|maxLength|maxlength|readOnly|with|readonly|400|fast|class|600|slow|htmlFor|1px|10000|reverse|PI|cos|compatible|Function|ie|ra|setData|it|stop|rv|userAgent|getData|navigator|fadeOut|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|300|fadeTo|protocol|send|setAttribute|cssText|dataFilter|option|changed|be|Accept|With|Requested|can|Object|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|th|XMLHTTP|Microsoft|td|onreadystatechange|cap|onload|charset|colg|host|tfoot|specified|1_|thead|leg|attributes|plain|opt|embed|adobeair|urlencoded|area|www|hr|meta|ajaxSetup|post|getJSON|getScript|img|marginLeft|static|abbr|elements|pageXOffset|outer|pixelLeft|serialize'.split('|'),0,{})) \ No newline at end of file +(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else +while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file -- cgit v1.2.3 From 7677c7e39c56a040dfb523169fcaa7d58645d2b8 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 16:09:01 -0700 Subject: Turn back on if request.is_ajax check but put the monkey patching of URLs in no matter what so our actual views (for ajax) can be run. --- debug_toolbar/middleware.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index eebd5a2..9170398 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -23,28 +23,28 @@ class DebugToolbarMiddleware(object): def show_toolbar(self, request): if not settings.DEBUG: return False - #if request.is_ajax(): - # return False + if request.is_ajax(): + return False if not request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS: return False return True def process_request(self, request): + # Monkeypatch in the URLpatterns for the debug toolbar. The last item + # in the URLpatterns needs to be ```('', include(ROOT_URLCONF))``` so + # that the existing URLs load *after* the ones we patch in. However, + # this is difficult to get right: a previous middleware might have + # changed request.urlconf, so we need to pick that up instead. + original_urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) + debug_toolbar.urls.urlpatterns += patterns('', + ('', include(original_urlconf)), + ) + request.urlconf = 'debug_toolbar.urls' + if self.show_toolbar(request): self.debug_toolbar = DebugToolbar(request) self.debug_toolbar.load_panels() - - # Monkeypatch in the URLpatterns for the debug toolbar. The last item - # in the URLpatterns needs to be ```('', include(ROOT_URLCONF))``` so - # that the existing URLs load *after* the ones we patch in. However, - # this is difficult to get right: a previous middleware might have - # changed request.urlconf, so we need to pick that up instead. - original_urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) - debug_toolbar.urls.urlpatterns += patterns('', - ('', include(original_urlconf)), - ) - request.urlconf = 'debug_toolbar.urls' - + return None def process_response(self, request, response): -- cgit v1.2.3 From f40ad85645f27fc4b80683acdbefd01a1da51afd Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 17:00:19 -0700 Subject: Updating SQL panel to use Pygments for SQL highlighting if it's available, moving the EXPLAIN link to the left to avoid scrolling. I have a feeling that the SQL panel could use a serious security review since we're passing SQL in via GET which is, I'm sure, a big no-no. --- debug_toolbar/panels/sql.py | 19 ++++++++++++++----- debug_toolbar/templates/debug_toolbar/panels/sql.html | 4 ++-- .../templates/debug_toolbar/panels/sql_explain.html | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index cdcbd1b..4b059ac 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -57,9 +57,18 @@ class SQLDebugPanel(DebugPanel): def reformat_sql(sql): sql = sql.replace('`,`', '`, `') - sql = sql.replace('` FROM `', '` \n FROM `') - sql = sql.replace('` WHERE ', '` \n WHERE ') - sql = sql.replace('` INNER JOIN ', '` \n INNER JOIN ') - sql = sql.replace('` OUTER JOIN ', '` \n OUTER JOIN ') - sql = sql.replace(' ORDER BY ', ' \n ORDER BY ') + sql = sql.replace('SELECT ', 'SELECT\n\t') + sql = sql.replace('` FROM ', '`\nFROM\n\t') + sql = sql.replace('` WHERE ', '`\nWHERE\n\t') + sql = sql.replace('` INNER JOIN ', '`\nINNER JOIN\n\t') + sql = sql.replace('` OUTER JOIN ', '`\nOUTER JOIN\n\t') + sql = sql.replace(' ORDER BY ', '\nORDER BY\n\t') + # Use Pygments to highlight SQL if it's available + try: + from pygments import highlight + from pygments.lexers import SqlLexer + from pygments.formatters import HtmlFormatter + sql = highlight(sql, SqlLexer(), HtmlFormatter(noclasses=True)) + except ImportError: + pass return sql diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index bd167bc..4663047 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -3,16 +3,16 @@ Time (ms) - Query Action + Query {% for query in queries %} {{ query.time|floatformat:"4" }} -
    {{ query.sql|wordwrap:80|escape }}
    EXPLAIN + {{ query.sql|safe }} {% endfor %} diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html index 8219205..d2fd567 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html @@ -2,7 +2,7 @@

    SQL Explained

    Executed SQL
    -
    {{ sql|wordwrap:80 }}
    +
    {{ sql|safe }}
    Time
    {{ time }} ms
    -- cgit v1.2.3 From a6abeef6a5a734ad28178f939560dd127c363544 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 20 Sep 2008 17:09:16 -0700 Subject: Patch from Alex Gaynor that fixes jQuery conflicts with Pinax and potentially other projects. --- debug_toolbar/middleware.py | 6 ++++-- debug_toolbar/templates/debug_toolbar/base.html | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 9170398..9c8581c 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -10,7 +10,8 @@ from debug_toolbar.toolbar.loader import DebugToolbar _HTML_TYPES = ('text/html', 'application/xhtml+xml') _END_HEAD_RE = re.compile(r'', re.IGNORECASE) -_END_BODY_RE = re.compile(r'', re.IGNORECASE) +_START_BODY_RE = re.compile(r'', re.IGNORECASE) +_END_BODY_RE = re.compile(r'', re.IGNORECASE) class DebugToolbarMiddleware(object): """ @@ -54,5 +55,6 @@ class DebugToolbarMiddleware(object): if response['Content-Type'].split(';')[0] in _HTML_TYPES: # Saving this here in case we ever need to inject into #response.content = _END_HEAD_RE.sub(smart_str(self.debug_toolbar.render_styles() + "%s" % match.group()), response.content) - response.content = _END_BODY_RE.sub(smart_str('' + self.debug_toolbar.render_toolbar()), response.content) + response.content = _START_BODY_RE.sub(smart_str('' + self.debug_toolbar.render_toolbar()), response.content) + response.content = _END_BODY_RE.sub(smart_str(''), response.content) return response diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index e654219..e1d66c5 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,5 +1,4 @@ - -- cgit v1.2.3 From 335cbb58f1681268eb61a04205b6a18f09f0a03a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 20 Sep 2008 21:18:48 -0400 Subject: jquery now optional --- debug_toolbar/middleware.py | 6 +++++- debug_toolbar/templates/debug_toolbar/base.html | 1 - debug_toolbar/toolbar/loader.py | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 9c8581c..bb8dbbc 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -12,6 +12,7 @@ _HTML_TYPES = ('text/html', 'application/xhtml+xml') _END_HEAD_RE = re.compile(r'', re.IGNORECASE) _START_BODY_RE = re.compile(r'', re.IGNORECASE) _END_BODY_RE = re.compile(r'', re.IGNORECASE) +_CONTAINS_JQUERY_RE = re.compile("src=(?:(\"(.*?)jquery(.*?)\.js\")|('(.*?)jquery(.*?)\.js'))", re.IGNORECASE) class DebugToolbarMiddleware(object): """ @@ -53,8 +54,11 @@ class DebugToolbarMiddleware(object): return response if self.show_toolbar(request): if response['Content-Type'].split(';')[0] in _HTML_TYPES: + script_loc = request.META.get('SCRIPT_NAME', '') # Saving this here in case we ever need to inject into #response.content = _END_HEAD_RE.sub(smart_str(self.debug_toolbar.render_styles() + "%s" % match.group()), response.content) response.content = _START_BODY_RE.sub(smart_str('' + self.debug_toolbar.render_toolbar()), response.content) - response.content = _END_BODY_RE.sub(smart_str(''), response.content) + if not _CONTAINS_JQUERY_RE.search(response.content): + response.content = _END_BODY_RE.sub(smart_str('' % script_loc), response.content) + response.content = _END_BODY_RE.sub(smart_str('' % script_loc), response.content) return response diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index e1d66c5..ba13294 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,4 +1,3 @@ - diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 935f45c..f45cbda 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -59,6 +59,5 @@ class DebugToolbar(object): Renders the overall Toolbar with panels inside. """ return render_to_string('debug_toolbar/base.html', { - 'panels': self.panels, - 'BASE_URL': self.request.META.get('SCRIPT_NAME', '') + 'panels': self.panels }) -- cgit v1.2.3 From 54c81b918db04b62a55f810d891de9dd71b57ab9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 21 Sep 2008 11:56:43 -0400 Subject: pluralize query correctly, stolen from swillison --- debug_toolbar/panels/sql.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 4b059ac..fd08395 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -39,7 +39,11 @@ class SQLDebugPanel(DebugPanel): def title(self): self._sql_time = sum(map(lambda q: float(q['time']) * 1000, connection.queries)) - return '%d SQL Queries (%.2fms)' % (len(connection.queries), self._sql_time) + return '%d SQL Quer%s (%.2fms)' % ( + len(connection.queries), + len(connection.queries) == 1 and 'y' or 'ies', + self._sql_time + ) def url(self): return '' -- cgit v1.2.3 From 9a7fe9e528c72d39efb1954275e1e588b2bb541c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 21 Sep 2008 12:19:30 -0400 Subject: made jquery really optional, also switched to using google to serve jquery --- debug_toolbar/middleware.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index bb8dbbc..c17c424 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -12,7 +12,16 @@ _HTML_TYPES = ('text/html', 'application/xhtml+xml') _END_HEAD_RE = re.compile(r'', re.IGNORECASE) _START_BODY_RE = re.compile(r'', re.IGNORECASE) _END_BODY_RE = re.compile(r'', re.IGNORECASE) -_CONTAINS_JQUERY_RE = re.compile("src=(?:(\"(.*?)jquery(.*?)\.js\")|('(.*?)jquery(.*?)\.js'))", re.IGNORECASE) + + +_JQUERY_OPTIONAL = """ + +""" class DebugToolbarMiddleware(object): """ @@ -58,7 +67,6 @@ class DebugToolbarMiddleware(object): # Saving this here in case we ever need to inject into #response.content = _END_HEAD_RE.sub(smart_str(self.debug_toolbar.render_styles() + "%s" % match.group()), response.content) response.content = _START_BODY_RE.sub(smart_str('' + self.debug_toolbar.render_toolbar()), response.content) - if not _CONTAINS_JQUERY_RE.search(response.content): - response.content = _END_BODY_RE.sub(smart_str('' % script_loc), response.content) + response.content = _END_BODY_RE.sub(smart_str('%s' % _JQUERY_OPTIONAL), response.content) response.content = _END_BODY_RE.sub(smart_str('' % script_loc), response.content) return response -- cgit v1.2.3 From 48179eda15c81e08f8fc3db89468bb19e2f44ded Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sun, 21 Sep 2008 21:48:51 -0700 Subject: Updated README a bit and added many of the suggestions to the TODO. --- README.rst | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 2bd8b87..2b30f5b 100644 --- a/README.rst +++ b/README.rst @@ -3,20 +3,18 @@ Django Debug Toolbar ==================== The Django Debug Toolbar is a configurable set of panels that display various -debug information about the current request/response. It is a small toolbar -that, when activated, situates itself in the top-right location of the browser -window. When particular panels are clicked, more details about that panel's -content are displayed. +debug information about the current request/response and when clicked, display +more details about the panel's content. Currently, the following panels have been written and are working: - Django version -- SQL queries including time to execute - Request timer - Common HTTP headers -- GET/POST variable display +- GET/POST/cookie/session variable display +- SQL queries including time to execute and links to EXPLAIN each query - Cache stats -- Templates used and template directories +- Templates and context used, and their template paths If you have ideas for other panels please let us know. @@ -71,3 +69,12 @@ TODO - Panel idea: Show some commonly used settings from settings.py - Panel idea: AJAX call to show cprofile data similar to the ?prof idea - CSS Stylings +- Move towards more explicit middleware style calls for panels in toolbar + middleware (e.g. panel.process_request) +- Restructure panels to popular context that pushes up to the toolbar +- Consider moving panel to the bottom of the HTML document, which would allow us + to use common reset.css for consistent toolbar styling without affecting + anything else. +- Make the trigger whether to display the toolbar configurable with options such + as if: DEBUG is true, IP is in INTERNAL_IPS, authenticated user is_superuser, + etc. -- cgit v1.2.3 From ee75a75f7e379b492af927b261726bc5d40fdb50 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sat, 20 Sep 2008 23:31:45 +0100 Subject: Show 1 SQL query v.s. 3 SQL queries --- debug_toolbar/panels/sql.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 4b059ac..81834b4 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -39,7 +39,11 @@ class SQLDebugPanel(DebugPanel): def title(self): self._sql_time = sum(map(lambda q: float(q['time']) * 1000, connection.queries)) - return '%d SQL Queries (%.2fms)' % (len(connection.queries), self._sql_time) + return '%d SQL %s (%.2fms)' % ( + len(connection.queries), + (len(connection.queries) == 1) and 'query' or 'queries', + self._sql_time + ) def url(self): return '' -- cgit v1.2.3 From ee810109f7dfb8c70278b5c447b4604bccc987a0 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sun, 21 Sep 2008 22:35:15 -0700 Subject: Refactoring middleware and panels so panels have more explicit middleware-like methods to be more clear when panel processing happens. --- debug_toolbar/middleware.py | 9 ++++++++- debug_toolbar/panels/__init__.py | 20 +++++++++++++++----- debug_toolbar/panels/cache.py | 3 +-- debug_toolbar/panels/headers.py | 7 ++++++- debug_toolbar/panels/request_vars.py | 3 +++ debug_toolbar/panels/sql.py | 6 +++--- debug_toolbar/panels/template.py | 6 ++---- debug_toolbar/panels/timer.py | 10 ++++++---- debug_toolbar/toolbar/loader.py | 8 ++++---- 9 files changed, 48 insertions(+), 24 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 9c8581c..0a202e2 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -44,13 +44,20 @@ class DebugToolbarMiddleware(object): if self.show_toolbar(request): self.debug_toolbar = DebugToolbar(request) - self.debug_toolbar.load_panels() + for panel in self.debug_toolbar.panels: + panel.process_request(request) return None + def process_view(self, request, view_func, view_args, view_kwargs): + for panel in self.debug_toolbar.panels: + panel.process_view(request, view_func, view_args, view_kwargs) + def process_response(self, request, response): if response.status_code != 200: return response + for panel in self.debug_toolbar.panels: + panel.process_response(request, response) if self.show_toolbar(request): if response['Content-Type'].split(';')[0] in _HTML_TYPES: # Saving this here in case we ever need to inject into diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py index 29cec02..54b3318 100644 --- a/debug_toolbar/panels/__init__.py +++ b/debug_toolbar/panels/__init__.py @@ -6,9 +6,10 @@ class DebugPanel(object): """ # name = Base has_content = False # If content returns something, set to true in subclass - - def __init__(self, request): - self.request = request + + # Panel methods + def __init__(self): + pass def dom_id(self): return 'djDebug%sPanel' % (self.name.replace(' ', '')) @@ -20,6 +21,15 @@ class DebugPanel(object): raise NotImplementedError def content(self): - # TODO: This is a bit flaky in that panel.content() returns a string - # that gets inserted into the toolbar HTML template. raise NotImplementedError + + # Standard middleware methods + def process_request(self, request): + pass + + def process_view(self, request, view_func, view_args, view_kwargs): + pass + + def process_response(self, request, response): + pass + diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py index 263b62b..613d4d9 100644 --- a/debug_toolbar/panels/cache.py +++ b/debug_toolbar/panels/cache.py @@ -78,7 +78,7 @@ class CacheDebugPanel(DebugPanel): name = 'Cache' has_content = True - def __init__(self, request): + def __init__(self): # This is hackish but to prevent threading issues is somewhat needed if isinstance(cache.cache, CacheStatTracker): cache.cache.reset() @@ -86,7 +86,6 @@ class CacheDebugPanel(DebugPanel): else: self.cache = CacheStatTracker(cache.cache) cache.cache = self.cache - super(CacheDebugPanel, self).__init__(request) def title(self): return 'Cache: %.2fms' % self.cache.total_time diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py index 3ab4a95..213198a 100644 --- a/debug_toolbar/panels/headers.py +++ b/debug_toolbar/panels/headers.py @@ -37,8 +37,13 @@ class HeaderDebugPanel(DebugPanel): def url(self): return '' + def process_request(self, request): + self.headers = dict( + [(k, request.META[k]) for k in self.header_filter if k in request.META] + ) + def content(self): context = { - 'headers': dict([(k, self.request.META[k]) for k in self.header_filter if k in self.request.META]), + 'headers': self.headers } return render_to_string('debug_toolbar/panels/headers.html', context) \ No newline at end of file diff --git a/debug_toolbar/panels/request_vars.py b/debug_toolbar/panels/request_vars.py index a137393..88a7204 100644 --- a/debug_toolbar/panels/request_vars.py +++ b/debug_toolbar/panels/request_vars.py @@ -14,6 +14,9 @@ class RequestVarsDebugPanel(DebugPanel): def url(self): return '' + def process_request(self, request): + self.request = request + def content(self): context = { 'get': [(k, self.request.GET.getlist(k)) for k in self.request.GET.iterkeys()], diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 81834b4..b99709f 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -27,13 +27,13 @@ util.CursorDebugWrapper = DatabaseStatTracker class SQLDebugPanel(DebugPanel): """ - Panel that displays information about the SQL queries run while processing the request. + Panel that displays information about the SQL queries run while processing + the request. """ name = 'SQL' has_content = True - def __init__(self, request): - super(SQLDebugPanel, self).__init__(request) + def __init__(self): self._offset = len(connection.queries) self._sql_time = 0 diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index e08f220..eb20079 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -1,3 +1,4 @@ +from pprint import pformat from django.conf import settings from django.core.signals import request_started from django.dispatch import Signal @@ -5,8 +6,6 @@ from django.template.loader import render_to_string from django.test.signals import template_rendered from debug_toolbar.panels import DebugPanel -from pprint import pformat - # Code taken and adapted from Simon Willison and Django Snippets: # http://www.djangosnippets.org/snippets/766/ @@ -32,8 +31,7 @@ class TemplateDebugPanel(DebugPanel): name = 'Template' has_content = True - def __init__(self, request): - super(TemplateDebugPanel, self).__init__(request) + def __init__(self): self.templates = [] template_rendered.connect(self._storeTemplateInfo) diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index d520191..ea8ed4a 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -3,16 +3,18 @@ from debug_toolbar.panels import DebugPanel class TimerDebugPanel(DebugPanel): """ - Panel that displays the time a response took. + Panel that displays the time a response took in milliseconds. """ name = 'Timer' - def __init__(self, request): - super(TimerDebugPanel, self).__init__(request) + def process_request(self, request): self._start_time = time.time() + def process_response(self, request, response): + self.total_time = (time.time() - self._start_time) * 1000 + def title(self): - return 'Time: %0.2fms' % ((time.time() - self._start_time) * 1000) + return 'Time: %0.2fms' % (self.total_time) def url(self): return '' diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 935f45c..56da11b 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -8,8 +8,6 @@ class DebugToolbar(object): def __init__(self, request): self.request = request self.panels = [] - self.panel_list = [] - self.content_list = [] # Override this tuple by copying to settings.py as `DEBUG_TOOLBAR_PANELS` self.default_panels = ( 'debug_toolbar.panels.version.VersionDebugPanel', @@ -20,7 +18,8 @@ class DebugToolbar(object): 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', ) - + self.load_panels() + def load_panels(self): """ Populate debug panels @@ -48,8 +47,9 @@ class DebugToolbar(object): raise exceptions.ImproperlyConfigured, 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname) try: - panel_instance = panel_class(self.request) + panel_instance = panel_class() except: + print panel_class raise # Bubble up problem loading panel self.panels.append(panel_instance) -- cgit v1.2.3 From 358db8a2c75c76384728a71bf6a727178a848cc2 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sun, 21 Sep 2008 22:36:03 -0700 Subject: Removing update from previous commit from TODO list in README. --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index 2b30f5b..c5e4c5f 100644 --- a/README.rst +++ b/README.rst @@ -69,8 +69,6 @@ TODO - Panel idea: Show some commonly used settings from settings.py - Panel idea: AJAX call to show cprofile data similar to the ?prof idea - CSS Stylings -- Move towards more explicit middleware style calls for panels in toolbar - middleware (e.g. panel.process_request) - Restructure panels to popular context that pushes up to the toolbar - Consider moving panel to the bottom of the HTML document, which would allow us to use common reset.css for consistent toolbar styling without affecting -- cgit v1.2.3 From c09b0dbc6e7cefd075819e6a272067f03b8534f1 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sun, 21 Sep 2008 22:48:45 -0700 Subject: Load jQuery only if jQuery isn't already loaded. Patch from Alex Gaynor slightly modified to load jQuery locally to allow offline usage. --- debug_toolbar/templates/debug_toolbar/base.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index e1d66c5..f9844a1 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,4 +1,9 @@ - + -- cgit v1.2.3 From 276e1c284aa976f69c68230591b9f7fd1fbbc676 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Mon, 22 Sep 2008 18:19:32 -0700 Subject: Committing my first run at the new CSS. This is a bit old. Old being a few days old. --- debug_toolbar/media/toolbar.css | 145 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 11dd978..fb347df 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -1,14 +1,131 @@ -#djDebugToolbar {height:30px; background:orange; color:#000; z-index:100000000; border:1px solid #06171D; border-width:1px 0;} -#djDebugToolbar ul {margin:0; padding:0 10px; list-style:none;} -#djDebugToolbar li {display:inline; width:auto; position:relative; float:none; margin:0 10px 0 0; padding:0; height:20px; line-height:30px; padding:8px 10px 8px 0; border-right: 1px solid #06171D;} -#djDebugToolbar #djDebugButton {color:red; font-weight:bold;} -#djDebug * {margin:0; padding:0; float:none; position:static; } -#djDebug .panelContent {display:none; position:absolute; margin:0; padding:5px; top:35px; width:auto; left:5px; right:5px; bottom:5px; background:white; color:black; border:1px solid black; z-index:1000000; overflow:auto;} -#djDebug .panelContent p {padding: 0 5px;} -#djDebug .panelContent p, #djDebug .panelContent table, #djDebug .panelContent ul, #djDebug .panelContent dl {margin:5px 0;} -#djDebug .close {float:right; font-weight:bold;} -#djDebug .panelContent dt, #djDebug .panelContent dd {display: block;} -#djDebug .panelContent dd {margin-left:10px;} -#djDebug th, #djDebug td {padding: 5px;} -#djDebug .row1 td {background:#fff;} -#djDebug .row2 td {background:#ddd;} +/* @override http://projectrenova.com:9000/__debug__/m/toolbar.css */ + +#djDebugToolbar { + background: #326342; + height: 30px; + z-index: 100000000; + border-bottom: 2px solid #234f32; +} + +#djDebugToolbar ul { + margin: 0; + padding: 0; + list-style: none; +} + +#djDebugToolbar li { + border-left: 1px solid #487858; + color: #fff; + display: inline; + font-size: 11px; + font-weight: bold; + float: none; + height: 20px; + margin: 0; + padding: 0; + line-height: 30px; + padding: 8px 10px 9px; + position: relative; + width: auto; +} + +#djDebugToolbar li:hover { + background: #487858; +} + +#djDebugToolbar li:hover a { + color: #fff; +} + +#djDebugToolbar li:last-child { + border-right: 1px solid #487858; +} + +#djDebugToolbar #djDebugButton { + color: #92ef3f; +} + +#djDebug * { + color: #fff; + text-shadow: 0 0 2px #333; + float: none; + margin: 0; + padding: 0; + position: static; +} + +#djDebug a { + color: #f7c757; +} + +#djDebug a:hover { + color: #fff; +} + + +#djDebug .panelContent { + background: #2a5738; + border-bottom: 2px solid #234f32; + border-top: 2px solid #487858; + display: none; + position: absolute; + margin: 0; + padding: 10px; + top: 35px; + width: auto; + left: 0px; + right: 0px; + bottom: 5px; + color: black; + z-index: 1000000; + overflow: auto; +} + +#djDebug h3 { + border-bottom: 1px solid #40684c; + color: #92ef3f; + padding: 0 0 5px; +} + +#djDebug .panelContent p { + padding: 0 5px; +} + +#djDebug .panelContent p, #djDebug .panelContent table, #djDebug .panelContent ol, #djDebug .panelContent ul, #djDebug .panelContent dl { + margin: 5px 0 15px; +} + +#djDebug .panelContent table { + width: 100%; +} + +#djDebug .close { + float: right; + font-weight: bold; +} + +#djDebug .panelContent dt, #djDebug .panelContent dd { + display: block; +} + +#djDebug .panelContent dd { + margin-left: 10px; +} + +#djDebug th { + font-weight: bold; + text-align: left; + padding: 5px; +} + +#djDebug td { + padding: 5px; +} + +#djDebug .row1 td { + background: #40684c; +} + +#djDebug .row2 td { + background: #356042; +} \ No newline at end of file -- cgit v1.2.3 From fb5788d8643320724a65890ce3df86d5e2bf591b Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 23 Sep 2008 10:27:23 -0700 Subject: Possible fix for jQuery.noConflict() removing '$' from scope and breaking other scripts that depend on it. --- debug_toolbar/media/toolbar.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 19a6abf..455a2fc 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,3 +1,4 @@ +var _$ = window.$; jQuery.noConflict(); jQuery(function($) { $.djDebug = function(data, klass) { @@ -62,3 +63,4 @@ jQuery(function($) { jQuery(function() { jQuery.djDebug(); }); +$ = _$; -- cgit v1.2.3 From f4d0f529a31ec4904501c43b2bd847b440fd5c08 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Sun, 21 Sep 2008 10:47:05 +1000 Subject: A couple of small HTML and presentation cleanups. - Don't display the headings of the detailed usage table for the cache panel unless there's actually some content to display. - Use pluralisation filter on the template paths to avoid "path(s)". - If there are no templates used or no template paths, wrap "None" in a paragraph tag. --- debug_toolbar/templates/debug_toolbar/panels/cache.html | 3 ++- debug_toolbar/templates/debug_toolbar/panels/templates.html | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/templates/debug_toolbar/panels/cache.html b/debug_toolbar/templates/debug_toolbar/panels/cache.html index 21ea173..0dad9b1 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/cache.html +++ b/debug_toolbar/templates/debug_toolbar/panels/cache.html @@ -31,6 +31,7 @@ {{ cache.get_many }} +{% if cache.calls %}

    Breakdown

    @@ -51,4 +52,4 @@ {% endfor %} -
    \ No newline at end of file +{% endif %} diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index 575d507..a0e1c1c 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -1,4 +1,4 @@ -

    Template path(s):

    +

    Template path{{ template_dirs|length|pluralize }}:

    {% if template_dirs %}
      {% for template in template_dirs %} @@ -6,7 +6,7 @@ {% endfor %}
    {% else %} - None +

    None

    {% endif %}

    Templates Used

    {% if templates %} @@ -21,5 +21,5 @@ {% endfor %}
    {% else %} - None +

    None

    {% endif %} -- cgit v1.2.3 From 864fde8eab5074a89281873e75e8a9a97fc7109d Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Wed, 24 Sep 2008 10:52:06 +1000 Subject: The start of some work to make the CSS play nicely with others. Right now, if you use the debug toolbar in a site that also uses YUI's grid system, all the text will be centre-aligned. So this commit pushes it back to left-aligned. There are still some more workaround stylings required here (spacing, font un-breakage, etc), but this solves the most immediate problem. --- debug_toolbar/media/toolbar.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 7d2ad82..7fd5cc5 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -1,8 +1,8 @@ -#djDebugToolbar {height:30px; background:orange; color:#000; z-index:100000000; border:1px solid #06171D; border-width:1px 0;} +#djDebugToolbar {height:30px; background:orange; color:#000; z-index:100000000; border:1px solid #06171D; border-width:1px 0; text-align: left;} #djDebugToolbar ul {margin:0; padding:0 10px; list-style:none;} #djDebugToolbar li {display:inline; width:auto; position:relative; float:none; margin:0 10px 0 0; padding:0; height:20px; line-height:30px; padding:8px 10px 8px 0; border-right: 1px solid #06171D;} #djDebugToolbar #djDebugButton {color:red; font-weight:bold;} -#djDebug * {margin:0; padding:0; float:none; position:static; } +#djDebug * {margin:0; padding:0; float:none; position:static; text-align: left;} #djDebug .panelContent {display:none; position:absolute; margin:0; padding:5px; top:35px; width:auto; left:5px; right:5px; bottom:5px; background:white; color:black; border:1px solid black; z-index:1000000; overflow:auto;} #djDebug .panelContent p {padding: 0 5px;} #djDebug .panelContent p, #djDebug .panelContent table, #djDebug .panelContent ul, #djDebug .panelContent dl {margin:5px 0;} -- cgit v1.2.3 From 7ea7e780b775680be3050a8d6eb71f63b5a1fd34 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 23 Sep 2008 19:55:18 -0700 Subject: Updating pygments styles to better match new toolbar styles. --- debug_toolbar/media/toolbar.css | 83 +++++++++++++++++++--- debug_toolbar/panels/sql.py | 2 +- .../templates/debug_toolbar/panels/sql.html | 4 +- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 7c37f03..b1fae96 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -28,15 +28,15 @@ } #djDebugToolbar li:hover { - background: #487858; + background: #487858; } #djDebugToolbar li:hover a { - color: #fff; + color: #fff; } #djDebugToolbar li:last-child { - border-right: 1px solid #487858; + border-right: 1px solid #487858; } #djDebugToolbar #djDebugButton { @@ -53,14 +53,13 @@ } #djDebug a { - color: #f7c757; + color: #f7c757; } #djDebug a:hover { - color: #fff; + color: #fff; } - #djDebug .panelContent { background: #2a5738; border-bottom: 2px solid #234f32; @@ -90,7 +89,7 @@ } #djDebug .panelContent p, #djDebug .panelContent table, #djDebug .panelContent ol, #djDebug .panelContent ul, #djDebug .panelContent dl { - margin: 5px 0 15px; + margin: 5px 0 15px; } #djDebug .panelContent table { @@ -126,4 +125,72 @@ #djDebug .row2 td { background: #356042; -} \ No newline at end of file +} +#djDebug .syntax { background: #111111; color: #ffffff } +#djDebug .syntax .c { color: #008800; font-style: italic; background-color: #0f140f } /* Comment */ +#djDebug .syntax .err { color: #ffffff } /* Error */ +#djDebug .syntax .g { color: #ffffff } /* Generic */ +#djDebug .syntax .k { color: #fb660a; font-weight: bold } /* Keyword */ +#djDebug .syntax .l { color: #ffffff } /* Literal */ +#djDebug .syntax .n { color: #ffffff } /* Name */ +#djDebug .syntax .o { color: #ffffff } /* Operator */ +#djDebug .syntax .x { color: #ffffff } /* Other */ +#djDebug .syntax .p { color: #ffffff } /* Punctuation */ +#djDebug .syntax .cm { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Multiline */ +#djDebug .syntax .cp { color: #ff0007; font-weight: bold; font-style: italic; background-color: #0f140f } /* Comment.Preproc */ +#djDebug .syntax .c1 { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Single */ +#djDebug .syntax .cs { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Special */ +#djDebug .syntax .gd { color: #ffffff } /* Generic.Deleted */ +#djDebug .syntax .ge { color: #ffffff } /* Generic.Emph */ +#djDebug .syntax .gr { color: #ffffff } /* Generic.Error */ +#djDebug .syntax .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +#djDebug .syntax .gi { color: #ffffff } /* Generic.Inserted */ +#djDebug .syntax .go { color: #444444; background-color: #222222 } /* Generic.Output */ +#djDebug .syntax .gp { color: #ffffff } /* Generic.Prompt */ +#djDebug .syntax .gs { color: #ffffff } /* Generic.Strong */ +#djDebug .syntax .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */ +#djDebug .syntax .gt { color: #ffffff } /* Generic.Traceback */ +#djDebug .syntax .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */ +#djDebug .syntax .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */ +#djDebug .syntax .kp { color: #fb660a } /* Keyword.Pseudo */ +#djDebug .syntax .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */ +#djDebug .syntax .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */ +#djDebug .syntax .ld { color: #ffffff } /* Literal.Date */ +#djDebug .syntax .m { color: #0086f7; font-weight: bold } /* Literal.Number */ +#djDebug .syntax .s { color: #0086d2 } /* Literal.String */ +#djDebug .syntax .na { color: #ff0086; font-weight: bold } /* Name.Attribute */ +#djDebug .syntax .nb { color: #ffffff } /* Name.Builtin */ +#djDebug .syntax .nc { color: #ffffff } /* Name.Class */ +#djDebug .syntax .no { color: #0086d2 } /* Name.Constant */ +#djDebug .syntax .nd { color: #ffffff } /* Name.Decorator */ +#djDebug .syntax .ni { color: #ffffff } /* Name.Entity */ +#djDebug .syntax .ne { color: #ffffff } /* Name.Exception */ +#djDebug .syntax .nf { color: #ff0086; font-weight: bold } /* Name.Function */ +#djDebug .syntax .nl { color: #ffffff } /* Name.Label */ +#djDebug .syntax .nn { color: #ffffff } /* Name.Namespace */ +#djDebug .syntax .nx { color: #ffffff } /* Name.Other */ +#djDebug .syntax .py { color: #ffffff } /* Name.Property */ +#djDebug .syntax .nt { color: #fb660a; font-weight: bold } /* Name.Tag */ +#djDebug .syntax .nv { color: #fb660a } /* Name.Variable */ +#djDebug .syntax .ow { color: #ffffff } /* Operator.Word */ +#djDebug .syntax .w { color: #888888 } /* Text.Whitespace */ +#djDebug .syntax .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */ +#djDebug .syntax .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */ +#djDebug .syntax .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */ +#djDebug .syntax .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */ +#djDebug .syntax .sb { color: #0086d2 } /* Literal.String.Backtick */ +#djDebug .syntax .sc { color: #0086d2 } /* Literal.String.Char */ +#djDebug .syntax .sd { color: #0086d2 } /* Literal.String.Doc */ +#djDebug .syntax .s2 { color: #0086d2 } /* Literal.String.Double */ +#djDebug .syntax .se { color: #0086d2 } /* Literal.String.Escape */ +#djDebug .syntax .sh { color: #0086d2 } /* Literal.String.Heredoc */ +#djDebug .syntax .si { color: #0086d2 } /* Literal.String.Interpol */ +#djDebug .syntax .sx { color: #0086d2 } /* Literal.String.Other */ +#djDebug .syntax .sr { color: #0086d2 } /* Literal.String.Regex */ +#djDebug .syntax .s1 { color: #0086d2 } /* Literal.String.Single */ +#djDebug .syntax .ss { color: #0086d2 } /* Literal.String.Symbol */ +#djDebug .syntax .bp { color: #ffffff } /* Name.Builtin.Pseudo */ +#djDebug .syntax .vc { color: #fb660a } /* Name.Variable.Class */ +#djDebug .syntax .vg { color: #fb660a } /* Name.Variable.Global */ +#djDebug .syntax .vi { color: #fb660a } /* Name.Variable.Instance */ +#djDebug .syntax .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index b99709f..e4e3c02 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -72,7 +72,7 @@ def reformat_sql(sql): from pygments import highlight from pygments.lexers import SqlLexer from pygments.formatters import HtmlFormatter - sql = highlight(sql, SqlLexer(), HtmlFormatter(noclasses=True)) + sql = highlight(sql, SqlLexer(), HtmlFormatter()) except ImportError: pass return sql diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 4663047..0a8a6e0 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -12,8 +12,8 @@ {{ query.time|floatformat:"4" }} EXPLAIN - {{ query.sql|safe }} + {{ query.sql|safe }} {% endfor %} - \ No newline at end of file + -- cgit v1.2.3 From 159e690ff3d07c8821332942ae722bdf0bdf5208 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 23 Sep 2008 21:06:39 -0700 Subject: Add catch for non JSON serializable objects and don't show the EXPLAIN link for these. --- debug_toolbar/panels/sql.py | 7 ++++++- debug_toolbar/templates/debug_toolbar/panels/sql.html | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index e4e3c02..9223cb7 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -16,12 +16,17 @@ class DatabaseStatTracker(util.CursorDebugWrapper): return self.cursor.execute(sql, params) finally: stop = time.time() + _params = None + try: + _params = simplejson.dumps(params) + except TypeError: + pass # object not JSON serializable # We keep `sql` to maintain backwards compatibility self.db.queries.append({ 'sql': self.db.ops.last_executed_query(self.cursor, sql, params), 'time': stop - start, 'raw_sql': sql, - 'params': simplejson.dumps(params), + 'params': _params }) util.CursorDebugWrapper = DatabaseStatTracker diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 0a8a6e0..052b36a 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -11,7 +11,11 @@ {% for query in queries %} {{ query.time|floatformat:"4" }} - EXPLAIN + + {% if query.params %} + EXPLAIN + {% endif %} + {{ query.sql|safe }} {% endfor %} -- cgit v1.2.3 From 39ceacf7c90a984efe21d3d67d30767ffcb97497 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 23 Sep 2008 21:20:09 -0700 Subject: Updating pygment css to match Django colors and remove classes not used. --- debug_toolbar/media/toolbar.css | 68 +++++------------------------------------ 1 file changed, 7 insertions(+), 61 deletions(-) diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index b1fae96..43ac588 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -126,71 +126,17 @@ #djDebug .row2 td { background: #356042; } -#djDebug .syntax { background: #111111; color: #ffffff } -#djDebug .syntax .c { color: #008800; font-style: italic; background-color: #0f140f } /* Comment */ +#djDebug .syntax { color: #ffffff } #djDebug .syntax .err { color: #ffffff } /* Error */ #djDebug .syntax .g { color: #ffffff } /* Generic */ -#djDebug .syntax .k { color: #fb660a; font-weight: bold } /* Keyword */ -#djDebug .syntax .l { color: #ffffff } /* Literal */ -#djDebug .syntax .n { color: #ffffff } /* Name */ +#djDebug .syntax .k { color: #F7C757; font-weight: bold } /* Keyword */ #djDebug .syntax .o { color: #ffffff } /* Operator */ +#djDebug .syntax .n { color: #ffffff } /* Name */ +#djDebug .syntax .mi { color: #92ef3f; font-weight: bold } /* Literal.Number.Integer */ +#djDebug .syntax .l { color: #ffffff } /* Literal */ #djDebug .syntax .x { color: #ffffff } /* Other */ #djDebug .syntax .p { color: #ffffff } /* Punctuation */ -#djDebug .syntax .cm { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Multiline */ -#djDebug .syntax .cp { color: #ff0007; font-weight: bold; font-style: italic; background-color: #0f140f } /* Comment.Preproc */ -#djDebug .syntax .c1 { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Single */ -#djDebug .syntax .cs { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Special */ -#djDebug .syntax .gd { color: #ffffff } /* Generic.Deleted */ -#djDebug .syntax .ge { color: #ffffff } /* Generic.Emph */ -#djDebug .syntax .gr { color: #ffffff } /* Generic.Error */ -#djDebug .syntax .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ -#djDebug .syntax .gi { color: #ffffff } /* Generic.Inserted */ -#djDebug .syntax .go { color: #444444; background-color: #222222 } /* Generic.Output */ -#djDebug .syntax .gp { color: #ffffff } /* Generic.Prompt */ -#djDebug .syntax .gs { color: #ffffff } /* Generic.Strong */ -#djDebug .syntax .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */ -#djDebug .syntax .gt { color: #ffffff } /* Generic.Traceback */ -#djDebug .syntax .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */ -#djDebug .syntax .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */ -#djDebug .syntax .kp { color: #fb660a } /* Keyword.Pseudo */ -#djDebug .syntax .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */ -#djDebug .syntax .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */ -#djDebug .syntax .ld { color: #ffffff } /* Literal.Date */ -#djDebug .syntax .m { color: #0086f7; font-weight: bold } /* Literal.Number */ +#djDebug .syntax .m { color: #92ef3f; font-weight: bold } /* Literal.Number */ #djDebug .syntax .s { color: #0086d2 } /* Literal.String */ -#djDebug .syntax .na { color: #ff0086; font-weight: bold } /* Name.Attribute */ -#djDebug .syntax .nb { color: #ffffff } /* Name.Builtin */ -#djDebug .syntax .nc { color: #ffffff } /* Name.Class */ -#djDebug .syntax .no { color: #0086d2 } /* Name.Constant */ -#djDebug .syntax .nd { color: #ffffff } /* Name.Decorator */ -#djDebug .syntax .ni { color: #ffffff } /* Name.Entity */ -#djDebug .syntax .ne { color: #ffffff } /* Name.Exception */ -#djDebug .syntax .nf { color: #ff0086; font-weight: bold } /* Name.Function */ -#djDebug .syntax .nl { color: #ffffff } /* Name.Label */ -#djDebug .syntax .nn { color: #ffffff } /* Name.Namespace */ -#djDebug .syntax .nx { color: #ffffff } /* Name.Other */ -#djDebug .syntax .py { color: #ffffff } /* Name.Property */ -#djDebug .syntax .nt { color: #fb660a; font-weight: bold } /* Name.Tag */ -#djDebug .syntax .nv { color: #fb660a } /* Name.Variable */ -#djDebug .syntax .ow { color: #ffffff } /* Operator.Word */ #djDebug .syntax .w { color: #888888 } /* Text.Whitespace */ -#djDebug .syntax .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */ -#djDebug .syntax .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */ -#djDebug .syntax .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */ -#djDebug .syntax .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */ -#djDebug .syntax .sb { color: #0086d2 } /* Literal.String.Backtick */ -#djDebug .syntax .sc { color: #0086d2 } /* Literal.String.Char */ -#djDebug .syntax .sd { color: #0086d2 } /* Literal.String.Doc */ -#djDebug .syntax .s2 { color: #0086d2 } /* Literal.String.Double */ -#djDebug .syntax .se { color: #0086d2 } /* Literal.String.Escape */ -#djDebug .syntax .sh { color: #0086d2 } /* Literal.String.Heredoc */ -#djDebug .syntax .si { color: #0086d2 } /* Literal.String.Interpol */ -#djDebug .syntax .sx { color: #0086d2 } /* Literal.String.Other */ -#djDebug .syntax .sr { color: #0086d2 } /* Literal.String.Regex */ -#djDebug .syntax .s1 { color: #0086d2 } /* Literal.String.Single */ -#djDebug .syntax .ss { color: #0086d2 } /* Literal.String.Symbol */ -#djDebug .syntax .bp { color: #ffffff } /* Name.Builtin.Pseudo */ -#djDebug .syntax .vc { color: #fb660a } /* Name.Variable.Class */ -#djDebug .syntax .vg { color: #fb660a } /* Name.Variable.Global */ -#djDebug .syntax .vi { color: #fb660a } /* Name.Variable.Instance */ -#djDebug .syntax .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */ +#djDebug .syntax .il { color: #92ef3f; font-weight: bold } /* Literal.Number.Integer.Long */ -- cgit v1.2.3 From d74431411b5c390379bcac89a60628a26365d8c9 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 24 Sep 2008 12:40:02 +0200 Subject: Added context processors to TemplateDebugPanel --- debug_toolbar/panels/template.py | 7 +++++++ .../templates/debug_toolbar/panels/templates.html | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index eb20079..9cab618 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -4,6 +4,7 @@ from django.core.signals import request_started from django.dispatch import Signal from django.template.loader import render_to_string from django.test.signals import template_rendered +from django.template.context import get_standard_processors from debug_toolbar.panels import DebugPanel # Code taken and adapted from Simon Willison and Django Snippets: @@ -44,6 +45,11 @@ class TemplateDebugPanel(DebugPanel): def url(self): return '' + def process_request(self, request): + self.context_processors = dict( + [("%s.%s" % (k.__module__, k.__name__), pformat(k(request))) for k in get_standard_processors()] + ) + def content(self): template_context = [] for i, d in enumerate(self.templates): @@ -65,5 +71,6 @@ class TemplateDebugPanel(DebugPanel): context = { 'templates': template_context, 'template_dirs': settings.TEMPLATE_DIRS, + 'context_processors': self.context_processors, } return render_to_string('debug_toolbar/panels/templates.html', context) diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html index 575d507..e878be2 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/templates.html +++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html @@ -23,3 +23,17 @@ {% else %} None {% endif %} +{% if context_processors %} +

    Context processors used:

    +
    +{% for key, value in context_processors.iteritems %} +
    {{ key|escape }}
    +
    + + +
    +{% endfor %} +
    +{% else %} + None +{% endif %} -- cgit v1.2.3 From 85d879803c88aa036934d36977a10b5d28b70aaa Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Wed, 24 Sep 2008 16:23:01 -0700 Subject: Adding a SHA-1 hash to the parameters passed to get the EXPLAIN query to avoid any sort of tampering of the SQL or parameters. --- debug_toolbar/panels/sql.py | 7 +++++-- debug_toolbar/templates/debug_toolbar/panels/sql.html | 2 +- debug_toolbar/views.py | 13 ++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 9223cb7..22d65a7 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -1,9 +1,11 @@ import time from debug_toolbar.panels import DebugPanel +from django.conf import settings from django.db import connection from django.db.backends import util from django.template.loader import render_to_string from django.utils import simplejson +from django.utils.hashcompat import sha_constructor class DatabaseStatTracker(util.CursorDebugWrapper): """ @@ -26,7 +28,8 @@ class DatabaseStatTracker(util.CursorDebugWrapper): 'sql': self.db.ops.last_executed_query(self.cursor, sql, params), 'time': stop - start, 'raw_sql': sql, - 'params': _params + 'params': _params, + 'hash': sha_constructor(settings.SECRET_KEY + sql + _params).hexdigest(), }) util.CursorDebugWrapper = DatabaseStatTracker @@ -37,7 +40,7 @@ class SQLDebugPanel(DebugPanel): """ name = 'SQL' has_content = True - + def __init__(self): self._offset = len(connection.queries) self._sql_time = 0 diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 052b36a..e218f22 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -13,7 +13,7 @@ {{ query.time|floatformat:"4" }} {% if query.params %} - EXPLAIN + EXPLAIN {% endif %} {{ query.sql|safe }} diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index 97739e6..b67a70b 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -8,8 +8,10 @@ import os import django.views.static from django.conf import settings from django.db import connection +from django.http import HttpResponse from django.shortcuts import render_to_response from django.utils import simplejson +from django.utils.hashcompat import sha_constructor def debug_media(request, path): root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None) @@ -21,16 +23,21 @@ def debug_media(request, path): def sql_explain(request): """ Returns the output of the SQL EXPLAIN on the given query. - + Expected GET variables: - sql: urlencoded sql with position arguments + sql: urlencoded sql with positional arguments params: JSON encoded parameter values time: time for SQL to execute passed in from toolbar just for redisplay + hash: the hash of (secret + sql + params) for tamper checking """ from debug_toolbar.panels.sql import reformat_sql sql = request.GET.get('sql', '') + params = request.GET.get('params', '') + hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() + if hash != request.GET.get('hash', ''): + return HttpResponse('

    Tamper alert

    ') # SQL Tampering alert if sql.lower().startswith('select'): - params = simplejson.loads(request.GET.get('params', '')) + params = simplejson.loads(params) cursor = connection.cursor() cursor.execute("EXPLAIN %s" % (sql,), params) headers = [d[0] for d in cursor.description] -- cgit v1.2.3 From c70df302e1564a7f7fe7883d3e042419ece1d9e6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 27 Sep 2008 15:50:47 -0400 Subject: added logger panel --- debug_toolbar/media/toolbar.css | 2 +- debug_toolbar/panels/logger.py | 73 ++++++++++++++++++++++ .../templates/debug_toolbar/panels/logger.html | 26 ++++++++ debug_toolbar/toolbar/loader.py | 1 + 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 debug_toolbar/panels/logger.py create mode 100644 debug_toolbar/templates/debug_toolbar/panels/logger.html diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 43ac588..bad28c5 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -22,7 +22,7 @@ margin: 0; padding: 0; line-height: 30px; - padding: 8px 10px 9px; + padding: 8px 9px 9px; position: relative; width: auto; } diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py new file mode 100644 index 0000000..e3fd21e --- /dev/null +++ b/debug_toolbar/panels/logger.py @@ -0,0 +1,73 @@ +import datetime +import logging + +try: + import threading +except ImportError: + threading = None + +from django.template.loader import render_to_string + +from debug_toolbar.panels import DebugPanel + +class ThreadTrackingHandler(logging.Handler): + def __init__(self): + if threading is None: + raise NotImplementedError("threading module is not available, \ + the logging panel cannot be used without it") + logging.Handler.__init__(self) + self.records = {} # a dictionary that maps threads to log records + + def emit(self, record): + self.get_records().append(record) + + def get_records(self, thread=None): + """ + Returns a list of records for the provided thread, of if none is provided, + returns a list for the current thread. + """ + if thread is None: + thread = threading.currentThread() + if thread not in self.records: + self.records[thread] = [] + return self.records[thread] + + def clear_records(self, thread=None): + if thread is None: + thread = threading.currentThread() + if thread in self.records: + del self.records[thread] + +handler = ThreadTrackingHandler() +logging.root.setLevel(logging.NOTSET) +logging.root.addHandler(handler) + +class LoggingPanel(DebugPanel): + name = 'Logging' + has_content = True + + def process_request(self, request): + handler.clear_records() + + def get_and_delete(self): + records = handler.get_records() + handler.clear_records() + return records + + def title(self): + return "Logging (%s message%s)" % (len(handler.get_records()), (len(handler.get_records()) == 1) and '' or 's') + + def url(self): + return '' + + def content(self): + records = [] + for record in self.get_and_delete(): + records.append({ + 'message': record.getMessage(), + 'time': datetime.datetime.fromtimestamp(record.created), + 'level': record.levelname, + 'file': record.pathname, + 'line': record.lineno, + }) + return render_to_string('debug_toolbar/panels/logger.html', {'records': records}) diff --git a/debug_toolbar/templates/debug_toolbar/panels/logger.html b/debug_toolbar/templates/debug_toolbar/panels/logger.html new file mode 100644 index 0000000..93443be --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/logger.html @@ -0,0 +1,26 @@ +

    Log Messages

    +{% if records %} + + + + + + + + + + + {% for record in records %} + + + + + + + {% endfor %} + +
    LevelTimeMessageLocation
    {{ record.level }}{{ record.time|date:"h:i:s m/d/Y" }}{{ record.message }}{{ record.file }}:{{ record.line }}
    +{% else %} +

    No messages logged.

    +{% endif %} + diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 0ac9096..e2c9793 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -17,6 +17,7 @@ class DebugToolbar(object): 'debug_toolbar.panels.sql.SQLDebugPanel', 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', + 'debug_toolbar.panels.logger.LoggingPanel', ) self.load_panels() -- cgit v1.2.3 From 76dbd5b1d2cf1a9ab1a6384a016e5628444b0a5c Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 27 Sep 2008 22:23:03 -0700 Subject: Adding info about the Logging panel to the README --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index c5e4c5f..7c0c8f3 100644 --- a/README.rst +++ b/README.rst @@ -15,6 +15,7 @@ Currently, the following panels have been written and are working: - SQL queries including time to execute and links to EXPLAIN each query - Cache stats - Templates and context used, and their template paths +- Logging output via Python's built-in logging module If you have ideas for other panels please let us know. @@ -58,6 +59,7 @@ Installation 'debug_toolbar.panels.sql.SQLDebugPanel', 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', + 'debug_toolbar.panels.logger.LoggingPanel', ) You can change the ordering of this tuple to customize the order of the -- cgit v1.2.3 From ce8c68b79c2de4abde01b29b1c73754ce4deb981 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sun, 28 Sep 2008 08:36:17 -0700 Subject: Updated to fail nicely when DEBUG=False. --- debug_toolbar/middleware.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 0a202e2..6d2391c 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -50,10 +50,13 @@ class DebugToolbarMiddleware(object): return None def process_view(self, request, view_func, view_args, view_kwargs): - for panel in self.debug_toolbar.panels: - panel.process_view(request, view_func, view_args, view_kwargs) + if self.debug_toolbar: + for panel in self.debug_toolbar.panels: + panel.process_view(request, view_func, view_args, view_kwargs) def process_response(self, request, response): + if not self.debug_toolbar: + return response if response.status_code != 200: return response for panel in self.debug_toolbar.panels: -- cgit v1.2.3