From 90c5da3ffa580fa4514579e405eb130adabe2ad5 Mon Sep 17 00:00:00 2001 From: Costas Yiotis Date: Tue, 18 Nov 2014 13:24:55 +0200 Subject: [PATCH] myslice reputation plugin v0.1 --- portal/reputationview.py | 308 ++++++++++++++ .../static/reputation_static/css/delete.gif | Bin 0 -> 752 bytes .../reputation_static/css/images/star-off.png | Bin 0 -> 685 bytes .../reputation_static/css/images/star-on.png | Bin 0 -> 631 bytes .../css/images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../css/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../css/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../css/images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../css/images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../css/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../css/jquery-ui-1.9.2.custom.min.css | 5 + .../reputation_static/css/jquery.rating.css | 12 + portal/static/reputation_static/css/main.css | 196 +++++++++ .../static/reputation_static/img/star-off.png | Bin 0 -> 685 bytes .../static/reputation_static/img/star-on.png | Bin 0 -> 631 bytes portal/static/reputation_static/img/star.gif | Bin 0 -> 815 bytes .../reputation_static/js/jquery-1.9.0.min.js | 4 + .../reputation_static/js/jquery.raty.min.js | 12 + .../js/ui/jquery-ui-1.9.2.custom.min.js | 6 + portal/templates/reputation.html | 399 ++++++++++++++++++ portal/urls.py | 7 + 28 files changed, 949 insertions(+) create mode 100644 portal/reputationview.py create mode 100644 portal/static/reputation_static/css/delete.gif create mode 100644 portal/static/reputation_static/css/images/star-off.png create mode 100644 portal/static/reputation_static/css/images/star-on.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 portal/static/reputation_static/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 portal/static/reputation_static/css/images/ui-icons_222222_256x240.png create mode 100644 portal/static/reputation_static/css/images/ui-icons_2e83ff_256x240.png create mode 100644 portal/static/reputation_static/css/images/ui-icons_454545_256x240.png create mode 100644 portal/static/reputation_static/css/images/ui-icons_888888_256x240.png create mode 100644 portal/static/reputation_static/css/images/ui-icons_cd0a0a_256x240.png create mode 100644 portal/static/reputation_static/css/jquery-ui-1.9.2.custom.min.css create mode 100644 portal/static/reputation_static/css/jquery.rating.css create mode 100644 portal/static/reputation_static/css/main.css create mode 100644 portal/static/reputation_static/img/star-off.png create mode 100644 portal/static/reputation_static/img/star-on.png create mode 100644 portal/static/reputation_static/img/star.gif create mode 100644 portal/static/reputation_static/js/jquery-1.9.0.min.js create mode 100644 portal/static/reputation_static/js/jquery.raty.min.js create mode 100644 portal/static/reputation_static/js/ui/jquery-ui-1.9.2.custom.min.js create mode 100644 portal/templates/reputation.html diff --git a/portal/reputationview.py b/portal/reputationview.py new file mode 100644 index 00000000..4699dd22 --- /dev/null +++ b/portal/reputationview.py @@ -0,0 +1,308 @@ +from django.contrib.auth import authenticate, login, logout +from django.template import RequestContext +from django.shortcuts import render, render_to_response + +from manifoldapi.manifoldresult import ManifoldResult +from ui.topmenu import topmenu_items, the_user +from myslice.configengine import ConfigEngine +from manifold.core.query import Query +from unfold.page import Page +from manifoldapi.manifoldapi import execute_admin_query, execute_query +from unfold.loginrequired import LoginRequiredAutoLogoutView + +from myslice.theme import ThemeView +import json +import hashlib +import datetime +import urllib2 +import ast +from django.views.decorators.csrf import csrf_exempt +from django.http import * + +def response_mimetype(request): + + if "application/json" in request.META['HTTP_ACCEPT']: + return "application/json" + else: + return "text/plain" + + +def json_to_rest(url, data ): + + req = urllib2.Request(url) + req.add_header('Content-Type', 'application/json') + response = urllib2.urlopen(req, json.dumps(data)) + + if data == "a": + mylist = ast.literal_eval(response.read()) + else: + mylist = response.read().translate(None, '"[]').split(",") + + return (mylist) + + +def unix_to_timestamp(timest): + try: + return datetime.datetime.fromtimestamp(int(timest)).strftime('%Y-%m-%d %H:%M:%S') + except: + return timest + +def timestamp_to_unix(timest): + try: + pass + except: + pass + + +def slice_to_exp(slices_users): + experiments = {} + testbeds = {} + + + for slice in slices_users: + nodes={} + leases = slice['lease'] + if leases is not None: + for lease in leases: + resource = lease['resource'] + start_t = lease['start_time'] + end_t = lease['end_time'] + #node = lease['resource'] + + testbed_start = resource.index('IDN+')+4 + testbed_end = resource.index('+node+') + + testbed = resource[testbed_start:testbed_end] + node = resource[testbed_end+6:] + + if testbed in testbeds: + if node not in testbeds[testbed]: + testbeds[testbed].append(node) + else: + testbeds[testbed] = [node] + + #group nodes in consecutive timeslots + if not node in nodes: + nodes[node]={str(start_t):{'start_t':start_t, 'nodes':node, 'end_t':end_t}} + else: + if not str(start_t) in nodes[node]: + f=0 + for n in nodes[node]: + if n[str(end_t)] == start_t: + n[str(end_t)] == end_t + f=1 + if f==0: + nodes[node][str(start_t)]={'start_t':start_t, 'nodes':node, 'end_t':end_t} + + #group grouped nodes in experiments + for n in nodes: + for exp in nodes[n]: + key = str(exp) + str(nodes[n][exp]['end_t']) + + if key not in experiments: + experiments[key]={'slice_hrn':slice['slice_hrn'], \ + 'start':nodes[n][exp]['start_t'], 'end':nodes[n][exp]['end_t'], 'nodes':[nodes[n][exp]['nodes']]} + elif nodes[n][exp]['end_t'] == experiments[key]['end']: + experiments[key]['nodes'].append(nodes[n][exp]['nodes']) + + return (experiments,testbeds) + +class ReputationView (LoginRequiredAutoLogoutView, ThemeView): + template_name = 'reputation.html' + + # expose this so we can mention the backend URL on the welcome page + def default_env (self): + return { + 'MANIFOLD_URL':ConfigEngine().manifold_url(), + } + + def post (self,request): + env = self.default_env() + env['theme'] = self.theme + + + + with open('/home/coyiotis/testlog.log') as f: + f.write(str('test')) + + + return render_to_response(self.template, env, context_instance=RequestContext(request)) + + + + + def get (self, request, state=None): + env = self.default_env() + + ##### *** Reputation Plugin-specific START *** ############ + with open('/home/coyiotis/testlog.log', 'w') as f: + f.write(str(request.GET)) + for key in request.GET: + f.write('\n') + f.write(str(request.GET[key])) + + #The following 'if' is a dirty way for bypassing the JS AJAX cross-domain prevention policy...not pretty + if request.GET.has_key(u'slicedata[user_eval][overall]'): + dict_to_send = {} + dict_to_send['eid'] = str(request.GET[u'slicedata[id]']) + dict_to_send['slice_hrn'] = str(request.GET[u'slicedata[slice_hrn]']) + dict_to_send['user_hrn'] = str(request.GET[u'slicedata[user_hrn]']) + dict_to_send['start_tunix'] = str(request.GET[u'slicedata[start_tunix]']) + dict_to_send['end_tunix'] = str(request.GET[u'slicedata[end_tunix]']) + dict_to_send['start_t'] = str(request.GET[u'slicedata[start_t]']) + dict_to_send['end_t'] = str(request.GET[u'slicedata[end_t]']) + dict_to_send['testbeds'] = ast.literal_eval(str(request.GET[u'testbeds'])) + dict_to_send['user_eval'] = {} + dict_to_send['user_eval']['reuse'] = str(request.GET[u'slicedata[user_eval][reuse]']) + dict_to_send['user_eval']['availability'] = str(request.GET[u'slicedata[user_eval][availability]']) + dict_to_send['user_eval']['pay'] = str(request.GET[u'slicedata[user_eval][pay]']) + dict_to_send['user_eval']['support'] = str(request.GET[u'slicedata[user_eval][support]']) + dict_to_send['user_eval']['overall'] = str(request.GET[u'slicedata[user_eval][overall]']) + dict_to_send['user_eval']['link_quality'] = str(request.GET[u'slicedata[user_eval][link_quality]']) + dict_to_send['user_eval']['problems'] = str(request.GET[u'slicedata[user_eval][problems]']) + dict_to_send['user_eval']['quality'] = str(request.GET[u'slicedata[user_eval][quality]']) + + slicedata_received = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/json', dict_to_send ) + + return HttpResponse(json.dumps(slicedata_received), content_type = response_mimetype(self.request)) + + + slices_users = [] + + #get slices + userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease') + slice_details = execute_query(self.request, userslice_query) + + #get local users + local_user_query = Query().get('local:user').select('email','status','config') + local_user_details = execute_admin_query(self.request, local_user_query) + + #get users - create dict[email]=hrn + user_query = Query().get('user').select('user_hrn','user_urn','user_email') + user_details = execute_admin_query(self.request, user_query) + users_hrn = {} + for item in user_details: + users_hrn[item['user_email']] = item['user_hrn'] + + #get currenct username (email) + if request.user.is_authenticated(): + cur_username = request.user.username + + #get a list of all the slices for the logged in user + testbeds = [] + + for slice in slice_details: + + if users_hrn[cur_username] in slice['users']: + slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \ + , 'resource':slice['resource'], 'lease':slice['lease'] }) + + + env['slices_users'] = slices_users ### For logging + + #####create slicelist for template & JSON + experiments,testbeds = slice_to_exp(slices_users) + + all_exp = [] + iddata = [] + + for exp in experiments: + experiment = {} + experiment['slice_hrn'] = experiments[exp]['slice_hrn'] + experiment['user_hrn'] = users_hrn[cur_username] + experiment['start_tunix'] = experiments[exp]['start'] + experiment['end_tunix'] = experiments[exp]['end'] + experiment['start_t'] = unix_to_timestamp(experiments[exp]['start']) + experiment['end_t'] = unix_to_timestamp(experiments[exp]['end']) + experiment['testbeds'] = {} + for exp_node in experiments[exp]['nodes']: + list_testbeds = [ key for key,val in testbeds.items()] + for tkey in list_testbeds: + if exp_node in testbeds[tkey]: + if tkey in experiment['testbeds']: + if exp_node not in experiment['testbeds'][tkey]: + experiment['testbeds'][tkey].append(exp_node) + else: + experiment['testbeds'][tkey] = [exp_node] + tempid = hashlib.sha1(str(experiment)).hexdigest() + experiment['id'] = tempid + + iddata.append(tempid) + all_exp.append(experiment) + + + ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated + unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata) + + for item in all_exp: + if item['id'] in unrated_exp: + pass + else: + all_exp.pop(all_exp.index(item)) + + + + ###### Get Reputation values from Reputation DB + reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a") + env['logging_test'] = reps + + services = [] + for item in reps: + for serv in item['services']: + if serv.keys()[0] not in services: + services.append(serv.keys()[0]) + + + #in json, sevices are in the form: 'services':[{'serv1':x}, {'serv2':y}], so we transform it to 'services':[x,y] based on + # the services dict above. If for a specific service there is no applicable value, we put N/A + for testbed in reps: + d = list(testbed['services']) + del testbed['services'] + testbed['services'] = [] + for s in services: + set_v = 0 + for i in d: + try: + testbed['services'].append(i[s]) + set_v=1 + except: + pass + if set_v == 0 : + testbed['services'].append('N/A') + + ###### Pass variables to template + env['logging_test'] = json.dumps(all_exp, ensure_ascii=False) + env['reputation'] = reps + env['rep_serv'] = services + env['slicelist'] = all_exp + env['json_data'] = json.dumps(all_exp, ensure_ascii=False) + + ###### *** Reputation Plugin-specific END *** ############ + + + if request.user.is_authenticated(): + env['person'] = self.request.user + else: + env['person'] = None + + env['theme'] = self.theme + #env['user_list']= user_list + + env['username']=the_user(request) + env['topmenu_items'] = topmenu_items(None, request) + if state: env['state'] = state + elif not env['username']: env['state'] = None + # use one or two columns for the layout - not logged in users will see the login prompt + env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html" + + return render_to_response(self.template, env, context_instance=RequestContext(request)) + + + + + + + + + + \ No newline at end of file diff --git a/portal/static/reputation_static/css/delete.gif b/portal/static/reputation_static/css/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..43c6ca8763d79bde87bcf437e497af00c8be562d GIT binary patch literal 752 zcmZ?wbhEHb6kt$bc*el6GthYN-n}zt&b)vB{*)i+-#|NQy$ zABXln&Q1FL`t{#CH*SY|{oJwc*Qz;h;)0))7aYq9ewP~fc2e)_P3vAY)$9wl{IzJp zy{ydlr;a^HiGHwZ{*SH8FZkJhE{gei`OM?;ir*_{?@ji478&@mD*tSH_`A&5@6Vqe z@G<&xeCOwiq-WvY-eS5f?;vgCP8#IHGBw=+^cY}xvy zx8c*8mDl2ff1W;kCeZrNm9vlQYX1NK&p;cX_>+Z^ogs-q2V^`bP8it#HzYMRx3so$ zF*EY=GO}~EC229rFl%YC^9nP!YVooQGRw%YcdE>8;_4NY5n8);hDv`DyO7oz#vMD^ znPi%Jw{#!u5n@zn;$6t7dHRenuME@iEvL?$J}1MnZ|zLsyZ4S<+^jO=&OKpv7NHgA zW;}Z?%p};%tnyr_TZmnSg}wC)(_{-41%(Ck7lx{^2uxAnpLDogfP3qOq@?40TINv> ziwuq&<5G;P+py!nVu4oKn3w|>8e2IgD|0*WWEmc5?B>!~;?U^isv@M?wB-RqGpkpd zy2pHzPNpO63k(92QYJWVUDc=?mcen0k@-|d*6BGamJ^)=rb&1lTvm|OxMl&1lR5*>Dl0QrnVHn1Ly)Enp;##exZh7()Uk zR1!C3adKe*!lVgta&se2n3x!5BLe|s!Nt*~X-#y7B3eoUik5~%+lD(Tz0ZL^0YjVU zv%Pu#yl=keg9gZ?Q_Q(|Z0g_5!WIoz~V%6X6SCq;x5j%6#A6o&%l(m4W2o+DSkrok{@j zfS9fu_%t7u6-EyR*{?cCDbX|y$Ei}>*}-*d*tQMu1GuLQBnNZ({Kj-B6r%H5Cv9zQ z1OftQ-v&TRiEZ1cs+abw?R0hbV45b`)$HqmfpE80>NxE=6Ci}>F?0hV0tABwPH{}X=zm$k-d TM0>cp00000NkvXXu0mjfLk}+u0K@`S+@BV*_sWrqlwFo8}(kQkaqzD;A z=u{lE-2?}_II1YR)S)U)E*26HCl}q?MW=Ld6)l=U=ui@ZMFoe7jcsaT?tgaXnG9{0ZQ-FLi$F8Gk$pICVsN_6A+-I}LP#xf!zP`KEQ*A|86(eYX?Vrxqg`*m?> zyc17#YQ&Emm{YDS9%UIE2;KXq0p(YRuVBj4qCoke?8ek~ZfK?*SF$toUz&(q^LzVF zc)m+{o=z$CtKX9fo)4nH88Gx=Z0LtIJw+2pF{o}Aa&I@D_|-bv)_zWzpnQfNU|%D| z2ONlib6`yct1JCRlQx>P4J2Q!lkr}!P)`rD5RWn;!ch^BrauSPHXPUh?BDz@Ut;od zmQ4>}ahc!a2^JEAoD+yQ#m?=B%^vZad=f}S8X&Tqm1m)@;e`m!IcA(C>>M0F#2E0tt%Gn#jhcX3%^aLBZN-xDTU?LbBKJ1?Kz|Loh!06cE>#5u?R;17H*+`wdH ROO^lt002ovPDHLkV1mP{6ITEL literal 0 HcmV?d00001 diff --git a/portal/static/reputation_static/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/portal/static/reputation_static/css/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0y~yV9;P-U`XL$V_;zTl2TN~z`#)L>EalY(fIb9A>#oB z0S3bZ`zM)4s+63#z$ean)A;imdFy!gdmEalY(fIb9A>#oB z0fvo1|L4hb@|Yi(pmAc>%%5`K?(@yz2y2>}pc=tRT}nEuo8^e6(RDut1_lOCS3j3^ HP68$> literal 0 HcmV?d00001 diff --git a/portal/static/reputation_static/css/images/ui-bg_glass_75_dadada_1x400.png b/portal/static/reputation_static/css/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..5a46b47cb16631068aee9e0bd61269fc4e95e5cd GIT binary patch literal 111 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 literal 0 HcmV?d00001 diff --git a/portal/static/reputation_static/css/images/ui-icons_454545_256x240.png b/portal/static/reputation_static/css/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..59bd45b907c4fd965697774ce8c5fc6b2fd9c105 GIT binary patch literal 4369 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 ROO^lt002ovPDHLkV1mP{6ITEL literal 0 HcmV?d00001 diff --git a/portal/static/reputation_static/img/star.gif b/portal/static/reputation_static/img/star.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0948a70843bf01952d1f81dcfcdadc92976a04a GIT binary patch literal 815 zcmZ?wbhEHb6ksr5c*el6(A@m!(W5UnOP^`reSRqFN=wUy;^KSv?mbz*{y;*);~mc5 z-|RUW6m;#{wMW}bp6pHg_U+rN({8s`u6+0I-Q5+MAMeb%w`5!M# z{q=^=j}*N*e*EQepZ7;K-(U6l^W*)qy-uI5Mx04YJ9FmD@2@w0e|`3BzvYV!svmDJ zy1UBtA9dUx3IVz=bW<9TmSpMHPB|LHc1x92?H@6~*NPV?1P?R#4d zPbMV1-s|#ytJ9}D;U7+0e!n;8#jahi&$Zv4GUd&Fk1akv*Jf&ey1!wEi_79UZ*9oxQ@{%Dr9PJ(HT0dD+=#b_&nx zo;_uOvcT+F^B1kmTCm7;ooTnJOVgT->oy9stX9;+Wt=;yeVRh>v<^0t2hF-BCLB+)OxV~|o^Y7BxkbBn>L#;Ao2bb}zvIae zahR}heq*JZjX{FLp=Ns_o{$xV5e;md9fF}N76@+aTu|(0kmYkQu=Tj(f3H;@jz+F* zE<*n@V=6DYEK+(d@uu5D$x(?}?pCag`y!u3Z9G9D7L9DY&GMZleTpiK%ndGyDv=E7 z$&FTy{z^5m2}iwHO9kgx9CYOCnJS>zV-e%g(sW#yFMn!{VB=v%0Zpqso5qK!or$XY zaXAZwTD+%onQ(6KTY(0+g99hQ7@xbXJ z+afNRv>DeF7I;l%@6>bY*ucm&MaOd08xNO;E)FfDRRx7PY7?2XLNzux1TAWrpwX$& Tt$5|&@dlT46<$dZ4hCxgZKrs? literal 0 HcmV?d00001 diff --git a/portal/static/reputation_static/js/jquery-1.9.0.min.js b/portal/static/reputation_static/js/jquery-1.9.0.min.js new file mode 100644 index 00000000..50d1b22f --- /dev/null +++ b/portal/static/reputation_static/js/jquery-1.9.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st("