├── README.txt ├── kees.egg-info ├── not-zip-safe ├── top_level.txt ├── dependency_links.txt ├── entry_points.txt ├── requires.txt ├── PKG-INFO └── SOURCES.txt ├── CHANGES.txt ├── kees ├── static │ ├── pyramid.png │ ├── pyramid-16x16.png │ ├── ct.css │ ├── theme.min.css │ ├── theme.css │ ├── listpoints.html │ ├── showpoint.html │ ├── showlevel.html │ ├── listlevels.html │ └── zepto.min.js ├── tests.py ├── __init__.py ├── templates │ └── mytemplate.pt ├── views.py └── dblayer.py ├── MANIFEST.in ├── runit.py ├── production.ini ├── tryds.py ├── setup.py ├── development.ini └── testit.py /README.txt: -------------------------------------------------------------------------------- 1 | kees README 2 | -------------------------------------------------------------------------------- /kees.egg-info/not-zip-safe: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kees.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | kees 2 | -------------------------------------------------------------------------------- /kees.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 0.0 2 | --- 3 | 4 | - Initial version 5 | -------------------------------------------------------------------------------- /kees.egg-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [paste.app_factory] 2 | main = kees:main 3 | -------------------------------------------------------------------------------- /kees.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | pyramid 2 | pyramid_chameleon 3 | pyramid_debugtoolbar 4 | waitress -------------------------------------------------------------------------------- /kees/static/pyramid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/KEES/master/kees/static/pyramid.png -------------------------------------------------------------------------------- /kees/static/pyramid-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/KEES/master/kees/static/pyramid-16x16.png -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt *.ini *.cfg *.rst 2 | recursive-include kees *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml 3 | -------------------------------------------------------------------------------- /kees/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pyramid import testing 4 | 5 | 6 | class ViewTests(unittest.TestCase): 7 | def setUp(self): 8 | self.config = testing.setUp() 9 | 10 | def tearDown(self): 11 | testing.tearDown() 12 | 13 | def test_my_view(self): 14 | from .views import my_view 15 | request = testing.DummyRequest() 16 | info = my_view(request) 17 | self.assertEqual(info['project'], 'kees') 18 | -------------------------------------------------------------------------------- /runit.py: -------------------------------------------------------------------------------- 1 | from wsgiref.simple_server import make_server 2 | import sys, os 3 | 4 | # Switch to the virtualenv if we're not already there 5 | #INTERP = os.path.expanduser("~/env/pyramid/bin/python") 6 | 7 | #if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) 8 | 9 | from paste.deploy import loadapp 10 | application = loadapp( 11 | 'config:' + 12 | os.path.expanduser('/home/chozabu/git/KEES/development.ini')) 13 | 14 | server = make_server('0.0.0.0', 8080, application) 15 | server.serve_forever() 16 | 17 | -------------------------------------------------------------------------------- /kees.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.1 2 | Name: kees 3 | Version: 0.0 4 | Summary: kees 5 | Home-page: UNKNOWN 6 | Author: UNKNOWN 7 | Author-email: UNKNOWN 8 | License: UNKNOWN 9 | Description: kees README 10 | 11 | 12 | 0.0 13 | --- 14 | 15 | - Initial version 16 | 17 | Keywords: web pyramid pylons 18 | Platform: UNKNOWN 19 | Classifier: Programming Language :: Python 20 | Classifier: Framework :: Pyramid 21 | Classifier: Topic :: Internet :: WWW/HTTP 22 | Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application 23 | -------------------------------------------------------------------------------- /kees.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | CHANGES.txt 2 | MANIFEST.in 3 | README.txt 4 | development.ini 5 | production.ini 6 | setup.py 7 | kees/__init__.py 8 | kees/dblayer.py 9 | kees/testdb.py 10 | kees/tests.py 11 | kees/views.py 12 | kees.egg-info/PKG-INFO 13 | kees.egg-info/SOURCES.txt 14 | kees.egg-info/dependency_links.txt 15 | kees.egg-info/entry_points.txt 16 | kees.egg-info/not-zip-safe 17 | kees.egg-info/requires.txt 18 | kees.egg-info/top_level.txt 19 | kees/static/pyramid-16x16.png 20 | kees/static/pyramid.png 21 | kees/static/theme.css 22 | kees/static/theme.min.css 23 | kees/templates/mytemplate.pt -------------------------------------------------------------------------------- /kees/static/ct.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: e9f5f1; 3 | color: #222222; 4 | text-shadow: rgba(250,250,255, .4) 0em 0em 4px; 5 | font: 12pt Ubuntu, Verdana, Arial, Helvetica, sans-serif; 6 | margin: 10px; 7 | } 8 | 9 | #chatout { 10 | margin-left: 520px; 11 | } 12 | 13 | .PIPanel, body > ul > li { 14 | background: white; 15 | padding: 5px 10px; 16 | border: #bbbbbb 1px solid; 17 | text-align: left; 18 | margin: 5px; 19 | border-radius: 5px; 20 | box-shadow: 2px 2px 2px #bbbbbb; 21 | } 22 | 23 | .PIPanel:hover { 24 | border: gray 1px solid; 25 | border-color: #666666; 26 | } 27 | 28 | .PIPanel > span { 29 | font-size: 10pt; 30 | } 31 | 32 | .PIPanel > div { 33 | margin-top: 10px; 34 | } 35 | 36 | span.postname { 37 | font-weight: bold; 38 | } 39 | 40 | span.postid { 41 | font-size: 8pt; 42 | float: right; 43 | } 44 | 45 | body > ul { 46 | margin: 0px; 47 | padding: 0px; 48 | list-style-type: none; 49 | text-align: left; 50 | float: left; 51 | width: 480px; 52 | } 53 | -------------------------------------------------------------------------------- /production.ini: -------------------------------------------------------------------------------- 1 | ### 2 | # app configuration 3 | # http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/environment.html 4 | ### 5 | 6 | [app:main] 7 | use = egg:kees 8 | 9 | pyramid.reload_templates = false 10 | pyramid.debug_authorization = false 11 | pyramid.debug_notfound = false 12 | pyramid.debug_routematch = false 13 | pyramid.default_locale_name = en 14 | 15 | ### 16 | # wsgi server configuration 17 | ### 18 | 19 | [server:main] 20 | use = egg:waitress#main 21 | host = 0.0.0.0 22 | port = 6543 23 | 24 | ### 25 | # logging configuration 26 | # http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/logging.html 27 | ### 28 | 29 | [loggers] 30 | keys = root, kees 31 | 32 | [handlers] 33 | keys = console 34 | 35 | [formatters] 36 | keys = generic 37 | 38 | [logger_root] 39 | level = WARN 40 | handlers = console 41 | 42 | [logger_kees] 43 | level = WARN 44 | handlers = 45 | qualname = kees 46 | 47 | [handler_console] 48 | class = StreamHandler 49 | args = (sys.stderr,) 50 | level = NOTSET 51 | formatter = generic 52 | 53 | [formatter_generic] 54 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s 55 | -------------------------------------------------------------------------------- /tryds.py: -------------------------------------------------------------------------------- 1 | 2 | import dataset 3 | 4 | #db = dataset.connect('sqlite:///:memory:') 5 | db = dataset.connect('sqlite:///mydatabase.db') 6 | 7 | table = db['sometable'] 8 | table.insert(dict(name='John Doe', age=37)) 9 | table.insert(dict(name='Jane Doe', age=34, gender='female')) 10 | 11 | john = table.find_one(name='John Doe') 12 | 13 | print john 14 | 15 | def newAccount(request, username, password): 16 | username = username.replace(".","") 17 | eUser = database.users.find_one({"_id":username}) 18 | if(eUser): 19 | print "dupe account creation attempt on name: " + username 20 | return {"result":"fail", "message":"name taken"} 21 | newUser = {} 22 | newUser['createdAt'] = time.time() 23 | newUser['lastTouch'] = time.time() 24 | newUser['salt'] = uuid.uuid4().get_hex() 25 | newUser['_id'] = username 26 | makeImage(username) 27 | newUser['username'] = username 28 | newUser['groups'] = [] 29 | newUser['password'] = hashlib.sha512(password + newUser['salt']).hexdigest() 30 | database.users.insert(newUser) 31 | print {"result":"sucess", "message":"account " + username + " created"} 32 | return {"result":"sucess", "message":"account " + username + " created"} -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import setup, find_packages 4 | 5 | here = os.path.abspath(os.path.dirname(__file__)) 6 | with open(os.path.join(here, 'README.txt')) as f: 7 | README = f.read() 8 | with open(os.path.join(here, 'CHANGES.txt')) as f: 9 | CHANGES = f.read() 10 | 11 | requires = [ 12 | 'pyramid', 13 | 'pyramid_chameleon', 14 | 'pyramid_debugtoolbar', 15 | 'waitress', 16 | ] 17 | 18 | setup(name='kees', 19 | version='0.0', 20 | description='kees', 21 | long_description=README + '\n\n' + CHANGES, 22 | classifiers=[ 23 | "Programming Language :: Python", 24 | "Framework :: Pyramid", 25 | "Topic :: Internet :: WWW/HTTP", 26 | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", 27 | ], 28 | author='', 29 | author_email='', 30 | url='', 31 | keywords='web pyramid pylons', 32 | packages=find_packages(), 33 | include_package_data=True, 34 | zip_safe=False, 35 | install_requires=requires, 36 | tests_require=requires, 37 | test_suite="kees", 38 | entry_points="""\ 39 | [paste.app_factory] 40 | main = kees:main 41 | """, 42 | ) 43 | -------------------------------------------------------------------------------- /kees/__init__.py: -------------------------------------------------------------------------------- 1 | from pyramid.config import Configurator 2 | 3 | 4 | def main(global_config, **settings): 5 | """ This function returns a Pyramid WSGI application. 6 | """ 7 | config = Configurator(settings=settings) 8 | config.include('pyramid_chameleon') 9 | config.add_static_view('static', 'static', cache_max_age=3600) 10 | config.add_static_view('pplevels', 'pplevels', cache_max_age=3600) 11 | config.add_static_view('thumbs', 'thumbs', cache_max_age=3600) 12 | config.add_route('home', '/') 13 | config.add_route('store_mp3_view', '/store_mp3_view') 14 | config.add_route('uploadLevel', '/uploadLevel') 15 | config.add_route('query_levels', '/query_levels') 16 | config.add_route('add_point', '/add_point') 17 | config.add_route('add_vote', '/add_vote') 18 | config.add_route('query_points', '/query_points') 19 | config.add_route('get_point', '/get_point') 20 | config.add_route('get_level', '/get_level') 21 | config.add_route('get_tags', '/get_tags') 22 | config.add_route('login', '/login') 23 | config.add_route('new_user', '/new_user') 24 | config.add_route('uploadCrash', '/uploadCrash') 25 | config.add_route('crashLogs', '/crashLogs') 26 | config.scan() 27 | return config.make_wsgi_app() 28 | -------------------------------------------------------------------------------- /development.ini: -------------------------------------------------------------------------------- 1 | ### 2 | # app configuration 3 | # http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/environment.html 4 | ### 5 | 6 | [app:main] 7 | use = egg:kees 8 | 9 | pyramid.reload_templates = true 10 | pyramid.debug_authorization = false 11 | pyramid.debug_notfound = false 12 | pyramid.debug_routematch = false 13 | pyramid.default_locale_name = en 14 | pyramid.includes = 15 | pyramid_debugtoolbar 16 | 17 | # By default, the toolbar only appears for clients from IP addresses 18 | # '127.0.0.1' and '::1'. 19 | # debugtoolbar.hosts = 127.0.0.1 ::1 20 | 21 | ### 22 | # wsgi server configuration 23 | ### 24 | 25 | [server:main] 26 | use = egg:waitress#main 27 | host = 0.0.0.0 28 | port = 6543 29 | 30 | ### 31 | # logging configuration 32 | # http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/logging.html 33 | ### 34 | 35 | [loggers] 36 | keys = root, kees 37 | 38 | [handlers] 39 | keys = console 40 | 41 | [formatters] 42 | keys = generic 43 | 44 | [logger_root] 45 | level = INFO 46 | handlers = console 47 | 48 | [logger_kees] 49 | level = DEBUG 50 | handlers = 51 | qualname = kees 52 | 53 | [handler_console] 54 | class = StreamHandler 55 | args = (sys.stderr,) 56 | level = NOTSET 57 | formatter = generic 58 | 59 | [formatter_generic] 60 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s 61 | -------------------------------------------------------------------------------- /testit.py: -------------------------------------------------------------------------------- 1 | 2 | import requests 3 | 4 | server = 'http://0.0.0.0:8080/' 5 | 6 | 7 | print "" 8 | print "Create user" 9 | params = {'username': "chozabu", 'password': "asd"}#open('otherthing.txt', 'rb')} 10 | r = requests.post(server+'new_user', data=params) 11 | print r.text 12 | 13 | print "" 14 | print "login user" 15 | params = {'username': "chozabu", 'password': "asd"}#open('otherthing.txt', 'rb')} 16 | r = requests.post(server+'login', data=params) 17 | print r.text 18 | session = r.json()['session'] 19 | 20 | 21 | print "" 22 | print "add_point" 23 | files = {'session':session, 'name': "apoint", 'text': "blah blah blah"}#open('otherthing.txt', 'rb')} 24 | r = requests.post(server+'add_point', data=files) 25 | print r.text 26 | 27 | 28 | print "" 29 | print "query points" 30 | params = {'sortKey': "rating", 'cursor': 0, 'limit':8}#open('otherthing.txt', 'rb')} 31 | r = requests.post(server+'query_points', data=params) 32 | print r.text 33 | #print r 34 | #print dir(r) 35 | ''' 36 | print "" 37 | print "upload level" 38 | files = {'session':session, 'author': "chozabu", 'name': "ICERUN", "leveldata":"someleveldata", 'sshot':'apicture'}#open('otherthing.txt', 'rb')} 39 | r = requests.post(server+'uploadLevel', files=files) 40 | print r.text 41 | 42 | 43 | print "" 44 | print "query levels" 45 | params = {'sortKey': "filename", 'cursor': 0, 'limit':8}#open('otherthing.txt', 'rb')} 46 | r = requests.post(server+'query_levels', data=params) 47 | print r.text 48 | #print r 49 | #print dir(r) 50 | ''' -------------------------------------------------------------------------------- /kees/static/theme.min.css: -------------------------------------------------------------------------------- 1 | @import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} -------------------------------------------------------------------------------- /kees/static/theme.css: -------------------------------------------------------------------------------- 1 | @import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); 2 | body { 3 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | font-weight: 300; 5 | color: #ffffff; 6 | background: #bc2131; 7 | } 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6 { 14 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 15 | font-weight: 300; 16 | } 17 | p { 18 | font-weight: 300; 19 | } 20 | .font-normal { 21 | font-weight: 400; 22 | } 23 | .font-semi-bold { 24 | font-weight: 600; 25 | } 26 | .font-bold { 27 | font-weight: 700; 28 | } 29 | .starter-template { 30 | margin-top: 250px; 31 | } 32 | .starter-template .content { 33 | margin-left: 10px; 34 | } 35 | .starter-template .content h1 { 36 | margin-top: 10px; 37 | font-size: 60px; 38 | } 39 | .starter-template .content h1 .smaller { 40 | font-size: 40px; 41 | color: #f2b7bd; 42 | } 43 | .starter-template .content .lead { 44 | font-size: 25px; 45 | color: #f2b7bd; 46 | } 47 | .starter-template .content .lead .font-normal { 48 | color: #ffffff; 49 | } 50 | .starter-template .links { 51 | float: right; 52 | right: 0; 53 | margin-top: 125px; 54 | } 55 | .starter-template .links ul { 56 | display: block; 57 | padding: 0; 58 | margin: 0; 59 | } 60 | .starter-template .links ul li { 61 | list-style: none; 62 | display: inline; 63 | margin: 0 10px; 64 | } 65 | .starter-template .links ul li:first-child { 66 | margin-left: 0; 67 | } 68 | .starter-template .links ul li:last-child { 69 | margin-right: 0; 70 | } 71 | .starter-template .links ul li.current-version { 72 | color: #f2b7bd; 73 | font-weight: 400; 74 | } 75 | .starter-template .links ul li a { 76 | color: #ffffff; 77 | } 78 | .starter-template .links ul li a:hover { 79 | text-decoration: underline; 80 | } 81 | .starter-template .links ul li .icon-muted { 82 | color: #eb8b95; 83 | margin-right: 5px; 84 | } 85 | .starter-template .links ul li:hover .icon-muted { 86 | color: #ffffff; 87 | } 88 | .starter-template .copyright { 89 | margin-top: 10px; 90 | font-size: 0.9em; 91 | color: #f2b7bd; 92 | text-transform: lowercase; 93 | float: right; 94 | right: 0; 95 | } 96 | @media (max-width: 1199px) { 97 | .starter-template .content h1 { 98 | font-size: 45px; 99 | } 100 | .starter-template .content h1 .smaller { 101 | font-size: 30px; 102 | } 103 | .starter-template .content .lead { 104 | font-size: 20px; 105 | } 106 | } 107 | @media (max-width: 991px) { 108 | .starter-template { 109 | margin-top: 0; 110 | } 111 | .starter-template .logo { 112 | margin: 40px auto; 113 | } 114 | .starter-template .content { 115 | margin-left: 0; 116 | text-align: center; 117 | } 118 | .starter-template .content h1 { 119 | margin-bottom: 20px; 120 | } 121 | .starter-template .links { 122 | float: none; 123 | text-align: center; 124 | margin-top: 60px; 125 | } 126 | .starter-template .copyright { 127 | float: none; 128 | text-align: center; 129 | } 130 | } 131 | @media (max-width: 767px) { 132 | .starter-template .content h1 .smaller { 133 | font-size: 25px; 134 | display: block; 135 | } 136 | .starter-template .content .lead { 137 | font-size: 16px; 138 | } 139 | .starter-template .links { 140 | margin-top: 40px; 141 | } 142 | .starter-template .links ul li { 143 | display: block; 144 | margin: 0; 145 | } 146 | .starter-template .links ul li .icon-muted { 147 | display: none; 148 | } 149 | .starter-template .copyright { 150 | margin-top: 20px; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /kees/templates/mytemplate.pt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Starter Scaffold for The Pyramid Web Framework 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 |
29 | 51 |
53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | 63 | 70 |
71 | 72 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /kees/static/listpoints.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KivEnt Server 4 | 5 | 6 | 7 |

KivEntEd Points

8 | 9 |
10 | name: 11 | pass: 12 | 13 | 14 |
15 | 16 |
17 | Title: 18 | Text: 19 | 20 | 21 |
22 | 23 |
24 | Sort by: 25 | 34 | 35 | Per Page: 36 | Start at page: 37 | 38 | 39 | Reverse sort
40 |
41 |
42 |
43 |
44 |
45 |
46 | 47 | 48 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /kees/static/showpoint.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KivEnt Server 4 | 5 | 6 | 7 |

KivEntEd Point

8 | 9 |
10 | name: 11 | pass: 12 | 13 | 14 |
15 | 16 |
17 | Tag: 18 | Value: 19 | 20 | 21 |
22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 | 30 | 31 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /kees/static/showlevel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KivEnt Server 4 | 5 | 6 | 7 |

KivEntEd Level

8 | 9 |
10 | name: 11 | pass: 12 | 13 | 14 |
15 | 16 |
17 | Tag: 18 | Value: 19 | 20 | 21 |
22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 | 30 | 31 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /kees/views.py: -------------------------------------------------------------------------------- 1 | from pyramid.view import view_config 2 | 3 | import os 4 | import uuid 5 | import string 6 | import dblayer 7 | import datetime 8 | from pyramid.response import Response 9 | 10 | 11 | if not os.path.exists("kees/pplevels"):os.makedirs("kees/pplevels") 12 | if not os.path.exists("kees/thumbs"):os.makedirs("kees/thumbs") 13 | if not os.path.exists("kees/crashs"):os.makedirs("kees/crashs") 14 | 15 | def pythonicVarName(field): 16 | firstLetter = True 17 | for word in field.split(' '): 18 | if firstLetter == False: 19 | wordCapped = str(word[0]).upper() + word[1:] 20 | id = id + wordCapped 21 | else: 22 | id = word.lower() 23 | firstLetter = False 24 | for i in string.punctuation: 25 | if i in id: 26 | id = id.replace(i, "") 27 | return id 28 | 29 | def write_a_file(file_path, input_file): 30 | temp_file_path = file_path + '~' 31 | output_file = open(temp_file_path, 'wb') 32 | 33 | # Finally write the data to a temporary file 34 | input_file.seek(0) 35 | while True: 36 | data = input_file.read(2<<16) 37 | if not data: 38 | break 39 | output_file.write(data) 40 | 41 | # If your data is really critical you may want to force it to disk first 42 | # using output_file.flush(); os.fsync(output_file.fileno()) 43 | 44 | output_file.close() 45 | 46 | # Now that we know the file has been fully saved to disk move it into place. 47 | 48 | os.rename(temp_file_path, file_path) 49 | def write_some_data(file_path, input_data): 50 | temp_file_path = file_path + '~' 51 | output_file = open(temp_file_path, 'wb') 52 | 53 | # Finally write the data to a temporary file 54 | output_file.write(input_data) 55 | 56 | # If your data is really critical you may want to force it to disk first 57 | # using output_file.flush(); os.fsync(output_file.fileno()) 58 | 59 | output_file.close() 60 | 61 | # Now that we know the file has been fully saved to disk move it into place. 62 | 63 | os.rename(temp_file_path, file_path) 64 | 65 | @view_config(route_name='home', renderer='templates/mytemplate.pt') 66 | def my_view(request): 67 | return {'project': 'kees'} 68 | 69 | 70 | #@view_config(route_name='home', renderer='json') 71 | #def my_view(request): 72 | # return {"text":"hello"} 73 | 74 | @view_config(route_name='new_user', renderer='json') 75 | def new_user(request): 76 | i = request.POST 77 | username = i['username'] 78 | print username 79 | password = i['password'] 80 | return dblayer.new_user(username,password) 81 | @view_config(route_name='login', renderer='json') 82 | def login(request): 83 | i = request.POST 84 | username = i['username'] 85 | password = i['password'] 86 | return dblayer.login(username,password) 87 | 88 | @view_config(route_name='query_levels', renderer='json') 89 | def query_levels(request): 90 | i = request.POST 91 | sortKey = str(i['sortKey']) 92 | cursor = int(i['cursor']) 93 | limit = int(i['limit']) 94 | levels = dblayer.query_levels(sortKey,cursor,limit) 95 | #return Response("OK") 96 | return levels 97 | 98 | @view_config(route_name='query_points', renderer='json') 99 | def query_points(request): 100 | print "points" 101 | i = request.POST 102 | sortKey = str(i['sortKey']) 103 | cursor = int(i['cursor']) 104 | limit = int(i['limit']) 105 | points = dblayer.query_points(sortKey,cursor,limit) 106 | print points 107 | return points 108 | 109 | @view_config(route_name='get_tags', renderer='json') 110 | def get_tags(request): 111 | print "TAGS" 112 | i = request.POST 113 | print i 114 | docid = i['id'] 115 | print "requesting: ", docid 116 | tags = dblayer.get_tags(docid) 117 | print tags 118 | return tags 119 | 120 | @view_config(route_name='get_point', renderer='json') 121 | def get_point(request): 122 | print "HELLO" 123 | i = request.POST 124 | print i 125 | docid = i['id'] 126 | dbid = 'points'#i['dbid'] 127 | print "docid=",docid 128 | point = dblayer.get_one(dbid, uid=docid) 129 | print point 130 | return point 131 | 132 | @view_config(route_name='get_level', renderer='json') 133 | def get_level(request): 134 | print "HELLO" 135 | i = request.POST 136 | print i 137 | docid = i['id'] 138 | dbid = 'pplevels'#i['dbid'] 139 | print "docid=",docid 140 | point = dblayer.get_one(dbid, uid=docid) 141 | print point 142 | return point 143 | 144 | @view_config(route_name='add_vote', renderer='json') 145 | def add_vote(request): 146 | i = request.POST 147 | print i 148 | dbid = str(i['dbid']) 149 | print dbid 150 | if dbid not in ['points', 'pplevels']: 151 | print "db not accepted" 152 | return {"status":"fail"} 153 | print "db accepted" 154 | session = str(i['session']) 155 | print "session=", session 156 | val = float(i['val']) 157 | print "val=", val 158 | docid = str(i['docid']) 159 | print "docid=", docid 160 | tag = i.get('tag', None) 161 | 162 | return dblayer.add_vote(session,val,docid,dbid,tag=tag) 163 | 164 | @view_config(route_name='add_point', renderer='json') 165 | def add_point(request): 166 | i = request.POST 167 | session = i['session'] 168 | print session 169 | name = i['name'] 170 | text = i['text'] 171 | return dblayer.add_point(session, name, text) 172 | 173 | @view_config(route_name='uploadLevel', renderer='json') 174 | def uploadLevel(request): 175 | i = request.POST 176 | session = i['session'].file.read() 177 | print session 178 | author = i['author'].file.read() 179 | name = i['name'].file.read() 180 | leveldata = i['leveldata'].file 181 | sshot = i['sshot'].file 182 | fullname = pythonicVarName(author+name) 183 | tags = i.get("tags_str").file.read() 184 | if dblayer.add_level(session, name, author, fullname, tags): 185 | 186 | 187 | namepath = "kees/pplevels/" + fullname 188 | write_a_file(namepath, leveldata) 189 | 190 | namepath = "kees/thumbs/" + fullname+".png" 191 | write_a_file(namepath, sshot) 192 | 193 | return {"result":"OK"} 194 | return {"result":"FAIL","dta":[session,author,name], "insessions":session in dblayer.sessions} 195 | #return Response("OK") 196 | 197 | 198 | 199 | @view_config(route_name='uploadCrash', renderer='json') 200 | def uploadCrash(request): 201 | i = request.POST 202 | print "POST uploading crash" 203 | 204 | now = str(datetime.datetime.now()) 205 | crashData = i['crashData'] 206 | 207 | namepath = "kees/crashs/" + now+"--" + str(i['version']) 208 | write_some_data(namepath, crashData) 209 | 210 | return {"result":"OK"} 211 | 212 | @view_config(route_name='crashLogs', renderer='json') 213 | def crashLogs(request): 214 | files = os.listdir('kees/crashs') 215 | #result = "".join(''+f+'
' for f in files) 216 | result = "".join(''+f+'
' for f in files) 217 | return Response(body=result,headerlist=[('Content-Type', 'text/html')]) 218 | 219 | 220 | @view_config(route_name='store_mp3_view', renderer='json') 221 | def store_mp3_view(request): 222 | # ``filename`` contains the name of the file in string format. 223 | # 224 | # WARNING: this example does not deal with the fact that IE sends an 225 | # absolute file *path* as the filename. This example is naive; it 226 | # trusts user input. 227 | 228 | filename = request.POST['mp3'].filename 229 | 230 | # ``input_file`` contains the actual file data which needs to be 231 | # stored somewhere. 232 | 233 | input_file = request.POST['mp3'].file 234 | 235 | # Note that we are generating our own filename instead of trusting 236 | # the incoming filename since that might result in insecure paths. 237 | # Please note that in a real application you would not use /tmp, 238 | # and if you write to an untrusted location you will need to do 239 | # some extra work to prevent symlink attacks. 240 | 241 | file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4()) 242 | 243 | # We first write to a temporary file to prevent incomplete files from 244 | # being used. 245 | 246 | temp_file_path = file_path + '~' 247 | output_file = open(temp_file_path, 'wb') 248 | 249 | # Finally write the data to a temporary file 250 | input_file.seek(0) 251 | while True: 252 | data = input_file.read(2<<16) 253 | if not data: 254 | break 255 | output_file.write(data) 256 | 257 | # If your data is really critical you may want to force it to disk first 258 | # using output_file.flush(); os.fsync(output_file.fileno()) 259 | 260 | output_file.close() 261 | 262 | # Now that we know the file has been fully saved to disk move it into place. 263 | 264 | os.rename(temp_file_path, file_path) 265 | 266 | return Response('OK') -------------------------------------------------------------------------------- /kees/dblayer.py: -------------------------------------------------------------------------------- 1 | import datetime, time 2 | import dataset 3 | import uuid, hashlib 4 | 5 | #db = dataset.connect('sqlite:///:memory:') 6 | sessions = {} 7 | db = dataset.connect('sqlite:///mydatabase.db') 8 | '''database=db 9 | 10 | table = db['sometable'] 11 | table.insert(dict(name='John Doe', age=37)) 12 | table.insert(dict(name='Jane Doe', age=34, gender='female')) 13 | 14 | john = table.find_one(name='John Doe') 15 | 16 | print john 17 | ''' 18 | 19 | def add_vote(session, val, docid, dbid='pplevels', tag=None): 20 | sRef = getsession(session) 21 | if not sRef: 22 | return False 23 | print val, docid, dbid, tag 24 | levelstable = db[dbid] 25 | for l in levelstable: 26 | print l 27 | record = levelstable.find_one(uid=docid) 28 | print docid 29 | print record, record==None 30 | if record == None: 31 | return {'result':'fail', 'reason':'voteable item not found'} 32 | username = sRef['username'] 33 | 34 | istag = tag!=None 35 | 36 | votes_stable = db['votes'] 37 | # votes_meta_table = db['votes_meta'] 38 | # vote_meta = votes_meta_table.find_one(docid=docid) 39 | # if not vote_meta: 40 | # vote_meta = dict(docid=docid, votenum=1, rating=val, heat=1.) 41 | # else: 42 | if not istag: 43 | votenum=record['ratingCount'] 44 | rating=record['rating'] 45 | print "RATING working directly on record" 46 | else: 47 | print "TAG - working on meta" 48 | votes_group_table = db['vote_groups'] 49 | vote_group = votes_group_table.find_one(dbid=dbid, docid=docid, tag=tag) 50 | if not vote_group: 51 | vote_group = new_vote_group(docid=docid, dbid=dbid, tag=tag) 52 | votenum=vote_group['ratingCount'] 53 | rating=vote_group['rating'] 54 | print "Rating was, ", rating 55 | print username,docid 56 | vote = votes_stable.find_one(user=username, docid=docid) 57 | print "-------------" 58 | print "vote=",vote 59 | print "val=", val 60 | print "" 61 | if not vote: 62 | vp1=float(votenum+1.) 63 | print "vp1=",vp1 64 | rating=rating/vp1*votenum+val/(vp1) 65 | votenum=vp1 66 | print "new vote, rating now, ", rating 67 | else: 68 | oldval=vote['value'] 69 | print oldval, votenum 70 | if votenum<1: 71 | rating=val 72 | else: 73 | rating=rating-oldval/votenum+val/votenum 74 | print "re-vote, rating now, ", rating 75 | 76 | if not istag: 77 | vote_meta = dict(uid=docid, ratingCount=votenum, rating=rating) 78 | levelstable.update(vote_meta,['uid']) 79 | else: 80 | vote_group['ratingCount']=votenum 81 | vote_group['rating']=rating 82 | votes_group_table.upsert(vote_group, ['uid']) 83 | for v in votes_group_table: 84 | print v 85 | 86 | newVote = {"user":username, "value":val, "time":time.time(), "docid":docid} 87 | votes_stable.upsert(newVote,['user', 'docid']) 88 | print "xoxoxoxoxoxoxoxoxoxoxox" 89 | for v in votes_stable: 90 | print v 91 | return True 92 | 93 | def get_tags(docid): 94 | votes_group_table = db['vote_groups'] 95 | for v in votes_group_table: 96 | print v['docid'] 97 | rawtags = votes_group_table.find(docid=docid) 98 | tags = [x for x in rawtags] 99 | print "tags=", tags 100 | return tags 101 | 102 | def new_voteable(name, author): 103 | newLevel = {} 104 | newLevel['uid'] = uuid.uuid4().get_hex() 105 | newLevel['name'] = name 106 | newLevel['author'] = author 107 | nowStamp = time.time() 108 | newLevel['rating'] = .5 109 | newLevel['ratingCount'] = 0 110 | newLevel['dateAdded'] = nowStamp 111 | newLevel['dateModified'] = nowStamp 112 | return newLevel 113 | 114 | def new_vote_group(docid, dbid, tag): 115 | newLevel = {} 116 | newLevel['uid'] = uuid.uuid4().get_hex() 117 | newLevel['docid'] = docid 118 | newLevel['dbid'] = dbid 119 | newLevel['tag'] = tag 120 | nowStamp = time.time() 121 | newLevel['rating'] = .5 122 | newLevel['ratingCount'] = 0 123 | newLevel['dateAdded'] = nowStamp 124 | newLevel['dateModified'] = nowStamp 125 | return newLevel 126 | 127 | def add_level(session, name, author, fullname, tags_str=None, tags=[]): 128 | ses = getsession(session) 129 | if not ses: 130 | return False 131 | isNew = True 132 | levelstable = db['pplevels'] 133 | record = levelstable.find_one(filename=fullname) 134 | print record, record==None 135 | if record != None: 136 | isNew = False 137 | print "not new" 138 | else: 139 | print "new" 140 | if (isNew): 141 | record = new_voteable(name,author) 142 | record['filename'] = fullname 143 | record['downloads'] = 0 144 | else: 145 | nowStamp = time.time() 146 | record['dateModified'] = nowStamp 147 | record['description'] = "description" 148 | #db.ppLevels[fullname] = newLevel 149 | levelstable.upsert(record,['filename']) 150 | print "tags_str:", tags_str 151 | if tags_str: 152 | tags = tags_str.split() 153 | print "tags:", tags 154 | if tags: 155 | for t in tags: 156 | print "adding tag:", t 157 | add_vote(session, 1, record['uid'], 'pplevels', tag=t) 158 | return True 159 | 160 | def add_point(session, name, text): 161 | ses = getsession(session) 162 | if not ses: 163 | return False 164 | author = ses['username'] 165 | isNew = True 166 | levelstable = db['points'] 167 | #record = levelstable.find_one(filename=fullname) 168 | record = new_voteable(name,author) 169 | #record['filename'] = fullname 170 | #record['downloads'] = 0 171 | record['text'] = text 172 | #db.ppLevels[fullname] = newLevel 173 | levelstable.insert(record) 174 | return record 175 | def query_levels(sortKey, cursor=0, limit=8, **_filter): 176 | levelstable = db['pplevels'] 177 | print limit, cursor, sortKey 178 | a= levelstable.find(_limit=limit, _offset=cursor, order_by=sortKey, **_filter) 179 | return [x for x in a] 180 | def query_points(sortKey, cursor=0, limit=8, **_filter): 181 | levelstable = db['points'] 182 | print limit, cursor, sortKey 183 | a= levelstable.find(_limit=limit, _offset=cursor, order_by=sortKey, **_filter) 184 | return [x for x in a] 185 | def get_one(dbid, **_filter): 186 | print "get_one" 187 | print dbid 188 | levelstable = db[dbid] 189 | print levelstable 190 | a= levelstable.find_one(**_filter) 191 | print a 192 | return a 193 | 194 | def getsession(session): 195 | if sessions.has_key(session) == False: 196 | return False 197 | sRef = sessions[session] 198 | sRef['lastTouch'] = time.time() 199 | return sRef 200 | 201 | def newSession(username, userRef): 202 | timeNow = time.time() 203 | session = {} 204 | session['_id'] = uuid.uuid4().get_hex() 205 | session['startTime'] = timeNow 206 | session['lastTouch'] = timeNow 207 | session['info'] = {} 208 | sessions[session['_id']] = session 209 | session['username'] = username 210 | # TODO CHECK FOR TIMED OUT SESSIONS elsewhere 211 | checkTimedOutSessions() 212 | return session 213 | 214 | def checkTimedOutSessions(): 215 | texpire = time.time()-1000*60*60#*24*7 216 | remsessions = [] 217 | for sid in sessions: 218 | sRef = sessions[sid] 219 | if sRef['lastTouch'] < texpire: 220 | remsessions.append(sid) 221 | #sessions.pop(sid) 222 | for s in remsessions: 223 | sessions.pop(s) 224 | 225 | def login(username, password): 226 | username = username.replace(".","") 227 | usertable = db['users'] 228 | eUser = usertable.find_one(username=username) 229 | if(eUser): 230 | # makeImage(username) 231 | if hashlib.sha512(password + eUser['salt']).hexdigest() == eUser['password']: 232 | session = newSession(username, eUser) 233 | eUser['lastTouch'] = time.time() 234 | usertable.update(eUser,['username']) 235 | returnInfo = {"result":"OK", "session":session['_id'], "message":"logged in", "username":username, "_id":username, "noteCount":eUser['noteCount']} 236 | print returnInfo 237 | return returnInfo 238 | wrongpass = {"result":"fail", "message":"incorrect password"} 239 | print wrongpass 240 | return wrongpass 241 | wrongUser = {"result":"fail", "message":"user not found"} 242 | print wrongUser 243 | return wrongUser 244 | 245 | def new_user(username, password): 246 | username = username.replace(".","") 247 | usertable = db['users'] 248 | #eUser = database.users.find_one({"_id":username}) 249 | eUser = usertable.find_one(username=username) 250 | print eUser 251 | if(eUser): 252 | print "dupe account creation attempt on name: " + username 253 | return login(username, password) 254 | return {"result":"fail", "message":"name taken"} 255 | newUser = {} 256 | newUser['createdAt'] = time.time() 257 | newUser['lastTouch'] = time.time() 258 | salt = newUser['salt'] = uuid.uuid4().get_hex() 259 | #newUser['_id'] = username 260 | #makeImage(username) 261 | newUser['username'] = username 262 | newUser['noteCount'] = 0 263 | #newUser['groups'] = [] 264 | newUser['password'] = hashlib.sha512(password + salt).hexdigest() 265 | usertable.insert(newUser) 266 | #database.users.insert(newUser) 267 | print {"result":"OK", "message":"account " + username + " created"} -------------------------------------------------------------------------------- /kees/static/listlevels.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KivEnt Server 4 | 5 | 6 | 7 |

KivEntEd Levels

8 |
9 | Sort by: 10 | 19 | 20 | Per Page: 21 | Start at page: 22 | 23 | 24 | Reverse sort
25 |
26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /kees/static/zepto.min.js: -------------------------------------------------------------------------------- 1 | /* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */ 2 | (function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Array.prototype.reduce===a&&(Array.prototype.reduce=function(b){if(this===void 0||this===null)throw new TypeError;var c=Object(this),d=c.length>>>0,e=0,f;if(typeof b!="function")throw new TypeError;if(d==0&&arguments.length==1)throw new TypeError;if(arguments.length>=2)f=arguments[1];else do{if(e in c){f=c[e++];break}if(++e>=d)throw new TypeError}while(!0);while(e0?c.fn.concat.apply([],a):a}function O(a){return a.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function P(a){return a in j?j[a]:j[a]=new RegExp("(^|\\s)"+a+"(\\s|$)")}function Q(a,b){return typeof b=="number"&&!l[O(a)]?b+"px":b}function R(a){var b,c;return i[a]||(b=h.createElement(a),h.body.appendChild(b),c=k(b,"").getPropertyValue("display"),b.parentNode.removeChild(b),c=="none"&&(c="block"),i[a]=c),i[a]}function S(a){return"children"in a?f.call(a.children):c.map(a.childNodes,function(a){if(a.nodeType==1)return a})}function T(c,d,e){for(b in d)e&&(J(d[b])||K(d[b]))?(J(d[b])&&!J(c[b])&&(c[b]={}),K(d[b])&&!K(c[b])&&(c[b]=[]),T(c[b],d[b],e)):d[b]!==a&&(c[b]=d[b])}function U(b,d){return d===a?c(b):c(b).filter(d)}function V(a,b,c,d){return F(b)?b.call(a,c,d):b}function W(a,b,c){c==null?a.removeAttribute(b):a.setAttribute(b,c)}function X(b,c){var d=b.className,e=d&&d.baseVal!==a;if(c===a)return e?d.baseVal:d;e?d.baseVal=c:b.className=c}function Y(a){var b;try{return a?a=="true"||(a=="false"?!1:a=="null"?null:isNaN(b=Number(a))?/^[\[\{]/.test(a)?c.parseJSON(a):a:b):a}catch(d){return a}}function Z(a,b){b(a);for(var c in a.childNodes)Z(a.childNodes[c],b)}var a,b,c,d,e=[],f=e.slice,g=e.filter,h=window.document,i={},j={},k=h.defaultView.getComputedStyle,l={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},m=/^\s*<(\w+|!)[^>]*>/,n=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,o=/^(?:body|html)$/i,p=["val","css","html","text","data","width","height","offset"],q=["after","prepend","before","append"],r=h.createElement("table"),s=h.createElement("tr"),t={tr:h.createElement("tbody"),tbody:r,thead:r,tfoot:r,td:s,th:s,"*":h.createElement("div")},u=/complete|loaded|interactive/,v=/^\.([\w-]+)$/,w=/^#([\w-]*)$/,x=/^[\w-]+$/,y={},z=y.toString,A={},B,C,D=h.createElement("div");return A.matches=function(a,b){if(!a||a.nodeType!==1)return!1;var c=a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.matchesSelector;if(c)return c.call(a,b);var d,e=a.parentNode,f=!e;return f&&(e=D).appendChild(a),d=~A.qsa(e,b).indexOf(a),f&&D.removeChild(a),d},B=function(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})},C=function(a){return g.call(a,function(b,c){return a.indexOf(b)==c})},A.fragment=function(b,d,e){b.replace&&(b=b.replace(n,"<$1>")),d===a&&(d=m.test(b)&&RegExp.$1),d in t||(d="*");var g,h,i=t[d];return i.innerHTML=""+b,h=c.each(f.call(i.childNodes),function(){i.removeChild(this)}),J(e)&&(g=c(h),c.each(e,function(a,b){p.indexOf(a)>-1?g[a](b):g.attr(a,b)})),h},A.Z=function(a,b){return a=a||[],a.__proto__=c.fn,a.selector=b||"",a},A.isZ=function(a){return a instanceof A.Z},A.init=function(b,d){if(!b)return A.Z();if(F(b))return c(h).ready(b);if(A.isZ(b))return b;var e;if(K(b))e=M(b);else if(I(b))e=[J(b)?c.extend({},b):b],b=null;else if(m.test(b))e=A.fragment(b.trim(),RegExp.$1,d),b=null;else{if(d!==a)return c(d).find(b);e=A.qsa(h,b)}return A.Z(e,b)},c=function(a,b){return A.init(a,b)},c.extend=function(a){var b,c=f.call(arguments,1);return typeof a=="boolean"&&(b=a,a=c.shift()),c.forEach(function(c){T(a,c,b)}),a},A.qsa=function(a,b){var c;return H(a)&&w.test(b)?(c=a.getElementById(RegExp.$1))?[c]:[]:a.nodeType!==1&&a.nodeType!==9?[]:f.call(v.test(b)?a.getElementsByClassName(RegExp.$1):x.test(b)?a.getElementsByTagName(b):a.querySelectorAll(b))},c.contains=function(a,b){return a!==b&&a.contains(b)},c.type=E,c.isFunction=F,c.isWindow=G,c.isArray=K,c.isPlainObject=J,c.isEmptyObject=function(a){var b;for(b in a)return!1;return!0},c.inArray=function(a,b,c){return e.indexOf.call(b,a,c)},c.camelCase=B,c.trim=function(a){return a.trim()},c.uuid=0,c.support={},c.expr={},c.map=function(a,b){var c,d=[],e,f;if(L(a))for(e=0;e=0?b:b+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){this.parentNode!=null&&this.parentNode.removeChild(this)})},each:function(a){return e.every.call(this,function(b,c){return a.call(b,c,b)!==!1}),this},filter:function(a){return F(a)?this.not(this.not(a)):c(g.call(this,function(b){return A.matches(b,a)}))},add:function(a,b){return c(C(this.concat(c(a,b))))},is:function(a){return this.length>0&&A.matches(this[0],a)},not:function(b){var d=[];if(F(b)&&b.call!==a)this.each(function(a){b.call(this,a)||d.push(this)});else{var e=typeof b=="string"?this.filter(b):L(b)&&F(b.item)?f.call(b):c(b);this.forEach(function(a){e.indexOf(a)<0&&d.push(a)})}return c(d)},has:function(a){return this.filter(function(){return I(a)?c.contains(this,a):c(this).find(a).size()})},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){var a=this[0];return a&&!I(a)?a:c(a)},last:function(){var a=this[this.length-1];return a&&!I(a)?a:c(a)},find:function(a){var b,d=this;return typeof a=="object"?b=c(a).filter(function(){var a=this;return e.some.call(d,function(b){return c.contains(b,a)})}):this.length==1?b=c(A.qsa(this[0],a)):b=this.map(function(){return A.qsa(this,a)}),b},closest:function(a,b){var d=this[0],e=!1;typeof a=="object"&&(e=c(a));while(d&&!(e?e.indexOf(d)>=0:A.matches(d,a)))d=d!==b&&!H(d)&&d.parentNode;return c(d)},parents:function(a){var b=[],d=this;while(d.length>0)d=c.map(d,function(a){if((a=a.parentNode)&&!H(a)&&b.indexOf(a)<0)return b.push(a),a});return U(b,a)},parent:function(a){return U(C(this.pluck("parentNode")),a)},children:function(a){return U(this.map(function(){return S(this)}),a)},contents:function(){return this.map(function(){return f.call(this.childNodes)})},siblings:function(a){return U(this.map(function(a,b){return g.call(S(b.parentNode),function(a){return a!==b})}),a)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(a){return c.map(this,function(b){return b[a]})},show:function(){return this.each(function(){this.style.display=="none"&&(this.style.display=null),k(this,"").getPropertyValue("display")=="none"&&(this.style.display=R(this.nodeName))})},replaceWith:function(a){return this.before(a).remove()},wrap:function(a){var b=F(a);if(this[0]&&!b)var d=c(a).get(0),e=d.parentNode||this.length>1;return this.each(function(f){c(this).wrapAll(b?a.call(this,f):e?d.cloneNode(!0):d)})},wrapAll:function(a){if(this[0]){c(this[0]).before(a=c(a));var b;while((b=a.children()).length)a=b.first();c(a).append(this)}return this},wrapInner:function(a){var b=F(a);return this.each(function(d){var e=c(this),f=e.contents(),g=b?a.call(this,d):a;f.length?f.wrapAll(g):e.append(g)})},unwrap:function(){return this.parent().each(function(){c(this).replaceWith(c(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(b){return this.each(function(){var d=c(this);(b===a?d.css("display")=="none":b)?d.show():d.hide()})},prev:function(a){return c(this.pluck("previousElementSibling")).filter(a||"*")},next:function(a){return c(this.pluck("nextElementSibling")).filter(a||"*")},html:function(b){return b===a?this.length>0?this[0].innerHTML:null:this.each(function(a){var d=this.innerHTML;c(this).empty().append(V(this,b,a,d))})},text:function(b){return b===a?this.length>0?this[0].textContent:null:this.each(function(){this.textContent=b})},attr:function(c,d){var e;return typeof c=="string"&&d===a?this.length==0||this[0].nodeType!==1?a:c=="value"&&this[0].nodeName=="INPUT"?this.val():!(e=this[0].getAttribute(c))&&c in this[0]?this[0][c]:e:this.each(function(a){if(this.nodeType!==1)return;if(I(c))for(b in c)W(this,b,c[b]);else W(this,c,V(this,d,a,this.getAttribute(c)))})},removeAttr:function(a){return this.each(function(){this.nodeType===1&&W(this,a)})},prop:function(b,c){return c===a?this[0]&&this[0][b]:this.each(function(a){this[b]=V(this,c,a,this[b])})},data:function(b,c){var d=this.attr("data-"+O(b),c);return d!==null?Y(d):a},val:function(b){return b===a?this[0]&&(this[0].multiple?c(this[0]).find("option").filter(function(a){return this.selected}).pluck("value"):this[0].value):this.each(function(a){this.value=V(this,b,a,this.value)})},offset:function(a){if(a)return this.each(function(b){var d=c(this),e=V(this,a,b,d.offset()),f=d.offsetParent().offset(),g={top:e.top-f.top,left:e.left-f.left};d.css("position")=="static"&&(g.position="relative"),d.css(g)});if(this.length==0)return null;var b=this[0].getBoundingClientRect();return{left:b.left+window.pageXOffset,top:b.top+window.pageYOffset,width:Math.round(b.width),height:Math.round(b.height)}},css:function(a,c){if(arguments.length<2&&typeof a=="string")return this[0]&&(this[0].style[B(a)]||k(this[0],"").getPropertyValue(a));var d="";if(E(a)=="string")!c&&c!==0?this.each(function(){this.style.removeProperty(O(a))}):d=O(a)+":"+Q(a,c);else for(b in a)!a[b]&&a[b]!==0?this.each(function(){this.style.removeProperty(O(b))}):d+=O(b)+":"+Q(b,a[b])+";";return this.each(function(){this.style.cssText+=";"+d})},index:function(a){return a?this.indexOf(c(a)[0]):this.parent().children().indexOf(this[0])},hasClass:function(a){return e.some.call(this,function(a){return this.test(X(a))},P(a))},addClass:function(a){return this.each(function(b){d=[];var e=X(this),f=V(this,a,b,e);f.split(/\s+/g).forEach(function(a){c(this).hasClass(a)||d.push(a)},this),d.length&&X(this,e+(e?" ":"")+d.join(" "))})},removeClass:function(b){return this.each(function(c){if(b===a)return X(this,"");d=X(this),V(this,b,c,d).split(/\s+/g).forEach(function(a){d=d.replace(P(a)," ")}),X(this,d.trim())})},toggleClass:function(b,d){return this.each(function(e){var f=c(this),g=V(this,b,e,X(this));g.split(/\s+/g).forEach(function(b){(d===a?!f.hasClass(b):d)?f.addClass(b):f.removeClass(b)})})},scrollTop:function(){if(!this.length)return;return"scrollTop"in this[0]?this[0].scrollTop:this[0].scrollY},position:function(){if(!this.length)return;var a=this[0],b=this.offsetParent(),d=this.offset(),e=o.test(b[0].nodeName)?{top:0,left:0}:b.offset();return d.top-=parseFloat(c(a).css("margin-top"))||0,d.left-=parseFloat(c(a).css("margin-left"))||0,e.top+=parseFloat(c(b[0]).css("border-top-width"))||0,e.left+=parseFloat(c(b[0]).css("border-left-width"))||0,{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||h.body;while(a&&!o.test(a.nodeName)&&c(a).css("position")=="static")a=a.offsetParent;return a})}},c.fn.detach=c.fn.remove,["width","height"].forEach(function(b){c.fn[b]=function(d){var e,f=this[0],g=b.replace(/./,function(a){return a[0].toUpperCase()});return d===a?G(f)?f["inner"+g]:H(f)?f.documentElement["offset"+g]:(e=this.offset())&&e[b]:this.each(function(a){f=c(this),f.css(b,V(this,d,a,f[b]()))})}}),q.forEach(function(a,b){var d=b%2;c.fn[a]=function(){var a,e=c.map(arguments,function(b){return a=E(b),a=="object"||a=="array"||b==null?b:A.fragment(b)}),f,g=this.length>1;return e.length<1?this:this.each(function(a,h){f=d?h:h.parentNode,h=b==0?h.nextSibling:b==1?h.firstChild:b==2?h:null,e.forEach(function(a){if(g)a=a.cloneNode(!0);else if(!f)return c(a).remove();Z(f.insertBefore(a,h),function(a){a.nodeName!=null&&a.nodeName.toUpperCase()==="SCRIPT"&&(!a.type||a.type==="text/javascript")&&!a.src&&window.eval.call(window,a.innerHTML)})})})},c.fn[d?a+"To":"insert"+(b?"Before":"After")]=function(b){return c(b)[a](this),this}}),A.Z.prototype=c.fn,A.uniq=C,A.deserializeValue=Y,c.zepto=A,c}();window.Zepto=Zepto,"$"in window||(window.$=Zepto),function(a){function b(a){var b=this.os={},c=this.browser={},d=a.match(/WebKit\/([\d.]+)/),e=a.match(/(Android)\s+([\d.]+)/),f=a.match(/(iPad).*OS\s([\d_]+)/),g=!f&&a.match(/(iPhone\sOS)\s([\d_]+)/),h=a.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),i=h&&a.match(/TouchPad/),j=a.match(/Kindle\/([\d.]+)/),k=a.match(/Silk\/([\d._]+)/),l=a.match(/(BlackBerry).*Version\/([\d.]+)/),m=a.match(/(BB10).*Version\/([\d.]+)/),n=a.match(/(RIM\sTablet\sOS)\s([\d.]+)/),o=a.match(/PlayBook/),p=a.match(/Chrome\/([\d.]+)/)||a.match(/CriOS\/([\d.]+)/),q=a.match(/Firefox\/([\d.]+)/);if(c.webkit=!!d)c.version=d[1];e&&(b.android=!0,b.version=e[2]),g&&(b.ios=b.iphone=!0,b.version=g[2].replace(/_/g,".")),f&&(b.ios=b.ipad=!0,b.version=f[2].replace(/_/g,".")),h&&(b.webos=!0,b.version=h[2]),i&&(b.touchpad=!0),l&&(b.blackberry=!0,b.version=l[2]),m&&(b.bb10=!0,b.version=m[2]),n&&(b.rimtabletos=!0,b.version=n[2]),o&&(c.playbook=!0),j&&(b.kindle=!0,b.version=j[1]),k&&(c.silk=!0,c.version=k[1]),!k&&b.android&&a.match(/Kindle Fire/)&&(c.silk=!0),p&&(c.chrome=!0,c.version=p[1]),q&&(c.firefox=!0,c.version=q[1]),b.tablet=!!(f||o||e&&!a.match(/Mobile/)||q&&a.match(/Tablet/)),b.phone=!b.tablet&&!!(e||g||h||l||m||p&&a.match(/Android/)||p&&a.match(/CriOS\/([\d.]+)/)||q&&a.match(/Mobile/))}b.call(a,navigator.userAgent),a.__detect=b}(Zepto),function(a){function g(a){return a._zid||(a._zid=d++)}function h(a,b,d,e){b=i(b);if(b.ns)var f=j(b.ns);return(c[g(a)]||[]).filter(function(a){return a&&(!b.e||a.e==b.e)&&(!b.ns||f.test(a.ns))&&(!d||g(a.fn)===g(d))&&(!e||a.sel==e)})}function i(a){var b=(""+a).split(".");return{e:b[0],ns:b.slice(1).sort().join(" ")}}function j(a){return new RegExp("(?:^| )"+a.replace(" "," .* ?")+"(?: |$)")}function k(b,c,d){a.type(b)!="string"?a.each(b,d):b.split(/\s/).forEach(function(a){d(a,c)})}function l(a,b){return a.del&&(a.e=="focus"||a.e=="blur")||!!b}function m(a){return f[a]||a}function n(b,d,e,h,j,n){var o=g(b),p=c[o]||(c[o]=[]);k(d,e,function(c,d){var e=i(c);e.fn=d,e.sel=h,e.e in f&&(d=function(b){var c=b.relatedTarget;if(!c||c!==this&&!a.contains(this,c))return e.fn.apply(this,arguments)}),e.del=j&&j(d,c);var g=e.del||d;e.proxy=function(a){var c=g.apply(b,[a].concat(a.data));return c===!1&&(a.preventDefault(),a.stopPropagation()),c},e.i=p.length,p.push(e),b.addEventListener(m(e.e),e.proxy,l(e,n))})}function o(a,b,d,e,f){var i=g(a);k(b||"",d,function(b,d){h(a,b,d,e).forEach(function(b){delete c[i][b.i],a.removeEventListener(m(b.e),b.proxy,l(b,f))})})}function t(b){var c,d={originalEvent:b};for(c in b)!r.test(c)&&b[c]!==undefined&&(d[c]=b[c]);return a.each(s,function(a,c){d[a]=function(){return this[c]=p,b[a].apply(b,arguments)},d[c]=q}),d}function u(a){if(!("defaultPrevented"in a)){a.defaultPrevented=!1;var b=a.preventDefault;a.preventDefault=function(){this.defaultPrevented=!0,b.call(this)}}}var b=a.zepto.qsa,c={},d=1,e={},f={mouseenter:"mouseover",mouseleave:"mouseout"};e.click=e.mousedown=e.mouseup=e.mousemove="MouseEvents",a.event={add:n,remove:o},a.proxy=function(b,c){if(a.isFunction(b)){var d=function(){return b.apply(c,arguments)};return d._zid=g(b),d}if(typeof c=="string")return a.proxy(b[c],b);throw new TypeError("expected function")},a.fn.bind=function(a,b){return this.each(function(){n(this,a,b)})},a.fn.unbind=function(a,b){return this.each(function(){o(this,a,b)})},a.fn.one=function(a,b){return this.each(function(c,d){n(this,a,b,null,function(a,b){return function(){var c=a.apply(d,arguments);return o(d,b,a),c}})})};var p=function(){return!0},q=function(){return!1},r=/^([A-Z]|layer[XY]$)/,s={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};a.fn.delegate=function(b,c,d){return this.each(function(e,f){n(f,c,d,b,function(c){return function(d){var e,g=a(d.target).closest(b,f).get(0);if(g)return e=a.extend(t(d),{currentTarget:g,liveFired:f}),c.apply(g,[e].concat([].slice.call(arguments,1)))}})})},a.fn.undelegate=function(a,b,c){return this.each(function(){o(this,b,c,a)})},a.fn.live=function(b,c){return a(document.body).delegate(this.selector,b,c),this},a.fn.die=function(b,c){return a(document.body).undelegate(this.selector,b,c),this},a.fn.on=function(b,c,d){return!c||a.isFunction(c)?this.bind(b,c||d):this.delegate(c,b,d)},a.fn.off=function(b,c,d){return!c||a.isFunction(c)?this.unbind(b,c||d):this.undelegate(c,b,d)},a.fn.trigger=function(b,c){if(typeof b=="string"||a.isPlainObject(b))b=a.Event(b);return u(b),b.data=c,this.each(function(){"dispatchEvent"in this&&this.dispatchEvent(b)})},a.fn.triggerHandler=function(b,c){var d,e;return this.each(function(f,g){d=t(typeof b=="string"?a.Event(b):b),d.data=c,d.target=g,a.each(h(g,b.type||b),function(a,b){e=b.proxy(d);if(d.isImmediatePropagationStopped())return!1})}),e},"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(b){a.fn[b]=function(a){return a?this.bind(b,a):this.trigger(b)}}),["focus","blur"].forEach(function(b){a.fn[b]=function(a){return a?this.bind(b,a):this.each(function(){try{this[b]()}catch(a){}}),this}}),a.Event=function(a,b){typeof a!="string"&&(b=a,a=b.type);var c=document.createEvent(e[a]||"Events"),d=!0;if(b)for(var f in b)f=="bubbles"?d=!!b[f]:c[f]=b[f];return c.initEvent(a,d,!0,null,null,null,null,null,null,null,null,null,null,null,null),c.isDefaultPrevented=function(){return this.defaultPrevented},c}}(Zepto),function($){function triggerAndReturn(a,b,c){var d=$.Event(b);return $(a).trigger(d,c),!d.defaultPrevented}function triggerGlobal(a,b,c,d){if(a.global)return triggerAndReturn(b||document,c,d)}function ajaxStart(a){a.global&&$.active++===0&&triggerGlobal(a,null,"ajaxStart")}function ajaxStop(a){a.global&&!--$.active&&triggerGlobal(a,null,"ajaxStop")}function ajaxBeforeSend(a,b){var c=b.context;if(b.beforeSend.call(c,a,b)===!1||triggerGlobal(b,c,"ajaxBeforeSend",[a,b])===!1)return!1;triggerGlobal(b,c,"ajaxSend",[a,b])}function ajaxSuccess(a,b,c){var d=c.context,e="success";c.success.call(d,a,e,b),triggerGlobal(c,d,"ajaxSuccess",[b,c,a]),ajaxComplete(e,b,c)}function ajaxError(a,b,c,d){var e=d.context;d.error.call(e,c,b,a),triggerGlobal(d,e,"ajaxError",[c,d,a]),ajaxComplete(b,c,d)}function ajaxComplete(a,b,c){var d=c.context;c.complete.call(d,b,a),triggerGlobal(c,d,"ajaxComplete",[b,c]),ajaxStop(c)}function empty(){}function mimeToDataType(a){return a&&(a=a.split(";",2)[0]),a&&(a==htmlType?"html":a==jsonType?"json":scriptTypeRE.test(a)?"script":xmlTypeRE.test(a)&&"xml")||"text"}function appendQuery(a,b){return(a+"&"+b).replace(/[&?]{1,2}/,"?")}function serializeData(a){a.processData&&a.data&&$.type(a.data)!="string"&&(a.data=$.param(a.data,a.traditional)),a.data&&(!a.type||a.type.toUpperCase()=="GET")&&(a.url=appendQuery(a.url,a.data))}function parseArguments(a,b,c,d){var e=!$.isFunction(b);return{url:a,data:e?b:undefined,success:e?$.isFunction(c)?c:undefined:b,dataType:e?d||c:c}}function serialize(a,b,c,d){var e,f=$.isArray(b);$.each(b,function(b,g){e=$.type(g),d&&(b=c?d:d+"["+(f?"":b)+"]"),!d&&f?a.add(g.name,g.value):e=="array"||!c&&e=="object"?serialize(a,g,c,b):a.add(b,g)})}var jsonpID=0,document=window.document,key,name,rscript=/)<[^<]*)*<\/script>/gi,scriptTypeRE=/^(?:text|application)\/javascript/i,xmlTypeRE=/^(?:text|application)\/xml/i,jsonType="application/json",htmlType="text/html",blankRE=/^\s*$/;$.active=0,$.ajaxJSONP=function(a){if("type"in a){var b="jsonp"+ ++jsonpID,c=document.createElement("script"),d=function(){clearTimeout(g),$(c).remove(),delete window[b]},e=function(c){d();if(!c||c=="timeout")window[b]=empty;ajaxError(null,c||"abort",f,a)},f={abort:e},g;return ajaxBeforeSend(f,a)===!1?(e("abort"),!1):(window[b]=function(b){d(),ajaxSuccess(b,f,a)},c.onerror=function(){e("error")},c.src=a.url.replace(/=\?/,"="+b),$("head").append(c),a.timeout>0&&(g=setTimeout(function(){e("timeout")},a.timeout)),f)}return $.ajax(a)},$.ajaxSettings={type:"GET",beforeSend:empty,success:empty,error:empty,complete:empty,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript",json:jsonType,xml:"application/xml, text/xml",html:htmlType,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},$.ajax=function(options){var settings=$.extend({},options||{});for(key in $.ajaxSettings)settings[key]===undefined&&(settings[key]=$.ajaxSettings[key]);ajaxStart(settings),settings.crossDomain||(settings.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(settings.url)&&RegExp.$2!=window.location.host),settings.url||(settings.url=window.location.toString()),serializeData(settings),settings.cache===!1&&(settings.url=appendQuery(settings.url,"_="+Date.now()));var dataType=settings.dataType,hasPlaceholder=/=\?/.test(settings.url);if(dataType=="jsonp"||hasPlaceholder)return hasPlaceholder||(settings.url=appendQuery(settings.url,"callback=?")),$.ajaxJSONP(settings);var mime=settings.accepts[dataType],baseHeaders={},protocol=/^([\w-]+:)\/\//.test(settings.url)?RegExp.$1:window.location.protocol,xhr=settings.xhr(),abortTimeout;settings.crossDomain||(baseHeaders["X-Requested-With"]="XMLHttpRequest"),mime&&(baseHeaders.Accept=mime,mime.indexOf(",")>-1&&(mime=mime.split(",",2)[0]),xhr.overrideMimeType&&xhr.overrideMimeType(mime));if(settings.contentType||settings.contentType!==!1&&settings.data&&settings.type.toUpperCase()!="GET")baseHeaders["Content-Type"]=settings.contentType||"application/x-www-form-urlencoded";settings.headers=$.extend(baseHeaders,settings.headers||{}),xhr.onreadystatechange=function(){if(xhr.readyState==4){xhr.onreadystatechange=empty,clearTimeout(abortTimeout);var result,error=!1;if(xhr.status>=200&&xhr.status<300||xhr.status==304||xhr.status==0&&protocol=="file:"){dataType=dataType||mimeToDataType(xhr.getResponseHeader("content-type")),result=xhr.responseText;try{dataType=="script"?(1,eval)(result):dataType=="xml"?result=xhr.responseXML:dataType=="json"&&(result=blankRE.test(result)?null:$.parseJSON(result))}catch(e){error=e}error?ajaxError(error,"parsererror",xhr,settings):ajaxSuccess(result,xhr,settings)}else ajaxError(null,xhr.status?"error":"abort",xhr,settings)}};var async="async"in settings?settings.async:!0;xhr.open(settings.type,settings.url,async);for(name in settings.headers)xhr.setRequestHeader(name,settings.headers[name]);return ajaxBeforeSend(xhr,settings)===!1?(xhr.abort(),!1):(settings.timeout>0&&(abortTimeout=setTimeout(function(){xhr.onreadystatechange=empty,xhr.abort(),ajaxError(null,"timeout",xhr,settings)},settings.timeout)),xhr.send(settings.data?settings.data:null),xhr)},$.get=function(a,b,c,d){return $.ajax(parseArguments.apply(null,arguments))},$.post=function(a,b,c,d){var e=parseArguments.apply(null,arguments);return e.type="POST",$.ajax(e)},$.getJSON=function(a,b,c){var d=parseArguments.apply(null,arguments);return d.dataType="json",$.ajax(d)},$.fn.load=function(a,b,c){if(!this.length)return this;var d=this,e=a.split(/\s/),f,g=parseArguments(a,b,c),h=g.success;return e.length>1&&(g.url=e[0],f=e[1]),g.success=function(a){d.html(f?$("
").html(a.replace(rscript,"")).find(f):a),h&&h.apply(d,arguments)},$.ajax(g),this};var escape=encodeURIComponent;$.param=function(a,b){var c=[];return c.add=function(a,b){this.push(escape(a)+"="+escape(b))},serialize(c,a,b),c.join("&").replace(/%20/g,"+")}}(Zepto),function(a){a.fn.serializeArray=function(){var b=[],c;return a(Array.prototype.slice.call(this.get(0).elements)).each(function(){c=a(this);var d=c.attr("type");this.nodeName.toLowerCase()!="fieldset"&&!this.disabled&&d!="submit"&&d!="reset"&&d!="button"&&(d!="radio"&&d!="checkbox"||this.checked)&&b.push({name:c.attr("name"),value:c.val()})}),b},a.fn.serialize=function(){var a=[];return this.serializeArray().forEach(function(b){a.push(encodeURIComponent(b.name)+"="+encodeURIComponent(b.value))}),a.join("&")},a.fn.submit=function(b){if(b)this.bind("submit",b);else if(this.length){var c=a.Event("submit");this.eq(0).trigger(c),c.defaultPrevented||this.get(0).submit()}return this}}(Zepto),function(a,b){function s(a){return t(a.replace(/([a-z])([A-Z])/,"$1-$2"))}function t(a){return a.toLowerCase()}function u(a){return d?d+a:t(a)}var c="",d,e,f,g={Webkit:"webkit",Moz:"",O:"o",ms:"MS"},h=window.document,i=h.createElement("div"),j=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,k,l,m,n,o,p,q,r={};a.each(g,function(a,e){if(i.style[a+"TransitionProperty"]!==b)return c="-"+t(a)+"-",d=e,!1}),k=c+"transform",r[l=c+"transition-property"]=r[m=c+"transition-duration"]=r[n=c+"transition-timing-function"]=r[o=c+"animation-name"]=r[p=c+"animation-duration"]=r[q=c+"animation-timing-function"]="",a.fx={off:d===b&&i.style.transitionProperty===b,speeds:{_default:400,fast:200,slow:600},cssPrefix:c,transitionEnd:u("TransitionEnd"),animationEnd:u("AnimationEnd")},a.fn.animate=function(b,c,d,e){return a.isPlainObject(c)&&(d=c.easing,e=c.complete,c=c.duration),c&&(c=(typeof c=="number"?c:a.fx.speeds[c]||a.fx.speeds._default)/1e3),this.anim(b,c,d,e)},a.fn.anim=function(c,d,e,f){var g,h={},i,t="",u=this,v,w=a.fx.transitionEnd;d===b&&(d=.4),a.fx.off&&(d=0);if(typeof c=="string")h[o]=c,h[p]=d+"s",h[q]=e||"linear",w=a.fx.animationEnd;else{i=[];for(g in c)j.test(g)?t+=g+"("+c[g]+") ":(h[g]=c[g],i.push(s(g)));t&&(h[k]=t,i.push(k)),d>0&&typeof c=="object"&&(h[l]=i.join(", "),h[m]=d+"s",h[n]=e||"linear")}return v=function(b){if(typeof b!="undefined"){if(b.target!==b.currentTarget)return;a(b.target).unbind(w,v)}a(this).css(r),f&&f.call(this)},d>0&&this.bind(w,v),this.size()&&this.get(0).clientLeft,this.css(h),d<=0&&setTimeout(function(){u.each(function(){v.call(this)})},0),this},i=null}(Zepto) --------------------------------------------------------------------------------