1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/.hgignore Mon Apr 26 11:16:23 2010 +0200
1.3 @@ -0,0 +1,23 @@
1.4 +.backups
1.5 +build*
1.6 +configure-stamp
1.7 +debian/file
1.8 +debian/.*ex
1.9 +debian/tmp
1.10 +debian/isi
1.11 +debian/isi-checkup
1.12 +debian/isi-docs
1.13 +debian/python-isi
1.14 +docs/allegati/netkit
1.15 +docs/.build
1.16 +docs/img/icone
1.17 +etc/isi/checkup/exclude
1.18 +log
1.19 +usr/share/isi-checkup/tests/TODO
1.20 +lib/isi.egg-info.*
1.21 +lab/srv-isi.disk
1.22 +#web
1.23 +lab/.*isi
1.24 +web/local_settings.py
1.25 +.exlude_rsync_files
1.26 +sync_all
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/2dreamnet Mon Apr 26 11:16:23 2010 +0200
2.3 @@ -0,0 +1,18 @@
2.4 +#!/bin/bash
2.5 +
2.6 +#remote_srv='isibeta6 192.168.1.220'
2.7 +#remote_srv='192.168.5.151'
2.8 +#remote_srv='192.168.1.233 isibeta6' # test-isi-lenny
2.9 +remote_srv='192.168.1.218'
2.10 +
2.11 +path_locale='/home/dream/src/isi/isi-checkup/usr'
2.12 +path_remoto='/usr'
2.13 +
2.14 +for srv in $remote_srv; do
2.15 + echo "rsync -P -r $path_locale/* root@$srv:$path_remoto/"
2.16 + rsync -P -r $path_locale/* root@$srv:$path_remoto/
2.17 + echo "ssh root@$srv isi-checkup -t isi"
2.18 + ssh root@$srv isi-checkup -T
2.19 + #echo ssh root@$srv isi-checkup
2.20 +done
2.21 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Makefile Mon Apr 26 11:16:23 2010 +0200
3.3 @@ -0,0 +1,40 @@
3.4 +# $pkg
3.5 +.PHONY: all install clean
3.6 +PKG=$(shell echo $(shell pwd)| sed 's/.*\///')
3.7 +DEB=$(shell cat debian/files |cut -f 1 -d " ")
3.8 +
3.9 +all:
3.10 + echo "nessuna compilazione"
3.11 +
3.12 +deb:
3.13 + dpkg-buildpackage -rfakeroot -us -uc -b | tee log
3.14 + echo pkg=$(PKG) deb=$(DEB)
3.15 +# hg status
3.16 +
3.17 +content:
3.18 + dpkg -c ../$(DEB)
3.19 +
3.20 +lcheck:
3.21 + find -newer ../$(DEB)
3.22 +
3.23 +upload:
3.24 + upload
3.25 +
3.26 +lenny:
3.27 + upload-deb lenny/main $(DEB)
3.28 +
3.29 +lenny-force:
3.30 + upload-deb -F lenny/main $(DEB)
3.31 +
3.32 +dpkg:
3.33 + su root "dpkg -i ../$(DEB)"
3.34 +
3.35 +check: lcheck
3.36 + find -newer uploaded
3.37 +
3.38 +ver:
3.39 + head -n1 debian/changelog
3.40 + echo dch -v
3.41 +
3.42 +clean:
3.43 + echo
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/TODO Mon Apr 26 11:16:23 2010 +0200
4.3 @@ -0,0 +1,17 @@
4.4 +TODO (#### = fatto)
4.5 +1. Debian:
4.6 + Control
4.7 + ###Changelog
4.8 + README
4.9 + rules
4.10 +
4.11 +2. file di conf
4.12 + #### /etc/isi/*
4.13 + #### /etc/skel
4.14 + #### /etc/samba/smb.conf
4.15 + /etc/ldap/ldap.conf
4.16 + /etc/ldap/slapd.conf
4.17 + #### samba.schema corretto
4.18 + /etc/smbldap-tools/*
4.19 +
4.20 +3. ### Makefile (editare solo con jmacs)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/checkup/isi-checkup Mon Apr 26 11:16:23 2010 +0200
5.3 @@ -0,0 +1,556 @@
5.4 +#!/usr/bin/python
5.5 +# coding: utf-8
5.6 +"""
5.7 +### DocString
5.8 +Opzioni supportate
5.9 +-------------------
5.10 +
5.11 +Gestire i template
5.12 +~~~~~~~~~~~~~~~~~~
5.13 +
5.14 +isi-checkup -l
5.15 +
5.16 +* elenca i template disponibili
5.17 +
5.18 +isi-checkup -t NOMETEMPLATE
5.19 +
5.20 +* abilita tutti i test rel relativo template
5.21 +* imposta il template scelto come template di default, salvando la preferenza
5.22 + nel file "/etc/isi/checkup/template-default".
5.23 +
5.24 +isi-checkup -T
5.25 +
5.26 +* Disabilita tutti i test attivi
5.27 +* SE ESISTE "/etc/isi/checkup/template-default" abilita tutti i test del profilo
5.28 + impostato come default.
5.29 +* SE NON ESISTE "/etc/isi/checkup/template-default" e dunque non è mai stato
5.30 + impostato un profilo di default, abilita tutti i test del profilo "isi".
5.31 +
5.32 +isi-checkup -r
5.33 +
5.34 +* disattiva tutti i test abilitati
5.35 +
5.36 +Tipi di test disponibili
5.37 +~~~~~~~~~~~~~~~~~~~~~~~~
5.38 +
5.39 +isi-checkup -s
5.40 +
5.41 +* lancia SOLO i TEST DI SISTEMA (boot, servizi, ISI)
5.42 +
5.43 +isi-checkup -u UTENTE
5.44 +
5.45 +* lancia SOLO i TEST relativi all'UTENTE per l'UTENTE SPECIFICATO
5.46 +
5.47 +isi-checkup -U
5.48 +
5.49 +* lancia SOLO i test relativi all'UTENTE per TUTTI GLI UTENTI
5.50 +
5.51 +isi-checkup -L
5.52 +
5.53 +* lancia SOLO i TEST LOCALI (se creati dall'amministratore di sistema)
5.54 +
5.55 +isi-checkup -A
5.56 +
5.57 +* lancia TUTTI i test disponibili (Sistema, Utente, Locali)
5.58 +
5.59 +Altre opzioni
5.60 +~~~~~~~~~~~~~
5.61 +
5.62 +isi-checkup -v
5.63 +
5.64 +* Mostra più informazioni relative ai test che vengono lanciati (verbose)
5.65 +
5.66 +isi-checkup -h
5.67 +
5.68 +* mostra le opzioni disponibili e ne fornisce una breve descrizione
5.69 +###
5.70 +"""
5.71 +
5.72 +from dry.utils import Container
5.73 +import sys
5.74 +
5.75 +### isi-checkup option
5.76 +USAGE = """
5.77 + usage: %prog [options]
5.78 + -t, --template=modello: imposta i test secondo il modello
5.79 + -T, --templateDefault: attiva i test del template di default
5.80 + -l, --list: elenca i template disponibili
5.81 + -r, --reset: disattiva tutti i test del template in uso
5.82 + -s, --system: lancia i test (boot, servizi, ISI)
5.83 + -u, --user=user: utente da testare
5.84 + -U, --users: lancia solo i test relativi agli utenti
5.85 + -L, --local: lancia solo i test locali
5.86 + -A, --all: lancia tutti i test
5.87 + -v, --verbose: be verbose
5.88 +"""
5.89 +
5.90 +import os
5.91 +import sys
5.92 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
5.93 +import re
5.94 +from dry import optionparse
5.95 +from dry.functions import execute
5.96 +from checkup import IsiTest, TestError
5.97 +from colorize import Colorize
5.98 +import inspect
5.99 +
5.100 +class NotAtest(Exception):
5.101 + pass
5.102 +
5.103 +class Test(object):
5.104 + path_tests = '/usr/share/isi-checkup/tests'
5.105 + path_links = '/etc/isi/checkup'
5.106 +
5.107 + def __init__(self, filename):
5.108 + pattern = '^(?P<order>\d+)+_(?P<name>.*)(?P<extension>.sh|.py)$'
5.109 + m = re.search(pattern, filename)
5.110 + if not m:
5.111 + raise NotAtest
5.112 + m = m.groupdict()
5.113 + self.filename = filename
5.114 + self.order = m['order']
5.115 + self.name = m['name']
5.116 + self.extension = m['extension']
5.117 + self.path_filename = '%s/%s' % (self.path_tests, filename)
5.118 + self.path_link = '%s/%s' % (self.path_links, filename)
5.119 +
5.120 +class TestList(Container):
5.121 + def del_element(self, key):
5.122 + if key in self._attrs:
5.123 + j = self._attrs.index(key)
5.124 + # Don't shift index if deleting a 'used' test
5.125 + if j < self._n:
5.126 + return
5.127 + self._attrs.pop(j)
5.128 +
5.129 +class TestManager(object):
5.130 + """
5.131 + files
5.132 +
5.133 + # TODO : trovare modo piu elegante per passare parametri a xrange()
5.134 + """
5.135 + path_tests = '/usr/share/isi-checkup/tests'
5.136 + path_links = '/etc/isi/checkup'
5.137 + path_templates = '/usr/share/isi-checkup'
5.138 + file_exclude = '/etc/isi/checkup/exclude'
5.139 + file_template_default = '/etc/isi/checkup/template-default'
5.140 +
5.141 +### Priority schema
5.142 + range_system = (0, 499)
5.143 + range_user = (500, 700)
5.144 + range_local = (701, 2000)
5.145 + range_any = (0, 2000)
5.146 +
5.147 + range_all_tests = (0, 2000)
5.148 + range_tests = (0, 499)
5.149 +
5.150 + msg_passed = Colorize('[ PASSATO ]').BOLD_GREEN
5.151 + msg_warning = Colorize('[ ATTENZIONE ]').BOLD_YELLOW
5.152 + msg_error = Colorize('[ ERRORE ]').BOLD_RED
5.153 +
5.154 +### Constructor
5.155 + def __init__(self):
5.156 + self.failed_tests = []
5.157 + self.set_range()
5.158 + self.excluded = self.get_excluded()
5.159 + self.tests = self.get_tests_enabled()
5.160 +
5.161 + def set_range(self):
5.162 + if opts.template:
5.163 + # if wrong template given
5.164 + if self.set_template(opts.template) == True:
5.165 + sys.exit(1)
5.166 + f = open(self.file_template_default, 'w')
5.167 + f.write(opts.template)
5.168 + f.close()
5.169 +
5.170 + sys.exit(0)
5.171 +
5.172 + elif opts.templateDefault:
5.173 + # se non viene specificato
5.174 + template = 'isi'
5.175 + if os.path.isfile(self.file_template_default):
5.176 + # Using Default template file found.
5.177 + f = open(self.file_template_default)
5.178 + for line in f.readlines():
5.179 + if re.search('^$', line):
5.180 + continue
5.181 + template = line
5.182 + self.reset_templates()
5.183 + self.set_template(template)
5.184 + sys.exit(0)
5.185 +
5.186 + elif opts.list:
5.187 + for t in self.get_templates(): print t
5.188 + sys.exit(0)
5.189 +
5.190 + elif opts.reset:
5.191 + self.reset_templates()
5.192 + sys.exit(0)
5.193 +
5.194 + else:
5.195 + # setting range
5.196 +
5.197 + if opts.system:
5.198 + self.range_tests = self.range_system
5.199 +
5.200 + if opts.user:
5.201 + self.range_tests = self.range_user
5.202 +
5.203 + if opts.users:
5.204 + self.range_tests = self.range_user
5.205 +
5.206 + if opts.local:
5.207 + self.range_tests = self.range_local
5.208 +
5.209 + if opts.all:
5.210 + self.range_tests = self.range_any
5.211 +
5.212 +
5.213 +### Templates Setting
5.214 + def get_template_tests(self, template=None):
5.215 + """ Returns list of tests in templates """
5.216 + path = self.path_templates
5.217 + tests = []
5.218 +
5.219 + if template:
5.220 + templates = ('%s.conf' % template).split()
5.221 + else:
5.222 + templates = os.listdir(path)
5.223 + for template in templates:
5.224 + pattern = '^(?P<name>.*)(?P<extension>.conf)$'
5.225 + m = re.search(pattern, template)
5.226 +
5.227 + if not m:
5.228 + continue
5.229 + if not os.path.isfile('%s/%s' % (path, template)):
5.230 + continue
5.231 +
5.232 + f = open('%s/%s' % (path, template))
5.233 + for line in f.readlines():
5.234 + line = line.strip()
5.235 + if line == '':
5.236 + continue
5.237 + tests.append(line)
5.238 + return tests
5.239 +
5.240 + def get_templates(self):
5.241 + """ Returns list of the Available Templates """
5.242 + path = self.path_templates
5.243 + templates = []
5.244 + for template in os.listdir(path):
5.245 + pattern = '^(?P<name>.*)(?P<extension>.conf)$'
5.246 + m = re.search(pattern, template)
5.247 + if not m:
5.248 + continue
5.249 + m = m.groupdict()
5.250 + test_name = m['name']
5.251 + templates.append(test_name)
5.252 + return templates
5.253 +
5.254 + def set_template(self, template):
5.255 + """
5.256 + Adds test symlinks for the given template
5.257 +
5.258 + Return True if given template's wrong
5.259 + """
5.260 + # PATH definition
5.261 + path_test = self.path_tests
5.262 + path_link = self.path_links
5.263 + tests = self.get_template_tests(template)
5.264 + linked_tests = []
5.265 + for test in tests:
5.266 + link_src = '/'.join([path_test, test])
5.267 + link_dest = '/'.join([path_link, test])
5.268 + if os.path.isfile(link_dest):
5.269 + continue
5.270 + os.symlink(link_src, link_dest)
5.271 + print ' Aggiunto test "%s"' % test
5.272 + linked_tests.append(test)
5.273 +
5.274 + if linked_tests:
5.275 + #print '\n Test aggiunti: ', linked_tests
5.276 + pass
5.277 + elif tests:
5.278 + print '\n Nessun altro test da aggiungere per il template "%s"\n' % template
5.279 + else:
5.280 + print 'Template sconosciuto "%s"' % template
5.281 + return True
5.282 +
5.283 + def is_to_be_deleted(self, order_number):
5.284 + if int(order_number) > 1000:
5.285 + return False
5.286 + else:
5.287 + return True
5.288 +
5.289 + def reset_templates(self):
5.290 + """ Resets template deleting links to tests """
5.291 + path = self.path_links
5.292 + files = os.listdir(path)
5.293 + files_removed = []
5.294 +
5.295 + for f in files:
5.296 + path_filename = '%s/%s' % (path, f)
5.297 + pattern = '^(?P<order>\d+)+_(?P<name>.*)(?P<extension>.sh|.py)$'
5.298 + m = re.search(pattern, f)
5.299 + if not m:
5.300 + continue
5.301 + m = m.groupdict()
5.302 + order = m['order']
5.303 + name = m['name']
5.304 + extension = m['extension']
5.305 + if not self.is_to_be_deleted(order):
5.306 + continue
5.307 + if not os.path.islink(path_filename):
5.308 + continue
5.309 + os.remove(path_filename)
5.310 + files_removed.append(f)
5.311 +
5.312 + print '%s test disabilitati' % files_removed.__len__()
5.313 +
5.314 +### Test Run
5.315 + def exec_test_python(self, test):
5.316 + # Eseguo script python
5.317 + for isi_test in self.get_isitest(test):
5.318 + try:
5.319 + obj = isi_test(user=opts.user)
5.320 + except Exception, e:
5.321 + print e
5.322 + continue
5.323 + if opts.verbose:
5.324 + print test.order, obj
5.325 + for key, meth in self.get_test_methods(obj):
5.326 + try:
5.327 + ## i metodi ritornano un booleano
5.328 + if not meth():
5.329 + self.failed_tests += [(obj.name, test)]
5.330 + self.skip_dependant(obj)
5.331 + except Exception, e:
5.332 + e.obj = obj
5.333 + e.method = meth
5.334 + print test.order, e
5.335 + #raise e
5.336 + obj.report()
5.337 + def exec_test_bash(self, test):
5.338 + # Eseguo script bash
5.339 +
5.340 + if opts.verbose:
5.341 + print test.order, test.name #test.name
5.342 + if opts.user:
5.343 + ret_code, out, err = execute([test.path_link, opts.user])
5.344 + else:
5.345 + ret_code, out, err = execute([test.path_link])
5.346 +
5.347 + if ret_code:
5.348 + print out
5.349 + self.failed_tests += [(test.name, test)]
5.350 +
5.351 + if opts.verbose:
5.352 + print "ERRORI:\n"+err
5.353 +
5.354 + def skip_dependant(self, obj):
5.355 + if isinstance(obj.skip, (str, unicode)):
5.356 + skip = obj.skip.split()
5.357 + else:
5.358 + skip = obj.skip
5.359 +
5.360 + for key in skip:
5.361 + self.tests.del_element(key)
5.362 +
5.363 + for key in self.expand(obj.skip_range):
5.364 + key = str(key)
5.365 + self.tests.del_element(key)
5.366 +
5.367 + def expand(self, range):
5.368 + ## FIXME
5.369 + start, stop = range
5.370 + return str(start)
5.371 +
5.372 + def get_test_methods(self, obj):
5.373 + meths = []
5.374 + for key in dir(obj):
5.375 + if not key.startswith('test'):
5.376 + continue
5.377 + attr = getattr(obj, key)
5.378 + if inspect.ismethod(attr):
5.379 + meths += [(key, attr)]
5.380 + return meths
5.381 +
5.382 + def get_isitest(self, test):
5.383 + GLOB = {}
5.384 + tests = []
5.385 + execfile(test.path_link, GLOB)
5.386 + for key, elem in GLOB.iteritems():
5.387 + if inspect.isclass(elem) and issubclass(elem, IsiTest):
5.388 + if elem.run:
5.389 + tests += [elem]
5.390 + return tests
5.391 +
5.392 + def is_to_be_run(self, test):
5.393 +
5.394 + name = "%s%s" % (test.name, test.extension)
5.395 + if name in self.excluded:
5.396 + return False
5.397 + # xrange(*self.range_test) ;-) è più breve, non più leggibile...
5.398 + start, end = self.range_tests
5.399 + if not int(test.order) in xrange(start, end):
5.400 + return False
5.401 + else:
5.402 + return True
5.403 +
5.404 + def run(self):
5.405 + """ Launches tests in self.test """
5.406 +
5.407 + for test in self.tests:
5.408 + if test.filename.endswith(".py"):
5.409 + self.exec_test_python(test)
5.410 +
5.411 + if test.filename.endswith(".sh"):
5.412 + self.exec_test_bash(test)
5.413 +
5.414 + def get_excluded(self):
5.415 + """ Returns exclude list
5.416 + es.
5.417 + ['need_process_dansguardian.py', 'need_process_master.py']
5.418 + """
5.419 + file_exclude = self.file_exclude
5.420 + exclude = [] # test *NAME*
5.421 +
5.422 + if not os.path.exists(file_exclude):
5.423 + return exclude
5.424 + ## Adding exclude-file tests to exclude list
5.425 + f = open(file_exclude)
5.426 + for line in f.readlines():
5.427 + # skips emtpy line
5.428 + if re.match('^$', line):
5.429 + continue
5.430 + exclude.append(line.split()[0])
5.431 +
5.432 + test_name = line.split()[0]
5.433 +
5.434 + exclude_dep = self.test2exclude_dep(exclude)
5.435 + exclude += exclude_dep
5.436 +
5.437 + return exclude
5.438 +
5.439 + def get_tests_enabled(self):
5.440 + """
5.441 + Returns a dictionary composed as follows:
5.442 + { order : testObject }
5.443 + """
5.444 + tests = TestList()
5.445 +
5.446 + for filename in sorted(os.listdir(self.path_links)):
5.447 + try:
5.448 + test = Test(filename)
5.449 + except Exception:
5.450 + continue
5.451 +
5.452 + if self.is_to_be_run(test):
5.453 + tests[test.order] = test
5.454 +
5.455 + return tests
5.456 +
5.457 + def _test2exclude_get_name(self, numbers):
5.458 + """ Returns filename list for the provided *numbers* of the test
5.459 + es.
5.460 + 012_test.py
5.461 + """
5.462 +
5.463 + path = self.path_links
5.464 + pattern = '^(?P<order>\d+)+_(?P<name>.*)(?P<extension>.sh|.py)$'
5.465 + test_dict = {}
5.466 + test_list = []
5.467 + for filename in os.listdir(path):
5.468 + m = re.search(pattern, filename)
5.469 + if not m:
5.470 + continue
5.471 + m = m.groupdict()
5.472 + order, extension, name = m.itervalues()
5.473 +
5.474 + test_filename = '%s%s' % (name, extension)
5.475 + test_dict[order] = test_filename
5.476 +
5.477 + for number in numbers:
5.478 + test_list += [test_dict[number]]
5.479 +
5.480 + return test_list
5.481 +
5.482 +
5.483 + def _test2exclude_get_pathfilename(self, test_name_list):
5.484 + """ Returns *complete* path+filename for test
5.485 + Returns None if test not found in path
5.486 + es.
5.487 + /etc/isi/checkup/tests/112_test.py
5.488 + """
5.489 + path = self.path_links
5.490 + path_filename_list = []
5.491 +
5.492 + for test_name in test_name_list:
5.493 + pattern = '^(?P<order>\d+)+_(?P<name>.*)(?P<extension>.sh|.py)$'
5.494 +# test_list = {}
5.495 + for filename in os.listdir(path):
5.496 + m = re.search(pattern, filename)
5.497 + if not m:
5.498 + continue
5.499 + m = m.groupdict()
5.500 + order, extension, name = m.itervalues()
5.501 +
5.502 + path_filename = '%s/%s_%s%s' % (path, order, name, extension)
5.503 +
5.504 + if test_name == '%s%s' % (name, extension):
5.505 + path_filename_list += [path_filename]
5.506 + else:
5.507 + continue
5.508 + return path_filename_list
5.509 +
5.510 + def _test2exclude_get_skips(self, path_filename_list):
5.511 + """ Looks in the provided *path_filename_list* for skips
5.512 + returning a skip list
5.513 +
5.514 + es.
5.515 + ['11', '22', '33', '44', '55', '66', '77', '88', '99']
5.516 + """
5.517 + GLOB = {}
5.518 + skip_list = []
5.519 +
5.520 + for path_filename in path_filename_list:
5.521 + execfile(path_filename, GLOB)
5.522 +
5.523 + for key, elem in GLOB.iteritems():
5.524 + if inspect.isclass(elem) and issubclass(elem, IsiTest):
5.525 + if hasattr(elem, 'skip') and elem.skip:
5.526 + skip_list += elem.skip.split()
5.527 + return skip_list
5.528 +
5.529 +
5.530 + def test2exclude_dep(self, exclude):
5.531 + """ Creates and returns the Dependent Test path_filename list """
5.532 + path_filename_list = []
5.533 + tests_to_exclude = []
5.534 +
5.535 + path_filename_list = self._test2exclude_get_pathfilename(exclude)
5.536 + #['/etc/isi/checkup/266_need_process_dansguardian.py', '/etc/isi/checkup/267_need_process_master.py'
5.537 +
5.538 + skip_list = self._test2exclude_get_skips(path_filename_list)
5.539 +
5.540 + tests_to_exclude = self._test2exclude_get_name(skip_list)
5.541 +
5.542 + return tests_to_exclude
5.543 +
5.544 +
5.545 +
5.546 +### Main ####
5.547 +opts, args = optionparse.parse(USAGE)
5.548 +
5.549 +isi_test = TestManager()
5.550 +isi_test.run()
5.551 +
5.552 +### Print Report
5.553 +if isi_test.failed_tests:
5.554 + msg = '\nI seguenti test non sono andati a buon fine'
5.555 + print Colorize(msg).BOLD_RED_U
5.556 + #print '-'*len(msg)
5.557 + for test_obj, test in isi_test.failed_tests:
5.558 + print "%-40s %s" % (test.name + test.extension, test_obj)
5.559 +###
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/debian/README Mon Apr 26 11:16:23 2010 +0200
6.3 @@ -0,0 +1,6 @@
6.4 +The Debian Package isi
6.5 +----------------------------
6.6 +
6.7 +Comments regarding the Package
6.8 +
6.9 + -- Sandro Dentella <[email protected]> Mon, 15 Feb 2022 17:18:50 +0100
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/debian/README.Debian Mon Apr 26 11:16:23 2010 +0200
7.3 @@ -0,0 +1,6 @@
7.4 +isi for Debian
7.5 +--------------
7.6 +
7.7 +<possible notes regarding this package - if none, delete this file>
7.8 +
7.9 + -- Sandro Dentella <[email protected]> Mon, 15 Feb 2022 17:18:50 +0100
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/debian/changelog Mon Apr 26 11:16:23 2010 +0200
8.3 @@ -0,0 +1,162 @@
8.4 +isi (2.7.3) hardy; urgency=low
8.5 +
8.6 + * web for printers: fix when administrator has a different password form
8.7 + ldap admin
8.8 +
8.9 + -- Sandro Dentella <[email protected]> Fri, 23 Apr 2021 11:32:57 +0200
8.10 +
8.11 +isi (2.7.2) hardy; urgency=low
8.12 +
8.13 + * ora logon.pl non è più considerato un modulo di configurazione
8.14 +
8.15 + -- Sandro Dentella <[email protected]> Wed, 21 Apr 2021 16:50:37 +0200
8.16 +
8.17 +isi (2.7.1) hardy; urgency=low
8.18 +
8.19 + * fix stampanti mancanti
8.20 +
8.21 + -- Sandro Dentella <[email protected]> Tue, 20 Apr 2021 16:56:06 +0200
8.22 +
8.23 +isi (2.7) hardy; urgency=low
8.24 +
8.25 + * printers with web interface, UserPrinter/PcPrinter
8.26 +
8.27 + -- Sandro Dentella <[email protected]> Mon, 19 Apr 2021 18:53:08 +0200
8.28 +
8.29 +isi (2.6) hardy; urgency=low
8.30 +
8.31 + * grub4dos, printers, web per IE
8.32 +
8.33 + -- Sandro Dentella <[email protected]> Sun, 18 Apr 2021 18:31:30 +0200
8.34 +
8.35 +isi (2.5.10) hardy; urgency=low
8.36 +
8.37 + * fix classse minuscola + permessi isi-alulink
8.38 +
8.39 + -- Sandro Dentella <[email protected]> Wed, 14 Apr 2021 00:51:49 +0200
8.40 +
8.41 +isi (2.5.9) hardy; urgency=low
8.42 +
8.43 + * fix in xls parser
8.44 +
8.45 + -- Sandro Dentella <[email protected]> Tue, 13 Apr 2021 15:01:49 +0200
8.46 +
8.47 +isi (2.5.8) hardy; urgency=low
8.48 +
8.49 + * important fix in dnsmasq configuration save
8.50 +
8.51 + -- Sandro Dentella <[email protected]> Tue, 13 Apr 2021 12:13:05 +0200
8.52 +
8.53 +isi (2.5.7) hardy; urgency=low
8.54 +
8.55 + * fix convert
8.56 +
8.57 + -- Sandro Dentella <[email protected]> Mon, 12 Apr 2022 20:16:59 +0200
8.58 +
8.59 +isi (2.5.6) hardy; urgency=low
8.60 +
8.61 + * fixes: new_passwd -> new_password
8.62 +
8.63 + -- Sandro Dentella <[email protected]> Mon, 12 Apr 2022 19:09:33 +0200
8.64 +
8.65 +isi (2.5.5) hardy; urgency=low
8.66 +
8.67 + * web interfaces fixes: dnsmasq + missing object template
8.68 +
8.69 + -- Sandro Dentella <[email protected]> Mon, 12 Apr 2022 12:04:35 +0200
8.70 +
8.71 +isi (2.5.4) hardy; urgency=low
8.72 +
8.73 + * minor fixes
8.74 +
8.75 + -- Sandro Dentella <[email protected]> Sun, 11 Apr 2022 20:23:48 +0200
8.76 +
8.77 +isi (2.5.3) hardy; urgency=low
8.78 +
8.79 + * web interface from code
8.80 +
8.81 + -- Sandro Dentella <[email protected]> Sun, 11 Apr 2022 17:46:08 +0200
8.82 +
8.83 +isi (2.5.2) hardy; urgency=low
8.84 +
8.85 + * migliorata gestione errori web e dipendenze. Isi-alulink in python
8.86 +
8.87 + -- Sandro Dentella <[email protected]> Sun, 11 Apr 2022 13:00:31 +0200
8.88 +
8.89 +isi (2.5.1) hardy; urgency=low
8.90 +
8.91 + * fix postinst
8.92 +
8.93 + -- Sandro Dentella <[email protected]> Sat, 10 Apr 2022 23:29:13 +0200
8.94 +
8.95 +isi (2.5) hardy; urgency=low
8.96 +
8.97 + * vari fix e migliorie all'interfaccia web
8.98 +
8.99 + -- Sandro Dentella <[email protected]> Sat, 10 Apr 2022 23:17:18 +0200
8.100 +
8.101 +isi (2.4.2) hardy; urgency=low
8.102 +
8.103 + * fix vari: cambo passwd/IsiUser -> Manager
8.104 +
8.105 + -- Sandro Dentella <[email protected]> Wed, 07 Apr 2022 15:35:23 +0200
8.106 +
8.107 +isi (2.4.1) hardy; urgency=low
8.108 +
8.109 + * navigazione
8.110 +
8.111 + -- Sandro Dentella <[email protected]> Tue, 06 Apr 2022 23:11:36 +0200
8.112 +
8.113 +isi (2.4) hardy; urgency=low
8.114 +
8.115 + * aggiunta quota e creazione link
8.116 +
8.117 + -- Sandro Dentella <[email protected]> Tue, 06 Apr 2022 16:56:32 +0200
8.118 +
8.119 +isi (2.3) hardy; urgency=low
8.120 +
8.121 + * isi-adduser + isi-convert in interfaccia web
8.122 +
8.123 + -- Sandro Dentella <[email protected]> Thu, 01 Apr 2022 21:19:43 +0200
8.124 +
8.125 +isi (2.2.2) hardy; urgency=low
8.126 +
8.127 + * qualche fix
8.128 +
8.129 + -- Sandro Dentella <[email protected]> Fri, 26 Mar 2022 02:36:48 +0100
8.130 +
8.131 +isi (2.2.1) hardy; urgency=low
8.132 +
8.133 + * defaults.py in /etc/isi + aggiunto quiet=False in get_user
8.134 +
8.135 + -- Sandro Dentella <[email protected]> Wed, 24 Mar 2022 13:07:54 +0100
8.136 +
8.137 +isi (2.2) hardy; urgency=low
8.138 +
8.139 + * fixes on isi-adduser
8.140 +
8.141 + -- Sandro Dentella <[email protected]> Wed, 24 Mar 2022 12:00:22 +0100
8.142 +
8.143 +isi (2.1-2) hardy; urgency=low
8.144 +
8.145 + * fix docs
8.146 +
8.147 + -- Sandro Dentella <[email protected]> Tue, 23 Mar 2022 16:36:18 +0100
8.148 +
8.149 +isi (2.1) hardy; urgency=low
8.150 +
8.151 + * complete rewrite of python library based on pumpkin
8.152 +
8.153 + -- Sandro Dentella <[email protected]> Mon, 22 Mar 2022 16:01:15 +0100
8.154 +
8.155 +isi (2.0.1) hardy; urgency=low
8.156 +
8.157 + * fix in isi-domain - isi-setup (Simone)
8.158 +
8.159 + -- Sandro Dentella <[email protected]> Sun, 28 Feb 2022 21:13:21 +0100
8.160 +
8.161 +isi (2.0) unstable; urgency=low
8.162 +
8.163 + * Initial Release.
8.164 +
8.165 + -- Sandro Dentella <[email protected]> Mon, 15 Feb 2022 17:18:50 +0100
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/debian/compat Mon Apr 26 11:16:23 2010 +0200
9.3 @@ -0,0 +1,1 @@
9.4 +5
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/debian/control Mon Apr 26 11:16:23 2010 +0200
10.3 @@ -0,0 +1,56 @@
10.4 +Source: isi
10.5 +Section: isi
10.6 +Priority: extra
10.7 +Maintainer: Sandro Dentella <[email protected]>
10.8 +Build-Depends: cdbs, debhelper (>= 5)
10.9 +Standards-Version: 3.7.2
10.10 +
10.11 +Package: isi
10.12 +Architecture: all
10.13 +Depends: at, acl, quota, tofrodos,
10.14 + procinfo, reiserfsprogs, xfsprogs, slapd, libnss-ldap, libpam-ldap,
10.15 + libnet-ldap-perl, samba, smbldap-tools, migrationtools, db4.2-util,
10.16 + libcrack2|cracklib2, python-ldap, python-dry, python-urwid, python-smbpasswd,
10.17 + win-perl, isi, mercurial, nscd, python-pumpkin, lsb-release,
10.18 + libcompress-zlib-perl, python-xlrd, python-isi (>= 2.7.3), smbclient
10.19 +Conflicts: isi-ldap3-def, isi-ldap3, isi-logon, isi-perl, isi-setup
10.20 +Replaces: isi-ldap3-def, isi-ldap3, isi-logon, isi-perl
10.21 +Description: all you need to setup and manage a pdc samba+ldap at school
10.22 +
10.23 +Package: python-isi
10.24 +Architecture: all
10.25 +Provides: python-isi
10.26 +Depends: python-ldap, python-pexpect, isi (>= 2.7.3)
10.27 +XB-Python-Version: ${python:Versions}
10.28 +Description: python modules for isi project
10.29 + Questa versione dipende da python 2.5 o successivi
10.30 +
10.31 +Package: isi-docs
10.32 +Architecture: all
10.33 +Depends:
10.34 +Description: documentazione progetto reteisi
10.35 + Documentazione completa del pacchetto reteisi.
10.36 + Al momento è possibile sfogliare la documentazione dal sito:
10.37 + http://reteisi.argolinux.org
10.38 +
10.39 +Package: isi-checkup
10.40 +Architecture: all
10.41 +Depends: python-dry, python-isi (>= 2.7.3)
10.42 +Description: suite di checkup per un sistema ReteIsi
10.43 + il sistema fornisce una struttura per potere gestire una serie di test
10.44 + per fare un checkup al sistema
10.45 +
10.46 +Package: isi-web
10.47 +Architecture: all
10.48 +Depends: python-django (>=1.2), python-vov (>= 0.8.5), isi (>=2.7.3),
10.49 + isi-docs (>=2.7.3),
10.50 + libapache2-mod-fastcgi, python-dry, ipython, python-flup, apache2
10.51 +Description: Interfaccia web per amministrazione ReteISI
10.52 + Interfaccia web per amministrazione ReteISI comprensivo di
10.53 + .
10.54 + * cambio nome dominio
10.55 + * configurazione logon.conf
10.56 + * gestione utenti
10.57 + * gestione dns/boot options
10.58 + * controllo navigazione classi (non squid/dansguardian)
10.59 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/debian/copyright Mon Apr 26 11:16:23 2010 +0200
11.3 @@ -0,0 +1,40 @@
11.4 +This package was debianized by Sandro Dentella <[email protected]> on
11.5 +Mon, 15 Feb 2022 17:18:50 +0100.
11.6 +
11.7 +It was downloaded from <url://example.com>
11.8 +
11.9 +Upstream Author(s):
11.10 +
11.11 + <put author's name and email here>
11.12 + <likewise for another author>
11.13 +
11.14 +Copyright:
11.15 +
11.16 + <Copyright (C) YYYY Name OfAuthor>
11.17 + <likewise for another author>
11.18 +
11.19 +License:
11.20 +
11.21 + This package is free software; you can redistribute it and/or modify
11.22 + it under the terms of the GNU General Public License as published by
11.23 + the Free Software Foundation; either version 2 of the License, or
11.24 + (at your option) any later version.
11.25 +
11.26 + This package is distributed in the hope that it will be useful,
11.27 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11.28 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.29 + GNU General Public License for more details.
11.30 +
11.31 + You should have received a copy of the GNU General Public License
11.32 + along with this package; if not, write to the Free Software
11.33 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11.34 +
11.35 +On Debian systems, the complete text of the GNU General
11.36 +Public License can be found in `/usr/share/common-licenses/GPL'.
11.37 +
11.38 +The Debian packaging is (C) 2010, Sandro Dentella <[email protected]> and
11.39 +is licensed under the GPL, see above.
11.40 +
11.41 +
11.42 +# Please also look if there are files or directories which have a
11.43 +# different copyright/license attached and list them here.
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/debian/files Mon Apr 26 11:16:23 2010 +0200
12.3 @@ -0,0 +1,5 @@
12.4 +isi_2.7.3_all.deb isi extra
12.5 +python-isi_2.7.3_all.deb isi extra
12.6 +isi-docs_2.7.3_all.deb isi extra
12.7 +isi-checkup_2.7.3_all.deb isi extra
12.8 +isi-web_2.7.3_all.deb isi extra
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/debian/isi-checkup.1 Mon Apr 26 11:16:23 2010 +0200
13.3 @@ -0,0 +1,59 @@
13.4 +.\" Hey, EMACS: -*- nroff -*-
13.5 +.\" First parameter, NAME, should be all caps
13.6 +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
13.7 +.\" other parameters are allowed: see man(7), man(1)
13.8 +.TH ISI-CHECKUP SECTION "aprile 11, 2008"
13.9 +.\" Please adjust this date whenever revising the manpage.
13.10 +.\"
13.11 +.\" Some roff macros, for reference:
13.12 +.\" .nh disable hyphenation
13.13 +.\" .hy enable hyphenation
13.14 +.\" .ad l left justify
13.15 +.\" .ad b justify to both left and right margins
13.16 +.\" .nf disable filling
13.17 +.\" .fi enable filling
13.18 +.\" .br insert line break
13.19 +.\" .sp <n> insert n+1 empty lines
13.20 +.\" for manpage-specific macros, see man(7)
13.21 +.SH NAME
13.22 +isi-checkup \- suite di test estendibile
13.23 +.SH SYNOPSIS
13.24 +.B isi-checkup
13.25 +.RI [ ] " files" ...
13.26 +.br
13.27 +.B bar
13.28 +.RI [ options ] " files" ...
13.29 +.SH DESCRIPTION
13.30 +This manual page documents briefly the
13.31 +.B isi-checkup
13.32 +and
13.33 +.B bar
13.34 +commands.
13.35 +.PP
13.36 +.\" TeX users may be more comfortable with the \fB<whatever>\fP and
13.37 +.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
13.38 +.\" respectively.
13.39 +\fBisi-checkup\fP is a program that...
13.40 +.SH OPTIONS
13.41 +These programs follow the usual GNU command line syntax, with long
13.42 +options starting with two dashes (`-').
13.43 +A summary of options is included below.
13.44 +For a complete description, see the Info files.
13.45 +.TP
13.46 +.B \-h, \-\-help
13.47 +Show summary of options.
13.48 +.TP
13.49 +.B \-v, \-\-version
13.50 +Show version of program.
13.51 +.SH SEE ALSO
13.52 +.BR bar (1),
13.53 +.BR baz (1).
13.54 +.br
13.55 +The programs are documented fully by
13.56 +.IR "The Rise and Fall of a Fooish Bar" ,
13.57 +available via the Info system.
13.58 +.SH AUTHOR
13.59 +isi-checkup was written by <upstream author>.
13.60 +.PP
13.61 +This manual page was written by Alessandro Dentella <[email protected]>,
13.62 +for the Debian project (but may be used by others).
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/debian/isi-checkup.install Mon Apr 26 11:16:23 2010 +0200
14.3 @@ -0,0 +1,2 @@
14.4 +checkup/isi-checkup usr/sbin
14.5 +usr/share/isi-checkup /usr/share/
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/debian/isi-checkup.manpages Mon Apr 26 11:16:23 2010 +0200
15.3 @@ -0,0 +1,1 @@
15.4 +debian/isi-checkup.1
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/debian/isi-checkup.postinst Mon Apr 26 11:16:23 2010 +0200
16.3 @@ -0,0 +1,43 @@
16.4 +#!/bin/sh
16.5 +# postinst script for isi
16.6 +#
16.7 +# see: dh_installdeb(1)
16.8 +
16.9 +set -e
16.10 +
16.11 +# summary of how this script can be called:
16.12 +# * <postinst> `configure' <most-recently-configured-version>
16.13 +# * <old-postinst> `abort-upgrade' <new version>
16.14 +# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
16.15 +# <new-version>
16.16 +# * <postinst> `abort-remove'
16.17 +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
16.18 +# <failed-install-package> <version> `removing'
16.19 +# <conflicting-package> <version>
16.20 +# for details, see http://www.debian.org/doc/debian-policy/ or
16.21 +# the debian-policy package
16.22 +
16.23 +
16.24 +case "$1" in
16.25 + configure)
16.26 + mkdir -p /etc/isi/checkup
16.27 + isi-checkup -T
16.28 + ;;
16.29 +
16.30 + abort-upgrade|abort-remove|abort-deconfigure)
16.31 + ;;
16.32 +
16.33 + *)
16.34 + echo "postinst called with unknown argument \`$1'" >&2
16.35 + exit 1
16.36 + ;;
16.37 +esac
16.38 +
16.39 +# dh_installdeb will replace this with shell code automatically
16.40 +# generated by other debhelper scripts.
16.41 +
16.42 +#DEBHELPER#
16.43 +
16.44 +exit 0
16.45 +
16.46 +
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/debian/isi-web.install Mon Apr 26 11:16:23 2010 +0200
17.3 @@ -0,0 +1,7 @@
17.4 +etc/apache2 /etc/
17.5 +etc/init.d/isiweb /etc/init.d
17.6 +etc/default etc
17.7 +web/logon web/samba web/dnsmasq web/navigazione web/users web/templates usr/share/isi/isiweb
17.8 +web/urls.py web/manage.py web/__init__.py web/logger.py web/static web/ldap-auth.py usr/share/isi/isiweb
17.9 +
17.10 +web/settings.py web/local_settings.py usr/share/doc/isi-web
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/debian/isi-web.links Mon Apr 26 11:16:23 2010 +0200
18.3 @@ -0,0 +1,3 @@
18.4 +/etc/isi/web/settings.py usr/share/isi/isiweb/settings.py
18.5 +/etc/isi/web/local_settings.py usr/share/isi/isiweb/local_settings.py
18.6 +var/cache/isiweb/mako_modules usr/share/isi/isiweb/mako_modules
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/debian/isi-web.postinst Mon Apr 26 11:16:23 2010 +0200
19.3 @@ -0,0 +1,73 @@
19.4 +#!/bin/bash
19.5 +# postinst script for isi
19.6 +#
19.7 +# see: dh_installdeb(1)
19.8 +
19.9 +set -e
19.10 +
19.11 +# summary of how this script can be called:
19.12 +# * <postinst> `configure' <most-recently-configured-version>
19.13 +# * <old-postinst> `abort-upgrade' <new version>
19.14 +# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
19.15 +# <new-version>
19.16 +# * <postinst> `abort-remove'
19.17 +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
19.18 +# <failed-install-package> <version> `removing'
19.19 +# <conflicting-package> <version>
19.20 +# for details, see http://www.debian.org/doc/debian-policy/ or
19.21 +# the debian-policy package
19.22 +
19.23 +function start_isiweb () {
19.24 + a2enmod rewrite
19.25 + a2enmod expires
19.26 + a2enmod fastcgi
19.27 +# a2dissite 000-default || true
19.28 + a2dissite isiweb-all.conf
19.29 + a2ensite isiweb.conf
19.30 + /etc/init.d/apache2 reload
19.31 + update-rc.d isiweb start 20 2 . stop 80 2 .
19.32 + mkdir -p /var/cache/isiweb/mako_modules
19.33 + PTH_DIR=/usr/lib/python2.5/site-packages
19.34 + if [ -d $PTH_DIR ] ; then
19.35 + echo /usr/share/isi > $PTH_DIR/isi.pth
19.36 + fi
19.37 +
19.38 + mkdir -p /etc/isi/web
19.39 + if [ ! -f /etc/isi/web/settings.py ] ; then
19.40 + cp /usr/share/doc/isi-web/settings.py /etc/isi/web
19.41 + fi
19.42 + if [ ! -f /etc/isi/web/local_settings.py ] ; then
19.43 + cp /usr/share/doc/isi-web/local_settings.py /etc/isi/web
19.44 + fi
19.45 + cd /usr/share/isi/isiweb
19.46 + ./manage.py syncdb --verbosity=0 --noinput
19.47 +
19.48 + /etc/init.d/isiweb start
19.49 +}
19.50 +
19.51 +case "$1" in
19.52 + configure)
19.53 + rm -f /usr/share/isi/isiweb/isi.db
19.54 + rm -f /etc/isi/web/settings.py
19.55 + if [ ! -f /usr/share/isi/isiweb/isi.db ]; then
19.56 + start_isiweb
19.57 + fi
19.58 + ;;
19.59 +
19.60 + abort-upgrade|abort-remove|abort-deconfigure)
19.61 + ;;
19.62 +
19.63 + *)
19.64 + echo "postinst called with unknown argument \`$1'" >&2
19.65 + exit 1
19.66 + ;;
19.67 +esac
19.68 +
19.69 +# dh_installdeb will replace this with shell code automatically
19.70 +# generated by other debhelper scripts.
19.71 +
19.72 +#DEBHELPER#
19.73 +
19.74 +exit 0
19.75 +
19.76 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/debian/isi.install Mon Apr 26 11:16:23 2010 +0200
20.3 @@ -0,0 +1,5 @@
20.4 +usr/bin /usr
20.5 +usr/sbin /usr
20.6 +usr/lib /usr
20.7 +usr/share/WinActivePerl
20.8 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/debian/isi.postinst Mon Apr 26 11:16:23 2010 +0200
21.3 @@ -0,0 +1,63 @@
21.4 +#!/bin/bash
21.5 +# postinst script for isi
21.6 +#
21.7 +# see: dh_installdeb(1)
21.8 +
21.9 +set -e
21.10 +
21.11 +# summary of how this script can be called:
21.12 +# * <postinst> `configure' <most-recently-configured-version>
21.13 +# * <old-postinst> `abort-upgrade' <new version>
21.14 +# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
21.15 +# <new-version>
21.16 +# * <postinst> `abort-remove'
21.17 +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
21.18 +# <failed-install-package> <version> `removing'
21.19 +# <conflicting-package> <version>
21.20 +# for details, see http://www.debian.org/doc/debian-policy/ or
21.21 +# the debian-policy package
21.22 +
21.23 +
21.24 +case "$1" in
21.25 + configure)
21.26 + mkdir -p /etc/isi/
21.27 + grep -v /etc/isi/defaults.py /usr/share/doc/isi/etc/isi/defaults.py > /etc/isi/defaults.py
21.28 + ### copia grub4dos nella share software
21.29 + if [ -d /home/shares/software ]; then
21.30 + GRUP_DEST=/home/shares/software
21.31 + else
21.32 + GRUP_DEST=/home/software
21.33 + fi
21.34 + if [ -d $GRUB_DEST ]; then
21.35 + if [ ! -d $GRUB_DEST/grub4dos ]; then
21.36 + cp -a /usr/share/doc/isi/grub4dos $GRUB_DEST
21.37 + fi
21.38 + find $GRUB_DEST/grub4dos -name \*gz -exec gunzip {} \;
21.39 + fi
21.40 + rm -f /etc/isi/logon.pl /etc/isi/logonupd.pl
21.41 + ## there was a time logon.pl was in /etc/isi (before 2.7.1) and
21.42 + ## we pointed there from WinActivePerl
21.43 + WIN_PERL=/usr/share/WinActivePerl/
21.44 + if test -h $WIN_PERL/logon.pl ; then
21.45 + rm -f $WIN_PERL/logon.pl $WIN_PERL/logonupd.pl
21.46 + cp /usr/share/doc/isi/etc/isi/{logon,logonupd}.pl $WIN_PERL
21.47 + fi
21.48 + ;;
21.49 +
21.50 + abort-upgrade|abort-remove|abort-deconfigure)
21.51 + ;;
21.52 +
21.53 + *)
21.54 + echo "postinst called with unknown argument \`$1'" >&2
21.55 + exit 1
21.56 + ;;
21.57 +esac
21.58 +
21.59 +# dh_installdeb will replace this with shell code automatically
21.60 +# generated by other debhelper scripts.
21.61 +
21.62 +#DEBHELPER#
21.63 +
21.64 +exit 0
21.65 +
21.66 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/debian/python-isi.install Mon Apr 26 11:16:23 2010 +0200
22.3 @@ -0,0 +1,1 @@
22.4 +debian/tmp/usr/lib/python2.5 /usr/lib/
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/debian/rules Mon Apr 26 11:16:23 2010 +0200
23.3 @@ -0,0 +1,21 @@
23.4 +#!/usr/bin/make -f
23.5 +
23.6 +#DEB_TAR_SRCDIR := python-dateutil
23.7 +DEB_AUTO_CLEANUP_RCS := yes
23.8 +
23.9 +DEB_PYTHON_SYSTEM = pysupport
23.10 +DEB_PYTHON_CLEAN_ARGS = --all
23.11 +
23.12 +# Add here any variable or target overrides you need
23.13 +include /usr/share/cdbs/1/rules/debhelper.mk
23.14 +include /usr/share/cdbs/1/class/python-distutils.mk
23.15 +#include /usr/share/cdbs/1/rules/patchsys-quilt.mk
23.16 +
23.17 +
23.18 +
23.19 +DEB_COMPRESS_EXCLUDE := .py
23.20 +
23.21 +# install/isi-docs::
23.22 +# mkdir -p doc/html doc/.doctrees
23.23 +# sphinx-build doc doc/html
23.24 +# perl -i -p -e 's/xxxx/$(VER)/g' doc/html/sqlkit/download.html
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/docs/Makefile Mon Apr 26 11:16:23 2010 +0200
24.3 @@ -0,0 +1,88 @@
24.4 +# Makefile for Sphinx documentation
24.5 +#
24.6 +
24.7 +# You can set these variables from the command line.
24.8 +SPHINXOPTS =
24.9 +SPHINXBUILD = sphinx-build
24.10 +PAPER =
24.11 +
24.12 +# Internal variables.
24.13 +PAPEROPT_a4 = -D latex_paper_size=a4
24.14 +PAPEROPT_letter = -D latex_paper_size=letter
24.15 +ALLSPHINXOPTS = -d .build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
24.16 +
24.17 +all: html
24.18 +
24.19 +.PHONY: help clean html web htmlhelp latex changes linkcheck
24.20 +
24.21 +help:
24.22 + @echo "Please use \`make <target>' where <target> is one of"
24.23 + @echo " html to make standalone HTML files"
24.24 + @echo " web to make files usable by Sphinx.web"
24.25 + @echo " htmlhelp to make HTML files and a HTML help project"
24.26 + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
24.27 + @echo " changes to make an overview over all changed/added/deprecated items"
24.28 + @echo " linkcheck to check all external links for integrity"
24.29 +
24.30 +clean:
24.31 + -rm -rf .build/*
24.32 +
24.33 +html:
24.34 + mkdir -p .build/html .build/doctrees
24.35 + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html
24.36 + @echo
24.37 + @echo "Build finished. The HTML pages are in .build/html."
24.38 +
24.39 +web:
24.40 + mkdir -p .build/web .build/doctrees
24.41 + $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) .build/web
24.42 + @echo
24.43 + @echo "Build finished; now you can run"
24.44 + @echo " python -m sphinx.web .build/web"
24.45 + @echo "to start the server."
24.46 +
24.47 +htmlhelp:
24.48 + mkdir -p .build/htmlhelp .build/doctrees
24.49 + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp
24.50 + @echo
24.51 + @echo "Build finished; now you can run HTML Help Workshop with the" \
24.52 + ".hhp project file in .build/htmlhelp."
24.53 +
24.54 +latex:
24.55 + mkdir -p .build/latex .build/doctrees
24.56 + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex
24.57 + @echo
24.58 + @echo "Build finished; the LaTeX files are in .build/latex."
24.59 + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
24.60 + "run these through (pdf)latex."
24.61 +
24.62 +changes:
24.63 + mkdir -p .build/changes .build/doctrees
24.64 + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes
24.65 + @echo
24.66 + @echo "The overview file is in .build/changes."
24.67 +
24.68 +linkcheck:
24.69 + mkdir -p .build/linkcheck .build/doctrees
24.70 + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck
24.71 + @echo
24.72 + @echo "Link check complete; look for any errors in the above output " \
24.73 + "or in .build/linkcheck/output.txt."
24.74 +
24.75 +rsync: html
24.76 + rsync -r --delete --progress --stats ./.build/html/ www3:docs/reteisi
24.77 +
24.78 +nrsync: html
24.79 + rsync -r --delete --progress --stats ./.build/html/ www3:docs/reteisi/2.0/
24.80 +
24.81 +pdf: latex
24.82 + cd .build/latex; make all-pdf || true
24.83 + Print -s -o "-b 20" .build/latex/reteisi.pdf
24.84 + gv --orientation=seascape .build/latex/reteisi.2.ps
24.85 +
24.86 +galeon:
24.87 + galeon ./.build/html/index.html
24.88 +firefox:
24.89 + firefox ./.build/html/index.html
24.90 +
24.91 +chtml: clean html
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/docs/README Mon Apr 26 11:16:23 2010 +0200
25.3 @@ -0,0 +1,12 @@
25.4 +Documentation can be generated with sphinx:
25.5 +
25.6 +
25.7 +easy_install sphinx
25.8 +make html
25.9 +make firefox
25.10 +
25.11 +
25.12 +it is available on the web:
25.13 +
25.14 + http://docs.argolinux.org/jungle/index.html
25.15 +
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/docs/_static/reteisi.css Mon Apr 26 11:16:23 2010 +0200
26.3 @@ -0,0 +1,520 @@
26.4 +/**
26.5 + * Alternate Sphinx design
26.6 + * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl.
26.7 + * modified by Sandro Dentella per ReteIsi
26.8 + */
26.9 +
26.10 +body {
26.11 + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif;
26.12 + font-size: 13px;
26.13 + letter-spacing: -0.01em;
26.14 + line-height: 130%;
26.15 + text-align: center;
26.16 + /*background-color: #AFC1C4; */
26.17 + background-color: #e9d56c;
26.18 + color: #333333;
26.19 + padding: 0;
26.20 + border: 1px solid #aaa;
26.21 +
26.22 + margin: 0px 80px 0px 80px;
26.23 + min-width: 740px
26.24 + }
26.25 +section h1 {
26.26 + background-color: #FDFAF3;
26.27 + font-size: 180%;
26.28 + font-weight: bold
26.29 + }
26.30 +.section h2, h2 {
26.31 + font-size: 150%;
26.32 + font-weight: normal
26.33 + }
26.34 +.section h1, .section h2, h1, h2 {
26.35 + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
26.36 + border-color: #E2DCC8;
26.37 + border-style: solid;
26.38 + border-width: 0pt 0pt 1px
26.39 + }
26.40 +.section h1, .section h2, .section h3, h1, h2, h3 {
26.41 + color: #940000
26.42 + }
26.43 +a {
26.44 + color: #CA7900;
26.45 + text-decoration: none
26.46 + }
26.47 +a:hover {
26.48 + color: #2491CF
26.49 + }
26.50 +pre {
26.51 + font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
26.52 + font-size: 0.95em;
26.53 + letter-spacing: 0.015em;
26.54 + padding: 0.5em;
26.55 + border: 1px solid #ccc;
26.56 + background-color: #f8f8f8
26.57 + }
26.58 +td.linenos pre {
26.59 + padding: 0;
26.60 + border: 0;
26.61 + background-color: transparent;
26.62 + color: #aaa
26.63 + }
26.64 +table.highlighttable {
26.65 + margin-left: 0.5em
26.66 + }
26.67 +table.highlighttable td {
26.68 + padding: 0 0.5em 0 0.5em
26.69 + }
26.70 +cite, code, tt {
26.71 + font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
26.72 + font-size: 1.05em;
26.73 + letter-spacing: 0.01em;
26.74 + font-style: normal
26.75 + }
26.76 +hr {
26.77 + border: 1px solid #abc;
26.78 + margin: 2em
26.79 + }
26.80 +tt {
26.81 + /* background-color: #f2f2f2; */
26.82 + /* border-bottom: 1px solid #ddd; */
26.83 + color: #222;
26.84 + font-weight: bold
26.85 + }
26.86 +tt.descname {
26.87 + background-color: transparent;
26.88 + font-weight: bold;
26.89 + font-size: 1.2em;
26.90 + border: 0
26.91 + }
26.92 +tt.descclassname {
26.93 + background-color: transparent;
26.94 + border: 0
26.95 + }
26.96 +tt.xref {
26.97 + background-color: transparent;
26.98 + font-weight: bold;
26.99 + border: 0
26.100 + }
26.101 +a tt {
26.102 + background-color: transparent;
26.103 + font-weight: bold;
26.104 + border: 0;
26.105 + color: #CA7900
26.106 + }
26.107 +a tt:hover {
26.108 + color: #2491CF;
26.109 +}
26.110 +
26.111 +.field-list ul {
26.112 + margin: 0;
26.113 + padding-left: 1em;
26.114 +}
26.115 +
26.116 +.field-list p {
26.117 + margin: 0;
26.118 +}
26.119 +
26.120 +dl {
26.121 + margin-bottom: 15px;
26.122 +}
26.123 +
26.124 +dd p {
26.125 + margin-top: 0px;
26.126 +}
26.127 +
26.128 +dd ul, dd table {
26.129 + margin-bottom: 10px;
26.130 +}
26.131 +
26.132 +dd {
26.133 + margin-top: 3px;
26.134 + margin-bottom: 10px;
26.135 + margin-left: 30px;
26.136 +}
26.137 +
26.138 +.refcount {
26.139 + color: #060;
26.140 +}
26.141 +
26.142 +dt:target,
26.143 +.highlight {
26.144 + background-color: #fbe54e;
26.145 +}
26.146 +
26.147 +dl.glossary dt {
26.148 + font-weight: bold;
26.149 + font-size: 1.1em;
26.150 +}
26.151 +
26.152 +pre {
26.153 + line-height: 120%;
26.154 +}
26.155 +
26.156 +pre a {
26.157 +/* color: inherit; */
26.158 + text-decoration: underline;
26.159 +}
26.160 +
26.161 +.first {
26.162 + margin-top: 0 !important;
26.163 +}
26.164 +
26.165 +div.document {
26.166 + background-color: white;
26.167 + text-align: left;
26.168 + background-image: url(contents.png);
26.169 + background-repeat: repeat-x;
26.170 +}
26.171 +
26.172 +/*
26.173 +div.documentwrapper {
26.174 + width: 100%;
26.175 +}
26.176 +*/
26.177 +
26.178 +div.clearer {
26.179 + clear: both;
26.180 +}
26.181 +
26.182 +div.related h3 {
26.183 + display: none;
26.184 +}
26.185 +
26.186 +div.related ul {
26.187 + background-image: url(navigation.png);
26.188 + height: 2em;
26.189 + list-style: none;
26.190 + border-top: 1px solid #ddd;
26.191 + border-bottom: 1px solid #ddd;
26.192 + margin: 0;
26.193 + padding-left: 10px;
26.194 +}
26.195 +
26.196 +div.related ul li {
26.197 + margin: 0;
26.198 + padding: 0;
26.199 + height: 2em;
26.200 + float: left;
26.201 +}
26.202 +
26.203 +div.related ul li.right {
26.204 + float: right;
26.205 + margin-right: 5px;
26.206 +}
26.207 +
26.208 +div.related ul li a {
26.209 + margin: 0;
26.210 + padding: 0 5px 0 5px;
26.211 + line-height: 1.75em;
26.212 + color: #EE9816;
26.213 +}
26.214 +
26.215 +div.related ul li a:hover {
26.216 + color: #3CA8E7;
26.217 +}
26.218 +
26.219 +div.body {
26.220 + margin: 0;
26.221 + padding: 0.5em 20px 20px 20px;
26.222 +}
26.223 +
26.224 +div.bodywrapper {
26.225 + margin: 0 240px 0 0;
26.226 + border-right: 1px solid #ccc;
26.227 +}
26.228 +
26.229 +div.body a {
26.230 + text-decoration: underline;
26.231 +}
26.232 +
26.233 +div.sphinxsidebar {
26.234 + margin: 0;
26.235 + padding: 0.5em 15px 15px 0;
26.236 + width: 210px;
26.237 + float: right;
26.238 + text-align: left;
26.239 +/* margin-left: -100%; */
26.240 +}
26.241 +
26.242 +div.sphinxsidebar h4, div.sphinxsidebar h3 {
26.243 + margin: 1em 0 0.5em 0;
26.244 + font-size: 0.9em;
26.245 + padding: 0.1em 0 0.1em 0.5em;
26.246 + color: #940000;
26.247 + border: 1px solid #940000;
26.248 + background-color: #f0ae4a
26.249 + }
26.250 +div.sphinxsidebar ul ul {
26.251 + padding-left: 1.5em;
26.252 + margin-top: 7px;
26.253 + list-style: none;
26.254 + padding: 0;
26.255 + line-height: 130%;
26.256 +}
26.257 +
26.258 +div.sphinxsidebar ul ul {
26.259 + list-style: square;
26.260 + margin-left: 20px;
26.261 +}
26.262 +
26.263 +p {
26.264 + margin: 0.8em 0 0.5em 0;
26.265 +}
26.266 +
26.267 +p.rubric {
26.268 + font-weight: bold;
26.269 +}
26.270 +
26.271 +h1 {
26.272 + margin: 0;
26.273 + padding: 0.7em 0 0.3em 0;
26.274 + font-size: 1.5em;
26.275 + color: #11557C;
26.276 +}
26.277 +
26.278 +h2 {
26.279 + margin: 1.3em 0 0.2em 0;
26.280 + font-size: 1.35em;
26.281 + padding: 0;
26.282 +}
26.283 +
26.284 +h3 {
26.285 + margin: 1em 0 -0.3em 0;
26.286 + font-size: 1.2em;
26.287 +}
26.288 +
26.289 +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
26.290 + color: #333333
26.291 + }
26.292 +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
26.293 + display: none;
26.294 + margin: 0 0 0 0.3em;
26.295 + padding: 0 0.2em 0 0.2em;
26.296 + color: #aaa!important;
26.297 +}
26.298 +
26.299 +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
26.300 +h5:hover a.anchor, h6:hover a.anchor {
26.301 + display: inline;
26.302 +}
26.303 +
26.304 +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
26.305 +h5 a.anchor:hover, h6 a.anchor:hover {
26.306 + color: #777;
26.307 + background-color: #eee;
26.308 +}
26.309 +
26.310 +table {
26.311 + border-collapse: collapse;
26.312 + margin: 0 -0.5em 0 -0.5em;
26.313 +}
26.314 +
26.315 +table td, table th {
26.316 + padding: 0.2em 0.5em 0.2em 0.5em;
26.317 +}
26.318 +
26.319 +div.footer {
26.320 + background-color: #f0ae4a;
26.321 + color: #86989B;
26.322 + padding: 3px 8px 3px 0;
26.323 + clear: both;
26.324 + font-size: 0.8em;
26.325 + text-align: right;
26.326 +}
26.327 +
26.328 +div.footer a {
26.329 + color: #86989B;
26.330 + text-decoration: underline;
26.331 +}
26.332 +
26.333 +div.pagination {
26.334 + margin-top: 2em;
26.335 + padding-top: 0.5em;
26.336 + border-top: 1px solid black;
26.337 + text-align: center;
26.338 +}
26.339 +
26.340 +div.sphinxsidebar ul.toc {
26.341 + margin: 1em 0 1em 0;
26.342 + padding: 0 0 0 0.5em;
26.343 + list-style: none;
26.344 +}
26.345 +
26.346 +div.sphinxsidebar ul.toc li {
26.347 + margin: 0.5em 0 0.5em 0;
26.348 + font-size: 0.9em;
26.349 + line-height: 130%;
26.350 +}
26.351 +
26.352 +div.sphinxsidebar ul.toc li p {
26.353 + margin: 0;
26.354 + padding: 0;
26.355 +}
26.356 +
26.357 +div.sphinxsidebar ul.toc ul {
26.358 + margin: 0.2em 0 0.2em 0;
26.359 + padding: 0 0 0 1.8em;
26.360 +}
26.361 +
26.362 +div.sphinxsidebar ul.toc ul li {
26.363 + padding: 0;
26.364 +}
26.365 +
26.366 +div.admonition, div.warning {
26.367 + font-size: 0.9em;
26.368 + margin: 1em 0 0 0;
26.369 + border: 1px solid #86989B;
26.370 + background-color: #f7f7f7;
26.371 +}
26.372 +
26.373 +div.admonition p, div.warning p {
26.374 + margin: 0.5em 1em 0.5em 1em;
26.375 + padding: 0;
26.376 +}
26.377 +
26.378 +div.admonition pre, div.warning pre {
26.379 + margin: 0.4em 1em 0.4em 1em;
26.380 +}
26.381 +
26.382 +div.admonition p.admonition-title,
26.383 +div.warning p.admonition-title {
26.384 + margin: 0;
26.385 + padding: 0.1em 0 0.1em 0.5em;
26.386 + color: white;
26.387 + border-bottom: 1px solid #86989B;
26.388 + font-weight: bold;
26.389 + background-color: #fe6f20;
26.390 +}
26.391 +
26.392 +div.warning {
26.393 + border: 1px solid #940000;
26.394 +}
26.395 +
26.396 +div.warning p.admonition-title {
26.397 + background-color: #CF0000;
26.398 + border-bottom-color: #940000;
26.399 +}
26.400 +
26.401 +div.admonition ul, div.admonition ol,
26.402 +div.warning ul, div.warning ol {
26.403 + margin: 0.1em 0.5em 0.5em 3em;
26.404 + padding: 0;
26.405 +}
26.406 +
26.407 +div.versioninfo {
26.408 + margin: 1em 0 0 0;
26.409 + border: 1px solid #ccc;
26.410 + background-color: #DDEAF0;
26.411 + padding: 8px;
26.412 + line-height: 1.3em;
26.413 + font-size: 0.9em;
26.414 +}
26.415 +
26.416 +
26.417 +a.headerlink {
26.418 + color: #c60f0f!important;
26.419 + font-size: 1em;
26.420 + margin-left: 6px;
26.421 + padding: 0 4px 0 4px;
26.422 + text-decoration: none!important;
26.423 + visibility: hidden;
26.424 +}
26.425 +
26.426 +h1:hover > a.headerlink,
26.427 +h2:hover > a.headerlink,
26.428 +h3:hover > a.headerlink,
26.429 +h4:hover > a.headerlink,
26.430 +h5:hover > a.headerlink,
26.431 +h6:hover > a.headerlink,
26.432 +dt:hover > a.headerlink {
26.433 + visibility: visible;
26.434 +}
26.435 +
26.436 +a.headerlink:hover {
26.437 + background-color: #ccc;
26.438 + color: white!important;
26.439 +}
26.440 +
26.441 +table.indextable td {
26.442 + text-align: left;
26.443 + vertical-align: top;
26.444 +}
26.445 +
26.446 +table.indextable dl, table.indextable dd {
26.447 + margin-top: 0;
26.448 + margin-bottom: 0;
26.449 +}
26.450 +
26.451 +table.indextable tr.pcap {
26.452 + height: 10px;
26.453 +}
26.454 +
26.455 +table.indextable tr.cap {
26.456 + margin-top: 10px;
26.457 + background-color: #f2f2f2;
26.458 +}
26.459 +
26.460 +img.toggler {
26.461 + margin-right: 3px;
26.462 + margin-top: 3px;
26.463 + cursor: pointer;
26.464 +}
26.465 +
26.466 +form.pfform {
26.467 + margin: 10px 0 20px 0;
26.468 +}
26.469 +
26.470 +table.contentstable {
26.471 + width: 90%;
26.472 +}
26.473 +
26.474 +table.contentstable p.biglink {
26.475 + line-height: 150%;
26.476 +}
26.477 +
26.478 +a.biglink {
26.479 + font-size: 1.3em;
26.480 +}
26.481 +
26.482 +span.linkdescr {
26.483 + font-style: italic;
26.484 + padding-top: 5px;
26.485 + font-size: 90%;
26.486 +}
26.487 +
26.488 +ul.search {
26.489 + margin: 10px 0 0 20px;
26.490 + padding: 0;
26.491 +}
26.492 +
26.493 +ul.search li {
26.494 + padding: 5px 0 5px 20px;
26.495 + background-image: url(file.png);
26.496 + background-repeat: no-repeat;
26.497 + background-position: 0 7px;
26.498 +}
26.499 +
26.500 +ul.search li a {
26.501 + font-weight: bold;
26.502 +}
26.503 +
26.504 +ul.search li div.context {
26.505 + color: #888;
26.506 + margin: 2px 0 0 30px;
26.507 + text-align: left;
26.508 +}
26.509 +
26.510 +ul.keywordmatches li.goodmatch a {
26.511 + font-weight: bold
26.512 + }
26.513 +div.sidebar {
26.514 + margin-left: 1em;
26.515 + margin-top: 1em;
26.516 + border: 1px solid orange;
26.517 + padding: 1em;
26.518 + background-color: #FFFFCC;
26.519 + width: 40%;
26.520 + float: right;
26.521 + clear: right;
26.522 + margin-bottom: 20px
26.523 + }
27.1 Binary file docs/_static/reteisi.png has changed
28.1 Binary file docs/_static/sphinx.png has changed
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/docs/_templates/index.html Mon Apr 26 11:16:23 2010 +0200
29.3 @@ -0,0 +1,86 @@
29.4 +{% extends "layout.html" %}
29.5 +{% set title = 'Overview' %}
29.6 +{% block body %}
29.7 +<!-- <p style="background-color: #fcc; font-size: large; border: 1px solid #f00; padding: 10px;">
29.8 + <b>Attention:</b> this is a preview. Sphinx is not released yet on PyPI,
29.9 + and the contents of this documentation are subject to change.
29.10 + </p> -->
29.11 +
29.12 + <h1>Benvenuti</h1>
29.13 +
29.14 + <p>
29.15 + La nuova documentazione è <a href="2.0/" >ora disponibile</a>
29.16 +
29.17 + ReteIsi è una soluzione che cerca di rendere l'amministrazione di un
29.18 + sistema scolastico accessibile al personale scolastico senza richiedere un
29.19 + eccessivo sforzo. Il progetto <a href="http://www.reteisi.org">ReteIsi</a>
29.20 + è nato come prodotto di una associazione di scuole nel 2002, anno in cui
29.21 + ricevette un cospicuo finanziamento, viene costantemente aggiornato e
29.22 + migliorato. Nel 2008 e 2010 ha ricevuto finanziamenti dal progetto
29.23 + <a href="http://www.reteidra.org">ReteIdra</a>grazie al quale fra le altre
29.24 + cose, è stata aggiunta una interfaccia web per la gestione utenti, dns e
29.25 + logon ed è stato potenziata la gestione del server come server LTSP.
29.26 +
29.27 + </p>
29.28 + <p>
29.29 + Questo obiettivo è raggiunto
29.30 + <ul>
29.31 + <li>
29.32 + Avendo fatto a monte una scelta degli strumenti più idonei (distribuzione,
29.33 + processo di autenticazione, firewall, ...)
29.34 + </li>
29.35 + <li>
29.36 + Avendo creato degli strumenti idonei alla gestione di utenti in massa
29.37 + (ad esempio l'inserimento di 5/800 utenti all'inizio dell'anno può
29.38 + essere fatta in una decina di minuti)
29.39 + </li>
29.40 + <li>
29.41 + Avendo raccolto la documentazione pertinente ai casi d'uso più
29.42 + frequenti
29.43 + </li>
29.44 + </ul>
29.45 +
29.46 + <h2>Stiamo lavorando su...</h2>
29.47 +
29.48 + I lavori appena ultimati sono:
29.49 + <ul>
29.50 + <li>Una completa riscrittura delle librerie in python che usa
29.51 + <a href="http://pumpkin.prymitive.com/">pumpkin</a>come wrapper per ldap<li>
29.52 + <li>Una <a href="gestione/web.html">interfaccia web</a> per la gestione degli utenti, del logon (da
29.53 + client Windows) e del dns (con particolare attenzione a boot di macchien
29.54 + LTSP in modalità thin e fat)</li>
29.55 + <li>Sandro Dentella sta tenendo un corso per amministratori scolastici
29.56 + in 8 giornate. Se siete interessati alle presentazioni delle lezioni
29.57 + le trovate nel sito del <a href="http://tickets.reteidra.org/corsi/">corso</a>
29.58 + </li>
29.59 + </ul>
29.60 +
29.61 + <h2>Documentazione</h2>
29.62 +
29.63 + La documentazione è scritta con un tool chiamato <a
29.64 + href="http://sphinx.pocoo.org/" >Sphinx</a>, sviluppato da Georg Brandl,
29.65 + originariamente scritto per il nuovo sistema di documentazione di
29.66 + <a href="http://docs.python.org/dev/">Python</a>. Sphinx è basato su un
29.67 + reST, un linguaggio di markup molto comodo da usare.
29.68 +
29.69 + Qui puoi leggere maggiori informazioni sul sistema di documentazione e su
29.70 + come puoi contribuire a renderlo migliore.
29.71 +
29.72 +
29.73 + <table class="contentstable" align="center" style="margin-left: 30px"><tr>
29.74 + <td width="50%">
29.75 + <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Contenuti</a><br>
29.76 + <span class="linkdescr">per la documentazione completa</span></p>
29.77 + <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br>
29.78 + <span class="linkdescr">cerca nella documentazione - non ancora configurato</span></p>
29.79 + </td><td width="50%">
29.80 + <p class="biglink"><a class="biglink" href="{{ pathto("genindex")
29.81 + }}">Indice Generale</a><br>
29.82 + <span class="linkdescr">comandi, voci utili....</span></p>
29.83 + <p class="biglink"><a class="biglink" href="http://sphinx.pocoo.org/rest.html">Markup</a><br>
29.84 + <span class="linkdescr">Sistema di markup usato (reST)</span></p>
29.85 + </td></tr>
29.86 + </table>
29.87 +
29.88 +
29.89 +{% endblock %}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/docs/_templates/indexsidebar.html Mon Apr 26 11:16:23 2010 +0200
30.3 @@ -0,0 +1,17 @@
30.4 +<h3>Download</h3>
30.5 +
30.6 + ReteIsi offre una distribuzione live scaricabile dal sito di
30.7 + <a href="http://download.argolinux.org/isi/">Argolinux</a>
30.8 +
30.9 + L'ultima versione è la
30.10 + <a href="http://download.argolinux.org/isi/newisi-libata-beta6.iso">
30.11 + newisi-libata-beta6</a> basata su etch.
30.12 +
30.13 +<h3>Domande? Problemi?</h3>
30.14 +
30.15 +<p>Iscriviti al <a href="http://groups.google.com/group/reteisi">
30.16 + Google group</a>:</p>
30.17 +<form action="http://groups.google.com/group/reteisi/boxsubscribe" style="padding-left: 1em">
30.18 + <input type="text" name="email" value="your@email"/>
30.19 + <input type="submit" name="sub" value="Subscribe" />
30.20 +</form>
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/docs/_templates/layout.html Mon Apr 26 11:16:23 2010 +0200
31.3 @@ -0,0 +1,17 @@
31.4 +{% extends "!layout.html" %}
31.5 +
31.6 +{% block rootrellink %}
31.7 + <li><a href="{{ pathto('index') }}">ReteIsi </a> | </li>
31.8 + <li><a href="{{ pathto('contents') }}">Documentazione </a> »</li>
31.9 +{% endblock %}
31.10 +
31.11 +{% block beforerelbar %}
31.12 +QUI
31.13 +<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px">
31.14 +<a href="http://www.reteisi.org" ><img src="{{ pathto("img/reteisi.png",1) }}" border="0"></a>
31.15 +</div>
31.16 +{% endblock %}
31.17 +
31.18 +{# put the sidebar before the body #}
31.19 +{% block sidebar1 %}{{ sidebar() }}{% endblock %}
31.20 +{% block sidebar2 %}{% endblock %}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/docs/_templates/macros.html Mon Apr 26 11:16:23 2010 +0200
32.3 @@ -0,0 +1,49 @@
32.4 +{%- macro sidebar %}
32.5 + {%- if builder != 'htmlhelp' %}
32.6 + <div class="sidebar_sphinx">
32.7 + <div class="sidebarwrapper">
32.8 + {% if display_toc %}
32.9 + <h3>Contentenuti</h3>
32.10 + {{ toc }}
32.11 + {% endif %}
32.12 + {%- if prev %}
32.13 + <h4>Argomento precedente</h4>
32.14 + <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
32.15 + {%- endif %}
32.16 + {%- if next %}
32.17 + <h4>Argomento successivo</h4>
32.18 + <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
32.19 + {%- endif %}
32.20 + {% if sourcename %}
32.21 + <h3>Questa Pagina</h3>
32.22 + <ul class="this-page-menu">
32.23 + {% if builder == 'web' %}
32.24 + <li><a href="#comments">Commenti ({{ comments|length }} so far)</a></li>
32.25 + <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
32.26 + <li><a href="{{ pathto('@source/' + sourcename)|e }}">Sorgente della pagina</a></li>
32.27 +
32.28 + {% elif builder == 'html' %}
32.29 + <li><a href="{{ pathto('_sources/' + sourcename, true)|e
32.30 + }}">Mostra Sorgente</a></li>
32.31 + {% endif %}
32.32 + </ul>
32.33 + {% endif %}
32.34 + {% if customsidebar %}
32.35 + {{ rendertemplate(customsidebar) }}
32.36 + {% endif %}
32.37 + {% if current_page_name != "search" %}
32.38 + <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
32.39 + <form class="search" action="{{ pathto('search') }}" method="get">
32.40 + <input type="text" name="q" size="18"> <input type="submit" value="Go">
32.41 + <input type="hidden" name="check_keywords" value="yes">
32.42 + <input type="hidden" name="area" value="default">
32.43 + </form>
32.44 + {% if builder == 'web' %}
32.45 + <p style="font-size: 90%">Enter a module, class or function name.</p>
32.46 + {% endif %}
32.47 + {% endif %}
32.48 + </div>
32.49 + </div>
32.50 + {%- endif %}
32.51 +{%- endmacro %}
32.52 +
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/docs/allegati/biblioteca.rst Mon Apr 26 11:16:23 2010 +0200
33.3 @@ -0,0 +1,10 @@
33.4 +=====================================
33.5 + Supporto alla biblioteca scolastica
33.6 +=====================================
33.7 +
33.8 +
33.9 +E` possibile installare u software di gestione della biblioteca (PBM) integrato
33.10 +nel sistema.
33.11 +
33.12 +
33.13 +DOCUMENTAZIONE DA SCRIVERE
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/docs/allegati/contents.rst Mon Apr 26 11:16:23 2010 +0200
34.3 @@ -0,0 +1,13 @@
34.4 +==========
34.5 + Allegati
34.6 +==========
34.7 +
34.8 +.. toctree::
34.9 +
34.10 + changelog
34.11 + glossario
34.12 + debug/contents
34.13 + netkit/intro
34.14 + masterizzare
34.15 + biblioteca
34.16 +
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/docs/allegati/debug/contents.rst Mon Apr 26 11:16:23 2010 +0200
35.3 @@ -0,0 +1,23 @@
35.4 +Troubleshooting
35.5 +=================
35.6 +
35.7 +In questo capitolo affrontiamo alcune linee guida per il debug di
35.8 +problemi. Lo strumento principale è :command:`isi-checkup` che però si
35.9 +limita a fare i test che è possibile fare **dall'interno** della macchina.
35.10 +
35.11 +Per i test che è necessario fare dall'esterno suggeriamo di usare macchine
35.12 +virtuali se il vostro server è sufficientemente potente per permettervelo.
35.13 +
35.14 +Una cosa che suggeriamo è di avere su ogni server reale anche un server
35.15 +vmware con un client per ogni SO che usate (W98, XP, ubuntu...). Vi sarà
35.16 +facile connettervi anche da remoto, abilitare il client e fare le prove
35.17 +necessarie in caso di intervento. Alternativamente dovrete chiedere di
35.18 +lasciare acceso un server con VNC attivato: è molto meno pratico.
35.19 +
35.20 +.. toctree::
35.21 +
35.22 + isi-checkup
35.23 + vmware
35.24 + faq
35.25 +
35.26 +
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/docs/allegati/debug/faq.rst Mon Apr 26 11:16:23 2010 +0200
36.3 @@ -0,0 +1,11 @@
36.4 +=====
36.5 + Faq
36.6 +=====
36.7 +::
36.8 +
36.9 + + prima installazione
36.10 + D: Ho inserito il cd e riavviato la macchina ma il sistema non boota da cd.
36.11 +
36.12 + R: Verificare che il bios sia configurato correttamente per boot da cdrom.
36.13 + Spesso l'impostazione default è di avviare direttamente dal primo disco
36.14 +
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/docs/allegati/debug/isi-checkup.rst Mon Apr 26 11:16:23 2010 +0200
37.3 @@ -0,0 +1,61 @@
37.4 +Server
37.5 +------
37.6 +
37.7 +E` appena stato terminato lo strumento :command:`isi-checkup` che renderà
37.8 +assolutamente semplice fare ogni controllo che possa essere fatto
37.9 +dall'interno della macchina per via di un :ref:`test`. Sarà facile per
37.10 +intendersi verificare se una password è valida o se gli utenti hanno i
37.11 +permessi corretti, mentre non sarà possibile verificare se un client riesce
37.12 +a fare il :ref:`join <join>`
37.13 +
37.14 +
37.15 +.. _test:
37.16 +
37.17 +test
37.18 +----
37.19 +
37.20 +Per test si intende un piccolo codice (una script bash o una funzione in
37.21 +python) che effettua un singolo controllo e ritorna un valore chiaro:
37.22 +
37.23 +* per una script di shell: 0 in caso il test sia passato e un valore
37.24 + positivo se il test non è passato
37.25 +
37.26 +* per una funzione in python: True se il test è passato ed un errore
37.27 + opportuno (ereditato da ``IsiCheckupError``) in caso contrario
37.28 +
37.29 +sarà possibile chiamare :command:`isi-checkup` in 3 modi:
37.30 +
37.31 +1. ``isi-checkup -s``: checkup dei test di sistema
37.32 +2. ``isi-checkup -u user``: checkup per un singolo user
37.33 +3. ``isi-checkup -a``: check di tutti gli utenti (lungo)
37.34 +
37.35 +Esempio bash
37.36 +~~~~~~~~~~~~
37.37 +:file:`/etc/isi/checkup/tests-enabled/test-smbd.sh` ::
37.38 +
37.39 + #!/bin/bash
37.40 +
37.41 + if pgrep -x smbd ; then
37.42 + exit 0
37.43 + else
37.44 + echo "il processo smbd non sta girando"
37.45 + exit 1
37.46 + fi
37.47 +
37.48 +Interoperabilità
37.49 +----------------
37.50 +
37.51 +edubuntu + dominio isi
37.52 +~~~~~~~~~~~~~~~~~~~~~~
37.53 +
37.54 + * gli utenti non sentono i suoni
37.55 + * gli utenti non montano la chiavetta e ricevono il seguente messaggio
37.56 + d'errore: HAL....
37.57 +
37.58 +windows + dominio
37.59 +~~~~~~~~~~~~~~~~~
37.60 +
37.61 + * win98 + dominio isi
37.62 + * win2k + dominio isi
37.63 + * xp + dominio isi
37.64 +
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/docs/allegati/debug/vmware.rst Mon Apr 26 11:16:23 2010 +0200
38.3 @@ -0,0 +1,54 @@
38.4 +
38.5 +Vmware Server
38.6 +=============
38.7 +
38.8 +Vmware è un server di virtualizzazione. La licenza è (verificare) e quindi è
38.9 +possibile utilizzarlo anche a scuola. Ne apprezzo la struttura in quanto è
38.10 +separato fra un server ed un client e quindi è possibile usarlo da remoto,
38.11 +fare partire e fermare le macchine virtuali e quindi rende possibile fare
38.12 +partire macchie virtuali su server che non siano dotati di server X.
38.13 +
38.14 +Installazione
38.15 +-------------
38.16 +
38.17 +Il CD di Argo ha già tutto quanto serve per installare vmware-server tranne
38.18 +vmware stesso.
38.19 +
38.20 +Per chi invece debba installarlo in una distribuzione debian semplice o in Argo
38.21 +probabilmente mancheranno alcune dipendenze::
38.22 +
38.23 + apt-get install libx11-6 libxtst6 libxext6 libxt6 libice6 libsm6 libxrender1
38.24 +
38.25 +L'installazione è composta da pochi passi:
38.26 +
38.27 +1. scompattazione della immagine scaricata dal sito hyyp://www.vmware.com
38.28 +2. ./vmware-install.pl
38.29 +
38.30 + Questa fase pone alcune domande: si può rispondere accettando i default,
38.31 + a tutte le domande, compresa la configurazione della rete, tranne a
38.32 + quelle in cui chiede il percorso del compilatore per le API perl di
38.33 + Vmware (che non vi servono).
38.34 +
38.35 + Nel CD Reteisi non c'è compilatore ma c'è un modulo per vmware quindi non
38.36 + è necessario. L installatore di Vmware se ne accorge e non vi chiede di
38.37 + compilarlo.
38.38 +
38.39 +3. installazione del sistema operativo nella macchina virtualizzata.
38.40 +
38.41 + Per fare questo in genere partirete da un CD o da una immagine iso. In
38.42 + questa ultima ipotesi non avete neanche bisogno di
38.43 + masterizzarla: configurate il CD della macchina (doppio click sulla icona
38.44 + del CD) perché usi l'immagine iso *come cd*
38.45 +
38.46 +
38.47 +Setup
38.48 +-----
38.49 +
38.50 +
38.51 +Personalmente (Sandro) facendo molti interventi da remoto nelle scuole, lo
38.52 +sto usando per testare la rete su macchine sicuramente ben configurate.
38.53 +
38.54 +Quando installo un laboratorio, installo anche una macchina client in
38.55 +vmware. Nel caso insorgano problemi posso usare quella macchina (virtuale)
38.56 +per prove da remoto.
38.57 +
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/docs/allegati/glossario.rst Mon Apr 26 11:16:23 2010 +0200
39.3 @@ -0,0 +1,91 @@
39.4 +===============
39.5 + MiniGlossario
39.6 +===============
39.7 +
39.8 +editor
39.9 +======
39.10 +
39.11 +.. glossary::
39.12 +
39.13 + nano
39.14 + editor considerano normalmente molto semplice da usare
39.15 +
39.16 + jmacs
39.17 + editor molto leggero, facile da usare secondo me (Sandro) per il fatto
39.18 + che ha gli stessi comandi di :term:`emacs`
39.19 +
39.20 + emacs
39.21 + il migliore degli editor, senza dubbi... almeno se fate programmazione,
39.22 + siete disposti ad essere di parte e.... siete dalla mia parte! \*:-)
39.23 +
39.24 +concetti
39.25 +========
39.26 +
39.27 +.. glossary::
39.28 +
39.29 +
39.30 + raid
39.31 + sistema di uso di più dischi che vengono visti dal sistema come una sola
39.32 + unità allo scopo di avere una ridondanza dei dati (raid1, raid5, raid6) o
39.33 + una maggiore velocità di accesso al disco (raid0)
39.34 +
39.35 +
39.36 + raid1
39.37 + sistema raid che mette i dischi in mirroring. I dati vengono
39.38 + scritti in parallelo su due (o più) dischi. La lettura risulta più
39.39 + rapida che con un solo disco. In caso di guasto di un disco, il sistema
39.40 + esclude il disco dall'array e permette di continuare il normale
39.41 + lavoro. A questo punto è necessario sostituire il disco. Può essere
39.42 + implementato sia via software che via hardware.
39.43 +
39.44 +
39.45 + network
39.46 + maschera di rete.
39.47 +
39.48 + .. seealso:: http://it.wikipedia.org/wiki/Subnet_mask
39.49 +
39.50 + gateway
39.51 + macchina o router che permette di congiungere due reti. Spesso una rete
39.52 + interna ad
39.53 +
39.54 +
39.55 +
39.56 +comandi di sistema
39.57 +==================
39.58 +
39.59 +.. glossary::
39.60 +
39.61 + ifconfig
39.62 + comando per impostare l'IP della interfaccia di rete::
39.63 +
39.64 + ifconfig eth0 192.168.5.1
39.65 +
39.66 +
39.67 + route
39.68 + comando di sistema che permette di impostare un instradamento, ovvero di
39.69 + dire al kernel che strada devono prendere i pacchetti per poter
39.70 + raggiungere una destinazione, il comando::
39.71 +
39.72 + route add -net default gw 192.168.5.254
39.73 +
39.74 + imposta come destinazione di default l'IP 192..168.5.254
39.75 +
39.76 + df
39.77 + disk free. Mostra quali partizioni sono montate e quanto spazio libero
39.78 + hanno. Molto comoda l'opzione ``-h`` che restituisce i dati in formato
39.79 + _human_ (Gbytes e non blocchi)
39.80 +
39.81 + ldapsearch
39.82 + client ldap. l'uso è sostanzialmente limitato al debug. Ad esempio::
39.83 +
39.84 + ldapsearch -xLLL uid=Administrator
39.85 +
39.86 + dovrebbe sempre restituire i dati dell'utente Administrator in formato
39.87 + ``ldif``
39.88 +
39.89 + getent
39.90 + ``getent passwd``: restituisce tutti gli utenti del sistema, sia reali
39.91 + che ldap, secondo quanto definito nel file :file:`/etc/nsswitch`
39.92 +
39.93 + ``getent group``: analogo al precedente restituisce i gruppi
39.94 +
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/docs/allegati/masterizzare.rst Mon Apr 26 11:16:23 2010 +0200
40.3 @@ -0,0 +1,26 @@
40.4 +.. _masterizzare_iso:
40.5 +
40.6 +==========================
40.7 + Masterizzare le immagini
40.8 +==========================
40.9 +
40.10 +
40.11 +Masterizzare un'immagine ISO da Windows
40.12 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40.13 +
40.14 ++ nero ...
40.15 ++ altri programmi
40.16 +
40.17 +Masterizzare un'immagine ISO da Linux
40.18 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40.19 +
40.20 +Aprire un terminale e posizionarsi nella directory contenente il file iso
40.21 +scaricato. Dopo aver inserito un cd vuoto, lanciare il comando::
40.22 +
40.23 + cdrecord -v nomefile.iso
40.24 +
40.25 +Qualora non fosse presente sul sistema in uso il programma *cdrecord*, lo si
40.26 +potrà installare lanciando come super-utente *root* il seguente comando::
40.27 +
40.28 + apt-get install cdrecord
40.29 +
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/docs/conf.py Mon Apr 26 11:16:23 2010 +0200
41.3 @@ -0,0 +1,172 @@
41.4 +# -*- coding: utf-8 -*-
41.5 +#
41.6 +# Sphinx documentation build configuration file, created by
41.7 +# sphinx-quickstart.py on Sat Mar 8 21:47:50 2008.
41.8 +#
41.9 +# This file is execfile()d with the current directory set to its containing dir.
41.10 +#
41.11 +# The contents of this file are pickled, so don't put values in the namespace
41.12 +# that aren't pickleable (module imports are okay, they're removed automatically).
41.13 +#
41.14 +# All configuration values have a default value; values that are commented out
41.15 +# serve to show the default value.
41.16 +
41.17 +import sys, os, re
41.18 +cur_dir = os.path.dirname(__file__)
41.19 +sys.path += [cur_dir]
41.20 +sys.path += [os.path.dirname(cur_dir)]
41.21 +import docusage
41.22 +extensions = ['sphinx.ext.autodoc', 'docusage']
41.23 +
41.24 +# If your extensions are in another directory, add it here.
41.25 +#sys.path.append(os.path.dirname(__file__))
41.26 +
41.27 +# General configuration
41.28 +# ---------------------
41.29 +
41.30 +# Add any Sphinx extension module names here, as strings. They can be extensions
41.31 +# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
41.32 +#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
41.33 +
41.34 +# Add any paths that contain templates here, relative to this directory.
41.35 +templates_path = ['_templates']
41.36 +language="it"
41.37 +# The suffix of source filenames.
41.38 +source_suffix = '.rst'
41.39 +
41.40 +# The master toctree document.
41.41 +master_doc = 'contents'
41.42 +
41.43 +# General substitutions.
41.44 +project = 'ReteIsi'
41.45 +#copyright = '2008, Sandro Dentella, Max Mancini'
41.46 +
41.47 +# The default replacements for |version| and |release|, also used in various
41.48 +# other places throughout the built documents.
41.49 +#
41.50 +# The short X.Y version.
41.51 +version = '0.1'
41.52 +# The full version, including alpha/beta/rc tags.
41.53 +release = '0.1'
41.54 +
41.55 +# There are two options for replacing |today|: either, you set today to some
41.56 +# non-false value, then it is used:
41.57 +#today = ''
41.58 +# Else, today_fmt is used as the format for a strftime call.
41.59 +today_fmt = '%B %d, %Y'
41.60 +
41.61 +# List of documents that shouldn't be included in the build.
41.62 +#unused_docs = []
41.63 +
41.64 +# If true, '()' will be appended to :func: etc. cross-reference text.
41.65 +#add_function_parentheses = True
41.66 +
41.67 +# If true, the current module name will be prepended to all description
41.68 +# unit titles (such as .. function::).
41.69 +#add_module_names = True
41.70 +
41.71 +show_authors = True
41.72 +
41.73 +# The name of the Pygments (syntax highlighting) style to use.
41.74 +pygments_style = 'sphinx'
41.75 +
41.76 +
41.77 +# Options for HTML output
41.78 +# -----------------------
41.79 +
41.80 +# The style sheet to use for HTML and HTML Help pages. A file of that name
41.81 +# must exist either in Sphinx' static/ path, or in one of the custom paths
41.82 +# given in html_static_path.
41.83 +#html_style = 'sphinxdoc.css'
41.84 +html_style = 'reteisi.css'
41.85 +
41.86 +html_logo = 'reteisi.png'
41.87 +
41.88 +# Add any paths that contain custom static files (such as style sheets) here,
41.89 +# relative to this directory. They are copied after the builtin static files,
41.90 +# so a file named "default.css" will overwrite the builtin "default.css".
41.91 +html_static_path = ['_static']
41.92 +
41.93 +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
41.94 +# using the given strftime format.
41.95 +html_last_updated_fmt = '%b %d, %Y'
41.96 +
41.97 +#html_logo = 'reteisi.png'
41.98 +
41.99 +# If true, SmartyPants will be used to convert quotes and dashes to
41.100 +# typographically correct entities.
41.101 +#html_use_smartypants = True
41.102 +
41.103 +# Content template for the index page.
41.104 +html_index = 'index.html'
41.105 +
41.106 +# Custom sidebar templates, maps page names to templates.
41.107 +html_sidebars = {'index': 'indexsidebar.html'}
41.108 +
41.109 +# Additional templates that should be rendered to pages, maps page names to
41.110 +# templates.
41.111 +html_additional_pages = {'index': 'index.html'}
41.112 +
41.113 +# If true, the reST sources are included in the HTML build as _sources/<name>.
41.114 +#html_copy_source = True
41.115 +
41.116 +# Output file base name for HTML help builder.
41.117 +htmlhelp_basename = 'Sphinxdoc'
41.118 +
41.119 +
41.120 +# Options for LaTeX output
41.121 +# ------------------------
41.122 +
41.123 +# The paper size ('letter' or 'a4').
41.124 +latex_paper_size = 'a4'
41.125 +
41.126 +# The font size ('10pt', '11pt' or '12pt').
41.127 +latex_font_size = '10pt'
41.128 +
41.129 +# Grouping the document tree into LaTeX files. List of tuples
41.130 +# (source start file, target name, title, author, document class [howto/manual]).
41.131 +latex_documents = [('contents', 'reteisi.tex', 'Documentazione ReteIsi',
41.132 + 'Sandro Dentella, Massimo Mancini, Simone Castellazzi',
41.133 + 'manual')]
41.134 +
41.135 +# Additional stuff for the LaTeX preamble.
41.136 +#latex_preamble = ''
41.137 +
41.138 +# Documents to append as an appendix to all manuals.
41.139 +#latex_appendices = []
41.140 +
41.141 +automodule_skip_lines = 4
41.142 +
41.143 +
41.144 +# Extension interface
41.145 +# -------------------
41.146 +
41.147 +from sphinx import addnodes
41.148 +
41.149 +dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
41.150 +
41.151 +def parse_directive(env, sig, signode):
41.152 + if not sig.startswith('.'):
41.153 + dec_sig = '.. %s::' % sig
41.154 + signode += addnodes.desc_name(dec_sig, dec_sig)
41.155 + return sig
41.156 + m = dir_sig_re.match(sig)
41.157 + if not m:
41.158 + signode += addnodes.desc_name(sig, sig)
41.159 + return sig
41.160 + name, args = m.groups()
41.161 + dec_name = '.. %s::' % name
41.162 + signode += addnodes.desc_name(dec_name, dec_name)
41.163 + signode += addnodes.desc_classname(args, args)
41.164 + return name
41.165 +
41.166 +
41.167 +def parse_role(env, sig, signode):
41.168 + signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
41.169 + return sig
41.170 +
41.171 +
41.172 +def setup(app):
41.173 + app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
41.174 + app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
41.175 + app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/docs/contents.rst Mon Apr 26 11:16:23 2010 +0200
42.3 @@ -0,0 +1,22 @@
42.4 +.. ReteIsi documentation master file, created by sphinx-quickstart on Thu Apr 10 21:38:49 2008.
42.5 + You can adapt this file completely to your liking, but it should at least
42.6 + contain the root `toctree` directive.
42.7 +
42.8 +=================================================
42.9 + Benvenuti nel sito di documentazione di ReteIsi
42.10 +=================================================
42.11 +
42.12 +
42.13 +.. toctree::
42.14 + :maxdepth: 2
42.15 +
42.16 + progetto/contents
42.17 + install/contents
42.18 + gestione/contents
42.19 + allegati/contents
42.20 +
42.21 +Indices and tables
42.22 +==================
42.23 +
42.24 +* :ref:`search`
42.25 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/docs/docusage.py Mon Apr 26 11:16:23 2010 +0200
43.3 @@ -0,0 +1,121 @@
43.4 +# -*- coding: utf-8 -*-
43.5 +'''
43.6 +This module provides the ``includesh`` directive. It is implemented by
43.7 +:class:`IncludeShellDirective` class.
43.8 +'''
43.9 +import os
43.10 +import re
43.11 +import types
43.12 +import tempfile
43.13 +
43.14 +# Import required docutils modules
43.15 +from sphinx.util.compat import Directive
43.16 +
43.17 +from docutils import io, nodes, statemachine, utils
43.18 +from docutils.parsers.rst import directives
43.19 +from docutils.parsers.rst.directives.misc import Include
43.20 +# from docutils.parsers.rst.directives.tables import ListTable
43.21 +
43.22 +import sphinx
43.23 +
43.24 +
43.25 +#---------------------------------------------------------#
43.26 +class IncludePyProgramDirective(Include):
43.27 + '''
43.28 + IncludeShellDirective implements the directive. The class
43.29 + is registered as a directive in :func:`rusty.includesh.setup`
43.30 + '''
43.31 + required_arguments = 1
43.32 + optional_arguments = 0
43.33 + has_content = None
43.34 + node_class = None
43.35 + option_spec = {
43.36 + 'verbatim': directives.flag,
43.37 + 'docstring': directives.unchanged,
43.38 + }
43.39 +
43.40 + #---------------------------------------------------------#
43.41 + def run(self):
43.42 + '''
43.43 + Called automatically by the docutils.
43.44 + '''
43.45 +
43.46 + # Take the current inclusion file, read it and save in
43.47 + # temporary location where the actual ``Include`` directive
43.48 + # can read it
43.49 +
43.50 + # This part is taken from docutils
43.51 + if not self.state.document.settings.file_insertion_enabled:
43.52 + raise self.warning('"%s" directive disabled.' % self.name)
43.53 +
43.54 + source = self.state_machine.input_lines.source(
43.55 + self.lineno - self.state_machine.input_offset - 1)
43.56 +
43.57 + source_dir = os.path.dirname(os.path.abspath(source))
43.58 + path = directives.path(self.arguments[0])
43.59 +
43.60 + if path.startswith('<') and path.endswith('>'):
43.61 + path = os.path.join(self.standard_include_path, path[1:-1])
43.62 +
43.63 + path = os.path.normpath(os.path.join(source_dir, path))
43.64 + path = utils.relative_path(None, path)
43.65 +
43.66 + try:
43.67 + self.state.document.settings.record_dependencies.add(path)
43.68 + include_file = open(path, 'r+b')
43.69 + except IOError, error:
43.70 + raise self.severe('Problems with "%s" directive path:\n%s: %s.'
43.71 + % (self.name, error.__class__.__name__, error))
43.72 +
43.73 + try:
43.74 + include_text = include_file.read()
43.75 + except UnicodeError, error:
43.76 + raise self.severe(
43.77 + 'Problem with "%s" directive:\n%s: %s'
43.78 + % (self.name, error.__class__.__name__, error))
43.79 +
43.80 + if not 'docstring' in self.options:
43.81 + self.options['docstring'] = '__doc__'
43.82 +
43.83 + self.arguments[0] = self.get_docstring_file(path)
43.84 +
43.85 + return Include.run(self)
43.86 +
43.87 + def get_docstring_file(self, path):
43.88 + p = Program(path)
43.89 + tfd, target_path = tempfile.mkstemp(prefix='sd-')
43.90 + f = open(target_path, 'wb')
43.91 + text = p.docstring
43.92 +
43.93 + if 'verbatim' in self.options:
43.94 + f.write('::\n')
43.95 + pat = re.compile('^', re.MULTILINE)
43.96 + text = re.sub(pat, " ", text )
43.97 +
43.98 + f.write("%s\n" % text)
43.99 + return target_path
43.100 +
43.101 +
43.102 +def setup(app):
43.103 + '''
43.104 + Extension setup, called by Sphinx
43.105 + '''
43.106 + # Sphinx 5 support
43.107 + if '5' in sphinx.__version__.split('.'):
43.108 + app.add_directive('docusage', IncludePyProgramDirective, 0, (0,0,0))
43.109 + else:
43.110 + app.add_directive('docusage', IncludePyProgramDirective)
43.111 +
43.112 +class Program(object):
43.113 +
43.114 + DOCSTRING = re.compile(
43.115 + r'''
43.116 + """(?P<docstring>.*?)"""
43.117 + ''',
43.118 + re.VERBOSE|re.DOTALL
43.119 + )
43.120 + def __init__(self, filename):
43.121 +
43.122 + self.text = open(filename).read()
43.123 + self.docstring = self.DOCSTRING.search(self.text).group('docstring')
43.124 +
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/docs/gestione/comandi_isi.rst Mon Apr 26 11:16:23 2010 +0200
44.3 @@ -0,0 +1,339 @@
44.4 +.. _gestione_comandi_isi:
44.5 +
44.6 +I comandi isi*
44.7 +==============
44.8 +
44.9 +Come operare sul server
44.10 +-----------------------
44.11 +
44.12 +E` possibile gestire gli utenti per mezzo dei comandi presentati di seguito
44.13 +o tramite l'interfaccia web.
44.14 +
44.15 +comandi isi2* e isi*
44.16 +--------------------
44.17 +
44.18 +Con la versione 2.0 di isi, tutti i comandi sono stati riscritti in
44.19 +Python. In un momento di transizione ci sono state due seria di comandi isi* ed isi2*
44.20 +ora gli unici comandi non hanno lídentificativo '2' ma sono quelli in python.
44.21 +
44.22 +Con questa release gli utenti vengono gestiti senza usare i tools
44.23 +smbldap-tools, il che permette in generale una velocità maggiore di
44.24 +esecuzione ed un controllo molto più elevato degli errori.
44.25 +
44.26 +Gestione utenti
44.27 +---------------
44.28 +
44.29 +.. index:: isi-adduser, creazione utenti;
44.30 +
44.31 +.. _isi-adduser:
44.32 +
44.33 +isi-adduser
44.34 +~~~~~~~~~~~~
44.35 +
44.36 +.. docusage:: ../../usr/sbin/isi-adduser
44.37 + :verbatim:
44.38 +
44.39 +Utility per aggiugere utenti. Puo' essere usata sia interattivamente sia in
44.40 +modo script leggendo da file (opzione ``-f``) che passando la definizione dell'
44.41 +alunno da riga di comando.
44.42 +
44.43 +.. note:: Formato file/formato dati
44.44 +
44.45 + Non bisogna confondete il formato dei dati (la successione delle colonne)
44.46 + con il formato del file (.csv o .xls). Nel gergo comune entrambi sono
44.47 + noti come "formato di file"
44.48 +
44.49 + ``csv`` (comma separated values) è un formato di testo in cui le colonne
44.50 + sono separate da "," o da altri caratteri (";" nel nostro caso, "Tab" a
44.51 + volte). Per editare un file .csv si può usare ``opencalc`` o anche un editor
44.52 + di testo qualunque.
44.53 +
44.54 + ``xls`` è un formato binario proprietario della suite Office di
44.55 + Microsoft, deve essere editto con un programma come Excel, opencalc della
44.56 + suite OpenOffice o gnumeric. Il motivo per cui lo supportiamo qui è che
44.57 + il programma ministeriale ``Sissi`` esporta i dati unicamnete in ``.xls``
44.58 +
44.59 + La successione delle colonne determina il modo in cui il programma
44.60 + interpreta i dati. E` una cosa completamente distinta (ed aggiuntiva)
44.61 + rispetto l formato del file, e sono descritti in modo completo di seguito.
44.62 +
44.63 +
44.64 +
44.65 +
44.66 +Formato file .isi
44.67 +.................
44.68 +
44.69 +Il formato della riga deve essere almeno::
44.70 +
44.71 + logname;cognome;nome;gruppo_principale;classe;CF;password
44.72 +
44.73 +possono essere accodati altri campi rispettando il seguente formato::
44.74 +
44.75 + sesso;indirizzo;cap;comune;provincia;telefono
44.76 +
44.77 +ogni campo puo' essere vuoto tranne ``logname``, ``cognome`` e ``gruppo
44.78 +principale`` che deve essere uno fra: admins, alunni, docenti, esterni,
44.79 +segreteria, ata. La classe ha senso per *alunni* ed *esterni* e verra'
44.80 +usata per connettere la risorsa classe.
44.81 +
44.82 +Aggiornamenti
44.83 +.............
44.84 +
44.85 +Se viene usata l'opzione ``--update-users`` ogni utente già esistente viene
44.86 +semplicemente ridefinito, questa è la situazione normale che avviene ad
44.87 +inizio anno. Se non viene usata questa opzione il programma esce con un errore.
44.88 +
44.89 +Ogni riga che inizi con ``-`` corrisponde ad un utente da eliminare. Esempi::
44.90 +
44.91 + -a_dntlsn
44.92 + -a_test;Alunno;Test
44.93 + d_test;Docente;test;docenti;;CF;isi
44.94 +
44.95 +Aggiunge un utente d_test con password *isi* ed elimina due utenti con
44.96 +logname a_dntlsn e a_test.
44.97 +
44.98 +L'opzione ``-z`` indica di eliminare la home degli utenti da cancellare,
44.99 +mentre l'opzione ``--home tar`` (default) crea un file .tgz della home.
44.100 +
44.101 +La forma ``isi-adduser user gruppo`` aggiunge l'utente al gruppo. Ogni nuovo
44.102 +utente viene aggiunto ad alcuni gruppi definiti in
44.103 +``/etc/isi/defaults.py`` nella variabile EXTRA_GROUPS: per default sono
44.104 +gruppi necessari per i sistemi LTSP ``plugdev`` e ``audio``::
44.105 +
44.106 +
44.107 + EXTRA_GROUPS = ['plugdev','audio']
44.108 +
44.109 +Gestione password
44.110 +.................
44.111 +
44.112 +nel momento dell'inserimento è possibile sovrascrivere la password
44.113 +eventualmente presente nel file in formato ``.isi`` con le opzioni di
44.114 +comando:
44.115 +
44.116 +:--default-passwd, -p: ogni utente avrà quella password assegnata
44.117 +
44.118 +:--use-cf, -C: usa i primi o caratteri del CF con la prima lettera maiuscola
44.119 +
44.120 +:--passwd-random, -P: viene generata una password randomica di 8 caratteri
44.121 +
44.122 +:--force-change-passwd, -B: viene imposto il cambio password al primo
44.123 + collegamento. Questo funziona sotto Windows ma non viene forzato con linux
44.124 + in quanto l'interfaccia grafica GDM non permette di fare il login e quindi
44.125 + non si riuscirebbe ad arrivare al cambio password... Accettiamo suggerimenti
44.126 +
44.127 +
44.128 +isi-deluser
44.129 +~~~~~~~~~~~~
44.130 +.. docusage:: ../../usr/sbin/isi-deluser
44.131 + :verbatim:
44.132 +
44.133 +
44.134 +isi-passwd
44.135 +~~~~~~~~~~~
44.136 +
44.137 +.. docusage:: ../../usr/bin/isi-passwd
44.138 + :verbatim:
44.139 +
44.140 +
44.141 +isi-groupcat
44.142 +~~~~~~~~~~~~~
44.143 +.. docusage:: ../../usr/sbin/isi-groupcat
44.144 + :verbatim:
44.145 +
44.146 +
44.147 +isi-alulink
44.148 +~~~~~~~~~~~~~
44.149 +.. docusage:: ../../usr/sbin/isi-alulink
44.150 + :verbatim:
44.151 +
44.152 +
44.153 +isi-classe
44.154 +~~~~~~~~~~~~~
44.155 +.. docusage:: ../../usr/sbin/isi-classe
44.156 + :verbatim:
44.157 +
44.158 +
44.159 +isi-computer
44.160 +~~~~~~~~~~~~~
44.161 +.. docusage:: ../../usr/sbin/isi-computer
44.162 + :verbatim:
44.163 +
44.164 +isi-quota
44.165 +~~~~~~~~~~~~~
44.166 +.. docusage:: ../../usr/sbin/isi-quota
44.167 + :verbatim:
44.168 +
44.169 +isi-wlg
44.170 +~~~~~~~~~~~~~
44.171 +.. docusage:: ../../usr/sbin/isi-wlg
44.172 + :verbatim:
44.173 +
44.174 +isi-perms
44.175 +~~~~~~~~~~
44.176 +
44.177 +.. docusage:: ../../usr/sbin/isi-perms
44.178 + :verbatim:
44.179 +
44.180 +.. _isi-convert:
44.181 +
44.182 +isi-convert
44.183 +~~~~~~~~~~~
44.184 +.. docusage:: ../../usr/sbin/isi-convert
44.185 + :verbatim:
44.186 +
44.187 +A differenza di ``isi-prepusers``, ``isi-convert`` non genera file se non
44.188 +richiesto. Analizza un file in :ref:`formato_sissi` (.csv o .xls), ovvero con colonne di nomi
44.189 +standard e compone un nome di login per l'utente, aggiungendo un progressivo se trova
44.190 +doppioni. E` possibile generare nomi con schemi differenti:
44.191 +
44.192 + :name: il logname viene composta con *nome.cognome*
44.193 + (alessandro.dentella). Opzione ``--name``
44.194 +
44.195 + :cf: il logname viene compostao come identificativo gruppo seguito dal
44.196 + codice fiscale (a_dntlsn63d07). Opzione ``--use-cf``
44.197 +
44.198 + :id-name: il logname viene composto da identificativo gruppo seguito da
44.199 + nome.cognome (d_sandro.dentella). Opzion e ``--id-name``
44.200 +
44.201 +E possibile ottenere come output l'elenco degli utenti che verranno
44.202 +eliminati (opt: ``--delete`` o quello degli utenti rinominati -usando un
44.203 +progressivo- a causa di colisione con nomi esistenti (opt: ``--rename``).
44.204 +
44.205 +Il formato esteso è usato solo nelle scuole dove viene gestita anche la
44.206 +biblioteca. In queste scuole è necessario che il file Sissi abbia anche i
44.207 +dati di residenza e telefono.
44.208 +
44.209 +Il file prodotto da isi-convert può essere usato come input per
44.210 +:ref:`isi-adduser`.
44.211 +
44.212 +``isi-convert`` accetta come input file con dati in due formati differenti:
44.213 +
44.214 +:sissi: il programma di gestione alunni usato da molte scuole italiane
44.215 +:isi: il formato ufficiale di ReteISI. l'ultilità di convertire da .isi a
44.216 + .isi è di potere:
44.217 +
44.218 + * gestire nomi doppi
44.219 + * usare file di input in formato .xls
44.220 +
44.221 +.. _formato_sissi:
44.222 +
44.223 +formato sissi
44.224 +.............
44.225 +
44.226 +Il formato "Sissi" è basato su alcune colonne con nomi standard, il nome
44.227 +della colonna deve rispettare anche nelle maiuscole/Minuscole quanto sotto
44.228 +riportato, ed è per altro il default di Sissi.:
44.229 +
44.230 +:Anno di corso: es.: 3 per la terza classe
44.231 +:Sezione: es.: A
44.232 +:Corso: es.: Programmatori Mercurio
44.233 +:Cognome: ovvio
44.234 +:Nome: ovvio
44.235 +:Codice fiscale: ovvio
44.236 +
44.237 +Da una tabella con queste intestazioni è possibile generare la classe di
44.238 +appartenenza solo in presenza di un opportuno file di corrispondenza fra il
44.239 +Corso e la sigla che si vuole usare, questo file è
44.240 +``/etc/isi/sissi-tabcorsi``::
44.241 +
44.242 + progetto cinque = geo
44.243 + geometri = geo
44.244 + indirizzo giuridico economico aziendale = ige
44.245 + programmatori mercurio = pro
44.246 +
44.247 +
44.248 +In questo esempio la classe di appartenenza dell'alunno è ``pro3a``
44.249 +
44.250 +
44.251 +isi-tools
44.252 +~~~~~~~~~~~
44.253 +
44.254 +.. docusage:: ../../usr/sbin/isi-tools
44.255 + :verbatim:
44.256 +
44.257 +isi-user
44.258 +~~~~~~~~~~~
44.259 +
44.260 +Il programma ``isi-user`` fa alcune funzioni che sono state reimplementate
44.261 +nella interfaccia web. Per questioni di usabilità e di manutenzione del
44.262 +codice raccomandiamo di usare l'interfaccia web.
44.263 +
44.264 +Importare utenti da sissi
44.265 +~~~~~~~~~~~~~~~~~~~~~~~~~
44.266 +
44.267 +.. note::
44.268 +
44.269 + le operazioni di importazione utenti da Sissi erano fatte nelle release
44.270 + precedenti da ``isi-prepusers``, un programma in perl. Nella
44.271 + ristrutturazione che ha portato alla nuova release di isi il prgramma è
44.272 + stato sostituito da ``isi-convert`` (in python) che ha alcune migliorie
44.273 + fra cui: l'abilità di leggere da formato ``.xls`` (formato di output di
44.274 + Sissi) e la maggiore estensibilità ad accettare altri formati in futuro.
44.275 +
44.276 +Estrazione dei dati con Open Sissi.
44.277 +Open Sissi è il programma di utilità compreso nel pacchetto SISSI in rete messo a
44.278 +disposizione di tutte le scuole italiane dal MIUR per la gestione delle segreterie
44.279 +scolastiche (e non solo). Per quanto ci riguarda, siamo interessati alla capacità
44.280 +di Open Sissi di produrre un file con i dati degli studenti estraendoli dal db Sql
44.281 +gestito da SISSI. La funzionalità da utilizzare è, dal menù di Open Sissi, Utilità,
44.282 +Report dinamici, che ci metterà in condizione di comporre un report con i campi
44.283 +desiderati (per noi, oltre a nome, cognome, data di nascita, anche codice fiscale,
44.284 +corso, anno di corso e sezione). Open Sissi produce il report in formato Excel che
44.285 +viene richiamato automaticamente (non sembra ci sia la possibilità di avere un semplice
44.286 +salvataggio del report, quindi bisogna che sulla macchina su cui gira Open Sissi
44.287 +ci sia anche Excel - incredibile ma vero).
44.288 +
44.289 +
44.290 +Da questo momento è possibile sia procedere via interfaccia web sia come
44.291 +descritto usando il comando :ref:`isi-convert`
44.292 +
44.293 +
44.294 +isi-perms
44.295 +~~~~~~~~~~~
44.296 +
44.297 +A cosa serve?
44.298 +..............
44.299 +
44.300 +Le ACL solitamente vengono impostate subito dopo l'installazione del sistema e
44.301 +non dovrebbero richiedere alcuna manutenzione. Esperienza insegna che questo
44.302 +non sempre è vero. Qualche imprevisto può sempre capitare e talvolta coinvolgere
44.303 +diversi utenti. Per garantire la ricostituzione di una situazione di "coerente"
44.304 +ci viene in aiuto isi-perms, grazie al quale è possibile impostare le acl
44.305 +impostate sul nostro filesystem.
44.306 +Chi non sapesse cosa sono le acl potrà approfondire `qui <http://a2.pluto.it/a2227.htm>`_
44.307 +
44.308 +I file di configurazione
44.309 +...........................
44.310 +
44.311 +isi-perms utilizza due file di configurazione:
44.312 +
44.313 +:/etc/isi/acl.conf: Configurazione di default
44.314 +
44.315 +:/etc/isi/acl-local.conf: Configurazione personalizzabile dall'utente; può
44.316 + sovrascrivere le opzioni di default.
44.317 +
44.318 +.. Note::
44.319 +
44.320 + Non apportare le tue modifiche a /etc/isi/acl.conf o rieschierai di perderle
44.321 + in fase di aggiornamento del sistema!.
44.322 +
44.323 +Per definire nuove acl per directory non definite nella configurazione di default,
44.324 +si potrà usare a modello il file ``acl.conf`` ed inserire le proprie
44.325 +ersonalizzazioni nel file acl-local.conf.
44.326 +Qualora si volesse sovrascrivere una particolare configurazione già definita,
44.327 +basterà ridefinirla (la versione inserita in acl-local.conf avrà sempre la
44.328 +precedenza).
44.329 +
44.330 +Esempi di utilizzo
44.331 +.....................
44.332 +
44.333 +Inizializzare le acl per tutti gli utenti e le share::
44.334 +
44.335 + isi-perms
44.336 +
44.337 +Risettare i permessi di una particolare directory::
44.338 +
44.339 + isi-perms <directory>
44.340 +
44.341 +isi-perms lanciato senza specificare una directory, può impiegare molto tempo.
44.342 +Quando possibile, lo si utilizi su directory ben precise.
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/docs/gestione/contents.rst Mon Apr 26 11:16:23 2010 +0200
45.3 @@ -0,0 +1,9 @@
45.4 +========
45.5 +Gestione
45.6 +========
45.7 +
45.8 +.. toctree::
45.9 +
45.10 + comandi_isi.rst
45.11 + web.rst
45.12 + isi-checkup.rst
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/docs/gestione/isi-checkup.rst Mon Apr 26 11:16:23 2010 +0200
46.3 @@ -0,0 +1,116 @@
46.4 +.. _isi-checkup:
46.5 +
46.6 +isi-checkup
46.7 +==============
46.8 +
46.9 +Esiste una esperienza di laboratorio sull'uso di :ref:`lab_checkup`
46.10 +
46.11 +Cos'è
46.12 +------
46.13 +
46.14 +``isi-checkup`` è la suite di diagnostica del progetto ReteISI. Nasce con lo scopo di
46.15 +rilevare e notificare i problemi di configurazione più comuni. Viene costantemente
46.16 +aggiornata al fine di permettere di indentificare un numero sempre crescente di
46.17 +errori.
46.18 +Molto importanti ed apprezzati, sono quindi tutte le segnalazioni di problemi non
46.19 +coperti dalla Suite, fatte in mailing list Rete ISI. Segnalazioni che si tradurranno
46.20 +con tutta probabilità in un nuovi test.
46.21 +
46.22 +Cosa non è
46.23 +-------------
46.24 +
46.25 +Non è una tool di correzione degli errori: effettua checkup, non fix!
46.26 +
46.27 +Installazione
46.28 +---------------
46.29 +
46.30 +Chi non lo avesse già installato potrà farlo, come root, con un semplice::
46.31 +
46.32 + apt-get install isi-checkup
46.33 +
46.34 +Le componenti
46.35 +----------------
46.36 +
46.37 +Il sistema è composto principalmente da:
46.38 +
46.39 +- test
46.40 +- template
46.41 +- file di esclusione : /etc/isi/checkup/exclude
46.42 +
46.43 +I test
46.44 +++++++++++
46.45 +
46.46 +I test presenti nel sistema, scritti principalmente in codice python( e
46.47 +qualcuno in shell script), sono contenuti in ``/usr/share/isi-checkup/tests/``.
46.48 +
46.49 +Ogni script di test ha un nome che indica, con la prima parte numerica, la sua
46.50 +appartenenza ad un particolare gruppo. I gruppi definiti ad oggi (release
46.51 +in hg numero 119) sono i seguenti :
46.52 +
46.53 +- test di sistema ( range 0 ~ 499 )
46.54 +- test utente ( range 500 ~ 700 )
46.55 +- test locali ( range 701 ~ 2000)
46.56 +- tutti i test ( range 0 ~ 2000)
46.57 +
46.58 +I test di ``sistema`` si occupano principalmente di rilevare problemi di configurazione
46.59 +legati al boot, file di configurazioni mancanti, etc...
46.60 +
46.61 +I test ``utente`` effettuano una serie di controlli concentrandosi esclusivamente
46.62 +su un singolo utente o tutti gli utenti. Viene controllato, ad esempio, che l'utente
46.63 +possa leggere, scrivere od attraversare determinati file o cartelle.
46.64 +Sarà capitato a tutti di incappare nel famigerato messaggio di windows "Impossibile
46.65 +trovare il profilo". Quasi sempre, questo problema è dovuto all'impossibilità
46.66 +dell'utente di accedere ad alcuni file della propria home directory.
46.67 +
46.68 +I test ``locali`` sono test che un utente può decidere di aggiungere per conto
46.69 +proprio. Andranno aggiunti in :file:`/etc/isi/checkup` e dovranno appartenere al range
46.70 +(701 ~ 2000).
46.71 +
46.72 +Per lanciare un particolare gruppo di test, basterà invocare il comando
46.73 +``isi-checkup`` con la relativa opzione. Si faccia riferimento all'help
46.74 +del comando per le opzioni da usare.
46.75 +
46.76 +I template
46.77 +++++++++++++
46.78 +
46.79 +In ``/usr/share/isi-checkup`` troveremo invece i file template *\*.conf*.
46.80 +Cos'è un template? Un template è un semplice file di testo in cui vengono
46.81 +elencati tutti i test da attivare all'attivazione del profilo. Questo
46.82 +permette, tramite la semplice preparazione di template differenti di coprire
46.83 +le necessità di differenti tipologie di macchine (server ReteISI, server
46.84 +LTSP, firewall, client Linux). Al momento esiste un solo template che è
46.85 +quello del server ReteISI.
46.86 +
46.87 +Volendo, ad esempio, attivare tutti i test contenuti nel profilo di default
46.88 +``isi.conf`` ::
46.89 +
46.90 + isi-checkup -t isi
46.91 +
46.92 +.. Note::
46.93 +
46.94 + - Il template ``isi.conf`` copre la totalità dei test presenti.
46.95 + - Non modificate i file di template, il file viene sovrascritto ad ogni
46.96 + aggiornamento della suite e le vostre modifiche andranno perdute.
46.97 +
46.98 +Il file exclude
46.99 ++++++++++++++++++
46.100 +
46.101 +E' possibile evitare che un test venga lanciato accodandone il nome al file
46.102 +/etc/isi/checkup/exclude.
46.103 +
46.104 +.. Note ::
46.105 +
46.106 + Con *nome* ci si riferisce al nome del file privo della parte numerica.
46.107 + es. squid_run_on_boot.py
46.108 +
46.109 + E' inoltre possibile copiare-incollare direttamente dal report a due
46.110 + colonne di isi-checkup.
46.111 +
46.112 +
46.113 + Esempio::
46.114 +
46.115 + I seguenti test non sono andati a buon fine
46.116 +
46.117 + squid_run_on_boot.py BootProcessSquid
46.118 +
46.119 + (notare la riga relativa al test squid_run_on_boot.py fallito)
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/docs/gestione/phpldapadmin.rst Mon Apr 26 11:16:23 2010 +0200
47.3 @@ -0,0 +1,71 @@
47.4 +.. _gestione_frontends_phpldapadmin:
47.5 +
47.6 +phpldapadmin
47.7 +============
47.8 +
47.9 +.. figure:: ../img/frontends/phpldapadmin.jpg
47.10 + :align: center
47.11 +
47.12 +Requisiti
47.13 +---------
47.14 +- Server Apache2 installato e configurato.
47.15 +- PHP5 (testata la versione versione 5).
47.16 +
47.17 +
47.18 +
47.19 +Installazione del pacchetto
47.20 +---------------------------
47.21 +
47.22 +Autenticarsi nel sistema come utente root e digitare::
47.23 +
47.24 + dpkg -l |grep phpldapadmin
47.25 +
47.26 +Se l'output mostrerà che il pacchetto è già installato (notare ``ii``) potremo
47.27 +saltare il passaggio successivo::
47.28 +
47.29 + ii phpldapadmin 0.9.8.3-8 web based interface for administering LDAP s
47.30 +
47.31 +In caso contrario, dovremo installare ``phpldapadmin`` come segue::
47.32 +
47.33 + apt-get install phpldapadmin
47.34 +
47.35 +Configurazione di apache2
47.36 +-------------------------
47.37 +
47.38 +La configurazione consisterà semplicemente nel creare un `alias` che permetta
47.39 +di raggiungere gli script php del programma ed una configurazione di default(
47.40 +modificabile come meglio si creda) relativa all'accesso alla risorsa, compresa
47.41 +tra `<Directory>` e `</Directory>`.
47.42 +
47.43 +Modificare quindi la configurazione del proprio sito aggiungendo tra `<VirtualHost>` e
47.44 +`</VirtualHost>` ::
47.45 +
47.46 + Alias "/usr/share/phpldapadmin/" /phpldapadmin/"
47.47 + <Directory "/usr/share/phpldapadmin/">
47.48 + Options Indexes MultiViews FollowSymLinks
47.49 + AllowOverride None
47.50 + Order deny,allow
47.51 + Deny from all
47.52 + Allow from 127.0.0.0/255.0.0.0 ::1/128
47.53 + </Directory>
47.54 +
47.55 +.. Note::
47.56 +
47.57 + Salvo casi particolari, la configurazione di apache da modificare dovrebbe
47.58 + essere contenuta nel file ``/etc/apache2/sites-available/default``.
47.59 +
47.60 + Si potrà provvedere dunque alla modifica di tale file con un editor di testo
47.61 + qualunque::
47.62 +
47.63 + jmacs /etc/apache2/sites-available/default
47.64 +
47.65 +Terminata la modifica alla configurazione, basterà farla ricaricare al servente::
47.66 +
47.67 + /etc/init.d/apache2 reload
47.68 +
47.69 +Verifica
47.70 +--------
47.71 +
47.72 +Sarà ora possibile verificare che tutto funzioni puntando il proprio browser
47.73 +all'url ``http://ip-WebServer/phpldapadmin``.
47.74 +
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/docs/gestione/web.rst Mon Apr 26 11:16:23 2010 +0200
48.3 @@ -0,0 +1,91 @@
48.4 +.. _web:
48.5 +
48.6 +================
48.7 +Interfaccia web
48.8 +================
48.9 +
48.10 +Struttura
48.11 +=========
48.12 +
48.13 +L'interfaccia web ha cinque sezioni:
48.14 +
48.15 +:utenti: permette di inserire utenti, modificarli, cancellarli, navigare fra
48.16 + gli utenti definiti, vedere i gruppi e le classi, impostare la
48.17 + quota per ogni grupo
48.18 +
48.19 +:samba: permette di rinominare il dominio
48.20 +
48.21 +:navigazione: gestisce il gruppo ``nowww``. Il proxy web può usare questo
48.22 + gruppo per interdire la navigazione agli utenti.
48.23 +
48.24 +:dnsmasq: questa è una interfaccia web alla configurazione del server dns e
48.25 + dhcp ``dnsmasq``
48.26 +
48.27 +:logon: permette la configurazione della fare di logon dei client Windows
48.28 +
48.29 +
48.30 +Screenshot
48.31 +==========
48.32 +
48.33 +Alcune immagini in ordine sparso:
48.34 +
48.35 +.. image:: ../img/web/web-start.png
48.36 +
48.37 +.. image:: ../img/web/web-utenti.png
48.38 +
48.39 +.. image:: ../img/web/web-users-file.png
48.40 +
48.41 +.. image:: ../img/web/web-nomi.png
48.42 +
48.43 +.. image:: ../img/web/web-sissi.png
48.44 +
48.45 +.. image:: ../img/web/web-classi.png
48.46 +
48.47 +.. image:: ../img/web/web-dns.png
48.48 +
48.49 +.. image:: ../img/web/web-navigazione.png
48.50 +
48.51 +Accesso
48.52 +=======
48.53 +
48.54 +
48.55 +L'accesso alla interfaccia web è garantito all'utente ``admin`` con password
48.56 +identica a quella contenuta in :file:`/etc/ldap.secret` (leggibile solo a
48.57 +root) o a qualunque utente del gruppo ``admins`` con la propria password.
48.58 +
48.59 +I docenti hanno pure accesso all'interfaccia limitatamente alla sola
48.60 +inibizione della navigazione.
48.61 +
48.62 +Installazione
48.63 +==============
48.64 +
48.65 +L'interfaccia web viene lanciata da uno script di init
48.66 +:file:`/etc/init.d/isiweb` che legge un file in :file:`/etc/defaults/isiweb`
48.67 +dove è possibile inibire l'avviamento dell'interfaccia valorizzando a '0' la
48.68 +variabile START_FSCGI::
48.69 +
48.70 + START_FSCI=1
48.71 +
48.72 +l'installazione del pacchetto ``isi-web`` viene fatta nel solito modo::
48.73 +
48.74 + apt-get install isi-web
48.75 +
48.76 +e mette la configurazione di apache in
48.77 +:file:`/etc/apache2/site-available/isiweb.conf` in come VirtualHost con nome
48.78 +web.isi.lan: questo significa che per potere raggiungere questa interfaccia
48.79 +occorre avere una risoluzione corretta nel server, che risolva l'ip del
48.80 +server. Questa risoluzioe può essere messa in :file:`/etc/hosts` del server se usate
48.81 +il server come dns ed usate dnsmasq, ad esempio se avete il server
48.82 +all'indirizzo 192.168.10.1::
48.83 +
48.84 + 192.168.10.1 web.isi.lan srv
48.85 + /etc/init.d/dnsmasq restart
48.86 +
48.87 +se non avete altre interfacce web sul server e quindi non vi serve avere i
48.88 +VirtualHosts potete semplicemente abilitare ``isiweb-all`` che è la
48.89 +configurazione che risponde su ogni nome::
48.90 +
48.91 + a2dissite isiweb.conf
48.92 + a2ensite isiweb-all.conf
48.93 + /etc/init.d/apache2 reload
48.94 +
49.1 Binary file docs/img/frontends/phpldapadmin.jpg has changed
50.1 Binary file docs/img/grub4dos/common_01_share-software.png has changed
51.1 Binary file docs/img/grub4dos/win98_03_menu-ltsp.png has changed
52.1 Binary file docs/img/grub4dos/win98_bat.png has changed
53.1 Binary file docs/img/grub4dos/xp_02b01_installazione-personalizzata.png has changed
54.1 Binary file docs/img/grub4dos/xp_02b02_installazione_personalizzata.png has changed
55.1 Binary file docs/img/grub4dos/xp_03_menu-lst.png has changed
56.1 Binary file docs/img/grub4dos/xp_bat.png has changed
57.1 Binary file docs/img/join/w98_1.png has changed
58.1 Binary file docs/img/join/w98_2.png has changed
59.1 Binary file docs/img/join/w98_3.png has changed
60.1 Binary file docs/img/join/w98_4.png has changed
61.1 Binary file docs/img/join/w98_5.png has changed
62.1 Binary file docs/img/join/w98_6.png has changed
63.1 Binary file docs/img/join/xp1.png has changed
64.1 Binary file docs/img/join/xp2.png has changed
65.1 Binary file docs/img/join/xp3.png has changed
66.1 Binary file docs/img/join/xp4.png has changed
67.1 Binary file docs/img/join/xp5.png has changed
68.1 Binary file docs/img/join/xp6.png has changed
69.1 Binary file docs/img/join/xp7.png has changed
70.1 Binary file docs/img/join/xp8.png has changed
71.1 Binary file docs/img/rete-fwisi.png has changed
72.1 Binary file docs/img/rete-srvisi.png has changed
73.1 Binary file docs/img/reteisi.png has changed
74.1 Binary file docs/img/ssh-key/big/0_accessoDominio.png has changed
75.1 Binary file docs/img/ssh-key/big/10_putty-connessione2.png has changed
76.1 Binary file docs/img/ssh-key/big/11_putty-connessione3.png has changed
77.1 Binary file docs/img/ssh-key/big/12_putty-connessione4.png has changed
78.1 Binary file docs/img/ssh-key/big/13_putty-connessione5.png has changed
79.1 Binary file docs/img/ssh-key/big/1_estensioni1.png has changed
80.1 Binary file docs/img/ssh-key/big/2_estensioni2.png has changed
81.1 Binary file docs/img/ssh-key/big/3_import1.png has changed
82.1 Binary file docs/img/ssh-key/big/4_import2.png has changed
83.1 Binary file docs/img/ssh-key/big/5_import3.png has changed
84.1 Binary file docs/img/ssh-key/big/6_import4.png has changed
85.1 Binary file docs/img/ssh-key/big/7_putty-addkey1.png has changed
86.1 Binary file docs/img/ssh-key/big/8_putty-addkey2.png has changed
87.1 Binary file docs/img/ssh-key/big/9_putty-connessione1.png has changed
88.1 Binary file docs/img/ssh-key/small/0_accessoDominio.jpg has changed
89.1 Binary file docs/img/ssh-key/small/10_putty-connessione2.jpg has changed
90.1 Binary file docs/img/ssh-key/small/11_putty-connessione3.jpg has changed
91.1 Binary file docs/img/ssh-key/small/12_putty-connessione4.jpg has changed
92.1 Binary file docs/img/ssh-key/small/13_putty-connessione5.jpg has changed
93.1 Binary file docs/img/ssh-key/small/1_estensioni1.jpg has changed
94.1 Binary file docs/img/ssh-key/small/2_estensioni2.jpg has changed
95.1 Binary file docs/img/ssh-key/small/3_import1.jpg has changed
96.1 Binary file docs/img/ssh-key/small/4_import2.jpg has changed
97.1 Binary file docs/img/ssh-key/small/5_import3.jpg has changed
98.1 Binary file docs/img/ssh-key/small/6_import4.jpg has changed
99.1 Binary file docs/img/ssh-key/small/7_putty-addkey1.jpg has changed
100.1 Binary file docs/img/ssh-key/small/8_putty-addkey2.jpg has changed
101.1 Binary file docs/img/ssh-key/small/9_putty-connessione1.jpg has changed
102.1 Binary file docs/img/web/web-classi.png has changed
103.1 Binary file docs/img/web/web-dns.png has changed
104.1 Binary file docs/img/web/web-navigazione.png has changed
105.1 Binary file docs/img/web/web-nomi.png has changed
106.1 Binary file docs/img/web/web-sissi.png has changed
107.1 Binary file docs/img/web/web-start.png has changed
108.1 Binary file docs/img/web/web-users-file.png has changed
109.1 Binary file docs/img/web/web-utenti.png has changed
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
110.2 +++ b/docs/install/client/client_linux.rst Mon Apr 26 11:16:23 2010 +0200
110.3 @@ -0,0 +1,393 @@
110.4 +==============
110.5 +Client Linux
110.6 +==============
110.7 +
110.8 +
110.9 +Per i sistemi Linux non esiste un'operazione analoga al join dei sistemi
110.10 +Microsoft ma è comunque possibile avere:
110.11 +
110.12 + #. Autenticazione unica su server centrale: questo significa che tutti gli
110.13 + utenti sono riconosciuti da ogni client e la password con cui si
110.14 + autenticano è la medesima (che potrebbe anche essere differente da
110.15 + quella usata epr il logon su windows)
110.16 +
110.17 + #. La home è servita dal fileserver: se il server è anche PDC la home è la
110.18 + medesima sia sotto windows che sotto Linux. Il server esporta la HOME
110.19 + degli utenti via :ref:`nfs <config_nfs>`. Fare riferimento a quel capitolo per
110.20 + capire come configurare anche il client.
110.21 +
110.22 +Limitiamo la nostra trattazione ai client linux Ubuntu ed ai sistemi Debian.
110.23 +
110.24 +
110.25 +Debian
110.26 +======
110.27 +
110.28 +Esiste il pacchetto isi-ldap3-client che si occupa di permettere
110.29 +l'autenticazione su server centrale. Manca la documentazione...
110.30 +
110.31 +Ubuntu
110.32 +======
110.33 +
110.34 +
110.35 +.. index::
110.36 + single: auth_config
110.37 + single: client; linux
110.38 +
110.39 +.. _auth_client:
110.40 +
110.41 +Configurazione di un client Ubuntu per l'accesso ad un dominio isi
110.42 +------------------------------------------------------------------
110.43 +
110.44 +Dalla release di Ubuntu 7.10, è stato introdotto auth_client_config_ che
110.45 +consente di gestire agevolmente più configurazioni(profili) e di passare da
110.46 +uno all'altro in modo molto semplce. I procedimenti seguenti utilizzeranno
110.47 +tale feature.
110.48 +
110.49 +.. _auth_client_config: https://wiki.ubuntu.com/AuthClientConfig
110.50 +
110.51 +Installare i pacchetti necessari::
110.52 +
110.53 + root@ubuntu-desktop:~# apt-get install ldap-auth-config ldap-utils
110.54 +
110.55 +.. Note::
110.56 +
110.57 + L'installazione del pacchetto ``ldap-utils`` non è strettamente necessaria.
110.58 + Torna però utile per testare le interrogazioni ldap.
110.59 +
110.60 +Una volta installati i pacchetti,verrà lanciato uno script di configurazione.
110.61 +Si risponda alle domande come indicato di seguito, sostituendo i dati di
110.62 +esempio con i propri:
110.63 +
110.64 +.. container:: debconf
110.65 +
110.66 + ============================================ =============================
110.67 + Should debconf manage LDAP configuration?: sì
110.68 +
110.69 + LDAP server Uniform Resource Identifier: ldap://192.168.1.150
110.70 +
110.71 + Distinguished name: dc=isi,dc=lan
110.72 +
110.73 + LDAP account for root: cn=admin,dc=isi,dc=lan
110.74 +
110.75 + Password di root: passwordDiRoot
110.76 +
110.77 + ============================================ =============================
110.78 +
110.79 +(Per ciò che non viene espressamente citato sopra, si accetti il valore
110.80 +di default proposto)
110.81 +
110.82 +.. Note ::
110.83 +
110.84 + ``Per Ubuntu versione 8.10``
110.85 +
110.86 + - ``/etc/ldap/ldap.conf`` non viene configurato automaticamente, sarà quindi necessario
110.87 + effettuarne la configurazione manualmente.
110.88 +
110.89 + ``Per Ubuntu versione < 8.10``
110.90 +
110.91 + - ``/etc/ldap/ldap.conf`` non viene configurato automaticamente, sarà quindi necessario
110.92 + effettuarne la configurazione manualmente.
110.93 + - ``/etc/ldap.conf`` viene configurato in modo errato, sarà quindi necessario verificarne
110.94 + la configurazione.
110.95 +
110.96 + Per le modifiche si faccia riferimento ai parametri indicati di seguito.
110.97 +
110.98 +``/etc/ldap.conf``
110.99 +::
110.100 +
110.101 + host 192.168.1.150
110.102 + base dc=isi,dc=lan
110.103 + rootbinddn cn=admin,dc=isi,dc=lan
110.104 + bind_policy soft
110.105 +
110.106 +controllare anche che la direttiva ldap1://192.168.150 ``sia commentata``,
110.107 +in presenza di più modi per identificare il server ldap, l'autenticazione
110.108 +non funzionerà.
110.109 +
110.110 +``/etc/ldap/ldap.conf``
110.111 +::
110.112 +
110.113 + BASE dc=isi,dc=lan
110.114 + URI ldap://192.168.1.150
110.115 +
110.116 +
110.117 +Creazione e aggiunta di un profilo ``auth-client-config``
110.118 +---------------------------------------------------------
110.119 +
110.120 +Creare, con un editor di testo, un file chiamato ``isi``, popolandolo con le
110.121 +righe seguenti, e salvarlo in ``/etc/auth-client-config/profile.d/``
110.122 +
110.123 +Se il sistema in uso è una Ubuntu di versione inferiore alla 8.10::
110.124 +
110.125 + [isi-ldap]
110.126 + nss_passwd=passwd: compat ldap
110.127 + nss_group=group: compat ldap
110.128 + nss_shadow=shadow: compat ldap
110.129 + pam_auth=auth sufficient pam_ldap.so
110.130 + auth required pam_unix.so nullok_secure use_first_pass
110.131 + pam_account=account sufficient pam_ldap.so
110.132 + account required pam_unix.so
110.133 + pam_password=password sufficient pam_ldap.so
110.134 + password required pam_unix.so nullok obscure min=4 max=8 md5
110.135 + pam_session=session required pam_unix.so
110.136 + session required pam_mkhomedir.so skel=/etc/skel/
110.137 + session optional pam_ldap.so
110.138 + session optional pam_foreground.so
110.139 +
110.140 + [isi-local]
110.141 + nss_group=group: compat
110.142 + nss_passwd=passwd: compat
110.143 + nss_shadow=shadow: compat
110.144 + pam_account=account required pam_unix.so
110.145 + pam_auth=auth required pam_unix.so nullok_secure
110.146 + pam_password=password required pam_unix.so nullok obscure md5
110.147 + pam_session=session required pam_unix.so
110.148 + session optional pam_foreground.so
110.149 +
110.150 +Se il sistema in uso è Ubuntu versione 8.10::
110.151 +
110.152 + [isi-ldap]
110.153 + nss_passwd=passwd: compat ldap
110.154 + nss_group=group: compat ldap
110.155 + nss_shadow=shadow: compat ldap
110.156 + nss_netgroup=netgroup: nis
110.157 + pam_auth=auth sufficient pam_ldap.so
110.158 + auth required pam_unix.so nullok_secure use_first_pass
110.159 + pam_account=account sufficient pam_ldap.so
110.160 + account required pam_unix.so
110.161 + pam_password=password sufficient pam_ldap.so
110.162 + password required pam_unix.so nullok obscure min=4 max=8 md5
110.163 + pam_session=session required pam_unix.so
110.164 + session required pam_mkhomedir.so skel=/etc/skel/
110.165 + session optional pam_ldap.so
110.166 + session optional pam_foreground.so
110.167 +
110.168 + [isi-local]
110.169 + nss_group=group: compat
110.170 + nss_netgroup=netgroup: nis
110.171 + nss_passwd=passwd: compat
110.172 + nss_shadow=shadow: compat
110.173 + pam_account=account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
110.174 + account [success=1 default=ignore] pam_ldap.so
110.175 + account requisite pam_deny.so
110.176 + account required pam_permit.so
110.177 + pam_auth=auth [success=2 default=ignore] pam_unix.so nullok_secure
110.178 + auth [success=1 default=ignore] pam_ldap.so use_first_pass
110.179 + auth requisite pam_deny.so
110.180 + auth required pam_permit.so
110.181 + pam_password=password [success=2 default=ignore] pam_unix.so obscure sha512
110.182 + password [success=1 user_unknown=ignore default=die] pam_ldap.so use_authtok try
110.183 + password requisite pam_deny.so
110.184 + password required pam_permit.so
110.185 + pam_session=session [default=1] pam_permit.so
110.186 + session requisite pam_deny.so
110.187 + session required pam_permit.so
110.188 + session required pam_unix.so
110.189 + session optional pam_ldap.so
110.190 + session optional pam_ck_connector.so nox11
110.191 +
110.192 +
110.193 +Per verificare che il profilo venga rilevato correttamente si potrà
110.194 +utilizzare il comando ``auth-client-config -l``::
110.195 +
110.196 + root@ubuntu-desktop:~# auth-client-config -l
110.197 + Available profiles are:
110.198 + isi-ldap
110.199 + isi-local
110.200 + kerberos_example
110.201 + lac_ldap
110.202 + ldap_example
110.203 +
110.204 +Come si può notare, i profili ``isi-ldap`` e ``isi-local`` aggiunti in
110.205 +precedenza vengono trovati ed elencati. Non resta che attivare il profilo ``isi-ldap``::
110.206 +
110.207 + root@ubuntu-desktop:~# auth-client-config -a -p isi-ldap
110.208 +
110.209 +Ed effettuare un tentativo di interrogazione del database ldap::
110.210 +
110.211 + root@ubuntu-desktop:~# getent passwd
110.212 +
110.213 +L'output del comando dovrebbe mostrare tutto il contenuto del file locale
110.214 +``/etc/passwd`` seguito da quello aggiuntivo fornito dal database ldap.
110.215 +
110.216 +.. note::
110.217 +
110.218 + E' indispensabile che in ``/etc/hosts`` venga inserito un riferimento del
110.219 + tipo <ipserver> <nomeserver> (es. 192.168.1.150 srv-isi). L'assenza di
110.220 + tale direttiva, comporterà un ritardo considerevole ad ogni interrogazione
110.221 + dell'albero ldap.
110.222 +
110.223 +Consentire ad un utente ldap l'utilizzo di stick usb e dell'audio del client ubuntu.
110.224 +------------------------------------------------------------------------------------
110.225 +
110.226 +In Ubuntu un utente ldap riesce a far funzionare uno stick usb solo in
110.227 +lettura e non ha accesso all'audio della macchina. Questo dipende dal fatto
110.228 +che per utilizzare l'audio e vedere montato il proprio dispositivo usb in
110.229 +lettura/scrittura l'utente deve essere membro dei gruppi locali *plugdev
110.230 +(46)* e *audio (29)*, il che è automatico per gli utenti locali ma non
110.231 +succede per quelli remoti. Occorre quindi implementare un meccanismo che
110.232 +assegni automaticamente l'appartenenza (membership) a questi gruppi agli
110.233 +utenti autenticati dal server ldap. Fortunatamente la cosa è piuttosto
110.234 +semplice, anche se comporta un riprocessamento di tutti gli utenti
110.235 +remoti. Vediamo quanto è necessario.
110.236 +
110.237 +LATO SERVER
110.238 +~~~~~~~~~~~
110.239 +
110.240 + 1. creare i gruppi ldap *plugdev* e *audio* (attenzione, quei gruppi
110.241 + esistono già sul server come gruppi locali, saranno quindi duplicati come
110.242 + gruppi ldap
110.243 +
110.244 + 2. assegnare gli utenti a cui si vuole consentiro l'uso dei dispositivi
110.245 + usb e audio del client (potenzialmente tutti) ai gruppi plugdev e audio
110.246 + (eventualmente ad altri)
110.247 +
110.248 +La prima operazione si fa con i comandi::
110.249 +
110.250 + smbldap-groupadd -o -g 46 plugdev
110.251 + smbldap-groupadd -o -g 29 audio
110.252 +
110.253 +``l'opzione -o`` è necessaria per la duplicazione dei gruppi. L'assegnazione
110.254 +della membership può eseguirsi con i comandi::
110.255 +
110.256 + isi-addgroup user_id plugdev
110.257 + isi-addgroup user_id audio
110.258 +
110.259 +LATO CLIENT
110.260 +~~~~~~~~~~~
110.261 +
110.262 +Per assegnare on the fly la membership ai gruppi locali agli utenti ldap
110.263 +occorre ricorrere a ``pam_group.so``, lo si fa aggiungedo al file
110.264 +``/etc/pam.d/common-auth`` la linea::
110.265 +
110.266 + auth optional pam_group.so
110.267 +
110.268 +A questo punto non resta che configurare ``pam_group``. Lo si fa aggiungendo
110.269 +in testa al suo file di configurazione ``/etc/security/group.conf`` le righe
110.270 +seguenti::
110.271 +
110.272 + gdm; *; *; Al0000-2400; audio, video, cdrom, floppy, plugdev
110.273 + kdm; *; *; Al0000-2400; audio, video, cdrom, floppy, plugdev
110.274 + login; *; *; Al0000-2400; audio, video, cdrom, floppy, plugdev
110.275 +
110.276 +(le prove fatte rivelano che i gruppi video, cdrom e floppy, possono essere
110.277 +omessi, in ogni caso male non fanno)
110.278 +
110.279 +Fare il reboot del client e godersi l'effetto
110.280 +
110.281 +
110.282 +
110.283 +LTSP
110.284 +====
110.285 +
110.286 +
110.287 +una menzione particolare per i client LTSP. Per questi client non c'è molto
110.288 +da dire, in quanto gli utenti sono definiti sul server LTSP per il quale
110.289 +potete seguire esattamente le istruzioni scritte sopra.
110.290 +
110.291 +L'unica informazione aggiuntiva che voglio dare è relativa alla
110.292 +configurazione di GRUB
110.293 +
110.294 +.. index:: ltsp; grub
110.295 +
110.296 +Un progetto alternativo a questo è il progetto drbl_ che include anche
110.297 +clonezilla (progetto simile a ghost)
110.298 +
110.299 +.. _drbl: http://drbl.sourceforge.net/
110.300 +
110.301 +GRUB
110.302 +----
110.303 +
110.304 +capita spesso che serva configurare una macchina per il dual boot Linux come
110.305 +client LTSP e windows. In questo caso è opportuno installare GRUB
110.306 +direttamente su hard disk e quindi in windows. Non c'è alcun problema, GRUB
110.307 +non è razzista, gli basta risiedere in un filesystem che riconosca al boot,
110.308 +e fat32 va bene (al momento non so dire se va bene anche ntfs).
110.309 +
110.310 +il driver
110.311 +~~~~~~~~~
110.312 +
110.313 +Occorre anzitutto procurarsi il driver della scheda di rete della vostra
110.314 +macchina, potete scaricarla da questo sito:
110.315 +http://www.rom-o-matic.net/5.4.1/ (la versione non è vincolante).
110.316 +Per il download vi chiedono il formato del file, scegliete .zlilo.
110.317 +
110.318 +/boot in C:
110.319 +~~~~~~~~~~~
110.320 +
110.321 +Installate ora la cartella ``boot`` con all'intero la cartella ``grub`` come
110.322 +fareste per una normale distro linux (copiate ad esempio ``/boot/grub`` del
110.323 +cd). Ipotizziamo ad esempio che la partizione windows (unico sistema sulla
110.324 +macchina) sia la numero 1::
110.325 +
110.326 + mount /dev/sda1 /mnt
110.327 + mkdir -p /boot
110.328 + cp -av /boot/grub /mnt/boot
110.329 +
110.330 +a questo punto dovete:
110.331 +
110.332 + 1. aggiungere il driver
110.333 + 2. cofigurare menu.lst ad esempio come segue::
110.334 +
110.335 + title LTSP (scheda
110.336 + root (hd0,0)
110.337 + kernel /boot/eb-5.0.8-3c509.lzlilo
110.338 +
110.339 + title Windows 95/98/NT/2000
110.340 + root (hd0,0)
110.341 + makeactive
110.342 + chainloader +1
110.343 +
110.344 +
110.345 +installazione grub
110.346 +~~~~~~~~~~~~~~~~~~
110.347 +
110.348 +Ultimo passo è quello di installare effettivamente grub sul MBR (Master boot
110.349 +record) del disco. Per questo basterà partire con il cd reteisi, fermersi
110.350 +subito (alla splash inisiale che attualmente ha i pinguini).
110.351 +
110.352 +Una voce dice "inizializzazione HD per RAID", che di fatto inizializza sia
110.353 +il primo che il secondo disco. Potete usarlo anche se avete un solo
110.354 +disco. Probabilmente si lamenta quando si accorge che manda il secondo
110.355 +disco, ma ormai il primo lo avr`a inizializzato correttamente.
110.356 +
110.357 +Se invece volete fare le cose senza scorciatoie, dicitate ``c`` che vi
110.358 +mette nella console di grub e digitate::
110.359 +
110.360 + root (hd0,0)
110.361 + setup (hd0)
110.362 +
110.363 +Se per case a partizione non fose la prima ma la seconda, usate
110.364 +``root (hd0,1)``
110.365 +
110.366 +
110.367 +
110.368 +dividere il carico fra più server
110.369 +-----------------------------------
110.370 +
110.371 +Qualora ci siano molti client ltsp e non sia possibile suddividere la rete,
110.372 +è possibile suddividere il carico fra più server lasciando al server dhcp
110.373 +il compito di assegnare non solo l'indirizzo di rete ma anche il server da
110.374 +cui prendere il root filesystem da caricare via nfs.
110.375 +
110.376 +La direttiva da usare è ``next-server`` ed indica quale sia il server
110.377 +successivo dopo quello che ha fornito il kernel. Un esemio per due macchine
110.378 +che usino rispettivamente il server ltsp 192.168.1.1 e 192.168.1.2 potrebbe
110.379 +essere così::
110.380 +
110.381 + host ltsp01 {
110.382 + hardware ethernet 00:a0:24:52:5a:bc;
110.383 + fixed-address 192.168.1.50;
110.384 + next-server 192.168.1.1;
110.385 + }
110.386 + host ltsp02 {
110.387 + hardware ethernet 00:a0:24:52:5a:bc;
110.388 + fixed-address 192.168.1.51;
110.389 + next-server 192.168.1.2;
110.390 + }
110.391 +
110.392 +APT
110.393 +===
110.394 +
110.395 +Ricordate che per potere usare apt con apt dovrete :ref:`apt_squid`
110.396 +
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/docs/install/client/client_microsoft.rst Mon Apr 26 11:16:23 2010 +0200
111.3 @@ -0,0 +1,74 @@
111.4 +.. _join:
111.5 +
111.6 +Inserire client Microsoft nel dominio: Il Join
111.7 +==============================================
111.8 +
111.9 +.. index::
111.10 + single: client; windows
111.11 +
111.12 +Esiste una esperienza di laboratorio sul :ref:`lab_join`
111.13 +
111.14 +XP Professional
111.15 +---------------
111.16 +
111.17 +.. sidebar:: ``Eliminare la sincronizzazione``
111.18 +
111.19 + Ricordati anche di eliminare la sincronizzazione dei file altrimenti
111.20 + ad ogni disconnessione si attendera' un tempo eterno!!!
111.21 +
111.22 +
111.23 +.. figure:: ../../img/join/xp1.png
111.24 + :align: center
111.25 +
111.26 +.. figure:: ../../img/join/xp2.png
111.27 + :align: center
111.28 +
111.29 +.. figure:: ../../img/join/xp3.png
111.30 + :align: center
111.31 +
111.32 +.. figure:: ../../img/join/xp4.png
111.33 + :align: center
111.34 +
111.35 +.. figure:: ../../img/join/xp5.png
111.36 + :align: center
111.37 +
111.38 +.. figure:: ../../img/join/xp6.png
111.39 + :align: center
111.40 +
111.41 +.. figure:: ../../img/join/xp7.png
111.42 + :align: center
111.43 +
111.44 +.. figure:: ../../img/join/xp8.png
111.45 + :align: center
111.46 +
111.47 +Windows 2000
111.48 +------------
111.49 +
111.50 +La procedura è analoga a quella per i Client XP
111.51 +
111.52 +Windows98 SE
111.53 +------------
111.54 +
111.55 +.. figure:: ../../img/join/w98_1.png
111.56 + :align: center
111.57 +
111.58 +.. figure:: ../../img/join/w98_2.png
111.59 + :align: center
111.60 +
111.61 +.. figure:: ../../img/join/w98_3.png
111.62 + :align: center
111.63 +
111.64 +.. figure:: ../../img/join/w98_4.png
111.65 + :align: center
111.66 +
111.67 +.. figure:: ../../img/join/w98_5.png
111.68 + :align: center
111.69 +
111.70 +.. figure:: ../../img/join/w98_6.png
111.71 + :align: center
111.72 +
111.73 +Sistemi non supportati
111.74 +----------------------
111.75 +
111.76 ++ Windows XP Home edition
111.77 ++ Windows 95
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
112.2 +++ b/docs/install/client/grub4dos.rst Mon Apr 26 11:16:23 2010 +0200
112.3 @@ -0,0 +1,122 @@
112.4 +.. _grub4dos:
112.5 +
112.6 +
112.7 +=============================
112.8 +Installazione GRUB sui client
112.9 +=============================
112.10 +
112.11 +In un sistema di dual boot occorre potere partire da Linux o da Windows. Il
112.12 +menu di scelta al boot è gestito direttamente dagli installer Linux se si
112.13 +installa Linux come secondo sistema operativo ma in una situazione di
112.14 +thin/fat client occorre installarlo a mano.
112.15 +
112.16 +Il progetto ReteISI propone una semplice soluzione basata sul software
112.17 +``grub4dos``. L'operazione va svolta sui singoli client ed è differente a
112.18 +seconda che si usi Windows 98 o un sistema più recente.
112.19 +
112.20 +L'obiettivo di questa procedura è quella di ottenere sui client una
112.21 +configurazione come questa:
112.22 +
112.23 +.. image:: ../../img/grub4dos/win98_03_menu-ltsp.png
112.24 + :align: right
112.25 + :scale: 40
112.26 +
112.27 +L'installazione del pacchetto ReteISI mette nella share :file:`software` una
112.28 +cartella chiamata appunto ``grub4dos`` che contiene tutti i file necessari,
112.29 +per cui è sufficiente eseguire il file di installazione (doppio click) per
112.30 +ogni client per installare grub.
112.31 +
112.32 +La fase di boot
112.33 +===============
112.34 +
112.35 +Normalmente il Master Boot Record (MBR) di un sistema Windows passa il
112.36 +comando alla partizione dove un loader Windows carica il sistema.
112.37 +
112.38 +Con ``grub4dos`` invece il MBR passa la palla al comando ``grldr`` che legge
112.39 +il file di configurazione :file:`menul.lst` che deve essere preparato per
112.40 +proporre le varie voci di menu. A noi interessa di avere la scelta:
112.41 +
112.42 +1. LTSP
112.43 +2. Windows
112.44 +
112.45 +Ovviamente LTSP *non* è un sistema operativo presente ma è un eseguibile che
112.46 +a sua volta emula un PXE, ovvero una scheda di rete con boot da rete. Noi
112.47 +abbiamo messo come default gPXE_ ed in particolare l'eseguibile con tutti i
112.48 +driver di rete diposnibili nel sito rom-o-matic_ in modo da coprire il maggior numero possibile di schede.
112.49 +
112.50 +
112.51 +.. _gPXE: http://etherboot.org/wiki/index.php
112.52 +.. _rom-o-matic: http://rom-o-matic.net/gpxe/gpxe-1.0.0/contrib/rom-o-matic/
112.53 +
112.54 +Personalizziamo il menu di avvio
112.55 +---------------------------------
112.56 +
112.57 +Nelle cartelle xp/c, win98/c, troverete il file :file:`menu.lst`. Questo
112.58 +file, che verrà copiato in ``c:`` dalla script che lancerete, contiene la
112.59 +configurazione del boot loader::
112.60 +
112.61 + # imposta i colori
112.62 + color blue/white white/green white/blue white/blue
112.63 +
112.64 + # imposta il tempo di attesa prima di scegliere la prima voce di menù
112.65 + timeout 10
112.66 +
112.67 + title gPXE (LTSP)
112.68 + find --set-root /boot/grub/gpxe.iso
112.69 + map /boot/grub/gpxe.iso (0xff) || map --mem /boot/grub/gpxe.iso (0xff)
112.70 + map --hook
112.71 + chainloader (0xff)
112.72 +
112.73 + title Windows XP/2K/NT
112.74 + find --set-root --ignore-floppies /ntldr
112.75 + chainloader /ntldr
112.76 +
112.77 + title halt
112.78 + halt
112.79 +
112.80 +
112.81 +Installare grub e gPXE da un sistema microsoft
112.82 +=================================================
112.83 +
112.84 +.. image:: ../../img/grub4dos/common_01_share-software.png
112.85 + :align: right
112.86 +
112.87 +
112.88 +Prima di procedere con l'installazione di grub, assicuriamoci che, in
112.89 +``Risorse del computer``, la share ``software`` sia montata; in caso
112.90 +contrario le script potrebbero non funzionare correttamente.
112.91 +
112.92 +Grub verrà installato diversamente a seconda del sistema operativo
112.93 +utilizzato, si segua dunque il percorso adatto alle proprie esigenze. I
112.94 +passaggi sono molto semplici si tratta di doppioclickare su di una script
112.95 +batch.
112.96 +
112.97 +
112.98 +Lanciamo la script di installazione in W98 ed w2k, XP rispettivamente
112.99 +
112.100 +.. image:: ../../img/grub4dos/win98_bat.png
112.101 + :align: left
112.102 +
112.103 +
112.104 +.. image:: ../../img/grub4dos/xp_bat.png
112.105 + :align: center
112.106 +
112.107 +
112.108 +Installazione di grub personalizzata
112.109 +-------------------------------------
112.110 +
112.111 +Chi dovesse avere esigente particolari come, ad esempio, installare il MBR
112.112 +su di un disco che non è il primo collegato (scelta di default), potrà
112.113 +affinare manualmente la propria installazione di grub con la seconda script
112.114 +presente: :file:``
112.115 +
112.116 +Dopo aver copiato i file necessari in ``c:\`` la script lancerà ``Grub4Dos
112.117 +Installer``, un'applicazione che permetterà in modo abbastanza semplice di
112.118 +installare grub nel disco desiderato. Fate riferimento ai numeri in figura
112.119 +per non saltare degli step importanti.
112.120 +
112.121 +.. figure:: ../../img/grub4dos/xp_02b02_installazione_personalizzata.png
112.122 + :scale: 50
112.123 + :align: center
112.124 +
112.125 +
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113.2 +++ b/docs/install/contents.rst Mon Apr 26 11:16:23 2010 +0200
113.3 @@ -0,0 +1,63 @@
113.4 +================================
113.5 + Installazione e configurazione
113.6 +================================
113.7 +
113.8 +Installazione
113.9 +=============
113.10 +Scelta dei setup e della topologia della rete.
113.11 +Installazione del sistema a partire da disco live.
113.12 +
113.13 +.. toctree::
113.14 + :maxdepth: 2
113.15 +
113.16 + intro
113.17 + install_base
113.18 +
113.19 +Configurazioni servizi server
113.20 +=============================
113.21 +
113.22 +Configurazione dei servizi essenziali che devono necessariamente risiedere
113.23 +sul server
113.24 +
113.25 +.. toctree::
113.26 + :maxdepth: 2
113.27 +
113.28 + eth_dns
113.29 + servizi/pdc
113.30 + reteisi
113.31 + sshd_key
113.32 + servizi/firewall
113.33 + servizi/nfs
113.34 + servizi/ftp
113.35 + servizi/sarg-report
113.36 + servizi/apache_userdir
113.37 + servizi/apache_limit_pub
113.38 +
113.39 +Configurazione servizi firewall
113.40 +===============================
113.41 +
113.42 +Configurazione dei servizi che possono essere installati sul server o su un
113.43 +firewall a scelta dell'amministratore a seconda della topologia della rete
113.44 +prescelta.
113.45 +
113.46 +.. toctree::
113.47 + :maxdepth: 2
113.48 +
113.49 + servizi/bind
113.50 + servizi/bind_server
113.51 + servizi/dhcpd
113.52 + servizi/squid_dans
113.53 +
113.54 +
113.55 +
113.56 +Configurazione Client
113.57 +=====================
113.58 +
113.59 +Configurazione delle macchine client
113.60 +
113.61 +.. toctree::
113.62 + :maxdepth: 2
113.63 +
113.64 + client/client_linux
113.65 + client/client_microsoft
113.66 + client/grub4dos
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114.2 +++ b/docs/install/eth_dns.rst Mon Apr 26 11:16:23 2010 +0200
114.3 @@ -0,0 +1,126 @@
114.4 +.. _config_eth_dns:
114.5 +
114.6 +Rete e dns (come client)
114.7 +========================
114.8 +
114.9 +Esiste una esperienza di laboratorio sui concetti base del
114.10 +:ref:`lab_routing` ed una sul :ref:`lab_tinydns`
114.11 +
114.12 +Configurazione /etc/hosts
114.13 +-------------------------
114.14 +
114.15 +Sostituire il proprio hostname e localdomain.
114.16 +
114.17 +A titolo di esempio è stato sostituito a::
114.18 +
114.19 + 127.0.0.1 argo localhost localhost.lan
114.20 +
114.21 +La seguente riga
114.22 +::
114.23 +
114.24 + 127.0.0.1 srv-scuolax localhost srv-scuolax.lan
114.25 +
114.26 +
114.27 +interfacce di rete
114.28 +------------------
114.29 +
114.30 +E' indispensabile che ogni interfaccia di rete che si intende utilizzare sia
114.31 +configurata con il proprio indirizzo IP.
114.32 +
114.33 +Per visualizzare l'elenco completo delle interfacce disponibili si usi il
114.34 +comando *ifconfig -a* ::
114.35 +
114.36 + root@argo:~$ ifconfig -a
114.37 +
114.38 + eth0 Link encap:Ethernet HWaddr 03:01:12:35:84:G2
114.39 + UP BROADCAST MULTICAST MTU:1500 Metric:1
114.40 + RX packets:0 errors:0 dropped:0 overruns:0 frame:0
114.41 + TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
114.42 + collisions:0 txqueuelen:1000
114.43 + RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
114.44 + Interrupt:5 Base address:0x8000 Memory:90000000-90000fff
114.45 +
114.46 + eth1 Link encap:Ethernet HWaddr 03:02:24:14:44:A1
114.47 + UP BROADCAST MULTICAST MTU:1500 Metric:1
114.48 + RX packets:0 errors:0 dropped:0 overruns:0 frame:0
114.49 + TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
114.50 + collisions:0 txqueuelen:1000
114.51 + RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
114.52 + Interrupt:5 Base address:0x8000 Memory:90000000-90000fff
114.53 +
114.54 + lo Link encap:Local Loopback
114.55 + inet addr:127.0.0.1 Mask:255.0.0.0
114.56 + inet6 addr: ::1/128 Scope:Host
114.57 + UP LOOPBACK RUNNING MTU:16436 Metric:1
114.58 + RX packets:382 errors:0 dropped:0 overruns:0 frame:0
114.59 + TX packets:382 errors:0 dropped:0 overruns:0 carrier:0
114.60 + collisions:0 txqueuelen:0
114.61 + RX bytes:58097 (56.7 KB) TX bytes:58097 (56.7 KB)
114.62 +
114.63 +
114.64 +Come si può notare dall'esempio sopra, sul sistema preso in esame sono
114.65 +presenti due interfacce di rete: *eth0* ed *eth1*.
114.66 +
114.67 +Configurare tali interfacce è molto semplice; l'operazione viene effettuata
114.68 +utilizzando il comando *ifconfig*.
114.69 +
114.70 +Si supponga di voler assegnare all'interfaccia di rete eth0 ip 192.168.1.1::
114.71 +
114.72 + argo:~# ifconfig eth0 192.168.1.1 up
114.73 +
114.74 +Per verificare che l'interfaccia sia stata configurata correttamente è
114.75 +possibile eseguire nuovamente il comando *ifconfig -a* od in alternativa il
114.76 +più selettivo *ifconfig INTERFACCIA* che, diversamente, mostrerà la
114.77 +configurazione attuale della sola interfaccia specificata, ad esempio eth0.
114.78 +
114.79 +Si supponga inoltre di volere impostare un gateway predefinito di ip
114.80 +192.168.1.254, raggiungibile attraverso l'interfaccia eth0::
114.81 +
114.82 + argo:~# route add -net default gw 192.168.1.254 eth0
114.83 +
114.84 +Sarà possibile verificare la bontà di tale configurazione con il comando *route -n*::
114.85 +
114.86 + Kernel IP routing table
114.87 + Destination Gateway Genmask Flags Metric Ref Use Iface
114.88 + 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
114.89 + 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 eth1
114.90 + 0.0.0.0 192.168.1.254 0.0.0.0 UG 100 0 0 eth0
114.91 +
114.92 +.. commento:
114.93 +
114.94 + Nota:
114.95 +
114.96 + 169.254.0.0 è un indirizzo che viene assegnato alle
114.97 + interfacce di rete *non* configurate quando
114.98 +
114.99 +Tutte le configurazione effettuate, sebbene già operative, hanno carattere
114.100 +temporaneo. Al riavvio della macchina verranno infatti perse. Per questa
114.101 +ragione è indispensabile "fissarle" modificando il file di sistema
114.102 +``/etc/network/interfaces``. Fortunatamente, un tool argo, rende questo
114.103 +passaggio del tutto automatico. Basterà infatti lanciare il comando
114.104 +``save-net`` per "fissare" la configurazione di rete attivata.
114.105 +
114.106 +
114.107 +Dns
114.108 +---
114.109 +
114.110 +Per impostare i DNS, basterà modificare il file */etc/resolv.conf*::
114.111 +
114.112 + nameserver INDIRIZZO_IP_DNS1
114.113 + nameserver INDIRIZZO_IP_DNS2
114.114 +
114.115 +*Nota*: L'ordine con il quale vengono elencati i server dns da utilizzare ne
114.116 + stabiliscono la priorità.
114.117 +
114.118 +
114.119 +Qualora si decidesse di utilizzare un servente DNS attivo sulla macchina
114.120 +stessa, basterà modificare ``/etc/resolv.conf`` come segue::
114.121 +
114.122 + nameserver 127.0.0.1
114.123 + nameserver INDIRIZZO_IP_DNS1
114.124 + nameserver INDIRIZZO_IP_DNS2
114.125 +
114.126 +In questo modo il DNS utilizzato prioritariamente sarà quello locale.
114.127 +
114.128 +
114.129 +
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
115.2 +++ b/docs/install/install_base.rst Mon Apr 26 11:16:23 2010 +0200
115.3 @@ -0,0 +1,240 @@
115.4 +.. _install_base:
115.5 +
115.6 +===========================
115.7 + Installazione base di ISI
115.8 +===========================
115.9 +
115.10 +Installazione in 3 passi
115.11 +========================
115.12 +
115.13 +Installare un sistema ReteIsi dal CD live ad un PDC perfettamente
115.14 +funzionante è molto semplice se si seguono poche linee sotto elencate che si
115.15 +riassumono in:
115.16 +
115.17 +#. decidere come creare le partizioni (:term:`raid` è suggerito). La
115.18 + installazione non è altro che una copia del cd live che avviene per mezzo
115.19 + di un comando che legge un file di configurazione. Se ne può usare uno
115.20 + preconfezionato (prelevandolo dalla cartella /etc/clone/examples) ed
115.21 + eventualmente modificarlo
115.22 +
115.23 +#. lanciare il comando ``clone`` e riavviare
115.24 +
115.25 +#. fare la prima configurazione con il comando::
115.26 +
115.27 + isi-startup DOMINIO NOME_PDC PWD
115.28 +
115.29 +Il sistema a questo punto è pronto per fare il join da una macchina Windows
115.30 +o per diventare server di autenticazione di una macchina Linux salvo le
115.31 +ovvie configurazioni di :ref:`firewalling <config_firewall>`
115.32 +e :ref:`rete <config_eth_dns>`.
115.33 +
115.34 +
115.35 +Note hardware
115.36 +-------------
115.37 +
115.38 +Quanti hardisk utilizzare
115.39 ++++++++++++++++++++++++++
115.40 +
115.41 +Talvolta, per una politica di risparmio, si preferisce utilizzare un solo
115.42 +disco. L'attuale costo degli hardisk ed il buon senso scoraggiano tale
115.43 +pratica in favore di una configurazione raid1(mirroring) che utilizzi due
115.44 +dischi. Tale configurazione assicura che, in caso di rottura di uno dei due
115.45 +dischi, il disco gemello garantisca il normale uso del sistema. Si potrà
115.46 +inoltre collegare in seguito, in sostituzione del disco danneggiato, un
115.47 +nuovo disco su cui riattivare il "gemellaggio".
115.48 +
115.49 +Procurarsi l'ultima versione di ISI
115.50 ++++++++++++++++++++++++++++++++++++
115.51 +
115.52 +Si potrà scaricare la versione più recente dal sito
115.53 +http://download.argolinux.org/isi/. Se avete problemi potete seguire qui le
115.54 +istruzioni per :ref:`masterizzarla <masterizzare_iso>`.
115.55 +
115.56 +Iniziare l'installazione
115.57 +------------------------
115.58 +
115.59 +Avviare la macchina con il cd dell'ultima release di ISI nel lettore cdrom (
115.60 +ci si assicuri preventivamente che il BIOS sia stato correttamente
115.61 +configurato per avviare prioritariamente da cdrom).
115.62 +
115.63 +La procedura di boot terminerà con una richiesta di autenticazione.
115.64 +::
115.65 +
115.66 + Debian GNU/Linux 4.0 argo tty1
115.67 +
115.68 + argo login: root
115.69 +
115.70 +Ci si autentichi inserendo come nome utente *root*; per quanto riguarda la
115.71 +password, basterà un semplice invio.
115.72 +
115.73 +.. commento: img/icone/dialog-information.svg
115.74 +
115.75 +
115.76 +Clone
115.77 +=======
115.78 +
115.79 +*Cos'è Clone*
115.80 +-------------
115.81 +
115.82 +Clone è una script (in python) che si occupa dell'intero processo di
115.83 +installazione a partire da un file di configurazione. Argoisi viene
115.84 +distribuita con una serie di esempi di file di configurazione e le modifiche
115.85 +da apportare a questi esempi sono minime
115.86 +
115.87 +
115.88 +Creazione del file di configurazione
115.89 +++++++++++++++++++++++++++++++++++++
115.90 +
115.91 +Il file di configurazione, contiene fra le altre queste informazioni:
115.92 +
115.93 +* se si vuole un RAID o no
115.94 +* il numero di partizioni da creare
115.95 +* gli hardisk da utilizzare
115.96 +* il tipo di filesystem scelto per ogni partizione
115.97 +
115.98 +Creazione di un file-schema ad hoc
115.99 +++++++++++++++++++++++++++++++++++
115.100 +
115.101 +ISI-live mette a disposizione in "/etc/clone/examples" una serie di modelli
115.102 +a tal proposito. A seconda del tipo di installazione che si intende
115.103 +effettuare potrebbe essere preferibile utilizzare un modello piuttosto che
115.104 +un altro. Per installare il sistema verrà utilizzato il modello
115.105 +``/etc/clone/examples/isi``. Si crei dunque copia di tale file in ``/etc/clone/isi`` e
115.106 +lo si modifichi affinchè risponda alle proprie esigenze. ::
115.107 +
115.108 + argo:~# cp /etc/clone/examples/isi /etc/clone/
115.109 +
115.110 + argo:~# jmacs /etc/clone/isi
115.111 +
115.112 +.. sidebar:: **Nota**
115.113 +
115.114 + Chi non avesse molta famigliarità con l'editor di testo :term:`jmacs` potrà
115.115 + utilizzare un editor di testo più intuitivo come :term:`nano` ::
115.116 +
115.117 + argo:~# nano /etc/clone/isi
115.118 +
115.119 +Aperto il file, si proceda alla modifica inserendo i dati più opportuni.
115.120 +::
115.121 +
115.122 + GRUB_DEV="hd0,0"
115.123 + EMAIL="[email protected]"
115.124 + RAID='raid1'
115.125 + PARTITIONING=1
115.126 + FORMATTING=1
115.127 + LIVE=1
115.128 + DISCS="/dev/sda /dev/sdb"
115.129 + DESCR="""
115.130 + mnt_p fmt fs dim part_n overwrite opt
115.131 + /boot 1 ext2 24 1 0
115.132 + swap 1 swap 512 5 1
115.133 + /free 1 reiserfs 3500 6 1
115.134 + / 1 reiserfs 3500 7 1 defaults,acl
115.135 + /home 1 reiserfs fill 8 0 defaults,acl
115.136 + """
115.137 +
115.138 +Qualche osservazione sul contenuto del file
115.139 ++++++++++++++++++++++++++++++++++++++++++++
115.140 +
115.141 +.. sidebar:: Nota
115.142 +
115.143 + In caso si stia utilizzando un solo disco, rinunciando quindi alla
115.144 + configurazione raid1, si dovrà commentare inserendo il simbolo # ad
115.145 + inizio riga) o rimuovere la riga contentente la direttiva
115.146 + ``RAID='raid1'`` ed impostare la direttiva ``DISCS`` con il solo disco
115.147 + disponibile. Un RAID hardware viene visto dal sistema come un disco unico
115.148 + e rientra quindi nel caso appena citato.
115.149 +
115.150 ++ Il parametro *DISCS* fa espresso riferimento al modo in cui gli hardisk
115.151 + vengono visti dal sistema. Alcuni sistemi potrebbero riferirsi a tali
115.152 + dispositivi utilizzando nome diversi a seconda del controller rilevato. Si
115.153 + potrebbe, per esempio, trovare ``/dev/hda`` al posto di ``/dev/sda``. Per
115.154 + fugare ogni dubbio in merito si dovrà utilizzare il seguente comando::
115.155 +
115.156 + argo:~# cat /proc/partitions
115.157 + major minor #blocks name
115.158 +
115.159 + 7 1 1612 loop1
115.160 + 7 2 2068 loop2
115.161 + 7 3 2284 loop3
115.162 + 7 4 4 loop4
115.163 + 7 5 12652 loop5
115.164 + 7 6 4 loop6
115.165 + 7 7 59840 loop7
115.166 + 7 8 2144 loop8
115.167 + 7 9 133264 loop9
115.168 + 7 10 22984 loop10
115.169 + 8 0 3145728 sda
115.170 + 8 0 3145728 sdb
115.171 +
115.172 +Come si può notare dall'output, i dischi vengono riconosciuti come come "sd*"
115.173 +
115.174 +.. sidebar:: Nota
115.175 +
115.176 + Utilizzando il parametro ``fill``, in sostituzione della dimensione da
115.177 + occupare, clone assegnerà alla partizione tutto lo spazio libero
115.178 + rimanente. Questo parametro può essere utilizzato solo nell'ultima
115.179 + partizione.
115.180 +
115.181 +
115.182 +Avvio del processo di Clonazione
115.183 +--------------------------------
115.184 +
115.185 +Ora che il file di configurazione è pronto, non resterà che lanciare *clone* in modo
115.186 +che carichi la configurazione appena creata::
115.187 +
115.188 + argo:~# clone /etc/clone/isi
115.189 + PARTITIONING : True
115.190 + FORMATTING : True
115.191 + RAID : True
115.192 + disc0 : sda sdb
115.193 + PART: /dev/sda1 /boot ext2 defaults 0 2 (format: True)
115.194 + PART: /dev/sda5 swap swap defaults 0 0 (format: True)
115.195 + PART: /dev/sda6 /free reiserfs defaults 0 2 (format: True)
115.196 + PART: /dev/sda7 / reiserfs defaults,acl 0 1 (format: True)
115.197 + PART: /dev/sda8 /home reiserfs defaults,acl 0 2 (format: True)
115.198 + Continuo? [Y/n (n default)]
115.199 +
115.200 +Dopo aver confermato l'avvio del processo e atteso il tempo di un caffè, non
115.201 +resterà che scegliere una password per l'utente amministrativo root e
115.202 +riavviare la macchina::
115.203 +
115.204 + bin... boot... dev... etc... lib... home... opt... sbin... root... usr... var...
115.205 + chroot /.clone mkinitramfs -o /boot/initrd-2.6.20.11argo1 -r /dev/sda6 2.6.20.11argo1
115.206 + Inoltro a [email protected]
115.207 + grub-install --recheck --force-lba --no-floppy --root-directory=/.clone /dev/sda
115.208 + chroot /.clone /usr/sbin/update-grub
115.209 + Total clone time 3:06 minutes
115.210 + fdisk: 0:06
115.211 + copy: 2:39
115.212 + format: 0:00
115.213 + New password:
115.214 + Re-enter new password:
115.215 + LDAP password information changed for root
115.216 + passwd: password updated successfully
115.217 + umount /.clone/boot
115.218 + umount /.clone/
115.219 +
115.220 + argo:~# reboot
115.221 +
115.222 +A reboot effettuato, si potrà accedere al sistema autenticandosi come utente
115.223 +*root* ed utilizzando la password scelta in precedenza.
115.224 +
115.225 +Configurazione Dominio
115.226 +----------------------
115.227 +
115.228 +Per installare il dominio è sufficiente lanciare il comando::
115.229 +
115.230 + isi-startup NOME_DOMINIO nome_server password_root
115.231 +
115.232 +questa script si occupa di fare tutto il necessario:
115.233 +
115.234 +* configura samba impostando il nome di dominio ed il nome server netbios
115.235 +* imposta la password di amministratore (root) della macchina linux
115.236 +* imposta la password di amminstratore samba (administrator) del dominio
115.237 +* imposta la password di accesso al sottosistema di autenticazione (ldap)
115.238 +* controlla che tutti i SID definiti in LDAP siano dello stesso dominio
115.239 +* cambia ove necessario il nome dell'host
115.240 +* corregge il campo dell'ID del'utente nuovo da creare
115.241 +* imposta i permessi del filesystem (``isi-perms`` & ``isi-classe``)
115.242 +
115.243 +
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
116.2 +++ b/docs/install/intro.rst Mon Apr 26 11:16:23 2010 +0200
116.3 @@ -0,0 +1,173 @@
116.4 +=================
116.5 + Possibili setup
116.6 +=================
116.7 +
116.8 +Firewall
116.9 +========
116.10 +
116.11 +.. figure:: ../img/rete-fwisi.png
116.12 + :align: center
116.13 +
116.14 ++ :ref:`La rete <config_eth_dns>`
116.15 +
116.16 ++ Le politiche di :ref:`firewalling <config_firewall>`
116.17 +
116.18 +
116.19 +Server di dominio ISI
116.20 +=====================
116.21 +
116.22 +.. figure:: ../img/rete-srvisi.png
116.23 + :align: center
116.24 +
116.25 +Questa tipologia di installazione presuppone che ci sia già un firewall a
116.26 +protezione della rete. Il comando ``firewall`` del server, configurato per
116.27 +considerare la zona a cui è collegato come *interna*, adotterà pertanto una
116.28 +politica di filtraggio più permissiva.
116.29 +
116.30 +
116.31 ++ :ref:`La rete <config_eth_dns>`
116.32 +
116.33 ++ Le politiche di :ref:`firewalling <config_firewall>`
116.34 +
116.35 ++ Attivare il server di Dominio
116.36 +
116.37 ++ I servizi principali
116.38 +
116.39 + + demone nfs
116.40 +
116.41 + + a cosa serve
116.42 +
116.43 + + files di configurazione
116.44 +
116.45 + + configurazione del servizio
116.46 +
116.47 + + demone dhcp
116.48 +
116.49 + + a cosa serve
116.50 +
116.51 + + files di configurazione
116.52 +
116.53 + + :ref:`configurazione del servizio <config_dhcpd>`
116.54 +
116.55 +
116.56 + + demone dns
116.57 +
116.58 + + a cosa serve
116.59 +
116.60 + + files di configurazione
116.61 +
116.62 + + configurazione del servizio
116.63 +
116.64 +
116.65 + + proxy
116.66 +
116.67 + + Squid
116.68 +
116.69 + + a cosa serve
116.70 +
116.71 + + files di configurazione
116.72 +
116.73 + + configurazione del servizio
116.74 +
116.75 + + Dans Guardian
116.76 +
116.77 + + a cosa serve
116.78 +
116.79 + + requisiti
116.80 +
116.81 + + files di configurazione
116.82 +
116.83 + + configurazione del servizio
116.84 +
116.85 + + ClamAV
116.86 +
116.87 + + a cosa serve
116.88 +
116.89 + + requisiti
116.90 +
116.91 + + files di configurazione
116.92 +
116.93 + + configurazione del servizio
116.94 +
116.95 +
116.96 + + sarg
116.97 +
116.98 + + a cosa serve
116.99 +
116.100 + + requisiti
116.101 +
116.102 + + files di configurazione
116.103 +
116.104 + + configurazione del servizio
116.105 +
116.106 + + web server: apache
116.107 +
116.108 + + posta
116.109 +
116.110 + + pop3
116.111 +
116.112 + popa3d
116.113 +
116.114 + + a cosa serve
116.115 +
116.116 + + requisiti
116.117 +
116.118 + + files di configurazione
116.119 +
116.120 + + configurazione del servizio
116.121 +
116.122 + + smtp
116.123 +
116.124 +
116.125 +
116.126 +Aggiornare una precedente release di ISI
116.127 +----------------------------------------
116.128 +
116.129 +DA COMPLETARE
116.130 +
116.131 ++ aggiornare un sistema ISI preesistente
116.132 +
116.133 + + Principali salti di versione (e link al changelog)
116.134 +
116.135 + + Aggiornare da una isi versione X ad una isi versione Y....
116.136 +
116.137 +
116.138 +
116.139 +
116.140 +
116.141 +Configurare i client per il dominio
116.142 +-----------------------------------
116.143 +
116.144 +
116.145 ++ Client Windows
116.146 +
116.147 + + Windows98 Second Edition
116.148 +
116.149 + procedura illustrata
116.150 +
116.151 + + Windows2000
116.152 +
116.153 + procedura illustrata
116.154 +
116.155 +
116.156 + + Windows XP Home
116.157 +
116.158 + tale versione non è in grado do accedere al dominio.
116.159 +
116.160 + + Windows XP Professional
116.161 +
116.162 + procedura illustrata
116.163 +
116.164 +
116.165 +
116.166 +
116.167 ++ Client Linux
116.168 +
116.169 + + Edubuntu linux
116.170 +
116.171 + pacchetti aggiuntivi necessari
116.172 +
116.173 + Configurazione del client
116.174 +
116.175 +
116.176 +
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/docs/install/reteisi.rst Mon Apr 26 11:16:23 2010 +0200
117.3 @@ -0,0 +1,39 @@
117.4 +.. _config_files:
117.5 +
117.6 +Reteisi
117.7 +=======
117.8 +
117.9 +
117.10 +/etc/isi
117.11 +--------
117.12 +
117.13 +.. index:: logon.bat
117.14 +
117.15 +logon.bat
117.16 +~~~~~~~~~
117.17 +
117.18 +.. index:: logon.conf
117.19 +
117.20 +logon.conf
117.21 +~~~~~~~~~~
117.22 +
117.23 +.. index:: acl.conf
117.24 +
117.25 +acl.conf
117.26 +~~~~~~~~
117.27 +
117.28 +
117.29 +Home e share
117.30 +============
117.31 +
117.32 +
117.33 +/home/users
117.34 +-----------
117.35 +
117.36 +/home/shares
117.37 +------------
117.38 +
117.39 +
117.40 +/home/samba
117.41 +-----------
117.42 +
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118.2 +++ b/docs/install/servizi/apache_limit_pub.rst Mon Apr 26 11:16:23 2010 +0200
118.3 @@ -0,0 +1,143 @@
118.4 +Pubblicare una directory e restringerne l'accsso via Apache2
118.5 +============================================================
118.6 +
118.7 +Cosa si intende con pubblicare una directory?
118.8 +------------------------------------------------
118.9 +
118.10 +Pubblicare una directory del nostro filesystem via webserver ci permette
118.11 +di poterla raggiungere remotamente con il nostro browser preferito, puntando
118.12 +semplicemente ad un indirizzo del tipo ``http://<server>/directory``.
118.13 +
118.14 +Un esempio concreto : Pubblichiamo le statistiche del server proxy Squid
118.15 +----------------------------------------------------------------------------
118.16 +
118.17 +Ci porremo come obiettivo la pubblicazione del contenuto della directory
118.18 +"/var/www/squid-reports", contenente i report generati da :ref:`sarg <sarg-report>`
118.19 +relativi al proxy.
118.20 +Dato che le informazioni contenute nella directory in questione sono
118.21 +riservate, l'accesso verra' limitato ad alcuni particolari network, ai quali
118.22 +si rendera' comunque obbligatorio un processo autenticativo.
118.23 +
118.24 +Prepariamo il file delle password
118.25 +---------------------------------
118.26 +Il file delle password contiene le credenziali necessarie per il processo di
118.27 +autenticazione.
118.28 +
118.29 +Creiamo la directory in cui mettere il nostro file::
118.30 +
118.31 + mkdir /etc/apache2/htpasswd-sites/squid-reports
118.32 +
118.33 +Generiamo il file password ::
118.34 +
118.35 + htpasswd -c /etc/apache2/htpasswd-sites/squid-reports nomeutente
118.36 +
118.37 +E ne restringiamo l'accesso il piu' possibile ::
118.38 +
118.39 + chown root.www-data /etc/apache2/htpasswd-sites/squid-reports
118.40 + chmod 640 /etc/apache2/htpasswd-sites/squid-reports
118.41 +
118.42 +Ora siamo pronti per apportare le modifiche ad apache2.
118.43 +
118.44 +Modifichiamo quindi "/etc/apache2/sites-enabled/000-default" od il file di
118.45 +configurazione di un sito abilitato (000-default e' solitamente attivo gia'
118.46 +attivo di default), e aggiungiamo nella sezione compresa tra
118.47 +<VirtualHost></VirtualHost>, una sottosezione <directory> che istruisca
118.48 +apache su come pubblicare la nostra directory "/var/www/squid-reports".
118.49 +
118.50 +Nella configurazione di esempio verrà consentito solo a localhost ed al
118.51 +network 192.168.1.0/24 l'accesso alla fase autenticativa che consente di
118.52 +raggiungere la directory, tutti gli altri host verranno rifiutati ::
118.53 +
118.54 + <Directory "/var/www/http/squid-reports/">
118.55 + #########################################################################
118.56 + # Permette solo a 127.0.0.1 ed al network 192.168.1.0/24 di accedere alla
118.57 + # directory
118.58 + Deny from all
118.59 + Order Deny,Allow
118.60 +
118.61 + Allow from 127.0.0.1/255.0.0.0 ::1/128
118.62 + Allow from 192.168.1.0/255.0.0.0
118.63 + #########################################################################
118.64 + # Attivare autenticazione tramite file di password
118.65 + # -----------------------------------------------------
118.66 + # Creare il file password ::
118.67 + #
118.68 + # htpasswd -c /dir/filepassword utente
118.69 + #
118.70 + # Limitiamo il piu' possibile i permessi del file ma teniamo anche presente
118.71 + # che Apache dovra' poterlo leggere per verificare le credenziali fornitegli::
118.72 + #
118.73 + # chown root.www-data /dir/filepassword
118.74 + # chmod 640 /dir/filepassword
118.75 + #
118.76 + AuthType Basic
118.77 + # Si potra' personalizzare il messaggio che compare alla richiesta di
118.78 + # autenticazione.
118.79 + AuthName "Area ad accesso limitato."
118.80 + AuthUserFile /dir/filepassword
118.81 + # Richiede un utente particolare
118.82 + # Require user nomeutente
118.83 + # Ritiene valido uno qualunque degli utenti inseriti nel file di password
118.84 + Require valid-user
118.85 + </Directory>
118.86 +
118.87 +E' anche possibile definire un Alias( lo si puo' intendere come un soprannome
118.88 +che diamo alla nostra directory di destinazione), anteponendo al blocco
118.89 +<Directory></Directory> una direttiva "Alias".
118.90 +
118.91 +Es. ::
118.92 +
118.93 + Alias /reports "/var/www/http/squid-reports/"
118.94 +
118.95 +Nell'esempio sopra si e' definito un Alias "reports" che permette di raggiungere
118.96 +"/var/www/http/squid-reports/" anche tramite l'url "http://server/reports".
118.97 +
118.98 +Ultimate le modifiche, il nostro file di configurazione dovrebbe contenere un
118.99 +blocco simile alla seguente ::
118.100 +
118.101 + Alias /reports "/var/www/http/squid-reports/"
118.102 + <Directory "/var/www/http/squid-reports/">
118.103 + #########################################################################
118.104 + # Permette solo a 127.0.0.1 ed al network 192.168.1.0/24 di accedere alla
118.105 + # directory
118.106 + Deny from all
118.107 + Order Deny,Allow
118.108 +
118.109 + Allow from 127.0.0.1/255.0.0.0 ::1/128
118.110 + Allow from 192.168.1.0/255.0.0.0
118.111 + #########################################################################
118.112 + # Attivare autenticazione tramite file di password
118.113 + # -----------------------------------------------------
118.114 + # Creare il file password ::
118.115 + #
118.116 + # htpasswd -c /dir/filepassword utente
118.117 + #
118.118 + # Limitiamo il piu' possibile i permessi del file ma teniamo anche presente
118.119 + # che Apache dovra' poterlo leggere per verificare le credenziali fornitegli::
118.120 + #
118.121 + # chown root.www-data /dir/filepassword
118.122 + # chmod 640 /dir/filepassword
118.123 + #
118.124 + AuthType Basic
118.125 + # Si potra' personalizzare il messaggio che compare alla richiesta di
118.126 + # autenticazione.
118.127 + AuthName "Area ad accesso limitato."
118.128 + AuthUserFile /dir/filepassword
118.129 + # Richiede un utente particolare
118.130 + # Require user nomeutente
118.131 + # Ritiene valido uno qualunque degli utenti inseriti nel file di password
118.132 + Require valid-user
118.133 + ### Personalizzazione messaggi di errore
118.134 + # CODICE 401 : Credenziali fornite non valide
118.135 + # CODICE 403 : Indirizzo di rete rifiutato
118.136 + ErrorDocument 401 "Credenziali fornite non valide !"
118.137 + ErrorDocument 403 "Non ti e' consentito accedere a quest'area."
118.138 +
118.139 + </Directory>
118.140 +
118.141 +
118.142 +
118.143 +Per spiegazioni ulteriori sulle direttive usate si rimanda alla
118.144 +documentazione_ ufficiale di apache2
118.145 +
118.146 +.. _documentazione: http://httpd.apache.org/docs/1.3/howto/auth.html
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
119.2 +++ b/docs/install/servizi/apache_userdir.rst Mon Apr 26 11:16:23 2010 +0200
119.3 @@ -0,0 +1,148 @@
119.4 +.. _config_apache_userdir:
119.5 +
119.6 +Pubblicare le home utente con Apache2
119.7 +=======================================
119.8 +
119.9 +Cosa serve?
119.10 +-----------
119.11 +
119.12 +1. Apache2 installato e configurato correttamente
119.13 +2. Modulo ``userdir`` del webserver configurato ed attivato
119.14 +
119.15 +Focalizzeremo la nostra attenzione sul punto ``2``.
119.16 +
119.17 +I moduli estendono le funzionalità del webserver. Per gestirne attivazione e
119.18 +disattivazione, Apache mette a disposizione due comandi:
119.19 +
119.20 +- ``a2enmod`` elenca i moduli `non avviati` disponibili e permette di attivarli.
119.21 +- ``a2dismod`` elenca i moduli `avviati` disponibili e permette di disattivarli.
119.22 +
119.23 +Nella pratica, attivazione e disattivazione consistono nella semplice creazione di
119.24 +un collegamento simbolico da ``/etc/apache2/mods-available/nomemodulo.load`` a
119.25 +``/etc/apache2/mods-enabled/.load``.
119.26 +Alcuni moduli hanno inoltre un file aggiuntivo di configurazione del tipo
119.27 +`nomemodulo.conf` qualora si procedesse all'attivazione manuale, non si dimentichi
119.28 +di aggiungere anche quel collegamento simbolico se necessario!.
119.29 +
119.30 +Quali moduli ho a disposizione?
119.31 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119.32 +
119.33 +::
119.34 +
119.35 + ls /etc/apache2/mods-available/
119.36 +
119.37 + actions.load authz_dbm.load charset_lite.load dump_io.load
119.38 + log_forensic.load proxy_connect.load unique_id.load
119.39 + alias.load authz_default.load dav_fs.conf env.load
119.40 + mem_cache.conf proxy_ftp.load userdir.conf
119.41 + asis.load authz_groupfile.load dav_fs.load expires.load
119.42 + mem_cache.load proxy_http.load userdir.load
119.43 + auth_basic.load authz_host.load dav.load ext_filter.load
119.44 + mime.load proxy.load usertrack.load
119.45 + auth_digest.load authz_owner.load dav_lock.load file_cache.load
119.46 + mime_magic.conf rewrite.load version.load
119.47 + authn_alias.load authz_user.load dbd.load filter.load
119.48 + mime_magic.load setenvif.load vhost_alias.load
119.49 + authn_anon.load autoindex.load deflate.conf headers.load
119.50 + negotiation.load sick-hack-to-update-modules
119.51 + authn_dbd.load cache.load deflate.load ident.load
119.52 + php5.conf speling.load
119.53 + authn_dbm.load cern_meta.load dir.conf imagemap.load
119.54 + php5.load ssl.conf
119.55 + authn_default.load cgid.conf dir.load include.load
119.56 + proxy_ajp.load ssl.load
119.57 + authn_file.load cgid.load disk_cache.conf info.load
119.58 + proxy_balancer.load status.load
119.59 + authnz_ldap.load cgi.load disk_cache.load ldap.load
119.60 + proxy.conf suexec.load
119.61 +
119.62 +Quali sono già stati attivati?
119.63 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119.64 +
119.65 +::
119.66 +
119.67 + ls /etc/apache2/mods-enabled/
119.68 +
119.69 + actions.load auth_basic.load authz_default.load authz_host.load
119.70 + autoindex.load dir.conf env.load negotiation.load php5.load
119.71 + status.load alias.load authn_file.load authz_groupfile.load
119.72 + authz_user.load cgi.load dir.load mime.load php5.conf setenvif.load
119.73 +
119.74 +.. Note::
119.75 +
119.76 + Notare l'assenza di ``userdir.load``
119.77 +
119.78 +Configurare il modulo ``userdir.load``
119.79 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119.80 +
119.81 +Affinchè il webserver pubblicizzi il sito personale di ogni utente, contenuto in
119.82 +~utente/public_html, modificheremo ``userdir.conf``.
119.83 +
119.84 +.. Note::
119.85 +
119.86 + Nota probabilmente ovvia:
119.87 + Nell'esempio che segue viene usato l'editor `jmacs`. Ovviamente nulla viete di
119.88 + usare il proprio editor di testi preferito.
119.89 +
119.90 +::
119.91 +
119.92 + jmacs /etc/apache2/mods-available/userdir.conf
119.93 +
119.94 + <IfModule mod_userdir.c>
119.95 + UserDir public_html
119.96 + UserDir disabled root
119.97 +
119.98 + <Directory /home/*/public_html>
119.99 + AllowOverride FileInfo AuthConfig Limit
119.100 + Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
119.101 + </Directory>
119.102 + </IfModule>
119.103 +
119.104 +In questo modo::
119.105 +
119.106 + <IfModule mod_userdir.c>
119.107 + UserDir public_html
119.108 + UserDir disabled root
119.109 +
119.110 + <Directory /home/users/*/*/public_html>
119.111 + AllowOverride FileInfo AuthConfig Limit
119.112 + Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
119.113 + </Directory>
119.114 + </IfModule>
119.115 +
119.116 +.. Note::
119.117 +
119.118 + Ovviamente è stato impostato ``/home/users/*/*/public_html`` per rispettare
119.119 + l'organizzazione delle `home utente` ISI.
119.120 +
119.121 +Attivare ``userdir.load``
119.122 +~~~~~~~~~~~~~~~~~~~~~~~~~
119.123 +
119.124 +Non resta che procedere all'attivazione di ``userdir`` usando ``a2enmod`` ::
119.125 +
119.126 + a2enmod userdir
119.127 +
119.128 + Module userdir installed; run /etc/init.d/apache2 force-reload to enable.
119.129 +
119.130 +E ad inizializzare apache2 come indicato da ``a2enmod``
119.131 +::
119.132 +
119.133 + /etc/init.d/apache2 force-reload
119.134 + Forcing reload of web server (apache2)...apache2: Could not reliably determine
119.135 + the server's fully qualified domain name, using 127.0.0.1 for ServerName
119.136 + waiting apache2: Could not reliably determine the server's fully qualified
119.137 + domain name, using 127.0.0.1 for ServerName
119.138 +
119.139 +Verificare che tutto funzioni
119.140 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119.141 +
119.142 +La verifica viene fatta, molto semplicemente, puntando un qualunque browser
119.143 +su ``http://server/~nomeutente``.
119.144 +
119.145 +Od in alternativa, direttamente da server, con un semplicissimo::
119.146 +
119.147 + lynx http://localhost/~test
119.148 +
119.149 +Se a risponderci sarà la pagina `index.html` contenuta in `~test/public_html` la
119.150 +procedura sarà andata a buon fine =)
119.151 +
120.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
120.2 +++ b/docs/install/servizi/bind.rst Mon Apr 26 11:16:23 2010 +0200
120.3 @@ -0,0 +1,52 @@
120.4 +.. _config_bind:
120.5 +
120.6 +dns server: bind9
120.7 +===================
120.8 +
120.9 +Bind è il server dns.
120.10 +
120.11 +.. sidebar:: Serve?
120.12 +
120.13 + La configurazione di questo servizio è necessaria solo
120.14 + se si ha un server web interno alla scuola, con IP privato e si deidera
120.15 + poterlo raggiungere con lo stesso nome dall'interno e dall'esterno della
120.16 + scuola. In questo caso la configurazione è più complessa di quanto riportato
120.17 + di seguito.
120.18 +
120.19 +
120.20 +L'attivazione di bind non richiede nessuna modifica particolare; la
120.21 +configurazione trovata di default andrà dunque benissimo.
120.22 +
120.23 +Ci si assicuri che sia avviato::
120.24 +
120.25 + srv-scuolax:/etc/dhcp3# ps aux|grep bind
120.26 + root 5118 0.0 0.2 2860 692 pts/0 R+ 17:24 0:00 grep bind
120.27 +
120.28 +Tale comando, visualizza l'elenco dei processi attivi al momento il cui nome
120.29 +contenga la parola *bind*. Come si evince dall'output non c'è nessun
120.30 +processo bind9 attivo nell'esempio.
120.31 +
120.32 +Qualora bind9 non fosse attivo si potrà avviarlo manualmente::
120.33 +
120.34 + srv-scuolax:/etc/dhcp3# /etc/init.d/bind9 start
120.35 + Starting domain name service...: bind.
120.36 +
120.37 +Verifichiamo che si sia attivato::
120.38 +
120.39 + srv-scuolax:~# ps aux | grep bind
120.40 + bind 5136 0.0 1.4 33972 3712 ? Ssl Feb15 0:00 /usr/sbin/named -u bind
120.41 + root 6723 0.0 0.2 2856 696 pts/0 S+ 00:01 0:00 grep bind
120.42 +
120.43 +
120.44 +Non resta che modificare di conseguenza ``/etc/resolv.conf`` affinchè, per la
120.45 +risoluzione degli hostname, venga usato prioritariamente bind9::
120.46 +
120.47 + srv-scuolax:/etc/dhcp3# cat /etc/resolv.conf
120.48 + nameserver 127.0.0.1
120.49 + nameserver 192.84.138.160
120.50 + nameserver 192.84.138.1
120.51 +
120.52 +E' importante verificare inoltre che il servizio venga attivato ad ogni
120.53 +avvio della macchina. A tal proposito, come visto in altre occasioni, si
120.54 +modifichi */etc/runlevel.conf* rimuovendo il simbolo # ad inizio riga, se
120.55 +presente.
121.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
121.2 +++ b/docs/install/servizi/bind_server.rst Mon Apr 26 11:16:23 2010 +0200
121.3 @@ -0,0 +1,260 @@
121.4 +.. _config_bind_server:
121.5 +
121.6 +DNS Server
121.7 +==========
121.8 +
121.9 +Qui troverete i file di configurazione del servizio DNS per una intranet
121.10 +scolastica concepita secondo il modello ISI. Il DNS assicurerà la
121.11 +risoluzione dei nomi delle macchine sulla intranet, comprese quelle ad
121.12 +indirizzo dinamico (aggiornamento del DNS via DHCP). Si tenga presente che
121.13 +nelle nostre scuole la segreteria opera in ambiente win2000 server
121.14 +configurato con Active Directory e quindi realizzante un dominio
121.15 +separato. Al momento l'integrazione segreteria resto della intranet è al
121.16 +livello della condivisione dell'accesso internet (magari con l'attivazione
121.17 +della doppia adsl) attraverso un unico firewall e alla connessione permessa
121.18 +solo da client particolari esterne alla sottorete specifica.
121.19 +
121.20 + * /etc/bind/named.conf.local
121.21 + * /etc/bind/named.conf.options
121.22 + * /etc/bind/miascuola.lan
121.23 + * /etc/bind/rev1.lan
121.24 + * /etc/bind/rev2.lan
121.25 + * /etc/bind/rev5.lan
121.26 +
121.27 +Per quanto riguarda i dettagli circa la configurazione di Bind9 si rimanda
121.28 +alla documentazione tecnica disponibile in rete, qui ci si limiterà ad
121.29 +illustrare l'organizzazione e il contenuto dei file di configurazione.
121.30 +
121.31 +L'architettura della intranet sia la seguente:
121.32 +
121.33 + * vlan1 sottorete di staff e di amministrazione
121.34 + * vlan2 sottorete di laboratorio (ce ne può essere una per laboratorio)
121.35 + * vlan5 sottorete della segreteria (si ipotizza che la segreteria
121.36 + sfrutti, per fondamentali ragioni di sicurezza) il firewall principale
121.37 + per l'accesso internet, si tenga presente inoltre che nel modello isi,
121.38 + la segreteria è integrata nella intranet dell'istituto.
121.39 +
121.40 +Il server DNS può essere ospitato dovunque, ma nel modello isi tale
121.41 +servizio, insieme al DHCP, è in funzione sulla macchina firewall che, grazie
121.42 +al sistema delle vlan, è attestata su tutte le vlan.
121.43 +
121.44 +il dominio dns si chiamerà miascuola.lan. Il che significa, ad esempio, che
121.45 +l'url del server web interno sarà www.miascuola.lan
121.46 +
121.47 +In Debian tutti i file di configurazione necessari si trovano sotto
121.48 +/etc/bind e quelli per noi significativi sono:
121.49 +
121.50 + * /etc/bind/named.conf in cui sono elencate le zone standard del domio
121.51 + DNS ALERT! lo si lascia inalterato
121.52 +
121.53 + * /etc/bind/named.conf.local in cui sono elencate le zone dirette del
121.54 + dominio e quelle inverse del nostro dominio
121.55 +
121.56 + * /etc/bind/named.conf.option in cui vengono elencate i forwarders
121.57 +
121.58 + * /etc/bind/miascuola.lan in cui sono elencate nomi e ip di tutte le
121.59 + macchine sulla rete
121.60 +
121.61 + * /etc/bind/rev1 e simili che costituiscono le zone inverse, cioè il
121.62 + meccanismo con cui dall'ip si risale al nome
121.63 +
121.64 +Ma vediamoli in dettaglio:
121.65 +
121.66 +/etc/bind/named.conf.local
121.67 +
121.68 +Si noti la direttiva key DHCP_UPDATER. Si ricordi che il valore di
121.69 +quest'ultima deve essere identico a quella dichiarata nel file di
121.70 +configurazione del server dhcp (/etc/dhcp3/dhcpd.conf) altrimenti
121.71 +l'aggiornamento dinamico dei record dns non funzionerà.::
121.72 +
121.73 + // -*- c++ -*-
121.74 + // Do any local configuration here
121.75 + //
121.76 +
121.77 + // Consider adding the 1918 zones here, if they are not used in your
121.78 + // organization
121.79 + //include "/etc/bind/zones.rfc1918";
121.80 +
121.81 +
121.82 + // Tells the nameserver who to allow updates from, with what keys
121.83 + controls {
121.84 + inet 127.0.0.1 allow { localhost; } keys { DHCP_UPDATER; };
121.85 + };
121.86 +
121.87 +
121.88 + // ddns - key
121.89 + key DHCP_UPDATER {
121.90 + algorithm HMAC-MD5.SIG-ALG.REG.INT;
121.91 + secret NmfU90eVsfpLk2Ht07R2IQ==;
121.92 + ';
121.93 +
121.94 + zone "miascuola.lan" {
121.95 + type master;
121.96 + file "/etc/bind/miascuola.lan";
121.97 + allow-update { key DHCP_UPDATER; ';
121.98 + };
121.99 +
121.100 +
121.101 + // staff - reverse - vlan1
121.102 + zone "1.168.192.in-addr.arpa" {
121.103 + type master;
121.104 + file "/etc/bind/rev1";
121.105 + allow-update { key DHCP_UPDATER; ';
121.106 + };
121.107 +
121.108 +
121.109 + // lab - reverse - vlan2
121.110 + zone "2.168.192.in-addr.arpa" {
121.111 + type master;
121.112 + file "/etc/bind/rev2";
121.113 + allow-update { key DHCP_UPDATER; ';
121.114 + };
121.115 +
121.116 +
121.117 + // segreteria - reverse - vlan5
121.118 + zone "5.168.192.in-addr.arpa" {
121.119 + type master;
121.120 + file "/etc/bind/rev5;
121.121 + allow-update { key DHCP_UPDATER; ';
121.122 + };
121.123 +
121.124 +
121.125 +/etc/bind/named.conf.options
121.126 +
121.127 +Qui la cosa importante sono i forwarders. Il concetto è semplice: quando il
121.128 +nostro DNS non riesce a risolvere un nome, perché esterno alle zone locali,
121.129 +passerà la richiesta ai server DNS esterni dichiarati dalla direttiva
121.130 +forwarders. In pratica si tratta dei DNS primario o secondario indicatici
121.131 +dal nostro provider oppure di DNS pubblici.::
121.132 +
121.133 + options {
121.134 + directory "/var/cache/bind";
121.135 +
121.136 + // If there is a firewall between you and nameservers you want
121.137 + // to talk to, you might need to uncomment the query-source
121.138 + // directive below. Previous versions of BIND always asked
121.139 + // questions using port 53, but BIND 8.1 and later use an unprivileged
121.140 + // port by default.
121.141 +
121.142 + // query-source address * port 53;
121.143 +
121.144 + // If your ISP provided one or more IP addresses for stable
121.145 + // nameservers, you probably want to use them as forwarders.
121.146 + // Uncomment the following block, and insert the addresses replacing
121.147 + // the all-0's placeholder.
121.148 +
121.149 + // i forwarders sono gli ip dei DNS esterni
121.150 + // (quelli del vostro provider)
121.151 + // qui saranno automaticamente redirette tutte le richieste DNS
121.152 + // non soddisfatte all'interno del nostro dominio
121.153 +
121.154 + forwarders {
121.155 + 151.99.125.2;
121.156 + 194.243.154.62;
121.157 + };
121.158 +
121.159 + auth-nxdomain no; # conform to RFC1035
121.160 +
121.161 + };
121.162 +
121.163 +
121.164 +/etc/bind/miascuola.lan
121.165 +
121.166 +Sono elencati i server, gli apparati di rete ed eventuali pc con ip
121.167 +statico. Questo file provvede alla fondamentale funzione di risoluzione dei
121.168 +nomi nel corrispondente indirizzo ip. Visualizzando questo file a server in
121.169 +funzione, vi si troveranno dentro anche gli aggiornamenti effettuati dal
121.170 +server dhcp ogni volta che un client si connette alla rete.
121.171 +
121.172 +fw-scuola = il firewall della scuola, cioè la macchina interposta fra la
121.173 +nostra rete e internet. Il router adsl è direttamente connesso a questa
121.174 +macchina attraverso una delle sue schede di rete (deve averne infatti almeno
121.175 +due, o tante quante sono le sottoreti che si vogliono gestire nel caso non
121.176 +si disponga di dispositivi 802.1q) srv-uno = il server principale (quello
121.177 +che fa anche da PDC)
121.178 +
121.179 +srv-due = un altro server stp-lx = stampanti laser di rete sw-xxx = switch
121.180 +managed con gestione VLAN (802.1q) rt-adslx = router adsl (potrebbe
121.181 +essercene piu' di uno) xp-xxxxx = client qualificati con ip statico e
121.182 +funzioni amministrative::
121.183 +
121.184 + $ORIGIN .
121.185 + $TTL 86400 ; 1 day
121.186 + miascuola.lan IN SOA fw-scuola.miascuola.lan. root.miascuola.lan. (
121.187 + 1 ; serial
121.188 + 28800 ; refresh (8 hours)
121.189 + 14400 ; retry (4 hours)
121.190 + 3600000 ; expire (5 weeks 6 days 16 hours)
121.191 + 86400 ; minimum (1 day)
121.192 + )
121.193 + NS fw-scuola.miascuola.lan.
121.194 + fw-scuola A 192.168.1.1 //sulla vlan1 (sottorete di staff)
121.195 + srv-uno A 192.168.1.2 //sulla vlan1
121.196 + srv-due A 192.168.1.3 //sulla vlan1
121.197 + stp-l1 A 192.168.1.6 //stampante tcp/ip su vlan1
121.198 + sw-uno A 192.168.1.21 //switch managed su vlan1
121.199 + sw-due A 192.168.1.22 //switch managed su vlan1
121.200 + rt-adsl1 A 192.168.200.2 //router adsl
121.201 + www CNAME srv-uno
121.202 + xp-admin01 A 192.168.1.25 //pc con funzioni particolari
121.203 + xp-preside A 192.168.1.26
121.204 + stp-l2 A 192.168.2.7 //stanpante tcp/ip su vlan2
121.205 + srv-segreteria A 192.168.5.2 //sulla vlan5 (segreteria)
121.206 +
121.207 +
121.208 +/etc/bind/rev1.lan
121.209 +File di risoluzione inversa per la vlan1
121.210 +
121.211 +::
121.212 +
121.213 + $ORIGIN .
121.214 + $TTL 86400 ; 1 day
121.215 + 1.168.192.in-addr.arpa IN SOA fw-scuola.miascuola.lan. root.miascuola.lan. (
121.216 + 1 ; serial
121.217 + 28800 ; refresh (8 hours)
121.218 + 14400 ; retry (4 hours)
121.219 + 3600000 ; expire (5 weeks 6 days 16 hours)
121.220 + 86400 ; minimum (1 day)
121.221 + )
121.222 + NS fw-scuola.miascuola.lan.
121.223 + 1 PTR fw-miascuola.miascuola.lan.
121.224 + 2 PTR srv-uno.miascuola.lan.
121.225 + 3 PTR srv-due.miascuola.lan.
121.226 + 6 PTR stp-l1.miascuola.lan.
121.227 + 10 PTR xp-preside.miascuola.lan.
121.228 + 11 PTR xp-admin01.miascuola.lan.
121.229 + 21 PTR sw-rag.miascuola.lan.
121.230 + 22 PTR sw-due.miascuola.lan.
121.231 +
121.232 +
121.233 +/etc/bind/rev2.lan
121.234 +::
121.235 +
121.236 + $ORIGIN .
121.237 + $TTL 86400 ; 1 day
121.238 + 2.168.192.in-addr.arpa IN SOA fw-scuola.miascuola.lan. root.miascuola.lan. (
121.239 + 1 ; serial
121.240 + 28800 ; refresh (8 hours)
121.241 + 14400 ; retry (4 hours)
121.242 + 3600000 ; expire (5 weeks 6 days 16 hours)
121.243 + 86400 ; minimum (1 day)
121.244 + )
121.245 + NS fw-scuola.miascuola.lan.
121.246 + 1 PTR fw-scuola.miascuola.lan.
121.247 + 7 PTR stp-l2.miascuola.lan.
121.248 +
121.249 +
121.250 + /etc/bind/rev5.lan
121.251 +
121.252 + $TTL 86400 ; 1 day
121.253 + 5.168.192.in-addr.arpa IN SOA fw-scuola.miascuola.lan. root.miascuola.lan. (
121.254 + 1 ; serial
121.255 + 28800 ; refresh (8 hours)
121.256 + 14400 ; retry (4 hours)
121.257 + 3600000 ; expire (5 weeks 6 days 16 hours)
121.258 + 86400 ; minimum (1 day)
121.259 + )
121.260 + NS fw-scuola.miascuola.lan.
121.261 + 1 PTR fw-scuola.miascuola.lan.
121.262 + 2 PTR srv-segreteria.miascuola.lan.
121.263 +
122.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
122.2 +++ b/docs/install/servizi/dhcpd.rst Mon Apr 26 11:16:23 2010 +0200
122.3 @@ -0,0 +1,86 @@
122.4 +.. _config_dhcpd:
122.5 +
122.6 +dhcpd
122.7 +==================================
122.8 +Il servizio dhcp consente di configurare automaticamente impostazioni di rete
122.9 +come ip, dns, winserver, e molto altro ancora ancora, su tutti i client presenti
122.10 +nella nostra rete, siano essi Linux o Microsoft.
122.11 +Usando un dhcp-server potremmo dunque evitare di configurare a mano le impostazioni
122.12 +di ogni singolo client.
122.13 +
122.14 +Per approfondimenti: `http://it.wikipedia.org/wiki/DHCP`.
122.15 +
122.16 +.. sidebar:: **Ci serve?**
122.17 +
122.18 + Non è necessario usare dhcp ma è mia esperienza che gli amministratori
122.19 + scolastici che spesso non comprendono l'importanza del winserver,
122.20 + dimenticano di impostarlo e conseguentemente -in alcune stutture di rete-
122.21 + alcuni client non trovano il server di dominio. Con il dhcp server siamo
122.22 + sicuri che tutti i client avranno la stessa configurazione.
122.23 +
122.24 +dhcpd.conf
122.25 +----------
122.26 +La configurazione del servizio viene effettuata modificando il file di
122.27 +configurazione ``/etc/dhcp3/dhcpd.conf`` con un qualunque editor di testo.
122.28 +*Nota*: Prestare attenzione a non confondere dhcp3 con dhcp( se presente).
122.29 +Essendo i parametri configurabili molteplici, verrà fornito, a seguire, un
122.30 +esempio pratico funzionante di configurazione utile in un ambiente ISI. Nulla
122.31 +vieta, come ovvio, di aggiungere o rimuovere direttive ulteriori.
122.32 +Una lettura del file del file ``/etc/dhcp3/dhcpd.conf.isi.sample`` potrebbe
122.33 +risultare utile fonte di spunto.
122.34 +
122.35 +La configurazione di ``/etc/dhcp3/dhcpd.conf`` suggerita, per un'installazione
122.36 +"standard", è la seguente::
122.37 +
122.38 + ##### option definitions common to all supported networks...
122.39 + option domain-name "srv-scuolax.lan";
122.40 + option domain-name-servers 10.1.2.1;
122.41 +
122.42 + option subnet-mask 255.255.255.0;
122.43 + default-lease-time 600;
122.44 + max-lease-time 7200;
122.45 +
122.46 + option option-128 code 128 = string;
122.47 + option option-129 code 129 = text;
122.48 +
122.49 + ##### subnet
122.50 + subnet 10.1.2.0 netmask 255.255.255.0 {
122.51 + range 10.1.2.100 10.1.2.200;
122.52 + option routers 10.1.2.1;
122.53 + option netbios-name-servers 10.1.2.1;
122.54 + option netbios-node-type 8;
122.55 +
122.56 + option subnet-mask 255.255.255.0;
122.57 + option broadcast-address 10.1.2.255;
122.58 + default-lease-time 600;
122.59 + max-lease-time 7200;
122.60 + }
122.61 +
122.62 +Adottando tale configurazione, il server dhcp risulterà impostato per:
122.63 +
122.64 ++ assegnare un indirizzo IP (ed una netmask)
122.65 ++ *GATEWAY* ( option routers )
122.66 ++ *DNS* ( domain-name-servers )
122.67 ++ *WINS* o server di risoluzione nomi netbios ( netbios-name-servers )
122.68 +
122.69 +.. Note:
122.70 +
122.71 + Ovviamente ai riferimenti dell'esempio andranno sostituiti i propri riferimenti
122.72 + di rete (network, ip, wins, etc...)
122.73 +
122.74 +Riavvio del servente
122.75 +--------------------
122.76 +
122.77 +Ultimata la modifica della configurazione, per attivare il servizio, non resterà
122.78 +che riavviarlo::
122.79 +
122.80 + srv-scuolax:/etc/dhcp3# /etc/init.d/dhcp3-server restart
122.81 + Stopping DHCP server: dhcpd3.
122.82 + Starting DHCP server: dhcpd3.
122.83 +
122.84 +Attivazione al boot
122.85 +-------------------
122.86 +Ora che DHCP è configurato e attivato, non resta che assicurare che venga avviato
122.87 +automaticamente in fase di boot. Ci si assicuri pertanto che nel file ``/etc/runlevel.conf``
122.88 +le linee riferite al servizio DHCP non siano commentate( commentata è una qualunque linea
122.89 +iniziante con il simbolo ``#``).
123.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123.2 +++ b/docs/install/servizi/firewall.rst Mon Apr 26 11:16:23 2010 +0200
123.3 @@ -0,0 +1,173 @@
123.4 +.. _config_firewall:
123.5 +
123.6 +Il firewall
123.7 +===========
123.8 +
123.9 +.. sidebar:: Serve?
123.10 +
123.11 + si. Il firewall deve essere sempre configurato. Probabilmente vi basta
123.12 + la configurazione base descritta di seguito ed ottenuta modificando il
123.13 + solo file ``fw.conf``
123.14 +
123.15 +Esiste una esperienza di laboratorio per la
123.16 +:ref:`configurazione base <lab_firewalling>` del firewall ed una sul
123.17 +:ref:`lab_dnat`
123.18 +
123.19 +.. note::
123.20 +
123.21 + dalla versione *lenny* di ``argo`` il comando ``firewall`` è stato sostituito
123.22 + dal comando ``pyrewall``, che ha i medesimi file di configurazione ma è
123.23 + implementato in Python
123.24 +
123.25 +Introduzione
123.26 +------------
123.27 +
123.28 +Ricordo che il firewalling in un sistema Linux è appannaggio del
123.29 +kernel. Possono essere usati molti programmi per configurare il kernel. Qui
123.30 +illustro il comando ``pyrewall`` sviluppato specificamente per la
123.31 +distribuzione Argolinux da una idea di una script analoga nella
123.32 +distribuzione gibraltar_.
123.33 +
123.34 +Il comando ``pyrewall`` legge due file di configurazione:
123.35 +
123.36 +:``fw.conf``: per le impostazioni di variabili
123.37 +:``fw.add``: per i comandi
123.38 +
123.39 +nel primo è sufficiente impostare alcune variabili ed avremo una
123.40 +configurazione sicura nella stragrande maggioranza delle situazioni
123.41 +
123.42 +.. index:: pyrewall; fw.add
123.43 +
123.44 +variabili disponibili in fw.conf
123.45 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123.46 +INT lista dei device 'interni' per il traffico entrante da questi device
123.47 + ha come politica di defaul ``ACCEPT``
123.48 +
123.49 +EXT lista dei device 'esterni' per il traffico entrante da questi device
123.50 + ha come politica di defaul ``DROP``
123.51 +
123.52 +LAN IPs e network che dovranno essere mascherati (nattati)
123.53 +
123.54 +
123.55 +FORWARD
123.56 + Abilita il forward dei pacchetti tramite ``/proc/sys/net/ipv4/ip_forwad``
123.57 + if this variable is not set to 0. Ivviamente il forward andrà
123.58 + in ogni caso esplicitamente accettato
123.59 +
123.60 +IP_MODE
123.61 + Può essere ``static`` e ``dynamic``. Determina se la modalità sarà
123.62 + ``masquerading`` (dynamic) o ``natting`` (static)
123.63 + Se si sceglie statico occorre anche definire IP_EXT.
123.64 +
123.65 +
123.66 +LOG if this value is set to 1, logging will take
123.67 + place before dropping packets. You can "color
123.68 + parse" log fil with fwparse(1). 2 different
123.69 + labels are used to mark packets dropped in INPUT
123.70 + chain or FORWARD chain.
123.71 +
123.72 +INPUT_CHAINS
123.73 + List of INPUT chains that should be created/destroyed with start/stop
123.74 +
123.75 +FWD_CHAINS
123.76 + List of in the FORWARD chains that should be
123.77 + created/destroyed with start/stop
123.78 +
123.79 +TCP_DPORTS
123.80 + List of tcp ports that should be opened from the
123.81 + external interface
123.82 +
123.83 +UDP_DPORTS
123.84 + List of udp ports that should be opened from the
123.85 + external interface
123.86 +
123.87 +PROXY_REDIR_PORT
123.88 + Porta alla quale redirigere il traffico che cerca di passare dalla
123.89 + porta 80. normalmente è 3128 o 8128 a seconda che si usi squid o
123.90 + dansguardian. Questo è utile solo in caso di proxy trasparente (non
123.91 + raccomandato nelle scuole).
123.92 +
123.93 + Nel caso di proxy non trasparente non è sufficiente a fare funzionare
123.94 + il proxy ma è sufficiente a bloccare il traffico sulla 80.
123.95 +
123.96 +
123.97 +
123.98 +principi funzionamento fw.add
123.99 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123.100 +
123.101 +
123.102 +Il principio di funzionamento di ``fw.add`` è invece particolarmente adatto
123.103 +quando ci siano (molte) configurazioni aggiuntive, combinazioni di ip e porte
123.104 +che vogliamo filtrare o nattare. In questo caso ``pyrewall`` permette
123.105 +sintassi molto succinte per un utilizzo efficace di un programma che fa il
123.106 +prodotto cartesiano [1]_ delle variabili.
123.107 +
123.108 +Configurazione di *pyrewall* per FileServer ISI
123.109 +-----------------------------------------------
123.110 +
123.111 +.. figure:: ../../img/rete-srvisi.png
123.112 + :align: center
123.113 + :width: 400
123.114 +
123.115 + caso firewall separato dal server
123.116 +
123.117 +
123.118 +Presupponendo che la rete sia protetta a monte da un firewall e che si stia
123.119 +utilizzando una sola interfaccia di rete eth0, impostiamo l'interfaccia
123.120 +``eth0`` come interfaccia interna, modificando ``/etc/argo/fw.conf`` come
123.121 +segue::
123.122 +
123.123 + INT="eth0"
123.124 + #EXT="eth1"
123.125 + TCP_DPORTS="22"
123.126 +
123.127 +*Nota*: Si è commentata la linea relativa alla seconda interfaccia, in
123.128 + quanto non presente.
123.129 +
123.130 +Per appplicare le modifiche appena effettuate, sarà necessario riavviare
123.131 +*pyrewall*::
123.132 +
123.133 + argo:~# pyrewall restart
123.134 +
123.135 +Configurazione di *pyrewall* per un Firewall ISI
123.136 +------------------------------------------------
123.137 +
123.138 +.. figure:: ../../img/rete-fwisi.png
123.139 + :align: center
123.140 +
123.141 +Presupponendo che il Firewall ISI abbia due interfacce di rete *eth0* ed
123.142 +*eth1*, *eth1* collegata direttamente al gateway ADSL ed *eth1* l'altra ad
123.143 +uno switch, in contatto dunque con il resto della LAN interna, imposteremo
123.144 +il *firewall* affinchè consideri l'interfaccia *eth0* interna e
123.145 +l'interfaccia *eth1* esterna, modificando ``/etc/argo/fw.conf`` come segue::
123.146 +
123.147 + INT="eth0"
123.148 + EXT="eth1"
123.149 + TCP_DPORTS="22"
123.150 +
123.151 +Nota: In questo caso la direttiva "EXT" è ovviamente necessaria.
123.152 +
123.153 +Per appplicare le modifiche appena effettuate, sarà necessario riavviare
123.154 +*pyrewall*::
123.155 +
123.156 + argo:~# pyrewall restart
123.157 +
123.158 +-------------
123.159 +
123.160 +.. _gibraltar: http://www.gibraltar.at
123.161 +
123.162 +.. [1]
123.163 + prodotto cartesiano di due insiemi A e B è l'insieme delle coppie ordinate
123.164 + (a,b) con a in A e b in B. Si pensi a questo esempio dove il comando mex
123.165 + opera il prodotto cartesiano fra l'insieme SRC e l'insieme DST::
123.166 +
123.167 + SRC="192.168.1.1 192.168.1.2"
123.168 + DST="10.10.1.1 10.10.1.2"
123.169 + mex iptables -A FORAWRD -s $SRC -d $DST -j ACCEPT
123.170 +
123.171 + iptables -A FORAWRD -s 192.168.1.1 -d 10.10.1.1 -j ACCEPT
123.172 + iptables -A FORAWRD -s 192.168.1.2 -d 10.10.1.1 -j ACCEPT
123.173 + iptables -A FORAWRD -s 192.168.1.1 -d 10.10.1.2 -j ACCEPT
123.174 + iptables -A FORAWRD -s 192.168.1.2 -d 10.10.1.2 -j ACCEPT
123.175 +
123.176 +
124.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124.2 +++ b/docs/install/servizi/ftp.rst Mon Apr 26 11:16:23 2010 +0200
124.3 @@ -0,0 +1,62 @@
124.4 +Proftpd
124.5 +=======
124.6 +
124.7 +
124.8 +Ftp-proxy
124.9 +=========
124.10 +
124.11 +Cos'è?
124.12 +------
124.13 +
124.14 +*Citando la man page*...
124.15 +
124.16 +FTP-Proxy acts as an application level gateway between FTP clients and servers.
124.17 +Its main purpose is to secure local FTP servers against possibly insecure clients
124.18 +or malicious attacks. FTP-Proxy is believed to be immune against current
124.19 +known attacks based on the FTP protocol.
124.20 +
124.21 +FTP-Proxy can be started from the inetd (or xinetd, or any other) internet super
124.22 +daemon or executed on its own as a standalone daemon, in which case it will fork
124.23 +child processes to handle connections. The behaviour depends on the
124.24 +ftp-proxy.conf(5) configuration option ServerType or the -i and -d command line
124.25 +switches, where the latter two take precedence.
124.26 +
124.27 +FTP-Proxy features a rich set of auditing and command restriction capabilities
124.28 +and is specifically suited for deployment in firewall environments.
124.29 +
124.30 +
124.31 +Installazione
124.32 +-------------
124.33 +
124.34 +L'installazione è molto semplice e si riduce al solo::
124.35 +
124.36 + apt-get install ftp-proxy
124.37 +
124.38 +Configurazione
124.39 +--------------
124.40 +
124.41 +Modificare con il proprio editor di testo preferito ``/etc/proxy-suite/ftp-proxy.conf``
124.42 +impostando le seguenti direttive:
124.43 +
124.44 +- DestinationAddress ( Indirizzo del servente FTP )
124.45 +- DestinationPort ( Porta del servente FTP )
124.46 +- ServerType ( modalità di avvio del servizio )
124.47 +
124.48 +``ftp-proxy`` supporta numerose opzioni. E', ad esempio, possibile imporre la
124.49 +modalità Attiva / Passiva che, di default, viene scelta in base alla richiesta dei
124.50 +client.
124.51 +
124.52 +Verifica della configurazione
124.53 +-----------------------------
124.54 +
124.55 +E' possibile verificare la propria configurazione del servizio grazie al comando
124.56 +``ftp-proxy -c``.
124.57 +
124.58 +L'output restituito dovrebbe rispecchiare quello che segue di esempio ::
124.59 +
124.60 + Config-File: '/etc/proxy-suite/ftp-proxy.conf'
124.61 + Config-Section ------ '(-global-)'
124.62 + Config: DestinationAddress = '192.168.1.253'
124.63 + Config: DestinationPort = '21'
124.64 + Config: ServerType = 'standalone'
124.65 +
125.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125.2 +++ b/docs/install/servizi/nfs.rst Mon Apr 26 11:16:23 2010 +0200
125.3 @@ -0,0 +1,159 @@
125.4 +.. _config_nfs:
125.5 +
125.6 +=====
125.7 + NFS
125.8 +=====
125.9 +
125.10 +Lato Server
125.11 +===========
125.12 +
125.13 +Il protocollo NFS consente di condividere il contenuto di intere directory
125.14 +tra macchine Linux/Unix. Tali risorse condivise, potranno essere *esportate*
125.15 +dalla macchina server e *montate* dai client desiderati.
125.16 +
125.17 +Come si può immaginare, l'utilizzo di NFS, è fondamentale in un contesto come
125.18 +quello di ReteISI, dove si vuole che i file degli utenti restino ospitati
125.19 +dal server di dominio. Ciò verrà garantito imponendo che la ``/home`` dei singoli
125.20 +client coincida con la ``/home`` esportata dal server.
125.21 +
125.22 +Installazione dei pacchetti necessari::
125.23 +
125.24 + apt-get install nfs-common nfs-kernel-server
125.25 +
125.26 +Alla domanda "Should portmap be bound to the loopback address?" Scegliere
125.27 +No (default) a meno che non vi siano particolari esigenze.
125.28 +
125.29 +Le singole macchine, od i network, a cui verrà esportato il fileserver andranno
125.30 +inserite in ``/etc/exports``.
125.31 +Modificare dunque tale file aggiungendo una linea come la seguente::
125.32 +
125.33 + /home 192.168.1.0/255.255.255.0(rw,no_root_squash)
125.34 +
125.35 +*Nota:*
125.36 +192.168.1.0 è il network in cui risulterà visibile la risorsa ``/home`` esportata.
125.37 +
125.38 +Sarà possibile elencare le esportazioni attive grazie al comando ``showmount`` ::
125.39 +
125.40 + srv-isi:~# showmount --all
125.41 + All mount points on srv-isi:
125.42 + 192.168.1.0/255.255.255.0:/home
125.43 + 192.168.1.230:192.168.1.0/255.255.255.0
125.44 +
125.45 +
125.46 +Lato Client (ubuntu 7.10)
125.47 +=========================
125.48 +
125.49 +Montare una directory esportata via nfs in una directory locale non-vuota
125.50 +impedirà l'accesso al contenuto locale preesistente. Tale contenuto tornerà
125.51 +accessibile una volta smontata la risorsa.
125.52 +
125.53 +utenti solo locali
125.54 +------------------
125.55 +
125.56 +Qualora si desideri mantenere la possibilità di loggarsi anche con utenti
125.57 +locali, sarà quindi necessario rinominare la ``/home`` locale in ``/home_local`` e
125.58 +si creerà una nuova ``/home`` locale, vuota, in cui montare la ``/home`` remota.
125.59 +Ovviamente saranno anche da aggiornare in ``/etc/passwd`` i percorsi delle
125.60 +home-utente, portandoli da ``/home`` a ``/home_local``::
125.61 +
125.62 + root@ubuntu-desktop:~# mv /home/ /home_local
125.63 + root@ubuntu-desktop:~# mkdir /home
125.64 + root@ubuntu-desktop:~# sed -i 's/home\//home_local\//g' /etc/passwd
125.65 +
125.66 +/home
125.67 +-----
125.68 +
125.69 +Si potrà ora procedere con l'installazione del client nfs::
125.70 +
125.71 + root@ubuntu-desktop:~# sudo apt-get install nfs-common
125.72 +
125.73 +e la modifica di ``/etc/fstab``, al quale andrà aggiunta la seguente direttiva ::
125.74 +
125.75 + srv-isi:/home /home nfs defaults,soft,rw,auto 0 2
125.76 +
125.77 +*Dove:*
125.78 + "srv-isi" è l'hostname (ci si assicuri che tale nome sia presente in ``/etc/hosts``)
125.79 + della macchina che esporta risorse nfs.
125.80 + "/home" che segue i due punti la da essa risorsa esportata.
125.81 + il secondo "/home" è il punto locale in cui verrà montata la risorsa remota.
125.82 +
125.83 +*Nota:*
125.84 +Ci si assicuri che il file ``/etc/fstab`` sia terminato con un "a capo".
125.85 +
125.86 +NFS con automount
125.87 +=================
125.88 +
125.89 +NFS può essere associato ad ``autofs`` per ottenere il mount al volo della cartella esportata a seconda dell'utente che effettua il login
125.90 +
125.91 +Lato server
125.92 +-----------
125.93 +Non c'è differenza rispetto a quanto detto in precedenza, viene però mostrato il contenuto
125.94 +di ``/etc/exports`` nel caso della struttura di cartelle ReteIsi e in modo che le stesse possano
125.95 +essere raggiunte da più sottoreti (si osservino ip e ipmask)::
125.96 +
125.97 + /home/users/admins 192.168.0.0/255.255.0.0(rw,sync)
125.98 + /home/users/alunni 192.168.0.0/255.255.0.0(rw,sync)
125.99 + /home/users/ata 192.168.0.0/255.255.0.0(rw,sync)
125.100 + /home/users/docenti 192.168.0.0/255.255.0.0(rw,sync)
125.101 + /home/users/esterni 192.168.0.0/255.255.0.0(rw,sync)
125.102 + /home/shares/classi 192.168.0.0/255.255.0.0(rw,sync)
125.103 +
125.104 +Lato client
125.105 +-----------
125.106 +Installazione dei pacchetti necessari::
125.107 +
125.108 + apt-get install portmap nfs-common autofs
125.109 +
125.110 +Verranno generati in /etc due file di configurazione il cui contenuto potrà essere il seguente (nel caso si vogliano esportare solo le radici delle home di ciascun gruppo principale):
125.111 +
125.112 +``/etc/auto.master``
125.113 +::
125.114 +
125.115 + /home/users/alunni /etc/auto.home_alunni
125.116 + /home/users/admins /etc/auto.home_admins
125.117 + /home/users/ata /etc/auto.home_ata
125.118 + /home/users/docenti /etc/auto.home_docenti
125.119 + /home/users/esterni /etc/auto.home_esterni
125.120 + /home/shares/classi /etc/auto.classi
125.121 +
125.122 +``/etc/auto.misc``
125.123 +::
125.124 +
125.125 + lasciare invariato
125.126 +
125.127 +occorrerà poi creare i seguenti altri file di configurazione, uno per ogni cartella esportata (SERVER è l'ip o il namehost della macchina che esporta)
125.128 +
125.129 +``/etc/auto.classi``
125.130 +::
125.131 +
125.132 + * -fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/shares/classi/&
125.133 +
125.134 +``/etc/auto.home_admins``
125.135 +::
125.136 +
125.137 + * -fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/users/admins/&
125.138 +
125.139 +``/etc/auto.home_alunni``
125.140 +::
125.141 +
125.142 + * -fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/users/alunni/&
125.143 +
125.144 +``/etc/auto.home_ata``
125.145 +::
125.146 +
125.147 + *-fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/users/alunni/&
125.148 +
125.149 +``/etc/auto.home_docenti``
125.150 +::
125.151 +
125.152 + * -fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/users/docenti/&
125.153 +
125.154 +``/etc/auto.home_esterni``
125.155 +::
125.156 +
125.157 + *-fstype=nfs,soft,intr,rsize=32768,wsize=32768 SERVER:/home/users/esterni/&
125.158 +
125.159 +Per far funzionare il tutto basterà a questo punto fa ripartire il servizio autofs
125.160 +::
125.161 +
125.162 + /etc/init.d/autofs restart
126.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126.2 +++ b/docs/install/servizi/pdc.rst Mon Apr 26 11:16:23 2010 +0200
126.3 @@ -0,0 +1,99 @@
126.4 +.. _config_pdc:
126.5 +
126.6 +Dominio PDC
126.7 +===========
126.8 +
126.9 +Configurazione del dominio: isi-startup
126.10 +---------------------------------------
126.11 +
126.12 +Per configurare l'intero dominio, basterà lanciare il comando::
126.13 +
126.14 + isi-startup <NOMEDOMINIO> <nomenetbios> <password>
126.15 +
126.16 +Per semplicità, si suggerisce di utilzzare il nome del proprio istituto
126.17 +scolastico come *nome di DOMINIO* e, come *nome netbios*, il nome dell'istituto
126.18 +preceduto da "srv-", scritto in minuscolo.
126.19 +
126.20 +Esempio:
126.21 +
126.22 ++ *nome dominio: SCUOLAX*
126.23 +
126.24 ++ *nome server: srv-scuolax*
126.25 +
126.26 +La password da specificare sarà quella che verrà assegnata
126.27 +
126.28 + * all'utente root
126.29 + * all'admin di slapd
126.30 + * all'utente administrator con il quale potremo fare il join dei
126.31 + client windows
126.32 +
126.33 +Si proceda dunque come segue::
126.34 +
126.35 + argo:~# isi-startup SCUOLAX srv-scuolax segreto
126.36 + check_syntax
126.37 + read_conf
126.38 + SID per ISI-DOMAIN: S-1-5-21-4285446429-3958797296-3242910830
126.39 + reset_secrets
126.40 + Setting stored password for "cn=admin,dc=isi,dc=lan" in secrets.tdb
126.41 + fix_DOMAIN_name
126.42 + fix_PDC_name
126.43 + get_set_new_SID
126.44 + Esiste un SID memorizzato. Vuoi usare questo (s/n)? N
126.45 + NUOVO SID: S-1-5-21-4285446429-3958797296-3242910830
126.46 + NEW SID: S-1-5-21-4285446429-3958797296-3242910830
126.47 + change_password
126.48 + sistema
126.49 + smbtools
126.50 + ldap
126.51 + ldapmodify -x -h 127.0.0.1 -w isi -D cn=admin,dc=isi,dc=lan
126.52 + modifying entry "cn=admin,dc=isi,dc=lan"
126.53 +
126.54 + smbpasswd
126.55 + Setting stored password for "cn=admin,dc=isi,dc=lan" in secrets.tdb
126.56 + root samba
126.57 + ldap.secret libnss-ldap.secret pam_ldap.secret
126.58 + reimposto pwd
126.59 + fix_SID_in_ldap
126.60 + fix_SID_in_smbldap_tools
126.61 + add_samba_at_boot
126.62 + samba already in /etc/runlevel.conf: No change.
126.63 + start_samba
126.64 + Stopping Samba daemons: nmbd smbd.
126.65 + Samba spento
126.66 + Starting Samba daemons: nmbd smbd.
126.67 + Nuovo pid di samba 6161 6155, nmbd: 6153
126.68 + fix_LDAP_sambaDomainName
126.69 + ldapsearch -x -LLL -xD cn=admin,dc=isi,dc=lan -w segreto (sambaDomainName=SCUOLAX)
126.70 + modifying entry "sambaDomainName=SCUOLAX,dc=isi,dc=lan"
126.71 +
126.72 + ----------------------prima-----
126.73 + dn: sambaDomainName=SCUOLAX,dc=isi,dc=lan
126.74 + gidNumber: 1009
126.75 + uidNumber: 1000
126.76 +
126.77 + modifying entry "sambaDomainName=SCUOLAX,dc=isi,dc=lan"
126.78 +
126.79 + ----------------------dopo-----
126.80 + dn: sambaDomainName=SCUOLAX,dc=isi,dc=lan
126.81 + gidNumber: 1009
126.82 + uidNumber: 1000
126.83 +
126.84 +Alla domanda *Esiste un SID memorizzato. Vuoi usare questo (s/n)?* si risponda negativamente.
126.85 +
126.86 +Il processo di attivazione del dominio è completato. Da questo momento in
126.87 +poi sarà possibile iniziare ad effettuare il join di tutti i client della
126.88 +rete. Si suggerisce però, prima di continuare con tale operazione, di
126.89 +configurare ed attivare il servizio dhcp. In tal modo, tutti i client
126.90 +verranno istruire automaticamente con le informazioni di rete necessaria,
126.91 +evitando di dover configurare manualmente ogni client.
126.92 +
126.93 +.. Note ::
126.94 +
126.95 + Per join_ ci si riferisce all'operazione che permette di associare
126.96 + client Microsoft (Xp Professional o windows2000) al Dominio appena
126.97 + creato. Le W98 non contemplano questa operazione
126.98 +
126.99 +
126.100 +
126.101 +.. _join: ../client_microsoft.html
126.102 +
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/docs/install/servizi/sarg-report.rst Mon Apr 26 11:16:23 2010 +0200
127.3 @@ -0,0 +1,132 @@
127.4 +====================
127.5 + LOG e reportistica
127.6 +====================
127.7 +
127.8 +LOG SQUID con SARG-REPORT
127.9 +==========================
127.10 +
127.11 +Configurazione di sarg
127.12 +-----------------------
127.13 +
127.14 +Cercare in ``/etc/squid/sarg.conf`` la direttiva ``language English`` e sostituire
127.15 +a ``English`` il linguaggio voluto.
127.16 +es.::
127.17 +
127.18 + language Italian
127.19 +
127.20 +Assicurarsi che la direttiva ``access_log`` punti correttamente al file contenente
127.21 +i logs di squid (solitamente ``/var/log/squid/access.log``) e verificare che
127.22 +coincida con la direttiva ``access_log`` presente in ``/etc/squid.conf``.
127.23 +
127.24 +Per eventuali affinamenti alla configurazione si potrà fare riferimento ai numerosi
127.25 +esempi commentati nel file di configurazione.
127.26 +
127.27 +.. _sarg-report:
127.28 +
127.29 +Configurazione di sarg-reports
127.30 +------------------------------
127.31 +
127.32 +La configurazione di ``/etc/squid/sarg-reports.conf`` di default dovrebbe andare
127.33 +benone, modificarla eventualmente per rispondere alle proprie esigenze.
127.34 +
127.35 +
127.36 +sarg e sarg-reports
127.37 +-------------------
127.38 +
127.39 +``sarg-report`` è un shell script che permette di parsare il contenuto dei logs di
127.40 +squid relativi ad un certo periodo di tempo e, utilizzando ``sarg``, generare
127.41 +automaticamente del codice html. Il codice html, di default, viene salvato in
127.42 +``/var/www/https/squid-reports/``. Sarà necessario dunque modificare la configurazione
127.43 +di apache per assicurarsi che venga pubblicata.
127.44 +
127.45 +Nota
127.46 +----
127.47 +
127.48 +Si farà riferimento esclusivamente all'uso di ``sarg-report``.
127.49 +I più curiosi, dopo una rapida consultazione del suo help, potranno provare a generare
127.50 +con ``sarg`` qualche statistica personalizzata.
127.51 +
127.52 +L'help di sarg-reports è abbastanza esplicativo::
127.53 +
127.54 + sarg-reports --help
127.55 +
127.56 + SARG - Daily / Weekly / Monthly - Squid proxy usage reports creation tool
127.57 + Written by Ugo Viti <[email protected]>
127.58 + Version: 20050202
127.59 +
127.60 + Usage: /usr/sbin/sarg-reports [OPTIONS]
127.61 +
127.62 + Allowed options:
127.63 + manual, Create Manual report
127.64 + today, Create Today report
127.65 + daily, Create Daily report
127.66 + weekly, Create Weekly report
127.67 + montly, Create Monthly report
127.68 +
127.69 +Come riportato dall'help, se volessimo generare logs per una data specifica potremmo
127.70 +usare::
127.71 +
127.72 + sarg-reports manual 18/12/2021
127.73 +
127.74 +Tutte le informazioni relative al giorno 18/12/2021 trovate in ``/var/log/squid/access.log``
127.75 +verranno parsate e verrà generato un output html in ``/vaar/www/squid-reports/``
127.76 +
127.77 +Per verificare il risultato, si potrà provare a puntare con ``lynx`` a
127.78 +``/var/www/squid-reports/index.html`` come segue::
127.79 +
127.80 + lynx /var/www/squid-reports/index.html
127.81 +
127.82 +
127.83 +Automatizzare la creazione dei logs con Crontab
127.84 +-----------------------------------------------
127.85 +
127.86 +Aggiungere la creazione dei logs a Cron, per eseguirle in modo automatico alla
127.87 +cadenza voluta::
127.88 +
127.89 + crontab -e
127.90 +
127.91 + PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
127.92 + 00 00 * * * sarg-reports daily
127.93 + 00 01 * * 1 sarg-reports weekly
127.94 + 30 02 1 * * sarg-reports monthly
127.95 +
127.96 +Per chi non conoscesse Cron e la sintassi di definizione del tempo:
127.97 +http://www.adminschoice.com/docs/crontab.htm#Crontab%20file
127.98 +
127.99 +
127.100 +
127.101 +Dglog
127.102 +=====
127.103 +
127.104 +cos'è
127.105 +-----
127.106 +dglog è un utilissimo perl-script che permette di analizzare comodamente i logs
127.107 +generati da ``dansguardian``. Con questo utile strumento sarà possibile, ad
127.108 +esempio, elencare tutti i contenuti web negati/permessi ad un particolare utente.
127.109 +
127.110 +
127.111 +Configurazione dglog
127.112 +--------------------
127.113 +
127.114 +Creare il file di configurazione
127.115 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127.116 +::
127.117 +
127.118 + cd /etc/isi
127.119 + cp dglog.conf.pl.sample dglog.conf.pl
127.120 +
127.121 +Rendere eseguibile il cgi-script "dglog.pl"
127.122 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127.123 +::
127.124 +
127.125 + chmod +x /usr/lib/cgi-bin/dglog/dglog.pl
127.126 +
127.127 +
127.128 +Verifica
127.129 +~~~~~~~~
127.130 +
127.131 +Per una rapida verifica basterà puntare con il proprio browser al seguente URL:
127.132 +
127.133 +http://<IP SERVER>/cgi-bin/dglog/dglog.pl
127.134 +
127.135 +
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128.2 +++ b/docs/install/servizi/squid_dans.rst Mon Apr 26 11:16:23 2010 +0200
128.3 @@ -0,0 +1,253 @@
128.4 +.. _config_squid_dans:
128.5 +
128.6 +======================
128.7 + Squid & Dansguardian
128.8 +======================
128.9 +
128.10 +Squid
128.11 +=====
128.12 +
128.13 +Modificare ``/etc/squid/squid.conf``::
128.14 +
128.15 + visible_hostname srv-scuolax
128.16 +
128.17 + auth_param basic program /usr/lib/squid/ldap_auth -v 3 -b ou=People,dc=isi,dc=lan srv-scuolax
128.18 +
128.19 + external_acl_type ldap_group %LOGIN /usr/lib/squid/squid_ldap_group \
128.20 + -v 3 -b ou=Groups,dc=isi,dc=lan -B ou=People,dc=isi,dc=lan -f \
128.21 + "(&(memberUid=%v)(objectClass=posixGroup)(cn=%g))" srv-scuolax
128.22 +
128.23 +Assicurarsi inoltre che le seguenti direttive siano presenti::
128.24 +
128.25 + http_port 3128
128.26 + access_log /var/log/squid/access.log
128.27 +
128.28 +La seconda direttiva, è indispensabile se si intende utilizzare un
128.29 +analizzatore dei logs come "Sarg", già incluso nella distribuzione..
128.30 +
128.31 +Dans Guardian
128.32 +=============
128.33 +
128.34 +Le modifiche da apportare al fine di configurazione
128.35 +``/etc/dansguardian/dansguardian.conf`` sono modeste::
128.36 +
128.37 + language = 'italian'
128.38 + # the port that DansGuardian listens to.
128.39 + filterport = 8128
128.40 +
128.41 + # the ip of the proxy (default is the loopback - i.e. this server)
128.42 + proxyip = 127.0.0.1
128.43 +
128.44 + # the port DansGuardian connects to proxy on
128.45 + proxyport = 3128
128.46 +
128.47 + # accessdeniedaddress is the address of your web server to which the cgi
128.48 + # dansguardian reporting script was copied
128.49 + # Do NOT change from the default if you are not using the cgi.
128.50 + #
128.51 + accessdeniedaddress = 'http://localhost/cgi-bin/dansguardian.pl'
128.52 +
128.53 +è inoltre possibile, non indispensabile, attivare il filtro antivirus. Nella
128.54 +distribuzione si troverà già incluso il supporto per ClamAV.
128.55 +
128.56 +::
128.57 +
128.58 + virusscan = on
128.59 +
128.60 + # OPTION: virusengine
128.61 + # Set the embedded virus scan engine to be used
128.62 + virusengine = 'clamav'
128.63 +
128.64 +Si può dunque scegliere di disattivare la feature impostando la direttiva
128.65 +
128.66 +::
128.67 +
128.68 + virusscan = off
128.69 +
128.70 +Prima di attivare DansGuardian, come si evince dal suo contenuto, è
128.71 +indispensabile rimuovere la seguente riga (localizzata di solito ad inizio
128.72 +file)::
128.73 +
128.74 + UNCONFIGURED - Please remove this line after configuration
128.75 +
128.76 +Chi volesse modificare le varie tipologie di filtraggio, troverà
128.77 +indispensabile il file ``/etc/dansguardian/dansguardianf1.conf``
128.78 +
128.79 +Per ulteriori informazioni su dansguardian e le tipologie di filtraggio:
128.80 +http://dansguardian.org/
128.81 +
128.82 +.. sidebar: Nota
128.83 +
128.84 + Per installazioni datate potrebbe essere necessario, in caso si desideri
128.85 + utilizzare il sistema antivirus, aggiornare il pacchetto clamav all'ultima
128.86 + versione. Al fine di tenere sempre aggiornata la propria versione di
128.87 + ClamAV, si suggerisce di aggiungere il seguente repository al file
128.88 + ``/etc/apt/sources.lst``: ``deb http://ftp2.de.debian.org/debian-volatile sarge/volatile main``
128.89 +
128.90 +
128.91 +
128.92 +SARG
128.93 +====
128.94 +
128.95 +Per utilizzare SARG, utile strumento di interpretazione dei logs di accesso
128.96 +di squid, è *necessario* assicurare la presenza di
128.97 +``/var/log/squid/access.log``.
128.98 +
128.99 +Il file ``/var/log/squid/access.log``, di default assente( o così sembra,
128.100 +almeno su debian etch) , si può "far generare" aggiungendo al file
128.101 +*/etc/squid/squid.conf* la seguente direttiva::
128.102 +
128.103 + access_log /var/log/squid/access.log
128.104 +
128.105 +
128.106 +Grazie a SARG è possibile generare report al momento o semplicemente
128.107 +consultare quelli generati in automatico, in formato html, in
128.108 +*/var/www/squid-reports/*.
128.109 +
128.110 +Dall'help di sarg-reports ::
128.111 +
128.112 + Usage: /usr/sbin/sarg-reports [OPTIONS]
128.113 +
128.114 + Allowed options:
128.115 + manual, Create Manual report
128.116 + today, Create Today report
128.117 + daily, Create Daily report
128.118 + weekly, Create Weekly report
128.119 + montly, Create Monthly report
128.120 +
128.121 +
128.122 +I logs di SARG, generati con ``sarg-reports`` verranno salvati anch'essi come
128.123 +codice html, di default, in */var/www/squid-reports*. Tale percorso è
128.124 +modificabile apportando qualche semplice modifica a
128.125 +``/etc/squid/sarg-reports.conf``.
128.126 +
128.127 +Lo strano bug di /etc/logrotate.d/squid
128.128 +----------------------------------------
128.129 +
128.130 +Con le prime versioni di sarg, prima della rotazione dei log di squid,
128.131 +veniva invocata giornalmente la script "/usr/sbin/sarg-maint". Tale script è
128.132 +stata "recentemente" rimpiazzata con "/usr/sbin/sarg-reports". Non è stato
128.133 +però modificato il riferimento in "/etc/logrotate.d/squid", che punta ancora
128.134 +all'inesistente vecchia script.
128.135 +Curiosamente, sembra che ad oggi il bug non sia ancora stato corretto.
128.136 +
128.137 +La soluzione al problema
128.138 +-------------------------------
128.139 +
128.140 +E' stato modificato dunque il file "/etc/logrotate.d/squid" affinchè lanci
128.141 +"/usr/sbin/sarg-reports monthly".
128.142 +
128.143 +/etc/logrotate.d/squid originale ::
128.144 +
128.145 + #
128.146 + # Logrotate fragment for squid.
128.147 + #
128.148 + /var/log/squid/*.log {
128.149 + daily
128.150 + compress
128.151 + delaycompress
128.152 + rotate 1000
128.153 + missingok
128.154 + nocreate
128.155 + sharedscripts
128.156 + prerotate
128.157 + test ! -x /usr/sbin/sarg-maint || /usr/sbin/sarg-maint
128.158 + endscript
128.159 + postrotate
128.160 + test ! -e /var/run/squid.pid || /usr/sbin/squid -k rotate
128.161 + endscript
128.162 + }
128.163 +
128.164 +/etc/logrotate.d/squid modificato ::
128.165 +
128.166 + #
128.167 + # Logrotate fragment for squid.
128.168 + #
128.169 + /var/log/squid/*.log {
128.170 + monthly
128.171 + compress
128.172 + delaycompress
128.173 + rotate 1000
128.174 + missingok
128.175 + nocreate
128.176 + sharedscripts
128.177 + prerotate
128.178 + test ! -x /usr/sbin/sarg-reports || /usr/sbin/sarg-reports monthly
128.179 + endscript
128.180 + postrotate
128.181 + test ! -e /var/run/squid.pid || /usr/sbin/squid -k rotate
128.182 + endscript
128.183 + }
128.184 +
128.185 +Ed è stato riavviato il servizio "/etc/init.d/cron" ::
128.186 +
128.187 + /etc/init.d/cron restart
128.188 +
128.189 +Generazione dei report schedulata tramite crontab
128.190 +--------------------------------------------------------
128.191 +
128.192 +La creazione schedulata dei report( giornalieri, settimanali, mensili) viene
128.193 +garantita dalle seguenti script ::
128.194 +
128.195 + /etc/cron.daily/sarg
128.196 + /etc/cron.weekly/sarg
128.197 + /etc/cron.monthly/sarg
128.198 +
128.199 +Il cui codice, molto elementare, altro non fa che avviare "sarg-reports" e
128.200 +passargli il periodo di tempo di cui generare i logs.
128.201 +
128.202 +es. ::
128.203 +
128.204 + /usr/sbin/sarg-reports monthly
128.205 +
128.206 +
128.207 +Assicurarsi che i servizi voluti partiranno al boot
128.208 +===================================================
128.209 +
128.210 +Modificare ``/etc/runlevel.conf`` commentando i servizi che non si intende
128.211 +far partire al boot e decommentare quelli che si desidera far partire.
128.212 +
128.213 +
128.214 +Configurare i clientXP per passare da squid
128.215 +===========================================
128.216 +
128.217 +Affinchè le macchine XP vengano correttamente configurate, in fase di logon,
128.218 +per passare attraverso dansguardian, modificare ``/etc/isi/logon.conf``
128.219 +impostando le seguenti direttive::
128.220 +
128.221 + ### WinSet sezione 'proxy'
128.222 + ProxyServer = 192.168.1.222:8128 # DansGuardian
128.223 + ProxyServer[admins] = 192.168.1.222:3128 # Squid (FW permettendo)
128.224 + #ProxyOverride = www.XXX.XXX,<local>
128.225 +
128.226 +
128.227 +
128.228 +
128.229 +.. _apt_squid:
128.230 +
128.231 +Configurare apt dei client per passare da squid
128.232 +===============================================
128.233 +
128.234 +Affinchè le macchine debian/ubuntu possano passare il firewall occorre
128.235 +creare un account apposito ed istruire apt di usare quello per evitare di
128.236 +essere bloccato dal firewall che blocca appunto la porta 80.
128.237 +
128.238 +Apt-get legge un file di configurazione,
128.239 +
128.240 + 1. /etc/apt/apt.conf o un qualunque file della directory
128.241 + 2. etc/apt/apt.conf.d/
128.242 +
128.243 +E` sufficiente mettere in questo file la istruzione::
128.244 +
128.245 + Acquire::http::Proxy "http://user:pwd@ip_squid_box:3128";
128.246 +
128.247 +una scritta alternativa e'::
128.248 +
128.249 + Acquire
128.250 + {
128.251 + http
128.252 + {
128.253 + Proxy "http://user:pwd@ip_squid_box:3128";
128.254 + };
128.255 + };
128.256 +
129.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
129.2 +++ b/docs/install/sshd_key.rst Mon Apr 26 11:16:23 2010 +0200
129.3 @@ -0,0 +1,281 @@
129.4 +.. _config_sshd_key:
129.5 +
129.6 +=========
129.7 +Sicurezza
129.8 +=========
129.9 +
129.10 +.. sidebar:: Importante
129.11 +
129.12 + non possiamo lasciare nel cd reteisi il default nel modo più sicuro
129.13 + senza rendere la vita difficile a chi deve caricare le chiavi la
129.14 + prima volta.... voi però fatelo!!!
129.15 +
129.16 +Nel momento stesso in cui mettete una macchina in internet con alcune porte
129.17 +aperte sapete per certo che sarà oggetto di ogni possibile attacco. Spesso i
129.18 +nostri server funzionanao anche da firewall in situazioni "piccole", ovvero
129.19 +di poche macchine.
129.20 +
129.21 +In queste occasioni le fonti più comuni di debolezze sono:
129.22 +
129.23 +1. ssh tramite account troppo semplici (password banali)
129.24 +2. apache tramite applicazioni poso sicure
129.25 +
129.26 +per quanto riguarda il primo punto è facile mettere la macchina in sicurezza
129.27 +con ben poca fatica, tramite l'uso delle chiavi crittografiche.
129.28 +
129.29 +Accedere al server tramite SSH usando le chiavi
129.30 +===============================================
129.31 +
129.32 +Accedere remotamente al proprio server mediante l'utilizzo delle chiavi
129.33 +crittografiche aumenta la sicurezza del proprio server, rendendo inutile,
129.34 +ad esempio, la quasi totalità dei tipi di attacco di tipo `dizionario` o
129.35 +`brute force`.
129.36 +
129.37 +Per le delucidazioni circa il concetto di "chiave di criptazione" si rimanda
129.38 +al seguente indirizzo:
129.39 +http://it.wikipedia.org/wiki/Crittografia_asimmetrica
129.40 +
129.41 +
129.42 +Configurazione del server OpenSSH
129.43 +---------------------------------
129.44 +
129.45 +Senza dilungarci troppo in trattazioni sulla sicurezza, si suggerisce l'adozione
129.46 +dei seguenti accorgimenti, considerati ragionevole compromesso tra "paranoia" e
129.47 +usabilità.
129.48 +
129.49 +- disattivazione dell'accesso tramite password.
129.50 +- attivazione dell'accesso esclusivamente tramite chiavi.
129.51 +- disattivazione dell'accesso diretto al sistema da parte di root ( sarà comunque
129.52 + accessibile grazie al comando ``su -`` ).
129.53 +
129.54 +Per ottenere tutto ciò, sarà sufficiente assicurarsi che le direttive del proprio
129.55 +``/etc/ssh/sshd.conf`` siano così configurate::
129.56 +
129.57 + PasswordAuthentication no
129.58 + PubkeyAuthentication yes
129.59 + ChallengeResponseAuthentication no
129.60 + PermitRootLogin no
129.61 +
129.62 +Per i più curiosi, viene riportata di seguito una configurazione integrale del file
129.63 +``/etc/ssh/sshd.conf``::
129.64 +
129.65 + Port 22
129.66 + Protocol 2
129.67 + HostKey /etc/ssh/ssh_host_rsa_key
129.68 + HostKey /etc/ssh/ssh_host_dsa_key
129.69 + UsePrivilegeSeparation yes
129.70 +
129.71 + # Lifetime and size of ephemeral version 1 server key
129.72 + KeyRegenerationInterval 3600
129.73 + ServerKeyBits 768
129.74 +
129.75 + # Logging
129.76 + SyslogFacility AUTH
129.77 + LogLevel INFO
129.78 +
129.79 + # Authentication:
129.80 + LoginGraceTime 120s
129.81 + PermitRootLogin no
129.82 + StrictModes yes
129.83 + MaxAuthTries 4
129.84 +
129.85 + #RSAAuthentication no
129.86 + PubkeyAuthentication yes
129.87 + #AuthorizedKeysFile %h/.ssh/authorized_keys
129.88 +
129.89 + # Don't read the user's ~/.rhosts and ~/.shosts files
129.90 + IgnoreRhosts yes
129.91 + # For this to work you will also need host keys in /etc/ssh_known_hosts
129.92 + RhostsRSAAuthentication no
129.93 + # similar for protocol version 2
129.94 +
129.95 + HostbasedAuthentication no
129.96 + # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
129.97 + #IgnoreUserKnownHosts yes
129.98 +
129.99 + # To enable empty passwords, change to yes (NOT RECOMMENDED)
129.100 + PermitEmptyPasswords no
129.101 +
129.102 + # Change to yes to enable challenge-response passwords (beware issues with
129.103 + # some PAM modules and threads)
129.104 + ChallengeResponseAuthentication no
129.105 +
129.106 + # Change to no to disable tunnelled clear text passwords
129.107 + PasswordAuthentication no
129.108 +
129.109 + X11DisplayOffset 10
129.110 + PrintMotd no
129.111 + PrintLastLog yes
129.112 + TCPKeepAlive yes
129.113 +
129.114 + AcceptEnv LANG LC_*
129.115 +
129.116 + Subsystem sftp /usr/lib/openssh/sftp-server
129.117 +
129.118 + UsePAM yes
129.119 +
129.120 + #l'utente "utente1" si puo' loggare solo da qualunque indirizzo
129.121 + #AllowUsers utente1@*
129.122 +
129.123 + #l'utente "utente2" si puo' loggare solo da tutte le postazioni del network
129.124 + #192.168.0.0 :
129.125 + #[email protected].*
129.126 +
129.127 + #Solo "utente1" potrà collegarsi a ssh. Questa direttiva escluderà tutti gli
129.128 + #altri
129.129 + #AllowUsers utente1
129.130 +
129.131 + #Per creare un utente guest "localuser" con una password nota a tutti ma
129.132 + #impedirne l'accesso via ssh da remoto:
129.133 + #DenyUsers localuser
129.134 +
129.135 +.. Note::
129.136 +
129.137 + Le ultime righe commentate, potranno tornare utili a chi vorrà limitare
129.138 + ulteriormente i propri accessi.
129.139 +
129.140 +
129.141 +Generazione ed aggiunta delle chiavi utente sul server
129.142 +------------------------------------------------------
129.143 +
129.144 +1. Autenticarsi con il proprio utente per generare la coppia di chiavi pubblica/privata::
129.145 +
129.146 + utente1@srv-isi:~$ ssh-keygen -t dsa
129.147 + Generating public/private dsa key pair.
129.148 +
129.149 + Enter file in which to save the key (~utente1/.ssh/id_dsa):
129.150 + <INVIO>
129.151 + Created directory '~utente1/.ssh'.
129.152 +
129.153 + Enter passphrase (empty for no passphrase): <PASSWORD PER LA CHIAVE>
129.154 + Enter same passphrase again: <PASSWORD PER LA CHIAVE>
129.155 +
129.156 + Your identification has been saved in ~utente1/.ssh/id_dsa.
129.157 + Your public key has been saved in /home/users/admins/utente1/.ssh/id_dsa.pub.
129.158 + The key fingerprint is:
129.159 + 20:d6:94:95:cf:59:a8:81:f0:e4:1e:98:98:47:54:71 utente1@srv-isi
129.160 +
129.161 + cp .ssh/id_dsa.pub /tmp
129.162 + chmod a+r /tmp/id_dsa.pub
129.163 +
129.164 +2. Aggiungere la chiave `pubblica` generata nel file ``authorized_keys``
129.165 + dell'utente da controllare( utente2)::
129.166 +
129.167 + su utente2 <PASSWORD utente2>
129.168 +
129.169 + Ci si assicuri che la directory ``.ssh`` esista::
129.170 +
129.171 + cd
129.172 + ls .ssh
129.173 +
129.174 + Se non dovesse essere presente, si provveda a crearla::
129.175 +
129.176 + mkdir .ssh
129.177 +
129.178 + Sarà ora possibile aggiungere la propria chiave pubblica, precedentemente
129.179 + copiata in /tmp ::
129.180 +
129.181 + cat /tmp/id_dsa.pub >> .ssh/authorized_keys
129.182 +
129.183 +.. Note::
129.184 +
129.185 + Il file ``authorized_keys`` contiene le chiavi pubbliche degli utenti
129.186 + abilitati ad accedere remotamente, via ssh e senza password, all'account
129.187 + dell'utente. Modificando tale file con un editor di testo si potranno
129.188 + rimuovere le chiavi pubbliche aggiunte in precedenza, impedendo alle
129.189 + relative utenze di accedere senza password con il nostro utente.
129.190 +
129.191 +3. Testare che tutto funzioni, autenticandosi come `utente1` e cercando
129.192 + con esso di accedere, via ssh, all'account `utente2`::
129.193 +
129.194 + utente1@srv-isi:~$ ssh -l utente2 127.0.0.1
129.195 + Enter passphrase for key '/home/users/admins/utente1/.ssh/id_dsa':
129.196 + <PASSWORD DELLA CHIAVE PRIVATA>
129.197 + utente2@srv-isi:~$
129.198 +
129.199 +Utilizzo delle chiavi in ambiente Windows
129.200 +-----------------------------------------
129.201 +
129.202 +In ambiente windows, uno dei client più usati per controllo remoto via
129.203 +ssh è probabilmente ``Putty``. Esistono diverse pacchettizzazioni di tale
129.204 +programma, installabili tramite setup o `portabili`.
129.205 +Si suggerisce di optare per la versione `portabile`, che consente di
129.206 +portare putty sempre con sè, magari su chiavetta usb.
129.207 +
129.208 +.. Note::
129.209 +
129.210 + La procedura a seguire, tratterà esclusivamente della versione `portabile`.
129.211 +
129.212 +Da dove scaricare Putty?
129.213 +~~~~~~~~~~~~~~~~~~~~~~~~
129.214 +
129.215 +le versioni di putty sono liberamente scaricabili dai seguenti indirizzi:
129.216 +
129.217 +http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.60-installer.exe
129.218 +http://the.earth.li/~sgtatham/putty/latest/x86/putty.zip
129.219 +
129.220 +Configurazione ed utilizzo di putty
129.221 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129.222 +
129.223 +1. Accedere al dominio autenticandosi con il proprio utente.
129.224 +
129.225 +.. image:: ../img/ssh-key/small/0_accessoDominio.jpg
129.226 +
129.227 +2. Aprire una cartella qualunque ed attivare la visualizzazione delle
129.228 + "estensioni per i nomi file conosciuti".
129.229 +
129.230 +.. image:: ../img/ssh-key/small/1_estensioni1.jpg
129.231 +
129.232 +
129.233 +.. image:: ../img/ssh-key/small/2_estensioni2.jpg
129.234 +
129.235 +
129.236 +2. Scaricare ed estrarre il file ``putty.zip`` e lanciare l'eseguibile ``puttygen.exe``.
129.237 +
129.238 +3. Selezionare la voce di menù ``Conversions >> Import key`` ed importare la chiave
129.239 + privata **id_dsa** generata in precedenza sul server.
129.240 +
129.241 +.. Note::
129.242 +
129.243 + La chiave di `utente1` verrà localizzata dai client microsoft in **H:\\.ssh\\id_dsa**
129.244 + nella home del relativo utente.
129.245 +
129.246 +.. image:: ../img/ssh-key/small/3_import1.jpg
129.247 +
129.248 +
129.249 +.. image:: ../img/ssh-key/small/4_import2.jpg
129.250 +
129.251 +
129.252 +4. Una volta importata la chiave privata in formato Unix, si procederà alla sua
129.253 + conversione nel formato usato da putty, arrivando ad ottenere una chiave
129.254 + privata "id_dsa.ppk".
129.255 +
129.256 +.. image:: ../img/ssh-key/small/5_import3.jpg
129.257 +
129.258 +
129.259 +.. image:: ../img/ssh-key/small/6_import4.jpg
129.260 +
129.261 +
129.262 +5. Non resta che configurare putty affinchè utilizzi la nostra chiave appena convertita e si colleghi all'ip del nostro server.
129.263 +
129.264 +.. image:: ../img/ssh-key/small/7_putty-addkey1.jpg
129.265 +
129.266 +
129.267 +.. image:: ../img/ssh-key/small/8_putty-addkey2.jpg
129.268 +
129.269 +
129.270 +.. image:: ../img/ssh-key/small/9_putty-connessione1.jpg
129.271 +
129.272 +
129.273 +.. image:: ../img/ssh-key/small/10_putty-connessione2.jpg
129.274 +
129.275 +
129.276 +.. image:: ../img/ssh-key/small/11_putty-connessione3.jpg
129.277 +
129.278 +
129.279 +.. image:: ../img/ssh-key/small/12_putty-connessione4.jpg
129.280 +
129.281 +
129.282 +.. image:: ../img/ssh-key/small/13_putty-connessione5.jpg
129.283 +
129.284 +
130.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
130.2 +++ b/docs/progetto/contents.rst Mon Apr 26 11:16:23 2010 +0200
130.3 @@ -0,0 +1,25 @@
130.4 +.. _reteisi_intro:
130.5 +
130.6 +Il progetto ReteIsi
130.7 +===================
130.8 +
130.9 +ReteIsi, il cui acronimo significa Intranet Scolastiche Integrate, è una
130.10 +libera associazione di scuole nata per sviluppare una soluzione informatica
130.11 +open source per reti scolastiche. Lo scopo principale del progetto è
130.12 +sviluppare una soluzione facile da adottare, in cui le necessità di una
130.13 +scuola siano state affrontate e possibilmente risolte in modo semplice.
130.14 +
130.15 +Il CD di ReteIsi permette di fare funzionare un dominio Windows basato su
130.16 +samba senza neanche l'installazione con soli pochi comandi. Questo dominio
130.17 +serve in realtà solo per demo ma è una prova efficace della facilità di
130.18 +utilizzo. Le macchine Windows potranno fare un join, le macchine linux
130.19 +possono decidere di delegare a questo sistema l'autenticazione.
130.20 +
130.21 +.. toctree::
130.22 + :maxdepth: 2
130.23 +
130.24 + project
130.25 + presentazione_tecnica
130.26 + devel
130.27 + docs
130.28 +
131.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
131.2 +++ b/docs/progetto/devel.rst Mon Apr 26 11:16:23 2010 +0200
131.3 @@ -0,0 +1,43 @@
131.4 +.. _reteisi_devel:
131.5 +
131.6 +Sviluppo
131.7 +==========
131.8 +
131.9 +Lo sviluppo dell'infrastruttura ISI viene portato avanti principalmente da:
131.10 +
131.11 + * **Sandro Dentella**: consulente del progetto iniziale e principale
131.12 + responsabile della architettura nonché della riscrittura delle librerie
131.13 + in python. E` anche responsabile della distribuzione Argo_ su cui è
131.14 + basata la iso
131.15 +
131.16 + * **Massimo Mancini**: insegnante della scuola capofila e principale
131.17 + sviluppatore della fase di logon e di tutte le procedure di estrazione
131.18 + dei dati da SISSI. E` anche responsabile della integrazione di applicazioni
131.19 + open (PMB, TWiki) nell'ambiente determinato da una rete ISI
131.20 +
131.21 + * **Simone Castellazzi**: valente tester, scopritore di bug e autore di gran
131.22 + parte della documentazione.
131.23 +
131.24 +
131.25 +Mailing list
131.26 +============
131.27 +
131.28 + puoi seguire lo sviluppo, chiedere aiuto e contribuire allo sviluppo sul
131.29 + googlegroup: http://reteisi.google.com
131.30 +
131.31 +
131.32 +Sorgenti
131.33 +========
131.34 +
131.35 +Il codice è stato sviluppato nel corso di alcuni anni ed è composto da
131.36 +script di shell, perl e python. Attualmente tutti i comandi ad eccezione
131.37 +della fase di login stanno subendo una riscrittura in python_ per renderli
131.38 +più omogenei. Sono raggiungibili nella forma di repository mercurial al
131.39 +sito: http://hg.argolinux.org e sono quelli nella cartella isi.
131.40 +
131.41 +Vengono poi prodotti pacchetti debian che sono disponibili nel repository::
131.42 +
131.43 + deb http://apt.reteisi.org/ etch isi
131.44 +
131.45 +.. _python: http://www.python.org
131.46 +.. _Argo: http://www.argolinux.org
132.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
132.2 +++ b/docs/progetto/docs.rst Mon Apr 26 11:16:23 2010 +0200
132.3 @@ -0,0 +1,130 @@
132.4 +Documentazione
132.5 +==============
132.6 +
132.7 + Stiamo riscrivendo completamente la documentazione nella speranza di
132.8 + rendere un migliore servizio a tutti voi. In questo momento troverete molti
132.9 + punti incompleti: data la mole della documentazione non ci è facile
132.10 + aggiornarla tutta insieme.
132.11 +
132.12 + Avete due modi di contribuire:
132.13 +
132.14 + 1. In ogni pagina trovate un link a destra con scritto "Sorgente della
132.15 + pagina", potete vedere cosa sta scritto, copiare il sorgente, correggerlo
132.16 + e inviarcelo. Saremo ben contenti di integrarlo.
132.17 +
132.18 + 2. potete scaricare il repository mercurial della documentazione::
132.19 +
132.20 + hg clone http://hg.argolinux.org/isi/isi-docs/
132.21 +
132.22 + Ed `inviarmi <[email protected]>`_ la patch con le vostre migliorie
132.23 +
132.24 +
132.25 +TODO
132.26 +----
132.27 +
132.28 +Questa documentazione è chiaramente incompleta. Queste sono alcune delle
132.29 +cose che mi saltano all'occhio, siete incoraggiati ad aggiungere punti:
132.30 +
132.31 +1. Analisi della documentazione dal sito istituzionale_ per capire quali
132.32 + parti non sono state riportate, quali vadano riportate.
132.33 +
132.34 +2. Documentare LTSP: cosa è come integrarla con ReteIsi
132.35 +
132.36 +3. Parte relativa alle biblioteche (pmb)
132.37 +
132.38 +4. Documentazione librerie nuove e man di ogni comando
132.39 +
132.40 +5. Gestione stampanti
132.41 +
132.42 +6. Backup
132.43 +
132.44 +7. Gestione installazione/clonazione client
132.45 +
132.46 +8. Configurazione firefox nei client
132.47 +
132.48 +9. Creazione di tutte le voci degli indici
132.49 +
132.50 +10. Allegati formativi: acl, scripting bash, scripting python.
132.51 + Qui dovrebbero essere più propriamente link a documentazione esistente
132.52 +
132.53 +11. Uso di vmware per esercitazione e per test. Uso di VNC.
132.54 +
132.55 +12. sicurezza (ssh senza chiave anche con putty)
132.56 +
132.57 +13. documentare runlevel.conf
132.58 +
132.59 +14. chiave repository
132.60 +
132.61 +
132.62 +.. _istituzionale: http://www.reteisi.org
132.63 +
132.64 +Il pacchetto isi-docs
132.65 +---------------------
132.66 +
132.67 + Il comando qui sopra scarica sul vostro pc i sorgenti del pacchetto
132.68 + isi-docs come repository mercurial_ per generare la documentazione per
132.69 + provare in locale il risultato.
132.70 +
132.71 + Tutta la documentazione del sito è raccolta in un pacchetto debian
132.72 + ``isi-docs`` che potete installare con il comando::
132.73 +
132.74 + apt-get install isi-docs
132.75 +
132.76 +Contribuire alla documentazione
132.77 +-------------------------------
132.78 +
132.79 + Per contribuire alla documentazione occorre scrivere usando il sistema di
132.80 + markup reST. Vedrete presto che questo è facile e viene molto naturalmente.
132.81 +
132.82 + Occorrono però due passi:
132.83 +
132.84 + 1. Procurarsi il sorgente di isi-docs che è in un repository formato
132.85 + mercurial::
132.86 +
132.87 + apt-get install mercurial
132.88 + hg clone http://hg.argolinux.org/isi/isi-docs
132.89 +
132.90 + 2. Modificare le pagine che stanno in docs, eventualmente aggiungerne
132.91 + ed inviarmi le modifiche
132.92 +
132.93 + Per fare nel modo più comodo questo secondo passaggio, anche se non
132.94 + necessario, consiglio di installare sphinx::
132.95 +
132.96 + sudo apt-get install subversion-tools python-docutils python-jinja python-dev
132.97 + svn co http://svn.python.org/projects/doctools
132.98 + cd doctools/trunk
132.99 + python setup.py install
132.100 +
132.101 + Avendo sphinx installato, dalla cartella isi-docs::
132.102 +
132.103 + cd docs
132.104 + (editate i file)
132.105 + make html
132.106 +
132.107 + Che produce i file in formato html in docs/.build/html
132.108 + Chi ha diritto di accesso può committare i risultati, gli altri possono
132.109 + mandarmi un diff::
132.110 +
132.111 + hg tip > patch
132.112 + hg diff >> patch
132.113 + mutt -a patch -s "RetIsiDoc: aggiunta documentazione" [email protected] < /dev/null
132.114 +
132.115 +
132.116 +
132.117 +
132.118 +reST
132.119 +----
132.120 +
132.121 +Per contribuire alla documentazione vi conviene familiarizzare con la
132.122 +sintassi di reST_ , il linguaggio di markup usato
132.123 +
132.124 +.. toctree::
132.125 +
132.126 + rest
132.127 +
132.128 +.. _reST :ref: `reteisi_rest`
132.129 +
132.130 +.. _mercurial: http://www.selenic.com/mercurial/wiki/
132.131 +
132.132 +
132.133 +
133.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
133.2 +++ b/docs/progetto/presentazione_tecnica.rst Mon Apr 26 11:16:23 2010 +0200
133.3 @@ -0,0 +1,121 @@
133.4 +.. _reteisi_presentazione_tecnica:
133.5 +
133.6 +Presentazione tecnica
133.7 +=======================
133.8 +
133.9 +le fondamenta di ISI: argolinux
133.10 +-------------------------------
133.11 +
133.12 +ArgoLinux è un progetto basato su Debian (ramo stabile) con
133.13 +caratteristiche che abbiamo trovato adatte alle nostre esigenze, in
133.14 +particolare:
133.15 +
133.16 +
133.17 + * preinstallazione e preconfigurazione di tutti i pacchetti che servono
133.18 + ad implementare le previste funzionalità di networking
133.19 +
133.20 + * installazione e replica semplificata
133.21 +
133.22 + * funzionamento da cdrom con salvataggio della configurazione su
133.23 + floppy: in questo modo è facile implementare un servizio di firewall
133.24 + sicuro e di immediato ripristino
133.25 +
133.26 + * semplicità della gestione dei runlevel e della configurazione di
133.27 + startup dei servizi (Argo adotta il pacchetto Debian file-rc che
133.28 + mappa il sistema di cartelle e file di boot SysV? su un unico file)
133.29 +
133.30 + * facilità di configurazione del firewall
133.31 +
133.32 +Queste caratteristiche non alterano la compatibilità con la distribuzione
133.33 +ufficiale Debian stabile, di cui possono perciò essere adottati tutti i
133.34 +pacchetti esistenti. Sono garantite pertanto tutte quelle caratteristiche
133.35 +che fanno di Debian una delle distribuzione più stabili, sicure e meglio
133.36 +supportate in circolazione.
133.37 +
133.38 +
133.39 +requisiti hardware
133.40 +------------------
133.41 +
133.42 +ISI come firewall
133.43 ++++++++++++++++++
133.44 +
133.45 +Per realizzare un potente firewall da interporre tra il router ADSL e la
133.46 +rete locale in modo da evitare attacchi indesiderati da internet, e nel
133.47 +contempo consentire l'accesso da remoto ai server e agli apparati di rete, è
133.48 +sufficiente una macchina con le seguenti caratteristiche:
133.49 +
133.50 + * CPU pentium 2 (in teoria dovrebbe essere possibile anche con macchine
133.51 + pentium ma il kernel è ottimizzato per pentium2 e superiori)
133.52 +
133.53 + * RAM 64 mb sono stati sufficienti a gestire un firewall con 3 schede di
133.54 + rete 10/100 mbps (una per la lan e le altre per due router collegati a
133.55 + differenti linee adsl)
133.56 +
133.57 + * HD 10 Gb dovrebbe essere più che sufficiente anche per i log (I servizi
133.58 + offerti da una configurazione normale comprendono anche Dhcp e DNS
133.59 + server, VPN per il collegamento con i plessi non raggiungibili
133.60 + altrimenti)
133.61 +
133.62 +Per questa soluzione (non gira samba) è più indicato usare la distribuzione
133.63 +Argo originale.
133.64 +
133.65 +ISI come fileserver
133.66 ++++++++++++++++++++
133.67 +
133.68 +Per realizzare un file server è opportuno utilizzare una macchina più
133.69 +potente, sia come processore, che soprattutto come Ram e capacità di
133.70 +memorizzazione. Le macchine originariamente acquistate (2003) per il
133.71 +progetto ISI avevano le seguenti caratteristiche:
133.72 +
133.73 + * CPU Pentium 4 2,4 gHz
133.74 + * RAM 1 Gb ddr
133.75 + * HD n.2 dischi da 80 Gb in mirroring software
133.76 + * device di backup: masterizzatore DVD-ram
133.77 + * scheda di rete gigabit
133.78 +
133.79 +Tutto questo è largamente sufficiente per gestire una rete di 100-200 client
133.80 +con vari servizi, oltre al file server, e in particolare:
133.81 +
133.82 + * PDC per autenticazione utenti tramite Ldap e Samba
133.83 + * Web, Ftp e mail server
133.84 + * proxy
133.85 +
133.86 +Queste caratteristiche sono ora più che mai normali
133.87 +
133.88 +sistemi operativi supportati
133.89 +++++++++++++++++++++++++++++
133.90 +
133.91 + + Linux
133.92 +
133.93 + Qualunque distribuzione ( Per il nutrito numero di applicativi
133.94 + educativi contenuti è stata preferita EDUBUNTU )
133.95 +
133.96 + + Microsoft
133.97 +
133.98 + + Windows98 Second Edition
133.99 +
133.100 + + Windows2000
133.101 +
133.102 + + Windows XP Professional
133.103 +
133.104 +
133.105 +perché scegliere isi
133.106 +--------------------
133.107 +
133.108 + I vantaggi rispetto ad un sistema proprietario sono molteplici:
133.109 +
133.110 + + azzeramento degli onerosi costi di licenza
133.111 +
133.112 + + Maggiore sicurezza
133.113 +
133.114 + + Standard aperti
133.115 +
133.116 + + Personalizzabile per adattarla alle proprie esigenze
133.117 +
133.118 +ottenere isi
133.119 +------------
133.120 +
133.121 + è possibile scaricare la versione più recente all'indirizzo
133.122 + http://download.argolinux.org/isi/
133.123 +
133.124 +
134.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134.2 +++ b/docs/progetto/project.rst Mon Apr 26 11:16:23 2010 +0200
134.3 @@ -0,0 +1,155 @@
134.4 +.. _reteisi_project:
134.5 +
134.6 +Il progetto e le sue finalità
134.7 +=============================
134.8 +
134.9 +ReteIsi nasce nel 2002 come libera associazione di Scuole proponenti un
134.10 +progetto di informatizzazione dell'organizzazione scolastica finanziato
134.11 +dall'USR Lombardia nell'ambito degli interventi previsti dalla CM 152/2001
134.12 +(progetti azione B).
134.13 +
134.14 +Raggiunti gli obiettivi principali (definizione di un modello architetturale
134.15 +di una intranet scolastica, individuazione della piattaforma software e dei
134.16 +servizi da attivare, traduzione del modello e dei sistemi individuati in
134.17 +installazioni funzionanti) ora ReteIsi mette a disposizione di tutte le
134.18 +Istituzioni Scolastiche interessate a perseguire "politiche" informatiche
134.19 +non episodiche, i risultati raggiunti, proponendosi come punto di raccordo
134.20 +delle esperienze in atto.
134.21 +
134.22 +
134.23 +Finalità (estratto dai documenti di progetto)
134.24 +---------------------------------------------
134.25 +
134.26 +Il progetto ha come oggetto lo sviluppo, in ambiente Open Source, di un
134.27 +framework HW/SW modulare e standardizzato che consenta la razionalizzazione,
134.28 +la conservazione, la gestione collaborativa, la trasmissione e la
134.29 +pubblicazione dei flussi informativi generati dalle attività scolastiche
134.30 +relativamente
134.31 +
134.32 + * all'istituzione scolastica nel suo complesso e ai suoi rapporti con
134.33 + altri Istituti (processi interni di raccolta dati, di decisione, di
134.34 + pianificazione delle attività, ed esterni di trasmissione di
134.35 + informazioni, anche afferenti alla didattica, alle attività a distanza
134.36 + e alle collaborazioni su progetti comuni); Interoperable Delivery of
134.37 + European eGovernment Services
134.38 +
134.39 + * ai percorsi formativi degli alunni, (valutazione degli apprendimenti e
134.40 + problematica della relativa comunicazione scuola/famiglia anche
134.41 + attraverso l'accesso remoto al fascicolo dello studente );
134.42 +
134.43 + * ai rapporti dell'istituzione scolastica con il territorio (iniziative
134.44 + formative rivolte alla cittadinanza promosse in collaborazione con gli
134.45 + EE.LL., certificazione ECDL, pubblicazione/interrogazione patrimonio
134.46 + librario ecc., integrazione in eventuali reti civiche esistenti ecc).
134.47 +
134.48 +L'architettura HW/SW individuata a sostegno del progetto è quella della
134.49 +intranet d'Istituto, cioè la connessione tra le reti didattiche esistenti,
134.50 +la segreteria e gli ambienti di staff (presidenza, sale insegnanti,
134.51 +biblioteca e quant'altro costituisce luogo in cui abitualmente vengono poste
134.52 +in essere attività relative all'elaborazione e alla gestione delle attività
134.53 +della Scuola). Secondo il ventaglio illustrato nel RGL, le scuole aderenti a
134.54 +questo progetto si collocano, per motivi diversi, all'interno delle
134.55 +tipologie C-D-E: lo strato fisico di rete è già in gran parte disponibile, i
134.56 +completamenti necessari consistono nella posa di dorsali tra edifici diversi
134.57 +poco distanti, nell'aggiunta di punti rete in locali di staff non ancora
134.58 +raggiunti e nell'interconnessione dei segmenti LAN già in essere. Per quanto
134.59 +riguarda le aule tre di noi, ISSS Majorana, IC Bernareggio e IC Bellano,
134.60 +adotteranno anche soluzioni wireless. La connessione delle sedi staccate
134.61 +avverrà adottando canali VPN su ADSL (laddove ADSL è disponibile).
134.62 +
134.63 +Su questa infrastruttura, si definiranno in modo modulare, valutandone di
134.64 +volta in volta la completezza e la riutilizzabilità e utilizzando standard
134.65 +aperti e strumenti Open Source, procedure e servizi rivolti
134.66 +all'organizzazione e alla gestione di elementi importanti della vita
134.67 +scolastica quali:
134.68 +
134.69 +processi interni
134.70 +~~~~~~~~~~~~~~~~
134.71 +
134.72 + * definizione del 'manuale' per la configurazione e il buon uso della
134.73 + struttura intranet, comprese le fondamentali procedure di backup e
134.74 + quelle relative alla sicurezza;
134.75 +
134.76 + * gestione degli account personali di docenti, non docenti e alunni
134.77 + necessari per l'autenticazione e l'accesso sicuro e controllato alla
134.78 + rete d'Istituto e ai suoi servizi;
134.79 +
134.80 + * esportazione dei dati personali dello studente solitamente 'sepolti' in
134.81 + segreteria, per la predisposizione di modulistica e/o report;
134.82 +
134.83 + * pianificazione e documentazione della programmazione didattica e
134.84 + curricolare secondo modalità che ne permettano la pubblicazione sulla
134.85 + rete, il confronto e la verifica;
134.86 +
134.87 + * definizione del fascicolo dello studente (FAST) che è alla base di
134.88 + qualsiasi servizio interattivo scuola/famiglia riutilizzabile in ambito
134.89 + regionale;
134.90 +
134.91 + * registro elettronico dei voti e delle valutazioni;
134.92 +
134.93 + * gestione delle verbalizzazioni e degli strumenti di supporto alle
134.94 + decisioni (griglie, quadri valutativi);
134.95 +
134.96 + * procedure per la pianificazione e il calendario delle attività;
134.97 +
134.98 + * comunicazioni interne: albi elettronici con funzionalità di
134.99 + organizzazione e ricerca documentale;
134.100 +
134.101 + * gestione delle risorse strumentali disponibili (prenotazione,
134.102 + monitoraggio dell'uso, manutenzioni);
134.103 +
134.104 + * gestione della biblioteca e dei servizi correlati (compresa
134.105 + l'interrogazione remota e l'eventuale integrazione del patrimonio
134.106 + librario scolastico con quello delle locali biblioteche civiche);
134.107 +
134.108 +processi esterni
134.109 +~~~~~~~~~~~~~~~~
134.110 +
134.111 + * connessione (VPN) delle sedi staccate e/o dei plessi in cui si articola
134.112 + l'Istituto;
134.113 +
134.114 + * assistenza/manutenzione remota degli apparati server anche fra Istituti
134.115 + diversi (collaborazione sistemistica e consolidamento delle competenze
134.116 + interne rese disponibili anche ad altri istituti);
134.117 +
134.118 + * interazione remota territorio-scuola (comunicazioni scuola/famiglia e
134.119 + problematica dell'autenticazione e del riconoscimento digitale,
134.120 + integrazione in reti civiche esistenti,);
134.121 +
134.122 +La natura eterogenea del raggruppamento di Scuole che presenta questo
134.123 +progetto e gli accordi orientati allo sviluppo parallelo e mutuamente
134.124 +assistibile della piattaforma intranet, consentirà
134.125 +
134.126 + * lo sviluppo di un modello hw/sw di intranet scolastica facilmente
134.127 + duplicabile in altre realtà grazie alla standardizzazione,
134.128 + all'economicità e al modelle di sviluppo aperto che caratterizza le
134.129 + soluzioni sistemistiche adottate;
134.130 +
134.131 + * lo studio delle problematiche connesse con l'autenticazione e il
134.132 + riconoscimento digitale di tutti i soggetti che per vari motivi devono
134.133 + o vogliono interagire in modo sicuro con la scuola;
134.134 +
134.135 + * l'individuazione dei sistemi per la comunicazione sicura tra plessi e/o
134.136 + scuole diverse (connessioni VPN, sviluppo collaborativo di siti web,
134.137 + forum);
134.138 +
134.139 + * lo sviluppo di servizi significativi per la gestione, il monitoraggio,
134.140 + il reporting e la comunicazione dell'attività didattica anche
134.141 + attraverso connessioni remote sicure e personalizzate;
134.142 +
134.143 + * lo sviluppo di strutture dati fondamentali, estensibili ed aperte,
134.144 + capaci di descrivere e rendere accessibili ed elaborabili i flussi
134.145 + informativi legati all'ordinaria attività didattica e alla sua
134.146 + organizzazione;
134.147 +
134.148 + * la definizione e lo sviluppo di servizi sicuri per l'interrogazione
134.149 + remota di database scolastici;
134.150 +
134.151 + * la costitituzione di una rete di scuole di ordini diversi che
134.152 + condividono soluzioni applicative modulari, sia hardware che software,
134.153 + sperimentando anche forme di assistenza remota di tipo sistemistico su
134.154 + infrastrutture simili;
134.155 +
134.156 + * la sperimentazione di forme di lavoro collaborativo relativamente alla
134.157 + progettazione di infrastrutture e servizi comuni ad istituzioni
134.158 + scolastiche di natura diversa.
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
135.2 +++ b/docs/progetto/rest.rst Mon Apr 26 11:16:23 2010 +0200
135.3 @@ -0,0 +1,264 @@
135.4 +.. _reteisi_rest:
135.5 +
135.6 +reStructuredText Primer
135.7 +=======================
135.8 +
135.9 +This section is a brief introduction to reStructuredText (reST) concepts and
135.10 +syntax, intended to provide authors with enough information to author documents
135.11 +productively. Since reST was designed to be a simple, unobtrusive markup
135.12 +language, this will not take too long.
135.13 +
135.14 +.. seealso::
135.15 +
135.16 + The authoritative `reStructuredText User
135.17 + Documentation <http://docutils.sourceforge.net/rst.html>`_.
135.18 +
135.19 +
135.20 +Paragraphs
135.21 +----------
135.22 +
135.23 +The paragraph is the most basic block in a reST document. Paragraphs are simply
135.24 +chunks of text separated by one or more blank lines. As in Python, indentation
135.25 +is significant in reST, so all lines of the same paragraph must be left-aligned
135.26 +to the same level of indentation.
135.27 +
135.28 +
135.29 +Inline markup
135.30 +-------------
135.31 +
135.32 +The standard reST inline markup is quite simple: use
135.33 +
135.34 +* one asterisk: ``*text*`` for emphasis (italics),
135.35 +* two asterisks: ``**text**`` for strong emphasis (boldface), and
135.36 +* backquotes: ````text```` for code samples.
135.37 +
135.38 +If asterisks or backquotes appear in running text and could be confused with
135.39 +inline markup delimiters, they have to be escaped with a backslash.
135.40 +
135.41 +Be aware of some restrictions of this markup:
135.42 +
135.43 +* it may not be nested,
135.44 +* content may not start or end with whitespace: ``* text*`` is wrong,
135.45 +* it must be separated from surrounding text by non-word characters. Use a
135.46 + backslash escaped space to work around that: ``thisis\ *one*\ word``.
135.47 +
135.48 +These restrictions may be lifted in future versions of the docutils.
135.49 +
135.50 +reST also allows for custom "interpreted text roles"', which signify that the
135.51 +enclosed text should be interpreted in a specific way. Sphinx uses this to
135.52 +provide semantic markup and cross-referencing of identifiers, as described in
135.53 +the appropriate section. The general syntax is ``:rolename:`content```.
135.54 +
135.55 +
135.56 +Lists and Quotes
135.57 +----------------
135.58 +
135.59 +List markup is natural: just place an asterisk at the start of a paragraph and
135.60 +indent properly. The same goes for numbered lists; they can also be
135.61 +autonumbered using a ``#`` sign::
135.62 +
135.63 + * This is a bulleted list.
135.64 + * It has two items, the second
135.65 + item uses two lines.
135.66 +
135.67 + 1. This is a numbered list.
135.68 + 2. It has two items too.
135.69 +
135.70 + #. This is a numbered list.
135.71 + #. It has two items too.
135.72 +
135.73 +Note that Sphinx disables the use of enumerated lists introduced by alphabetic
135.74 +or roman numerals, such as ::
135.75 +
135.76 + A. First item
135.77 + B. Second item
135.78 +
135.79 +
135.80 +Nested lists are possible, but be aware that they must be separated from the
135.81 +parent list items by blank lines::
135.82 +
135.83 + * this is
135.84 + * a list
135.85 +
135.86 + * with a nested list
135.87 + * and some subitems
135.88 +
135.89 + * and here the parent list continues
135.90 +
135.91 +Definition lists are created as follows::
135.92 +
135.93 + term (up to a line of text)
135.94 + Definition of the term, which must be indented
135.95 +
135.96 + and can even consist of multiple paragraphs
135.97 +
135.98 + next term
135.99 + Description.
135.100 +
135.101 +
135.102 +Paragraphs are quoted by just indenting them more than the surrounding
135.103 +paragraphs.
135.104 +
135.105 +
135.106 +Source Code
135.107 +-----------
135.108 +
135.109 +Literal code blocks are introduced by ending a paragraph with the special marker
135.110 +``::``. The literal block must be indented, to be able to include blank lines::
135.111 +
135.112 + This is a normal text paragraph. The next paragraph is a code sample::
135.113 +
135.114 + It is not processed in any way, except
135.115 + that the indentation is removed.
135.116 +
135.117 + It can span multiple lines.
135.118 +
135.119 + This is a normal text paragraph again.
135.120 +
135.121 +The handling of the ``::`` marker is smart:
135.122 +
135.123 +* If it occurs as a paragraph of its own, that paragraph is completely left
135.124 + out of the document.
135.125 +* If it is preceded by whitespace, the marker is removed.
135.126 +* If it is preceded by non-whitespace, the marker is replaced by a single
135.127 + colon.
135.128 +
135.129 +That way, the second sentence in the above example's first paragraph would be
135.130 +rendered as "The next paragraph is a code sample:".
135.131 +
135.132 +
135.133 +Hyperlinks
135.134 +----------
135.135 +
135.136 +External links
135.137 +^^^^^^^^^^^^^^
135.138 +
135.139 +Use ```Link text <http://target>`_`` for inline web links. If the link text
135.140 +should be the web address, you don't need special markup at all, the parser
135.141 +finds links and mail addresses in ordinary text.
135.142 +
135.143 +Internal links
135.144 +^^^^^^^^^^^^^^
135.145 +
135.146 +Internal linking is done via a special reST role, see the section on specific
135.147 +markup, :ref: `ref-role`.
135.148 +
135.149 +
135.150 +Sections
135.151 +--------
135.152 +
135.153 +Section headers are created by underlining (and optionally overlining) the
135.154 +section title with a punctuation character, at least as long as the text::
135.155 +
135.156 + =================
135.157 + This is a heading
135.158 + =================
135.159 +
135.160 +Normally, there are no heading levels assigned to certain characters as the
135.161 +structure is determined from the succession of headings. However, for the
135.162 +Python documentation, this convention is used which you may follow:
135.163 +
135.164 +* ``#`` with overline, for parts
135.165 +* ``*`` with overline, for chapters
135.166 +* ``=``, for sections
135.167 +* ``-``, for subsections
135.168 +* ``^``, for subsubsections
135.169 +* ``"``, for paragraphs
135.170 +
135.171 +
135.172 +Explicit Markup
135.173 +---------------
135.174 +
135.175 +"Explicit markup" is used in reST for most constructs that need special
135.176 +handling, such as footnotes, specially-highlighted paragraphs, comments, and
135.177 +generic directives.
135.178 +
135.179 +An explicit markup block begins with a line starting with ``..`` followed by
135.180 +whitespace and is terminated by the next paragraph at the same level of
135.181 +indentation. (There needs to be a blank line between explicit markup and normal
135.182 +paragraphs. This may all sound a bit complicated, but it is intuitive enough
135.183 +when you write it.)
135.184 +
135.185 +
135.186 +Directives
135.187 +----------
135.188 +
135.189 +A directive is a generic block of explicit markup. Besides roles, it is one of
135.190 +the extension mechanisms of reST, and Sphinx makes heavy use of it.
135.191 +
135.192 +Basically, a directive consists of a name, arguments, options and content. (Keep
135.193 +this terminology in mind, it is used in the next chapter describing custom
135.194 +directives.) Looking at this example, ::
135.195 +
135.196 + .. function:: foo(x)
135.197 + foo(y, z)
135.198 + :bar: no
135.199 +
135.200 + Return a line of text input from the user.
135.201 +
135.202 +``function`` is the directive name. It is given two arguments here, the
135.203 +remainder of the first line and the second line, as well as one option ``bar``
135.204 +(as you can see, options are given in the lines immediately following the
135.205 +arguments and indicated by the colons).
135.206 +
135.207 +The directive content follows after a blank line and is indented relative to the
135.208 +directive start.
135.209 +
135.210 +
135.211 +Images
135.212 +------
135.213 +
135.214 +reST supports an image directive, used like so::
135.215 +
135.216 + .. image:: filename
135.217 + (options)
135.218 +
135.219 +When used within Sphinx, the ``filename`` given must be relative to the source
135.220 +file, and Sphinx will automatically copy image files over to a subdirectory of
135.221 +the output directory on building.
135.222 +
135.223 +
135.224 +Footnotes
135.225 +---------
135.226 +
135.227 +For footnotes, use ``[#]_`` to mark the footnote location, and add the footnote
135.228 +body at the bottom of the document after a "Footnotes" rubric heading, like so::
135.229 +
135.230 + Lorem ipsum [#]_ dolor sit amet ... [#]_
135.231 +
135.232 + .. rubric:: Footnotes
135.233 +
135.234 + .. [#] Text of the first footnote.
135.235 + .. [#] Text of the second footnote.
135.236 +
135.237 +You can also explicitly number the footnotes for better context.
135.238 +
135.239 +
135.240 +Comments
135.241 +--------
135.242 +
135.243 +Every explicit markup block which isn't a valid markup construct (like the
135.244 +footnotes above) is regarded as a comment.
135.245 +
135.246 +
135.247 +Source encoding
135.248 +---------------
135.249 +
135.250 +Since the easiest way to include special characters like em dashes or copyright
135.251 +signs in reST is to directly write them as Unicode characters, one has to
135.252 +specify an encoding:
135.253 +
135.254 +All documentation source files must be in UTF-8 encoding, and the HTML
135.255 +documents written from them will be in that encoding as well.
135.256 +
135.257 +
135.258 +Gotchas
135.259 +-------
135.260 +
135.261 +There are some problems one commonly runs into while authoring reST documents:
135.262 +
135.263 +* **Separation of inline markup:** As said above, inline markup spans must be
135.264 + separated from the surrounding text by non-word characters, you have to use
135.265 + an escaped space to get around that.
135.266 +
135.267 +.. XXX more?
136.1 Binary file docs/reteisi.png has changed
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
137.2 +++ b/etc/apache2/sites-available/isiweb-all.conf Mon Apr 26 11:16:23 2010 +0200
137.3 @@ -0,0 +1,45 @@
137.4 +#### configurazione con fastcgi
137.5 +
137.6 +<VirtualHost *:80>
137.7 + #ServerName fscgi.isi.lan
137.8 + #ServerAlias web.isi.lan
137.9 +
137.10 + FastCGIExternalServer /usr/share/isi/isiweb.fcgi -host 127.0.0.1:3033 -idle-timeout 800
137.11 + #FastCGIExternalServer /usr/share/isi/isiweb.fcgi -socket /var/run/isiweb.sock
137.12 +
137.13 +
137.14 + DocumentRoot /usr/share/isi/
137.15 + Alias /static/ /usr/share/isi/isiweb/static/
137.16 + Alias /media/ /usr/share/python-support/python-django/django/contrib/admin/media/
137.17 + Alias /docs/ /usr/share/doc/isi/html/
137.18 +
137.19 + RewriteEngine On
137.20 + RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
137.21 + RewriteRule ^/(static.*)$ /$1 [QSA,L,PT]
137.22 + RewriteRule ^/(docs.*)$ /$1 [QSA,L,PT]
137.23 + RewriteCond %{REQUEST_FILENAME} !-f
137.24 + RewriteRule ^/(.*)$ /isiweb.fcgi/$1 [QSA,L]
137.25 +
137.26 +
137.27 + <LocationMatch "/(static|media)/">
137.28 + SetHandler none
137.29 + ExpiresActive On
137.30 + ExpiresByType application/javascript "access plus 4 weeks"
137.31 + ExpiresByType text/html "access plus 4 weeks"
137.32 + ExpiresByType text/css "access plus 4 weeks"
137.33 + ExpiresDefault "now plus 2 days"
137.34 + </LocationMatch>
137.35 +
137.36 +
137.37 + <Directory "/usr/share/isi/">
137.38 + Order Deny,Allow
137.39 + Allow from 10 172 192 127
137.40 + Deny from all
137.41 + </Directory>
137.42 +
137.43 + ErrorLog /var/log/apache2/isi.lan-error.log
137.44 +
137.45 + LogLevel warn
137.46 + CustomLog /var/log/apache2/isi.lan-access.log combined
137.47 +
137.48 +</VirtualHost>
138.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
138.2 +++ b/etc/apache2/sites-available/isiweb.conf Mon Apr 26 11:16:23 2010 +0200
138.3 @@ -0,0 +1,45 @@
138.4 +#### configurazione con fastcgi
138.5 +
138.6 +<VirtualHost *:80>
138.7 + ServerName fscgi.isi.lan
138.8 + ServerAlias web.isi.lan
138.9 +
138.10 + FastCGIExternalServer /usr/share/isi/isiweb.fcgi -host 127.0.0.1:3033 -idle-timeout 800
138.11 + #FastCGIExternalServer /usr/share/isi/isiweb.fcgi -socket /var/run/isiweb.sock
138.12 +
138.13 +
138.14 + DocumentRoot /usr/share/isi/
138.15 + Alias /static/ /usr/share/isi/isiweb/static/
138.16 + Alias /media/ /usr/share/python-support/python-django/django/contrib/admin/media/
138.17 + Alias /docs/ /usr/share/doc/isi/html/
138.18 +
138.19 + RewriteEngine On
138.20 + RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
138.21 + RewriteRule ^/(static.*)$ /$1 [QSA,L,PT]
138.22 + RewriteRule ^/(docs.*)$ /$1 [QSA,L,PT]
138.23 + RewriteCond %{REQUEST_FILENAME} !-f
138.24 + RewriteRule ^/(.*)$ /isiweb.fcgi/$1 [QSA,L]
138.25 +
138.26 +
138.27 + <LocationMatch "/(static|media)/">
138.28 + SetHandler none
138.29 + ExpiresActive On
138.30 + ExpiresByType application/javascript "access plus 4 weeks"
138.31 + ExpiresByType text/html "access plus 4 weeks"
138.32 + ExpiresByType text/css "access plus 4 weeks"
138.33 + ExpiresDefault "now plus 2 days"
138.34 + </LocationMatch>
138.35 +
138.36 +
138.37 + <Directory "/usr/share/isi/">
138.38 + Order Deny,Allow
138.39 + Allow from 10 172 192 127
138.40 + Deny from all
138.41 + </Directory>
138.42 +
138.43 + ErrorLog /var/log/apache2/isi.lan-error.log
138.44 +
138.45 + LogLevel warn
138.46 + CustomLog /var/log/apache2/isi.lan-access.log combined
138.47 +
138.48 +</VirtualHost>
139.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139.2 +++ b/etc/default/isiweb Mon Apr 26 11:16:23 2010 +0200
139.3 @@ -0,0 +1,1 @@
139.4 +START_FSCI=1
140.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
140.2 +++ b/etc/init.d/isiweb Mon Apr 26 11:16:23 2010 +0200
140.3 @@ -0,0 +1,144 @@
140.4 +#! /bin/sh
140.5 +### BEGIN INIT INFO
140.6 +# Provides: skeleton
140.7 +# Required-Start: $remote_fs
140.8 +# Required-Stop: $remote_fs
140.9 +# Default-Start: 2 3 4 5
140.10 +# Default-Stop: 0 1 6
140.11 +# Short-Description: Example initscript
140.12 +# Description: This file should be used to construct scripts to be
140.13 +# placed in /etc/init.d.
140.14 +### END INIT INFO
140.15 +
140.16 +# Author: Foo Bar <[email protected]>
140.17 +#
140.18 +# Please remove the "Author" lines above and replace them
140.19 +# with your own name if you copy and modify this script.
140.20 +
140.21 +# Do NOT "set -e"
140.22 +
140.23 +# PATH should only include /usr/* if it runs after the mountnfs.sh script
140.24 +PATH=/sbin:/usr/sbin:/bin:/usr/bin
140.25 +DESC="Interfaccia Web per ReteISI"
140.26 +NAME=isiweb
140.27 +#DAEMON=/usr/sbin/$NAME
140.28 +DAEMON_ARGS="socket=$SOCKET pidfile=$PIDFILE"
140.29 +PIDFILE=/var/run/$NAME.pid
140.30 +SCRIPTNAME=/etc/init.d/$NAME
140.31 +SOCKET=/var/run/$NAME.sock
140.32 +PROJDIR="/usr/share/isi/isiweb/"
140.33 +#DAEMON_ARGS="socket=$SOCKET pidfile=$PIDFILE maxspare=1"
140.34 +DAEMON_ARGS="host=127.0.0.1 port=3033 pidfile=$PIDFILE maxspare=1 errlog=/var/log/isiweb.log"
140.35 +
140.36 +# # Exit if the package is not installed
140.37 +# [ -x "$DAEMON" ] || exit 0
140.38 +
140.39 +# Read configuration variable file if it is present
140.40 +[ -r /etc/default/$NAME ] && . /etc/default/$NAME
140.41 +
140.42 +# Load the VERBOSE setting and other rcS variables
140.43 +. /lib/init/vars.sh
140.44 +
140.45 +# Define LSB log_* functions.
140.46 +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
140.47 +. /lib/lsb/init-functions
140.48 +
140.49 +#
140.50 +# Function that starts the daemon/service
140.51 +#
140.52 +do_start()
140.53 +{
140.54 + do_stop
140.55 + cd $PROJDIR
140.56 + if [ $START_FSCI = 1 ] ; then
140.57 + echo "Starting $DESC" $NAME
140.58 + exec /usr/bin/env - \
140.59 + PYTHONPATH="../python:.." ./manage.py runfcgi $DAEMON_ARGS
140.60 + RETVAL=$?
140.61 + echo -e "\n"
140.62 + return $RETVAL
140.63 + else
140.64 + echo "You must enable in /etc/default/isiweb: START_FSCI=1"
140.65 + fi
140.66 +
140.67 +}
140.68 +
140.69 +#
140.70 +# Function that stops the daemon/service
140.71 +#
140.72 +do_stop()
140.73 +{
140.74 + cd $PROJDIR
140.75 + if [ -f $PIDFILE ]; then
140.76 + kill `cat -- $PIDFILE`
140.77 + RETVAL=$?
140.78 + rm -f -- $PIDFILE
140.79 + fi
140.80 + return $RETVAL
140.81 +}
140.82 +
140.83 +#
140.84 +# Function that sends a SIGHUP to the daemon/service
140.85 +#
140.86 +# do_reload() {
140.87 +
140.88 +# do_stop()
140.89 +# do_start()
140.90 +# }
140.91 +
140.92 +case "$1" in
140.93 + start)
140.94 + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
140.95 + do_start
140.96 + case "$?" in
140.97 + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
140.98 + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
140.99 + esac
140.100 + ;;
140.101 + stop)
140.102 + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
140.103 + do_stop
140.104 + case "$?" in
140.105 + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
140.106 + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
140.107 + esac
140.108 + ;;
140.109 + #reload|force-reload)
140.110 + #
140.111 + # If do_reload() is not implemented then leave this commented out
140.112 + # and leave 'force-reload' as an alias for 'restart'.
140.113 + #
140.114 + #log_daemon_msg "Reloading $DESC" "$NAME"
140.115 + #do_reload
140.116 + #log_end_msg $?
140.117 + #;;
140.118 + restart|force-reload)
140.119 + #
140.120 + # If the "reload" option is implemented then remove the
140.121 + # 'force-reload' alias
140.122 + #
140.123 + log_daemon_msg "Restarting $DESC" "$NAME"
140.124 + do_stop
140.125 + case "$?" in
140.126 + 0|1)
140.127 + do_start
140.128 + case "$?" in
140.129 + 0) log_end_msg 0 ;;
140.130 + 1) log_end_msg 1 ;; # Old process is still running
140.131 + *) log_end_msg 1 ;; # Failed to start
140.132 + esac
140.133 + ;;
140.134 + *)
140.135 + # Failed to stop
140.136 + log_end_msg 1
140.137 + ;;
140.138 + esac
140.139 + ;;
140.140 + *)
140.141 + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
140.142 + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
140.143 + exit 3
140.144 + ;;
140.145 +esac
140.146 +
140.147 +:
141.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
141.2 +++ b/etc/isi/dglog.conf.pl.sample Mon Apr 26 11:16:23 2010 +0200
141.3 @@ -0,0 +1,3 @@
141.4 +$ldap_server ='127.0.0.1';
141.5 +$ldap_base ='<dc=isi,dc=lan>';
141.6 +@ldap_fields=('gecos','departmentNumber');
142.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
142.2 +++ b/etc/isi/logon.bat.sample Mon Apr 26 11:16:23 2010 +0200
142.3 @@ -0,0 +1,3 @@
142.4 +:: ##### LOGON.BAT creato da ISI-LOGON #####
142.5 +@ECHO OFF
142.6 +\\ISI-PDC\perl\bin\perl \\ISI-PDC\perl\logon.pl ISI-PDC
143.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
143.2 +++ b/lab/README Mon Apr 26 11:16:23 2010 +0200
143.3 @@ -0,0 +1,40 @@
143.4 +Uso di netkit
143.5 +-------------
143.6 +
143.7 +Pe rilanciare questo laboratorio occorre:
143.8 +
143.9 + 1. installare isi-netkit
143.10 +
143.11 + 2. copiare l'immagine
143.12 +
143.13 + http://download.argolinux.org/isi/lenny-isi-netkit.img.bz2
143.14 +
143.15 + in /usr/share/netkit/fs ed unzipparla
143.16 +
143.17 + 3. lanciare lstart da dentro questa cartella
143.18 +
143.19 + A questo punto si apre una console grafica che è la console sulla
143.20 + macchina virtuale srv-isi, il cui ip è 172.16.0.11 per cui potete
143.21 + aggiungere nella vostra macchina in /etc/hosts::
143.22 +
143.23 + 172.16.0.11 web.isi.lan srv-isi.isi.lan
143.24 +
143.25 +
143.26 + Questa macchina virtuale quando parte lancia automaticamente tutti i
143.27 + comandid che ci sono nel file srv-isi.startup, in particolare lancia:
143.28 +
143.29 + isi-setup isi srv-isi isi
143.30 +
143.31 + Potete connettervi a questa macchina virtuale via ssh
143.32 +
143.33 + 4. per lanciare i test, andate nella cartella 'tests' seguite le istruzioni
143.34 + la dentro.
143.35 +
143.36 +
143.37 +
143.38 +
143.39 +
143.40 +
143.41 +
143.42 +
143.43 +
144.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
144.2 +++ b/lab/lab.conf Mon Apr 26 11:16:23 2010 +0200
144.3 @@ -0,0 +1,16 @@
144.4 +LAB_DESCRIPTION="Interfaccia Web per ReteISI"
144.5 +LAB_VERSION="1.0"
144.6 +LAB_AUTHOR="Sandro Dentella"
144.7 +LAB_EMAIL="[email protected]"
144.8 +LAB_WEB="http://reteisi.argolinux.org/reteisi"
144.9 +
144.10 +## sede
144.11 +srv-isi[1]="lan1"
144.12 +#
144.13 +#srv-isi[eth0]=tap,172.16.0.254,172.16.0.1
144.14 +srv-isi[eth0]=tap,192.168.50.254,192.168.50.1
144.15 +srv-isi[m]=isi-lenny.img
144.16 +#srv-isi[m]=alcatel
144.17 +srv-isi[mem]=200
144.18 +srv-isi[no-log]=
144.19 +
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
145.2 +++ b/lab/srv-isi.startup Mon Apr 26 11:16:23 2010 +0200
145.3 @@ -0,0 +1,9 @@
145.4 +#!/bin/bash
145.5 +
145.6 +mount -o remount,acl /
145.7 +isi-setup -UAT isi srv-isi isi
145.8 +a2enmod rewrite
145.9 +a2enmod expires
145.10 +/etc/init.d/isiweb start
145.11 +/etc/init.d/apache2 restart
145.12 +
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/lab/srv-isi/etc/argo/fw.conf Mon Apr 26 11:16:23 2010 +0200
146.3 @@ -0,0 +1,32 @@
146.4 +# this is meant to just allow ssh to configure it
146.5 +
146.6 +### variable definitions
146.7 +# if LOG=1, a log chain is created to log all dropped packets
146.8 +# take care: log can be a lot of space!
146.9 +LOG=1
146.10 +
146.11 +INT=eth0
146.12 +EXT=eth1
146.13 +# LAN=192.168.0.0/24
146.14 +TCP_DPORTS=" 22 80 443"
146.15 +UDP_DPORTS=""
146.16 +
146.17 +# Input chains w/ 'tnl' in the name (expr match $name tnl -eq 3) will not
146.18 +# be considered by 'firewall' script
146.19 +INPUT_CHAINS="int ext "
146.20 +FWD_CHAINS="fwd "
146.21 +
146.22 +FORWARD=1
146.23 +IP_MODE=dynamic
146.24 +IP_EXT=
146.25 +
146.26 +# uncomment this for transparent proxy
146.27 +# PROXY_REDIR_PORT=3128
146.28 +
146.29 +# SSH_ADMINS="213.145.6.133 , 151.38.133.188 , 151.38.134.51 , 81.116.83.242"
146.30 +
146.31 +ICMP_TYPES=" 0 , 3 , 8 , 11 "
146.32 +# 0 = echo reply
146.33 +# 3 = dest unreachable
146.34 +# 8 = echo request
146.35 +# 11 = time exceeded for datagram
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147.2 +++ b/lab/srv-isi/etc/default/isiweb Mon Apr 26 11:16:23 2010 +0200
147.3 @@ -0,0 +1,1 @@
147.4 +START_FSCI=1
148.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148.2 +++ b/lab/srv-isi/etc/dnsmasq.conf Mon Apr 26 11:16:23 2010 +0200
148.3 @@ -0,0 +1,98 @@
148.4 +# -*- mode: conf -*-
148.5 +# non inoltrare mai ai server dns esterni
148.6 +# query senza nome dominio
148.7 +domain-needed
148.8 +
148.9 +# Tutti i reverse lookup per la subnet privata
148.10 +# non presenti in /etc/hosts o nei lease dhcp
148.11 +# ottengono "host not found"
148.12 +# invece di essere inoltrati ai dns esterni
148.13 +bogus-priv
148.14 +
148.15 +# Filtra le ricorrenti richieste SOA, SRV e altre,
148.16 +# provenienti da macchine windows
148.17 +# serve in particolare a non attivare
148.18 +# per sbaglio il link quando si
148.19 +# hanno connessioni "on demand"
148.20 +filterwin2k
148.21 +
148.22 +# server dns esterni di riferimento
148.23 +# inserire i server dns uno per riga
148.24 +# usati in questo caso i server di opendns.org
148.25 +server=208.67.220.220
148.26 +server=208.67.220.220
148.27 +
148.28 +# aggiunge sempre il nome dominio al nome host
148.29 +expand-hosts
148.30 +
148.31 +# nome del mio dominio
148.32 +domain=vega.it
148.33 +
148.34 +# Se si intende passare ai client un dominio differente
148.35 +# dhcp-option=option:domain-name,isi.lan
148.36 +
148.37 +# range dei lease dhcp: indirizzo iniziale, indirizzo finale, netmask, durata del lease
148.38 +dhcp-range=192.168.50.130,192.168.50.140,255.255.255.0,8h
148.39 +
148.40 +# Range dhcp per-tag
148.41 +# ~~~~~~~~~~~~~~~~~~~
148.42 +# E` anche possibile riservare un determinato range filtrando per TAG.
148.43 +# I tag possono essere associati anche ad un'intera famiglia di indirizzi MAC
148.44 +# Ciò risulta utilissimo, ad esempio, per limitare le macchine virtuali vmware
148.45 +# ad un certo range.
148.46 +#
148.47 +# Settare il tag "macchinevmware" per le macchine con mac iniziante per
148.48 +# 00:0c:29:*:*:* (gruppo di indirizzi mac riservati a vmware)
148.49 +#
148.50 +# dhcp-mac=macchinevmware,00:0c:29:*:*:*
148.51 +#
148.52 +# Sintassi ::
148.53 +#
148.54 +# dhcp-range=[[net:]network-id,]<start-addr>,<end-addr>[[,<net‐netmask>],<broadcast>][,<lease time>]
148.55 +#
148.56 +# Esempio ::
148.57 +#
148.58 +# dhcp-range=net:macchinevmware,192.168.150,160,255.255.255.0,8h
148.59 +
148.60 +
148.61 +# Esempio di ip-reservation per client
148.62 +#
148.63 +# MAC address, indirizzo, nome host, tag(utile per associare a più server)
148.64 +#
148.65 +# dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1
148.66 +# dhcp-host=00:0c:29:5e:69:b5,192.168.96.191,vm-ltsp02,net:ns2 # client2
148.67 +#
148.68 +# le associazioni vengono definite esternamente, vedi inclusioni a fine file.
148.69 +# il file usato è /etc/isi/dns/dnsmasq/hosts.mac
148.70 +
148.71 +# dnsmasq supporta la maggior parte delle
148.72 +# opzioni dhcp e bootp specificate in
148.73 +# http://www.faqs.org/rfcs/rfc2132.html
148.74 +# la sintassi e':
148.75 +# dhcp-option=[numero relativo all'opzione],parametro
148.76 +
148.77 +# GATEWAY di default (3)
148.78 +dhcp-option=44,192.168.50.1
148.79 +
148.80 +# DNS da passare ai client (6)
148.81 +dhcp-option=6,192.168.50.1
148.82 +
148.83 +# WINS da passare ai client (44)
148.84 +dhcp-option=44,192.168.96.1
148.85 +#
148.86 +# Il server dhcp sarà AUTORITATIVO.
148.87 +dhcp-authoritative
148.88 +cache-size=1024
148.89 +### LOG
148.90 +# da usare per debug
148.91 +log-queries
148.92 +
148.93 +# Da abilitare *solo* in caso di debug, logga tutte le transazioni che avvengono
148.94 +# tra servente DHCP e i client.
148.95 +#
148.96 +log-dhcp
148.97 +
148.98 +# Configurazione aggiuntiva per isi.
148.99 +conf-file=/etc/isi/dnsmasq/boot
148.100 +conf-file=/etc/isi/dnsmasq/hosts.mac
148.101 +dhcp-option=3,192.168.50.254
148.102 \ No newline at end of file
149.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149.2 +++ b/lab/srv-isi/etc/hosts Mon Apr 26 11:16:23 2010 +0200
149.3 @@ -0,0 +1,7 @@
149.4 +127.0.0.1 localhost
149.5 +#172.16.0.254 srv-isi web.isi.lan
149.6 +#172.16.0.1 gw
149.7 +
149.8 +192.168.50.254 srv-isi web.isi.lan
149.9 +192.168.50.1 gw
149.10 +
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150.2 +++ b/lab/srv-isi/etc/init.d/isiweb Mon Apr 26 11:16:23 2010 +0200
150.3 @@ -0,0 +1,144 @@
150.4 +#! /bin/sh
150.5 +### BEGIN INIT INFO
150.6 +# Provides: skeleton
150.7 +# Required-Start: $remote_fs
150.8 +# Required-Stop: $remote_fs
150.9 +# Default-Start: 2 3 4 5
150.10 +# Default-Stop: 0 1 6
150.11 +# Short-Description: Example initscript
150.12 +# Description: This file should be used to construct scripts to be
150.13 +# placed in /etc/init.d.
150.14 +### END INIT INFO
150.15 +
150.16 +# Author: Foo Bar <[email protected]>
150.17 +#
150.18 +# Please remove the "Author" lines above and replace them
150.19 +# with your own name if you copy and modify this script.
150.20 +
150.21 +# Do NOT "set -e"
150.22 +
150.23 +# PATH should only include /usr/* if it runs after the mountnfs.sh script
150.24 +PATH=/sbin:/usr/sbin:/bin:/usr/bin
150.25 +DESC="Interfaccia Web per ReteISI"
150.26 +NAME=isiweb
150.27 +#DAEMON=/usr/sbin/$NAME
150.28 +DAEMON_ARGS="socket=$SOCKET pidfile=$PIDFILE"
150.29 +PIDFILE=/var/run/$NAME.pid
150.30 +SCRIPTNAME=/etc/init.d/$NAME
150.31 +SOCKET=/var/run/$NAME.sock
150.32 +PROJDIR="/usr/share/isi/isiweb/"
150.33 +#DAEMON_ARGS="socket=$SOCKET pidfile=$PIDFILE maxspare=1"
150.34 +DAEMON_ARGS="host=127.0.0.1 port=3033 pidfile=$PIDFILE maxspare=1 errlog=/var/log/isiweb.log"
150.35 +
150.36 +# # Exit if the package is not installed
150.37 +# [ -x "$DAEMON" ] || exit 0
150.38 +
150.39 +# Read configuration variable file if it is present
150.40 +[ -r /etc/default/$NAME ] && . /etc/default/$NAME
150.41 +
150.42 +# Load the VERBOSE setting and other rcS variables
150.43 +. /lib/init/vars.sh
150.44 +
150.45 +# Define LSB log_* functions.
150.46 +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
150.47 +. /lib/lsb/init-functions
150.48 +
150.49 +#
150.50 +# Function that starts the daemon/service
150.51 +#
150.52 +do_start()
150.53 +{
150.54 + do_stop
150.55 + cd $PROJDIR
150.56 + if [ $START_FSCI = 1 ] ; then
150.57 + echo "Starting $DESC" $NAME
150.58 + exec /usr/bin/env - \
150.59 + PYTHONPATH="../python:.." ./manage.py runfcgi $DAEMON_ARGS
150.60 + RETVAL=$?
150.61 + echo -e "\n"
150.62 + return $RETVAL
150.63 + else
150.64 + echo "You must enable in /etc/default/isiweb: START_FSCI=1"
150.65 + fi
150.66 +
150.67 +}
150.68 +
150.69 +#
150.70 +# Function that stops the daemon/service
150.71 +#
150.72 +do_stop()
150.73 +{
150.74 + cd $PROJDIR
150.75 + if [ -f $PIDFILE ]; then
150.76 + kill `cat -- $PIDFILE`
150.77 + RETVAL=$?
150.78 + rm -f -- $PIDFILE
150.79 + fi
150.80 + return $RETVAL
150.81 +}
150.82 +
150.83 +#
150.84 +# Function that sends a SIGHUP to the daemon/service
150.85 +#
150.86 +# do_reload() {
150.87 +
150.88 +# do_stop()
150.89 +# do_start()
150.90 +# }
150.91 +
150.92 +case "$1" in
150.93 + start)
150.94 + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
150.95 + do_start
150.96 + case "$?" in
150.97 + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
150.98 + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
150.99 + esac
150.100 + ;;
150.101 + stop)
150.102 + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
150.103 + do_stop
150.104 + case "$?" in
150.105 + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
150.106 + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
150.107 + esac
150.108 + ;;
150.109 + #reload|force-reload)
150.110 + #
150.111 + # If do_reload() is not implemented then leave this commented out
150.112 + # and leave 'force-reload' as an alias for 'restart'.
150.113 + #
150.114 + #log_daemon_msg "Reloading $DESC" "$NAME"
150.115 + #do_reload
150.116 + #log_end_msg $?
150.117 + #;;
150.118 + restart|force-reload)
150.119 + #
150.120 + # If the "reload" option is implemented then remove the
150.121 + # 'force-reload' alias
150.122 + #
150.123 + log_daemon_msg "Restarting $DESC" "$NAME"
150.124 + do_stop
150.125 + case "$?" in
150.126 + 0|1)
150.127 + do_start
150.128 + case "$?" in
150.129 + 0) log_end_msg 0 ;;
150.130 + 1) log_end_msg 1 ;; # Old process is still running
150.131 + *) log_end_msg 1 ;; # Failed to start
150.132 + esac
150.133 + ;;
150.134 + *)
150.135 + # Failed to stop
150.136 + log_end_msg 1
150.137 + ;;
150.138 + esac
150.139 + ;;
150.140 + *)
150.141 + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
150.142 + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
150.143 + exit 3
150.144 + ;;
150.145 +esac
150.146 +
150.147 +:
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/lab/srv-isi/etc/isi/dnsmasq/boot Mon Apr 26 11:16:23 2010 +0200
151.3 @@ -0,0 +1,30 @@
151.4 +# le prossime sono quelle che servono
151.5 +# in particolare ai thin client
151.6 +# root-path (17)
151.7 +# percorso dove montare la partizione root, usata con nfs
151.8 +# dhcp-option=17,"/opt/ltsp/i386"
151.9 +
151.10 +# file di boot (percorso relativo alla root del server tftp),
151.11 +# nome tftp server, ip tftp server
151.12 +# l'indirizzo e il nome del server
151.13 +# devono essere inseriti in /etc/hosts
151.14 +dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
151.15 +
151.16 +# file di boot (percorso relativo alla root del server tftp),
151.17 +# nome tftp server, ip tftp server
151.18 +# l'indirizzo e il nome del server
151.19 +# devono essere inseriti in /etc/hosts
151.20 +#dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
151.21 +
151.22 +# PXE / Etherboot
151.23 +#dhcp-vendorclass=pxe,PXEClient
151.24 +#dhcp-vendorclass=eth,Etherboot
151.25 +# dhcp-option=vendor:PXEClient,1,0.0.0.0
151.26 +dhcp-boot=net:thin_srv1,/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
151.27 +dhcp-boot=net:fat_srv1,/ltsp/ifat386/pxelinux.0,ltsp-server, 192.168.96.222
151.28 +dhcp-boot=net:fat_srv2,/ltsp/ifat386/pxelinux.0,ltsp-server, 192.168.96.224
151.29 +
151.30 +# other
151.31 +dhcp-boot=net:gpxe,/ltsp/i386/nbi.img,ltsp-server,192.168.96.222
151.32 +# default
151.33 +dhcp-boot=/ltsp/ifat386/pxelinux.0,ltsp-server, 192.168.96.222
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/lab/srv-isi/etc/isi/dnsmasq/hosts.mac Mon Apr 26 11:16:23 2010 +0200
152.3 @@ -0,0 +1,3 @@
152.4 +dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1
152.5 +dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1
152.6 +dhcp-host=00:0c:29:10:a6:48,192.168.5.55
152.7 \ No newline at end of file
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
153.2 +++ b/lab/srv-isi/etc/isi/web/local_settings.py Mon Apr 26 11:16:23 2010 +0200
153.3 @@ -0,0 +1,7 @@
153.4 +LOGON_FILE = '/etc/isi/logon.conf'
153.5 +SAMBA_FILE = '/etc/samba/smb.conf'
153.6 +DNSMASQ_CONF = '/etc/dnsmasq.conf'
153.7 +HOSTS_CONF = '/etc/hosts'
153.8 +MAC_CONF = '/etc/isi/dnsmasq/hosts.mac'
153.9 +LEASES_FILE = '/var/lib/misc/dnsmasq.leases'
153.10 +BOOT_CONF = '/etc/isi/dnsmasq/boot'
154.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
154.2 +++ b/lab/srv-isi/etc/libnss-ldap.conf Mon Apr 26 11:16:23 2010 +0200
154.3 @@ -0,0 +1,323 @@
154.4 +###DEBCONF###
154.5 +# the configuration of this file will be done by debconf as long as the
154.6 +# first line of the file says '###DEBCONF###'
154.7 +#
154.8 +# you should use dpkg-reconfigure libnss-ldap to configure this file.
154.9 +#
154.10 +# @(#)$Id: ldap.conf,v 2.48 2021/07/03 02:30:29 lukeh Exp $
154.11 +#
154.12 +# This is the configuration file for the LDAP nameservice
154.13 +# switch library and the LDAP PAM module.
154.14 +#
154.15 +# PADL Software
154.16 +# http://www.padl.com
154.17 +#
154.18 +
154.19 +# Your LDAP server. Must be resolvable without using LDAP.
154.20 +# Multiple hosts may be specified, each separated by a
154.21 +# space. How long nss_ldap takes to failover depends on
154.22 +# whether your LDAP client library supports configurable
154.23 +# network or connect timeouts (see bind_timelimit).
154.24 +#host 127.0.0.1
154.25 +
154.26 +# The distinguished name of the search base.
154.27 +base dc=example,dc=net
154.28 +
154.29 +# Another way to specify your LDAP server is to provide an
154.30 +uri ldapi:///
154.31 +# Unix Domain Sockets to connect to a local LDAP Server.
154.32 +#uri ldap://127.0.0.1/
154.33 +#uri ldaps://127.0.0.1/
154.34 +#uri ldapi://%2fvar%2frun%2fldapi_sock/
154.35 +# Note: %2f encodes the '/' used as directory separator
154.36 +
154.37 +# The LDAP version to use (defaults to 3
154.38 +# if supported by client library)
154.39 +ldap_version 3
154.40 +
154.41 +# The distinguished name to bind to the server with.
154.42 +# Optional: default is to bind anonymously.
154.43 +# Please do not put double quotes around it as they
154.44 +# would be included literally.
154.45 +#binddn cn=proxyuser,dc=padl,dc=com
154.46 +
154.47 +# The credentials to bind with.
154.48 +# Optional: default is no credential.
154.49 +#bindpw secret
154.50 +
154.51 +# The distinguished name to bind to the server with
154.52 +# if the effective user ID is root. Password is
154.53 +# stored in /etc/libnss-ldap.secret (mode 600)
154.54 +# Use 'echo -n "mypassword" > /etc/libnss-ldap.secret' instead
154.55 +# of an editor to create the file.
154.56 +rootbinddn cn=manager,dc=example,dc=net
154.57 +
154.58 +# The port.
154.59 +# Optional: default is 389.
154.60 +#port 389
154.61 +
154.62 +# The search scope.
154.63 +#scope sub
154.64 +#scope one
154.65 +#scope base
154.66 +
154.67 +# Search timelimit
154.68 +#timelimit 30
154.69 +
154.70 +# Bind/connect timelimit
154.71 +bind_timelimit 3
154.72 +
154.73 +# Reconnect policy:
154.74 +# hard_open: reconnect to DSA with exponential backoff if
154.75 +# opening connection failed
154.76 +# hard_init: reconnect to DSA with exponential backoff if
154.77 +# initializing connection failed
154.78 +# hard: alias for hard_open
154.79 +# soft: return immediately on server failure
154.80 +bind_policy soft
154.81 +
154.82 +# Connection policy:
154.83 +# persist: DSA connections are kept open (default)
154.84 +# oneshot: DSA connections destroyed after request
154.85 +#nss_connect_policy persist
154.86 +
154.87 +# Idle timelimit; client will close connections
154.88 +# (nss_ldap only) if the server has not been contacted
154.89 +# for the number of seconds specified below.
154.90 +#idle_timelimit 3600
154.91 +
154.92 +# Use paged rseults
154.93 +#nss_paged_results yes
154.94 +
154.95 +# Pagesize: when paged results enable, used to set the
154.96 +# pagesize to a custom value
154.97 +#pagesize 1000
154.98 +
154.99 +# Filter to AND with uid=%s
154.100 +#pam_filter objectclass=account
154.101 +
154.102 +# The user ID attribute (defaults to uid)
154.103 +#pam_login_attribute uid
154.104 +
154.105 +# Search the root DSE for the password policy (works
154.106 +# with Netscape Directory Server)
154.107 +#pam_lookup_policy yes
154.108 +
154.109 +# Check the 'host' attribute for access control
154.110 +# Default is no; if set to yes, and user has no
154.111 +# value for the host attribute, and pam_ldap is
154.112 +# configured for account management (authorization)
154.113 +# then the user will not be allowed to login.
154.114 +#pam_check_host_attr yes
154.115 +
154.116 +# Check the 'authorizedService' attribute for access
154.117 +# control
154.118 +# Default is no; if set to yes, and the user has no
154.119 +# value for the authorizedService attribute, and
154.120 +# pam_ldap is configured for account management
154.121 +# (authorization) then the user will not be allowed
154.122 +# to login.
154.123 +#pam_check_service_attr yes
154.124 +
154.125 +# Group to enforce membership of
154.126 +#pam_groupdn cn=PAM,ou=Groups,dc=padl,dc=com
154.127 +
154.128 +# Group member attribute
154.129 +#pam_member_attribute uniquemember
154.130 +
154.131 +# Specify a minium or maximum UID number allowed
154.132 +#pam_min_uid 0
154.133 +#pam_max_uid 0
154.134 +
154.135 +# Template login attribute, default template user
154.136 +# (can be overriden by value of former attribute
154.137 +# in user's entry)
154.138 +#pam_login_attribute userPrincipalName
154.139 +#pam_template_login_attribute uid
154.140 +#pam_template_login nobody
154.141 +
154.142 +# HEADS UP: the pam_crypt, pam_nds_passwd,
154.143 +# and pam_ad_passwd options are no
154.144 +# longer supported.
154.145 +#
154.146 +# Do not hash the password at all; presume
154.147 +# the directory server will do it, if
154.148 +# necessary. This is the default.
154.149 +#pam_password clear
154.150 +
154.151 +# Hash password locally; required for University of
154.152 +# Michigan LDAP server, and works with Netscape
154.153 +# Directory Server if you're using the UNIX-Crypt
154.154 +# hash mechanism and not using the NT Synchronization
154.155 +# service.
154.156 +#pam_password crypt
154.157 +
154.158 +# Remove old password first, then update in
154.159 +# cleartext. Necessary for use with Novell
154.160 +# Directory Services (NDS)
154.161 +#pam_password nds
154.162 +
154.163 +# RACF is an alias for the above. For use with
154.164 +# IBM RACF
154.165 +#pam_password racf
154.166 +
154.167 +# Update Active Directory password, by
154.168 +# creating Unicode password and updating
154.169 +# unicodePwd attribute.
154.170 +#pam_password ad
154.171 +
154.172 +# Use the OpenLDAP password change
154.173 +# extended operation to update the password.
154.174 +#pam_password exop
154.175 +
154.176 +# Redirect users to a URL or somesuch on password
154.177 +# changes.
154.178 +#pam_password_prohibit_message Please visit http://internal to change your password.
154.179 +
154.180 +# Use backlinks for answering initgroups()
154.181 +#nss_initgroups backlink
154.182 +
154.183 +# Enable support for RFC2307bis (distinguished names in group
154.184 +# members)
154.185 +#nss_schema rfc2307bis
154.186 +
154.187 +# RFC2307bis naming contexts
154.188 +# Syntax:
154.189 +# nss_base_XXX base?scope?filter
154.190 +# where scope is {base,one,sub}
154.191 +# and filter is a filter to be &'d with the
154.192 +# default filter.
154.193 +# You can omit the suffix eg:
154.194 +# nss_base_passwd ou=People,
154.195 +# to append the default base DN but this
154.196 +# may incur a small performance impact.
154.197 +#nss_base_passwd ou=People,dc=padl,dc=com?one
154.198 +#nss_base_shadow ou=People,dc=padl,dc=com?one
154.199 +#nss_base_group ou=Group,dc=padl,dc=com?one
154.200 +#nss_base_hosts ou=Hosts,dc=padl,dc=com?one
154.201 +#nss_base_services ou=Services,dc=padl,dc=com?one
154.202 +#nss_base_networks ou=Networks,dc=padl,dc=com?one
154.203 +#nss_base_protocols ou=Protocols,dc=padl,dc=com?one
154.204 +#nss_base_rpc ou=Rpc,dc=padl,dc=com?one
154.205 +#nss_base_ethers ou=Ethers,dc=padl,dc=com?one
154.206 +#nss_base_netmasks ou=Networks,dc=padl,dc=com?ne
154.207 +#nss_base_bootparams ou=Ethers,dc=padl,dc=com?one
154.208 +#nss_base_aliases ou=Aliases,dc=padl,dc=com?one
154.209 +#nss_base_netgroup ou=Netgroup,dc=padl,dc=com?one
154.210 +
154.211 +# attribute/objectclass mapping
154.212 +# Syntax:
154.213 +#nss_map_attribute rfc2307attribute mapped_attribute
154.214 +#nss_map_objectclass rfc2307objectclass mapped_objectclass
154.215 +
154.216 +# configure --enable-nds is no longer supported.
154.217 +# NDS mappings
154.218 +#nss_map_attribute uniqueMember member
154.219 +
154.220 +# Services for UNIX 3.5 mappings
154.221 +#nss_map_objectclass posixAccount User
154.222 +#nss_map_objectclass shadowAccount User
154.223 +#nss_map_attribute uid msSFU30Name
154.224 +#nss_map_attribute uniqueMember msSFU30PosixMember
154.225 +#nss_map_attribute userPassword msSFU30Password
154.226 +#nss_map_attribute homeDirectory msSFU30HomeDirectory
154.227 +#nss_map_attribute homeDirectory msSFUHomeDirectory
154.228 +#nss_map_objectclass posixGroup Group
154.229 +#pam_login_attribute msSFU30Name
154.230 +#pam_filter objectclass=User
154.231 +#pam_password ad
154.232 +
154.233 +# configure --enable-mssfu-schema is no longer supported.
154.234 +# Services for UNIX 2.0 mappings
154.235 +#nss_map_objectclass posixAccount User
154.236 +#nss_map_objectclass shadowAccount user
154.237 +#nss_map_attribute uid msSFUName
154.238 +#nss_map_attribute uniqueMember posixMember
154.239 +#nss_map_attribute userPassword msSFUPassword
154.240 +#nss_map_attribute homeDirectory msSFUHomeDirectory
154.241 +#nss_map_attribute shadowLastChange pwdLastSet
154.242 +#nss_map_objectclass posixGroup Group
154.243 +#nss_map_attribute cn msSFUName
154.244 +#pam_login_attribute msSFUName
154.245 +#pam_filter objectclass=User
154.246 +#pam_password ad
154.247 +
154.248 +# RFC 2307 (AD) mappings
154.249 +#nss_map_objectclass posixAccount user
154.250 +#nss_map_objectclass shadowAccount user
154.251 +#nss_map_attribute uid sAMAccountName
154.252 +#nss_map_attribute homeDirectory unixHomeDirectory
154.253 +#nss_map_attribute shadowLastChange pwdLastSet
154.254 +#nss_map_objectclass posixGroup group
154.255 +#nss_map_attribute uniqueMember member
154.256 +#pam_login_attribute sAMAccountName
154.257 +#pam_filter objectclass=User
154.258 +#pam_password ad
154.259 +
154.260 +# configure --enable-authpassword is no longer supported
154.261 +# AuthPassword mappings
154.262 +#nss_map_attribute userPassword authPassword
154.263 +
154.264 +# AIX SecureWay mappings
154.265 +#nss_map_objectclass posixAccount aixAccount
154.266 +#nss_base_passwd ou=aixaccount,?one
154.267 +#nss_map_attribute uid userName
154.268 +#nss_map_attribute gidNumber gid
154.269 +#nss_map_attribute uidNumber uid
154.270 +#nss_map_attribute userPassword passwordChar
154.271 +#nss_map_objectclass posixGroup aixAccessGroup
154.272 +#nss_base_group ou=aixgroup,?one
154.273 +#nss_map_attribute cn groupName
154.274 +#nss_map_attribute uniqueMember member
154.275 +#pam_login_attribute userName
154.276 +#pam_filter objectclass=aixAccount
154.277 +#pam_password clear
154.278 +
154.279 +# For pre-RFC2307bis automount schema
154.280 +#nss_map_objectclass automountMap nisMap
154.281 +#nss_map_attribute automountMapName nisMapName
154.282 +#nss_map_objectclass automount nisObject
154.283 +#nss_map_attribute automountKey cn
154.284 +#nss_map_attribute automountInformation nisMapEntry
154.285 +
154.286 +# Netscape SDK LDAPS
154.287 +#ssl on
154.288 +
154.289 +# Netscape SDK SSL options
154.290 +#sslpath /etc/ssl/certs
154.291 +
154.292 +# OpenLDAP SSL mechanism
154.293 +# start_tls mechanism uses the normal LDAP port, LDAPS typically 636
154.294 +#ssl start_tls
154.295 +#ssl on
154.296 +
154.297 +# OpenLDAP SSL options
154.298 +# Require and verify server certificate (yes/no)
154.299 +# Default is to use libldap's default behavior, which can be configured in
154.300 +# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for
154.301 +# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes".
154.302 +#tls_checkpeer yes
154.303 +
154.304 +# CA certificates for server certificate verification
154.305 +# At least one of these are required if tls_checkpeer is "yes"
154.306 +#tls_cacertfile /etc/ssl/ca.cert
154.307 +#tls_cacertdir /etc/ssl/certs
154.308 +
154.309 +# Seed the PRNG if /dev/urandom is not provided
154.310 +#tls_randfile /var/run/egd-pool
154.311 +
154.312 +# SSL cipher suite
154.313 +# See man ciphers for syntax
154.314 +#tls_ciphers TLSv1
154.315 +
154.316 +# Client certificate and key
154.317 +# Use these, if your server requires client authentication.
154.318 +#tls_cert
154.319 +#tls_key
154.320 +
154.321 +# Disable SASL security layers. This is needed for AD.
154.322 +#sasl_secprops maxssf=0
154.323 +
154.324 +# Override the default Kerberos ticket cache location.
154.325 +#krb5_ccname FILE:/etc/.ldapcache
154.326 +
155.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
155.2 +++ b/lab/srv-isi/etc/network/interfaces Mon Apr 26 11:16:23 2010 +0200
155.3 @@ -0,0 +1,3 @@
155.4 +auto lo
155.5 +iface lo inet loopback
155.6 +
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
156.2 +++ b/lab/srv-isi/root/.aptitude/config Mon Apr 26 11:16:23 2010 +0200
156.3 @@ -0,0 +1,2 @@
156.4 +aptitude "";
156.5 +aptitude::Ignore-Recommends-Important "true";
157.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
157.2 +++ b/lab/srv-isi/root/.bash_history Mon Apr 26 11:16:23 2010 +0200
157.3 @@ -0,0 +1,312 @@
157.4 +l
157.5 +jmacs /etc/inittab
157.6 +l
157.7 +ls
157.8 +ln -s ../init.d/netkit-phase1 /etc/rcS.d/S37netkit-phase1
157.9 +ln -s ../init.d/S99netkit-phase2 /etc/rcS.d/S99netkit-phase2
157.10 +l
157.11 +cd /etc/init.d/
157.12 +l
157.13 +l
157.14 +cd ..
157.15 +cd rcS.d/
157.16 +l
157.17 +l
157.18 +l
157.19 +rm S99netkit-phase2
157.20 +ln -s ../init.d/netkit-phase2 /etc/rcS.d/S99netkit-phase2
157.21 +l
157.22 +ls /etc/rc*.d/*
157.23 +ls /etc/rc*.d/fire*
157.24 +ls /etc/rc*.d/*/fire*
157.25 +ls /etc/rc*.d/*
157.26 +ls /etc/rc*.d/*firew*
157.27 +ls -l
157.28 +ln -s ../init.d/firewall /etc/rcS.d/S38firewall
157.29 +l
157.30 +mv S99netkit-phase2 ../rc2.d/
157.31 +cd ../rc2.d/
157.32 +l
157.33 +cd ..
157.34 +l
157.35 +cd rcS.d/
157.36 +l
157.37 +apt-get install -y openvpn
157.38 +apt-cache search locale
157.39 +apt-get install localepurge
157.40 +dpkg-reconfigure localepurge
157.41 +dpkg-reconfigure locale
157.42 +apt-get install locales
157.43 +apt-get update
157.44 +dpkg-reconfigure locales
157.45 +apt-get install -y openvpn squid
157.46 +mount
157.47 +l
157.48 +cd /etc/init.d/
157.49 +l
157.50 +cd ../
157.51 +ls rc*.d
157.52 +ls rc*.d/*squid
157.53 +ls rc*.d/S*squid
157.54 +rm rc*.d/S*squid
157.55 +ls rc*.d/S*openvpn
157.56 +rm rc*.d/S*openvpn
157.57 +apt-get install -y dansguardian
157.58 +l
157.59 +ls rc*.d/S*dansg*
157.60 +rm rc*.d/S*dansg*
157.61 +apt-get install vtund
157.62 +apt-get install vtun
157.63 +ls rc*.d/S*vtun*
157.64 +rm rc*.d/S*vtun*
157.65 +ls rc*.d/S*samba*
157.66 +ls /etc/rc*.d/S*samba*
157.67 +ls /etc/rc*.d/S*postfix*
157.68 +ls /etc/rc*.d/S*md*
157.69 +rm /etc/rc*.d/S*md*
157.70 +ls /etc/rc*.d/S*atop*
157.71 +rm /etc/rc*.d/S*atop*
157.72 +apt-get install mingetty
157.73 +jmacs /etc/inittab
157.74 +jmacs /etc/inittab
157.75 +l
157.76 +l
157.77 +l
157.78 +l
157.79 +cd /etc/rcS.d/
157.80 +l
157.81 +cp /etc/rc2.d/S99netkit-phase2 .
157.82 +l
157.83 +rm S99netkit-phase2
157.84 +ln -s ../init.d/netkit-phase2 S99netkit-phase2
157.85 +l
157.86 +rm ../rc2.d/S99netkit-phase2
157.87 +l
157.88 +dpkg-reconfigure firewall
157.89 +l
157.90 +l
157.91 +l
157.92 +cd /etc/
157.93 +cd rcS.d/
157.94 +l
157.95 +rm S99netkit-phase2
157.96 +cd ../rc2.d/
157.97 +ln -s ../init.d/netkit-phase2 S99netkit-phase2
157.98 +l
157.99 +l
157.100 +find . -uid 1001
157.101 +dpkg-reconfigure locales
157.102 +jmacs /etc/inittab
157.103 +cd /etc/
157.104 +ls rc*d
157.105 +ls rc*d/S*
157.106 +ls rc*d/S*samba*
157.107 +rm rc*d/S*samba*
157.108 +rm rc*d/S*postfix*
157.109 +rm rc*d/S*nscd*
157.110 +rm rc*d/S*slapd*
157.111 +rm rc*d/S*rsync*
157.112 +rm rc*d/S*clama*
157.113 +ls rc*d/S*samba*
157.114 +rm rc*d/S**
157.115 +l rc*d/
157.116 +l
157.117 +l rc*d/
157.118 +ls /etc/rc*
157.119 +l
157.120 +dpkg -l | grep open
157.121 +dpkg -l | grep pyre
157.122 +dpkg -l | grep isi
157.123 +cat /etc/squid/squid.conf
157.124 +cat /etc/squid/squid.conf |egrep -v "^#"
157.125 +cat /etc/squid/squid.conf |egrep -v "^#|^$"
157.126 +l
157.127 +dpkg -l |grep nma
157.128 +dpkg -l |grep smb
157.129 +dpkg -l |grep sam
157.130 +dpkg -l |grep isi
157.131 +apt-get update
157.132 +jmacs /etc/apt/sources.list
157.133 +apt-get update
157.134 +jmacs /etc/apt/sources.list
157.135 +apt-get update
157.136 +apt-get install tshark
157.137 +l
157.138 +aptitude clean
157.139 +aptitude autoclean
157.140 +l
157.141 +ls /etc/
157.142 +rm /etc/*~
157.143 +ls /root/
157.144 +l
157.145 +apt-get update
157.146 +apt-get install -y pyrewall
157.147 +dpkg -l | grep twire
157.148 +apt-get install twireshark
157.149 +cd
157.150 +cd /root/
157.151 +jmacs /etc/bash.bashrc
157.152 +. /etc/bash.bashrc
157.153 +ipl
157.154 +ls
157.155 +l
157.156 +apt-cache search
157.157 +apt-cache search lsb
157.158 +apt-get install lsb-release
157.159 +lsb_release -a
157.160 +ipl
157.161 +ipl
157.162 +ipl
157.163 +ipl
157.164 +ipl
157.165 +ipl
157.166 +l
157.167 +cd /etc/init.d/
157.168 +l
157.169 +cd ..
157.170 +cd rc0.d/
157.171 +l
157.172 +l
157.173 +cd ../rc1.d/
157.174 +l
157.175 +cd ../rc2.d/
157.176 +l
157.177 +l
157.178 +l
157.179 +ipl
157.180 +ls -l /tmp/
157.181 +ls -l /tmp/
157.182 +l
157.183 +ls
157.184 +l
157.185 +l
157.186 +cat /etc/init.d/netkit-phase1
157.187 +cd /etc/rc2.d/
157.188 +l
157.189 +l
157.190 +l
157.191 +cat $(which isi-setup )
157.192 +l
157.193 +apt-get install mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi libcrack2
157.194 +aptitude update
157.195 +apt-get install mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi libcrack2
157.196 +apt-get install mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi libcrack2
157.197 +apt-get install mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi libcrack2
157.198 +mount /proc/
157.199 +apt-get install mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi libcrack2
157.200 +apt-get install libapache2-mod-wsgi dnsmasq apache2
157.201 +apt-get install python-mako libjs-jquery libjs-jquery-ui
157.202 +aptitude show python-django
157.203 +apt-cache search python-django
157.204 +jmacs /etc/apt/sources.list
157.205 +aptitude udate
157.206 +aptitude update
157.207 +jmacs /etc/apt/sources.list
157.208 +aptitude update
157.209 +cd /tmp/
157.210 +wget http://www.backports.org/debian/pool/main/p/python-django/python-django_1.1.1-1~bpo50+1_all.deb
157.211 +dpkg -i python-django_1.1.1-1~bpo50+1_all.deb
157.212 +apt-show python-mako
157.213 +apt-cache show python-mako
157.214 +apt-get install python-mako
157.215 +apt-cache show libjs-jquery
157.216 +apt-et install libjs-jquery
157.217 +apt-get install libjs-jquery
157.218 +apt-get install libjs-jquery-ui
157.219 +aptitude show jquery
157.220 +aptitude search jquery
157.221 +wget http://http.us.debian.org/debian/pool/main/j/jqueryui/libjs-jquery-ui_1.7.2-1_all.deb
157.222 +dpkg -i libjs-jquery-ui_1.7.2-1_all.deb
157.223 +wget http://ftp.us.debian.org/debian/pool/main/j/jquery/libjs-jquery_1.4-1_all.deb
157.224 +dpkg -i libjs-jquery_1.4-1_all.deb
157.225 +dpkg -i libjs-jquery-ui_1.7.2-1_all.deb
157.226 +dpkg -l | grep libjs
157.227 +l
157.228 +dpkg -l | grep dhcp
157.229 +apt-get install dnsmasq apache2
157.230 +l
157.231 +cat /etc/samba/smb.conf
157.232 +cat /etc/samba/smb.conf
157.233 +umount /proc/
157.234 +edit /usr/sbin/isi-setup
157.235 +emacs /usr/sbin/isi-setup
157.236 +jmacs /usr/sbin/isi-setup
157.237 +l
157.238 +ls /etc/rc*
157.239 +l /etc/rc*
157.240 +tree -L /etc/rc*
157.241 +tree -L 2 /etc/rc*
157.242 +tree -L 2 /etc/rc*|grep -i slap
157.243 +l
157.244 +apt-get install ipython
157.245 +apt-get update
157.246 +gpg --keyserver subkeys.pgp.net --recv-keys EA8E8B2116BA136C
157.247 + gpg --export | apt-key add -
157.248 +apt-get update
157.249 +ls /etc/rc*.d/[K,S]*|grep network
157.250 +ls /etc/rc*.d/[K,S]*|grep slapd
157.251 +ls /etc/rc*.d/[K,S]*|grep samba
157.252 +update-rc.d samba start 20 S . stop 19 S .
157.253 +ls /etc/rc*.d/[K,S]*|grep samba
157.254 +update-rc.d
157.255 +update-rc.d samba start 20 2 . stop 19 S .
157.256 +ls /etc/rc*.d/[K,S]*|grep samba
157.257 +ls -l /etc/rc0.d/K19samba
157.258 +ln -s ../init.d/samba /etc/rc2.d/S20samba /etc/rc3.d/S20samba
157.259 +ln -s ../init.d/samba /etc/rc2.d/S20samba
157.260 +ln -s ../init.d/samba /etc/rc3.d/S20samba
157.261 +ln -s ../init.d/samba /etc/rc4.d/S20samba
157.262 +ln -s ../init.d/samba /etc/rc5.d/S20samba
157.263 +ls -l /etc/rc0.d/K19samba
157.264 +ls /etc/rc*.d/[K,S]*|grep samba
157.265 +ls /etc/rc*.d/[K,S]*|grep samba
157.266 +ls /etc/rc*.d/[K,S]*|grep slapd
157.267 +ls -l /etc/rc2.d/S19slapd
157.268 +ls -l /etc/rc2.d/S20samba
157.269 +ls -l /etc/rc*.d/*samba
157.270 +ln -s ../init.d/slapd /etc/rc2.d/S19slapd
157.271 +ln -s ../init.d/slapd /etc/rc3.d/S19slapd
157.272 +ln -s ../init.d/slapd /etc/rc4.d/S19slapd
157.273 +ln -s ../init.d/slapd /etc/rc5.d/S19slapd
157.274 +ls -l /etc/rc*.d/*samba
157.275 +ls -l /etc/rc*.d/*slapd
157.276 +ls -l /etc/rc*.d/*slapd
157.277 +ls -l /etc/rc*.d/*samba
157.278 +apt-get install etc_keeper
157.279 +aptitude search etckeeper
157.280 +apt-get install etckeeper
157.281 +l
157.282 +cd /etc/
157.283 +l
157.284 +jmacs /etc/cron.d/hgetc
157.285 +jmacs /etc/etckeeper/etckeeper.conf
157.286 +etckeeper init
157.287 +etckeeper status
157.288 +hg st
157.289 +etckeeper add
157.290 +etckeeper commit -m 'init'
157.291 +hg st
157.292 +hgtip
157.293 +hg tip
157.294 +hg rollback
157.295 +etckeeper commit 'initialize'
157.296 +hg st
157.297 +hgtip
157.298 +hg tip
157.299 +l
157.300 +cat /etc/cron.d/hgetc
157.301 +jmacs /etc/cron.d/hgetc
157.302 +ll
157.303 +hg st
157.304 +l
157.305 +
157.306 +dpkg -l | grep ipython
157.307 +hg rollback
157.308 +etckeeper commit 'initialize'
157.309 +hg st
157.310 +apt-get install bash-completion
157.311 +cd etc/
157.312 +hg st
157.313 +rm -Rf /root/.ipython/
157.314 +dpkg -l apache2
157.315 +ipl
158.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
158.2 +++ b/lab/srv-isi/root/.bashrc Mon Apr 26 11:16:23 2010 +0200
158.3 @@ -0,0 +1,37 @@
158.4 +# ~/.bashrc: executed by bash(1) for non-login shells.
158.5 +
158.6 +. /etc/bash.bashrc
158.7 +
158.8 +export PS1='\h:\w\$ '
158.9 +umask 022
158.10 +
158.11 +### get rid of autologin after first login
158.12 +if [ -f /etc/inittab-hd -a "$(tty)" = "/dev/tty1" ] ; then
158.13 + mv /etc/inittab-hd /etc/inittab
158.14 + init q
158.15 + ipl
158.16 + ESC="\033["
158.17 + RED="${ESC}31;1m"
158.18 + BLUE="${ESC}34;1m"
158.19 + GREEN="${ESC}44;33;1m"
158.20 + YELLOW="${ESC}33;1m"
158.21 + NOR="${ESC};0m"
158.22 +
158.23 + ps ax|grep 'login -f' |grep -v tty1|awk '{print $1}'|xargs kill
158.24 + echo -e "\n${YELLOW}Imposta una password per ${RED}root:${NOR} \n\n"
158.25 + passwd root
158.26 +
158.27 +fi
158.28 +
158.29 +
158.30 +# You may uncomment the following lines if you want `ls' to be colorized:
158.31 +# export LS_OPTIONS='--color=auto'
158.32 +# eval "`dircolors`"
158.33 +# alias ls='ls $LS_OPTIONS'
158.34 +# alias ll='ls $LS_OPTIONS -l'
158.35 +# alias l='ls $LS_OPTIONS -lA'
158.36 +#
158.37 +# Some more alias to avoid making mistakes:
158.38 +# alias rm='rm -i'
158.39 +# alias cp='cp -i'
158.40 +# alias mv='mv -i'
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
159.2 +++ b/lab/srv-isi/root/.emacs Mon Apr 26 11:16:23 2010 +0200
159.3 @@ -0,0 +1,396 @@
159.4 +;; FIRST: Do: M-x outline-minor-mode
159.5 +;; SECOND: try M-h too see the index of the file! (outline-minor-mode)
159.6 +; I don't know why it beahaves oddly if you force it w/ -*- line
159.7 +
159.8 +;;;; dir where to load & REMAPPING HELP!!! (C-h is to eat backword!!!)
159.9 +;; we add a dir where lo took for files when loading
159.10 +(setq load-path (cons "~/.emacsdir" load-path))
159.11 +(setq default-major-mode 'text-mode)
159.12 +
159.13 +;;;; Just for emacs21
159.14 +(if (string-equal "21" (substring (emacs-version) 10 12))
159.15 + (progn
159.16 + (blink-cursor-mode 0)
159.17 + ;; Insert newline when you press `C-n' (next-line)
159.18 + ;; at the end of the buffer
159.19 + (setq next-line-add-newlines t)
159.20 + ;; Turn on image viewing
159.21 + (auto-image-file-mode t)
159.22 + ;; Turn on menu bar (this bar has text)
159.23 + ;; (Use numeric argument to turn on)
159.24 + (menu-bar-mode 1)
159.25 + ;; Turn off tool bar (this bar has icons)
159.26 + ;; (Use numeric argument to turn on)
159.27 + (tool-bar-mode nil)
159.28 + ;; Turn off tooltip mode for tool bar
159.29 + ;; (This mode causes icon explanations to pop up)
159.30 + ;; (Use numeric argument to turn on)
159.31 +; (tooltip-mode nil)
159.32 + ;; If tooltips turned on, make tips appear promptly
159.33 + (setq tooltip-delay 0.1) ; default is one second
159.34 + ))
159.35 +
159.36 +
159.37 +; (hscroll-global-mode nil)
159.38 +;;;; hilighting & fill
159.39 +;(server-start nil)
159.40 +;;(load-file "~/.emacs.elc")
159.41 +;; this remaps C-h -> C-xh
159.42 +(global-set-key "\C-xh" 'help-command) ;; overrides mark-whole-buffer
159.43 +(global-unset-key "\C-h" )
159.44 +; non perdere l' ultimo bit dell' input
159.45 +;(set-input-mode nil nil 1)
159.46 +;;;; look & feel: decoration & hiligting
159.47 +;; maximum decoration in hilighting
159.48 + (setq font-lock-maximum-decoration t)
159.49 + (global-font-lock-mode t)
159.50 +; auto-copress will correcly deal w/ tar.gz files (gunzip then tar t)
159.51 + (auto-compression-mode nil)
159.52 +;; autofill si ferma alla colonna 77
159.53 + (setq-default fill-column 76)
159.54 +;;;; Scrolling 1 row at a time
159.55 + (global-set-key "\C-z" (lambda () (interactive) (scroll-up 1)))
159.56 + (global-set-key "\M-z" (lambda () (interactive) (scroll-up -1)))
159.57 + (global-set-key "\C-h" 'delete-backward-char)
159.58 +;; C-u kill backward
159.59 + (global-set-key "\C-cu" [?\C- ?\C-a ?\C-w])
159.60 +;;;; Paren
159.61 + (require 'paren)
159.62 + (show-paren-mode 1)
159.63 +;;;; kill & yank / search & replace
159.64 +;; search & replace
159.65 + (global-set-key "\C-cr" 'query-replace-regexp)
159.66 +;;;; Font-Lock Mode - Add color to text moden
159.67 +; Here I add some colors for text mode (my default)
159.68 + (defvar text-font-lock-keywords
159.69 + (eval-when-compile
159.70 + (list
159.71 + ;;
159.72 + ;; Function name declarations.
159.73 +; '("\\<\\(proc\\|AA\-\\)\\>[ \t]*\\(\\sw+\\)?\\(.*\\)"
159.74 + '("^\\(#.*|\\)[ \t]*\\([A-z(){}._]+\\)?\\(.*\\)"
159.75 + (1 font-lock-comment-face) (2 font-lock-function-name-face nil t)
159.76 + (3 font-lock-keyword-face nil t))
159.77 + '("^\\s-*\\([-]\\S-*\\) +\\(\\sw+\\)" (1 font-lock-warning-face)
159.78 + (2 font-lock-keyword-face nil t))
159.79 + ; bold face for *words*
159.80 + '("\\s-\\(\\*[^*]+\\*\\)\\s-" . font-lock-string-face)
159.81 + ; italic face for _words*
159.82 + '("\\s-\\(\\_[^*]+\\*\\)\\s-" . font-lock-comment-face)
159.83 + ; title row for menu.lst in grub...
159.84 + '("^\\(title \\)\\(.*\\)"
159.85 + (1 font-lock-comment-face) (2 font-lock-function-name-face nil t))
159.86 + ;; NOTE: it is important the order of the lines defining color match
159.87 + ; the next colors a line beginning w/ >% but > is redefined below
159.88 + '("^\\(\\s-*>\\s-*>.*\\|%[^\n]*\\)" . font-lock-type-face)
159.89 + ; the next colors a line beginning w/ >>
159.90 + '("^\\(\\s-*>[^>\n]+\\)" . font-lock-comment-face)
159.91 + '("^\\([.']H +\\w+\\) \\(.+\\)" (1 font-lock-keyword-face)
159.92 + (2 font-lock-function-name-face nil t))
159.93 + ))
159.94 + "Default expressions to highlight in text mode.")
159.95 +
159.96 + (add-hook 'text-mode-hook
159.97 + (function (lambda ()
159.98 + (make-local-variable 'font-lock-defaults)
159.99 + (setq font-lock-defaults
159.100 + '(text-font-lock-keywords nil nil ))
159.101 +; questo pare non servire... (?: . "w") (?_ . "w")
159.102 + ; copiato senza capire gran che' da tcl-mode
159.103 +; (set-syntax-table (copy-syntax-table))
159.104 + (modify-syntax-entry ?# "<")
159.105 +; (modify-syntax-entry ?\n ">")
159.106 + (modify-syntax-entry ?| ">")
159.107 + (modify-syntax-entry ?\n ">")
159.108 +)))
159.109 + (add-hook 'tex-mode-hook
159.110 + (function (lambda ()
159.111 + (make-local-variable 'font-lock-defaults)
159.112 + (setq font-lock-defaults nil)
159.113 +)))
159.114 +
159.115 +
159.116 +;;;; Outline & related bind - use add-hooks for tcl, text, python, sh
159.117 + (set-variable (quote outline-minor-mode-prefix) (quote "\C-ch"))
159.118 + (require 'outline)
159.119 +;; (require 'allout)
159.120 +;; (outline-init t)
159.121 + (require 'foldout)
159.122 +; (outline-minor-mode t)
159.123 +; (require 'out-xtra)
159.124 +; (make-local-variable (quote outline-regexp))
159.125 +; (global-set-key "\C-chi" 'make-indirect-buffer)
159.126 +; (global-set-key "\C-chj" 'show-entry)
159.127 +; (global-set-key "\C-chb" 'show-branches)
159.128 +; (global-set-key "\C-chh" 'hide-sublevels)
159.129 + (global-set-key "\M-h" 'hide-sublevels)
159.130 + (global-set-key "\M-j" 'show-subtree)
159.131 + (global-set-key "\M-k" 'hide-subtree)
159.132 +; (global-set-key "\C-chk" 'hide-leaves)
159.133 +; (global-set-key "\C-ch2" 'make-indirect-buffer)
159.134 +; (global-set-key "\C-cht" 'hide-body)
159.135 +; (global-set-key "\C-cht" 'hide-body)
159.136 + (add-hook 'tcl-mode-hook
159.137 + (function
159.138 + (lambda ()
159.139 + (turn-on-follow-mode)
159.140 + (outline-minor-mode t)
159.141 +; (hscroll-mode t)
159.142 + (make-local-variable (quote outline-regexp))
159.143 + (setq outline-level 'outline-level)
159.144 + (set-variable (quote outline-regexp)
159.145 + (quote "proc\\|####?\\|# - #\\| +###\\| for\\| if ")))))
159.146 + (add-hook 'python-mode-hook
159.147 + (function
159.148 + (lambda ()
159.149 +; (turn-on-follow-mode)
159.150 + (outline-minor-mode t)
159.151 +; (hscroll-mode t)
159.152 + (make-local-variable (quote outline-regexp))
159.153 + (set-variable (quote outline-regexp)
159.154 + (quote " *def ..\\|####?\\|# - #\\|class")))))
159.155 + (add-hook 'text-mode-hook
159.156 + (function
159.157 + (lambda ()
159.158 + (turn-on-follow-mode)
159.159 + (outline-minor-mode t)
159.160 +; (set-variable (quote comment-start) (quote "# "))
159.161 + (set (make-local-variable 'comment-start) "# ")
159.162 + (set (make-local-variable 'comment-start-skip) "# *")
159.163 + (make-local-variable (quote outline-regexp))
159.164 + (set-variable (quote outline-regexp) (quote "\\.H *[0-9]")))))
159.165 + (add-hook 'sh-mode-hook
159.166 + (function
159.167 + (lambda ()
159.168 + (turn-on-follow-mode)
159.169 + (outline-minor-mode t)
159.170 + (setq outline-level 'sh-outline-level)
159.171 + (make-local-variable (quote outline-regexp))
159.172 + (set-variable (quote outline-regexp)
159.173 + (quote "### \\|func\\|.*()")))))
159.174 + (add-hook 'lisp-mode-hook
159.175 + (function
159.176 + (lambda ()
159.177 + (outline-minor-mode t))))
159.178 +; (make-local-variable (quote outline-regexp)))))
159.179 +
159.180 +
159.181 +
159.182 +;;;; functions
159.183 +;; this function forces all pattern of outline-regexp of a function to behave
159.184 +;; the same way, independent of thei length. Use it in cnjunction w/
159.185 +; -*- outline-regexp: "## # \\|.*()" -*-
159.186 +;; and all functions will be part of the "index" toghether w/ all the lines
159.187 +;; that have ## # at the beginning
159.188 +(defun sh-outline-level () 1)
159.189 +
159.190 +;; sst C-cs
159.191 +;; I repeat it twice so that colors get ok... this seem to depend on outline
159.192 +;; mode being requested by the -*- line at beginning!!!
159.193 +(fset 'sd-sost
159.194 + [?\C-a ?\C- ?\M-f escape ?1 escape ?| ?s ?s ?t return])
159.195 +; (fset 'sd-sost
159.196 +; [?\C-a ?\C- ?\M-f escape ?1 escape ?| ?s ?s ?t return])
159.197 + (global-set-key "\C-cs" 'sd-sost)
159.198 +;;;; EDIFF
159.199 + (global-set-key "\C-cer" 'ediff-revision)
159.200 + (global-set-key "\C-cef" 'ediff-files)
159.201 + (global-set-key "\C-ceb" 'ediff-buffers)
159.202 + (global-set-key "\C-cem" 'ediff-merge)
159.203 + (global-set-key "\C-ced" 'ediff-directories)
159.204 + ; the following position the control-frame for ediff 5 pixel lower than default
159.205 + (set-variable (quote ediff-control-frame-upward-shift) -5)
159.206 +;;;; Comment region
159.207 + (global-set-key "\C-cc" 'comment-region)
159.208 + (global-set-key "\C-cU" [escape ?- ?1 ?\C-c ?c])
159.209 + ; (global-set-key "\C-cu" '(comment-region -1))
159.210 +;;;; Text-mode - definig paragraph
159.211 +(add-hook 'text-mode-hook
159.212 + (function
159.213 + (lambda ()
159.214 + (set-variable (quote paragraph-start) "[ ]*$\\|^\\|^[ ]*-"))))
159.215 +
159.216 +;;;; TAGS
159.217 + (global-set-key "\C-ctv" 'visit-tags-table)
159.218 + (global-set-key "\C-ctr" 'tags-reset-tags-tables)
159.219 + (global-set-key "\C-cts" 'tags-search)
159.220 + (global-set-key "\C-ctq" 'tags-query-replace)
159.221 + (global-set-key "\C-cta" 'tags-apropos)
159.222 +;;;; MULE & iso-accent
159.223 +;; Sistemiamo MULE (internazionalizzazione)
159.224 +; (standard-display-european t)
159.225 +; (set-input-mode nil nil 1)
159.226 + (load-library "iso-insert")
159.227 + (load-library "iso-acc")
159.228 + (add-hook 'text-mode-hook 'iso-accents-mode)
159.229 + ; Con la segg istruzione evito che // diventi �
159.230 +; (iso-accents-customize "french")
159.231 +; (iso-accents-customize "spanish")
159.232 + ;; non voglio che "a venga modificato: rinuncio anche alla dieresi: Tant pis
159.233 +(setq iso-accents-enable '(?' ?` ?^ ?~ ))
159.234 +;;;; Ispell (if .emacsdir is there)
159.235 +(if (file-exists-p "~/.emacsdir")
159.236 + (progn
159.237 + (require 'ispell)
159.238 + (load-library "ispell-patch.el")
159.239 + ; (setq ispell-dictionary-alist
159.240 + ; (append ispell-dictionary-alist
159.241 + ; '(("italian"
159.242 + ; "[A-Za-z]"
159.243 + ; "[^A-Za-z]"
159.244 + ; "[---']" t nil "~list" iso-8859-1))))
159.245 +
159.246 + (global-set-key "\C-cir" 'ispell-region)
159.247 + (global-set-key "\C-cib" 'ispell-buffer)
159.248 + (global-set-key "\C-cim" 'ispell-minor-mode)
159.249 + (global-set-key "\C-cid" 'ispell-change-dictionary)
159.250 + (global-set-key "\C-x\C-t" 'write-region)
159.251 + (set-default 'ispell-local-dictionary "italian-ge")))
159.252 +
159.253 +;;;; Misc: comint, repeat, goto...
159.254 + (add-hook 'text-mode-hook 'turn-on-auto-fill)
159.255 + ;; questo in origine e` C-x ESC ESC
159.256 + (global-set-key "\C-cx" 'repeat-complex-command)
159.257 + (global-set-key "\C-c " 'comint-dynamic-complete)
159.258 + (global-set-key "\C-\M-g" 'goto-line)
159.259 + (put 'downcase-region 'disabled nil)
159.260 +
159.261 + (setq auto-mode-alist
159.262 + (cons '("\\.py$" . python-mode) auto-mode-alist))
159.263 + (setq interpreter-mode-alist
159.264 + (cons '("python" . python-mode)
159.265 + interpreter-mode-alist))
159.266 + (autoload 'python-mode "python-mode" "Python editing mode." t)
159.267 + ;; psgml
159.268 + (autoload 'sgml-mode "psgml" "Major mode to edit SGML files." t)
159.269 + (autoload 'xml-mode "psgml" "Major mode to edit XML files." t)
159.270 +
159.271 +
159.272 +;;;; Desktop
159.273 + (load "desktop")
159.274 + (desktop-load-default)
159.275 + ; (desktop-read)
159.276 +;;;; ps-printing
159.277 + (setq ps-print-color-p t)
159.278 + ;; (setq ps-paper-type "a4")
159.279 + (set-variable (quote ps-paper-type) (quote a4))
159.280 + (setq ps-lpr-command "lpr")
159.281 + (setq ps-lpr-switches '("-Pfile"))
159.282 + (setq ps-bold-faces '(times))
159.283 + (setq ps-zebra-stripes t)
159.284 + (setq ps-build-face-reference t)
159.285 + (setq ps-zebra-stripe-height 4)
159.286 + (setq ps-line-number nil)
159.287 + (global-set-key "\C-cpb" 'ps-print-buffer-with-faces)
159.288 + (global-set-key "\C-cpr" 'ps-print-region-with-faces)
159.289 + (global-set-key "\C-cpxd" 'ps-despool)
159.290 + ;(global-set-key '(control f22) 'ps-despool)
159.291 +;;;; Latex & dvi
159.292 + (setq tex-dvi-view-command "tkdvi")
159.293 + ;(setq latex-run-command "lx -q")
159.294 + (setq latex-run-command "latex")
159.295 + ;;(setq tex-directory "./")
159.296 +;;;; custom set faces
159.297 +(custom-set-faces
159.298 + ;; custom-set-faces was added by Custom -- don't edit or cut/paste it!
159.299 + ;; Your init file should contain only one such instance.
159.300 + '(sh-heredoc-face ((((class color) (background light)) (:background "darkseagreen" :foreground "Navy")))))
159.301 +
159.302 +
159.303 +
159.304 +;;;; GNU Server
159.305 +(if (file-exists-p ".emacsdir/gnuserv")
159.306 + (progn
159.307 + (gnuserv-start)
159.308 + (global-set-key "\C-x\C-c" 'gnuserv-edit)))
159.309 +;(require 'preview)
159.310 +;;;; msb-mode - fancy buffer menu
159.311 +(msb-mode)
159.312 +(defconst msb--sd-many-menus
159.313 + '(((and (boundp 'server-buffer-clients)
159.314 + server-buffer-clients
159.315 + 'multi)
159.316 + 1010
159.317 + "Clients (%d)")
159.318 + ((and (boundp 'vc-mode) vc-mode 'multi)
159.319 + 1020
159.320 + "Version Control (%d)")
159.321 + ((and buffer-file-name
159.322 + (buffer-modified-p)
159.323 + 'multi)
159.324 + 1030
159.325 + "Changed files (%d)")
159.326 + ((and (get-buffer-process (current-buffer))
159.327 + 'multi)
159.328 + 1040
159.329 + "Processes (%d)")
159.330 + ((and msb-display-invisible-buffers-p
159.331 + (msb-invisible-buffer-p)
159.332 + 'multi)
159.333 + 1090
159.334 + "Invisible buffers (%d)")
159.335 + ((eq major-mode 'dired-mode)
159.336 + 2010
159.337 + "Dired (%d)"
159.338 + ;; Note this different menu-handler
159.339 + msb-dired-item-handler
159.340 + ;; Also note this item-sorter
159.341 + msb-sort-by-directory)
159.342 + ((eq major-mode 'Man-mode)
159.343 + 5030
159.344 + "Manuals (%d)")
159.345 + ((eq major-mode 'w3-mode)
159.346 + 5020
159.347 + "WWW (%d)")
159.348 + ((or (memq major-mode
159.349 + '(rmail-mode rmail-edit-mode vm-summary-mode vm-mode mail-mode))
159.350 + (memq major-mode '(mh-letter-mode mh-show-mode mh-folder-mode))
159.351 + (memq major-mode '(gnus-summary-mode message-mode gnus-group-mode
159.352 + gnus-article-mode score-mode
159.353 + gnus-browse-killed-mode)))
159.354 + 5010
159.355 + "Mail (%d)")
159.356 + ;; Catchup for all non-file buffers
159.357 + ((and (not buffer-file-name)
159.358 + 'no-multi)
159.359 + 5099
159.360 + "Other non-file buffers (%d)")
159.361 + ((and (string-match "/\\.[^/]*$" buffer-file-name)
159.362 + 'multi)
159.363 + 1080
159.364 + "Hidden Files (%d)")
159.365 + ((eq major-mode 'tcl-mode)
159.366 + 1071
159.367 + "Tcl Files (%d)")
159.368 + ((memq major-mode '(c-mode c++-mode))
159.369 + 3010
159.370 + "C/C++ Files (%d)")
159.371 + ((eq major-mode 'emacs-lisp-mode)
159.372 + 3020
159.373 + "Elisp Files (%d)")
159.374 + ((eq major-mode 'sh-mode)
159.375 + 3021
159.376 + "Shell Files (%d)")
159.377 + ((eq major-mode 'awk-mode)
159.378 + 3022
159.379 + "Awk Files (%d)")
159.380 + ((eq major-mode 'latex-mode)
159.381 + 3030
159.382 + "LaTex Files (%d)")
159.383 + ((eq major-mode 'nroff-mode)
159.384 + 3031
159.385 + "Nroff Files (%d)")
159.386 + ((eq major-mode 'text-mode)
159.387 + 3032
159.388 + "Text Files (%d)")
159.389 + ('no-multi
159.390 + 3099
159.391 + "Other files (%d)")))
159.392 +(custom-set-variables
159.393 + ;; custom-set-variables was added by Custom -- don't edit or cut/paste it!
159.394 + ;; Your init file should contain only one such instance.
159.395 + '(case-fold-search t)
159.396 + '(msb-display-most-recently-used 25)
159.397 + '(msb-max-menu-items 25)
159.398 + '(msb-menu-cond msb--sd-many-menus))
159.399 +(setq inhibit-splash-screen t)
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
160.2 +++ b/lab/srv-isi/root/.hgignore Mon Apr 26 11:16:23 2010 +0200
160.3 @@ -0,0 +1,10 @@
160.4 +syntax:glob
160.5 +*~
160.6 +
160.7 +syntax: regexp
160.8 +.*~
160.9 +\#.*[\#]
160.10 +\.\#.*
160.11 +.*.dpkg-new
160.12 +.*.dpkg-old
160.13 +mtab
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
161.2 +++ b/lab/srv-isi/root/.hgrc Mon Apr 26 11:16:23 2010 +0200
161.3 @@ -0,0 +1,4 @@
161.4 +[ui]
161.5 +username = root
161.6 +ignore.other = ~/.hgignore
161.7 +
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
162.2 +++ b/lab/srv-isi/root/.ipython/ipythonrc Mon Apr 26 11:16:23 2010 +0200
162.3 @@ -0,0 +1,636 @@
162.4 +# -*- Mode: Shell-Script -*- Not really, but shows comments correctly
162.5 +# $Id: ipythonrc 2156 2022-03-19 02:32:19Z fperez $
162.6 +
162.7 +#***************************************************************************
162.8 +#
162.9 +# Configuration file for IPython -- ipythonrc format
162.10 +#
162.11 +# ===========================================================
162.12 +# Deprecation note: you should look into modifying ipy_user_conf.py (located
162.13 +# in ~/.ipython or ~/_ipython, depending on your platform) instead, it's a
162.14 +# more flexible and robust (and better supported!) configuration
162.15 +# method.
162.16 +# ===========================================================
162.17 +#
162.18 +# The format of this file is simply one of 'key value' lines.
162.19 +# Lines containing only whitespace at the beginning and then a # are ignored
162.20 +# as comments. But comments can NOT be put on lines with data.
162.21 +
162.22 +# The meaning and use of each key are explained below.
162.23 +
162.24 +#---------------------------------------------------------------------------
162.25 +# Section: included files
162.26 +
162.27 +# Put one or more *config* files (with the syntax of this file) you want to
162.28 +# include. For keys with a unique value the outermost file has precedence. For
162.29 +# keys with multiple values, they all get assembled into a list which then
162.30 +# gets loaded by IPython.
162.31 +
162.32 +# In this file, all lists of things should simply be space-separated.
162.33 +
162.34 +# This allows you to build hierarchies of files which recursively load
162.35 +# lower-level services. If this is your main ~/.ipython/ipythonrc file, you
162.36 +# should only keep here basic things you always want available. Then you can
162.37 +# include it in every other special-purpose config file you create.
162.38 +include
162.39 +
162.40 +#---------------------------------------------------------------------------
162.41 +# Section: startup setup
162.42 +
162.43 +# These are mostly things which parallel a command line option of the same
162.44 +# name.
162.45 +
162.46 +# Keys in this section should only appear once. If any key from this section
162.47 +# is encountered more than once, the last value remains, all earlier ones get
162.48 +# discarded.
162.49 +
162.50 +
162.51 +# Automatic calling of callable objects. If set to 1 or 2, callable objects
162.52 +# are automatically called when invoked at the command line, even if you don't
162.53 +# type parentheses. IPython adds the parentheses for you. For example:
162.54 +
162.55 +#In [1]: str 45
162.56 +#------> str(45)
162.57 +#Out[1]: '45'
162.58 +
162.59 +# IPython reprints your line with '---->' indicating that it added
162.60 +# parentheses. While this option is very convenient for interactive use, it
162.61 +# may occasionally cause problems with objects which have side-effects if
162.62 +# called unexpectedly.
162.63 +
162.64 +# The valid values for autocall are:
162.65 +
162.66 +# autocall 0 -> disabled (you can toggle it at runtime with the %autocall magic)
162.67 +
162.68 +# autocall 1 -> active, but do not apply if there are no arguments on the line.
162.69 +
162.70 +# In this mode, you get:
162.71 +
162.72 +#In [1]: callable
162.73 +#Out[1]: <built-in function callable>
162.74 +
162.75 +#In [2]: callable 'hello'
162.76 +#------> callable('hello')
162.77 +#Out[2]: False
162.78 +
162.79 +# 2 -> Active always. Even if no arguments are present, the callable object
162.80 +# is called:
162.81 +
162.82 +#In [4]: callable
162.83 +#------> callable()
162.84 +
162.85 +# Note that even with autocall off, you can still use '/' at the start of a
162.86 +# line to treat the first argument on the command line as a function and add
162.87 +# parentheses to it:
162.88 +
162.89 +#In [8]: /str 43
162.90 +#------> str(43)
162.91 +#Out[8]: '43'
162.92 +
162.93 +autocall 1
162.94 +
162.95 +# Auto-edit syntax errors. When you use the %edit magic in ipython to edit
162.96 +# source code (see the 'editor' variable below), it is possible that you save
162.97 +# a file with syntax errors in it. If this variable is true, IPython will ask
162.98 +# you whether to re-open the editor immediately to correct such an error.
162.99 +
162.100 +autoedit_syntax 0
162.101 +
162.102 +# Auto-indent. IPython can recognize lines ending in ':' and indent the next
162.103 +# line, while also un-indenting automatically after 'raise' or 'return'.
162.104 +
162.105 +# This feature uses the readline library, so it will honor your ~/.inputrc
162.106 +# configuration (or whatever file your INPUTRC variable points to). Adding
162.107 +# the following lines to your .inputrc file can make indent/unindenting more
162.108 +# convenient (M-i indents, M-u unindents):
162.109 +
162.110 +# $if Python
162.111 +# "\M-i": " "
162.112 +# "\M-u": "\d\d\d\d"
162.113 +# $endif
162.114 +
162.115 +# The feature is potentially a bit dangerous, because it can cause problems
162.116 +# with pasting of indented code (the pasted code gets re-indented on each
162.117 +# line). But it's a huge time-saver when working interactively. The magic
162.118 +# function %autoindent allows you to toggle it on/off at runtime.
162.119 +
162.120 +autoindent 1
162.121 +
162.122 +# Auto-magic. This gives you access to all the magic functions without having
162.123 +# to prepend them with an % sign. If you define a variable with the same name
162.124 +# as a magic function (say who=1), you will need to access the magic function
162.125 +# with % (%who in this example). However, if later you delete your variable
162.126 +# (del who), you'll recover the automagic calling form.
162.127 +
162.128 +# Considering that many magic functions provide a lot of shell-like
162.129 +# functionality, automagic gives you something close to a full Python+system
162.130 +# shell environment (and you can extend it further if you want).
162.131 +
162.132 +automagic 1
162.133 +
162.134 +# Size of the output cache. After this many entries are stored, the cache will
162.135 +# get flushed. Depending on the size of your intermediate calculations, you
162.136 +# may have memory problems if you make it too big, since keeping things in the
162.137 +# cache prevents Python from reclaiming the memory for old results. Experiment
162.138 +# with a value that works well for you.
162.139 +
162.140 +# If you choose cache_size 0 IPython will revert to python's regular >>>
162.141 +# unnumbered prompt. You will still have _, __ and ___ for your last three
162.142 +# results, but that will be it. No dynamic _1, _2, etc. will be created. If
162.143 +# you are running on a slow machine or with very limited memory, this may
162.144 +# help.
162.145 +
162.146 +cache_size 1000
162.147 +
162.148 +# Classic mode: Setting 'classic 1' you lose many of IPython niceties,
162.149 +# but that's your choice! Classic 1 -> same as IPython -classic.
162.150 +# Note that this is _not_ the normal python interpreter, it's simply
162.151 +# IPython emulating most of the classic interpreter's behavior.
162.152 +classic 0
162.153 +
162.154 +# colors - Coloring option for prompts and traceback printouts.
162.155 +
162.156 +# Currently available schemes: NoColor, Linux, LightBG.
162.157 +
162.158 +# This option allows coloring the prompts and traceback printouts. This
162.159 +# requires a terminal which can properly handle color escape sequences. If you
162.160 +# are having problems with this, use the NoColor scheme (uses no color escapes
162.161 +# at all).
162.162 +
162.163 +# The Linux option works well in linux console type environments: dark
162.164 +# background with light fonts.
162.165 +
162.166 +# LightBG is similar to Linux but swaps dark/light colors to be more readable
162.167 +# in light background terminals.
162.168 +
162.169 +# keep uncommented only the one you want:
162.170 +#colors Linux
162.171 +colors LightBG
162.172 +#colors NoColor
162.173 +
162.174 +########################
162.175 +# Note to Windows users
162.176 +#
162.177 +# Color and readline support is avaialble to Windows users via Gary Bishop's
162.178 +# readline library. You can find Gary's tools at
162.179 +# http://sourceforge.net/projects/uncpythontools.
162.180 +# Note that his readline module requires in turn the ctypes library, available
162.181 +# at http://starship.python.net/crew/theller/ctypes.
162.182 +########################
162.183 +
162.184 +# color_info: IPython can display information about objects via a set of
162.185 +# functions, and optionally can use colors for this, syntax highlighting
162.186 +# source code and various other elements. This information is passed through a
162.187 +# pager (it defaults to 'less' if $PAGER is not set).
162.188 +
162.189 +# If your pager has problems, try to setting it to properly handle escapes
162.190 +# (see the less manpage for detail), or disable this option. The magic
162.191 +# function %color_info allows you to toggle this interactively for testing.
162.192 +
162.193 +color_info 1
162.194 +
162.195 +# confirm_exit: set to 1 if you want IPython to confirm when you try to exit
162.196 +# with an EOF (Control-d in Unix, Control-Z/Enter in Windows). Note that using
162.197 +# the magic functions %Exit or %Quit you can force a direct exit, bypassing
162.198 +# any confirmation.
162.199 +
162.200 +confirm_exit 0
162.201 +
162.202 +# Use deep_reload() as a substitute for reload() by default. deep_reload() is
162.203 +# still available as dreload() and appears as a builtin.
162.204 +
162.205 +deep_reload 0
162.206 +
162.207 +# Which editor to use with the %edit command. If you leave this at 0, IPython
162.208 +# will honor your EDITOR environment variable. Since this editor is invoked on
162.209 +# the fly by ipython and is meant for editing small code snippets, you may
162.210 +# want to use a small, lightweight editor here.
162.211 +
162.212 +# For Emacs users, setting up your Emacs server properly as described in the
162.213 +# manual is a good idea. An alternative is to use jed, a very light editor
162.214 +# with much of the feel of Emacs (though not as powerful for heavy-duty work).
162.215 +
162.216 +editor 0
162.217 +
162.218 +# log 1 -> same as ipython -log. This automatically logs to ./ipython.log
162.219 +log 0
162.220 +
162.221 +# Same as ipython -Logfile YourLogfileName.
162.222 +# Don't use with log 1 (use one or the other)
162.223 +logfile ''
162.224 +
162.225 +# banner 0 -> same as ipython -nobanner
162.226 +banner 0
162.227 +
162.228 +# messages 0 -> same as ipython -nomessages
162.229 +messages 1
162.230 +
162.231 +# Automatically call the pdb debugger after every uncaught exception. If you
162.232 +# are used to debugging using pdb, this puts you automatically inside of it
162.233 +# after any call (either in IPython or in code called by it) which triggers an
162.234 +# exception which goes uncaught.
162.235 +pdb 1
162.236 +
162.237 +# Enable the pprint module for printing. pprint tends to give a more readable
162.238 +# display (than print) for complex nested data structures.
162.239 +pprint 1
162.240 +
162.241 +# Prompt strings
162.242 +
162.243 +# Most bash-like escapes can be used to customize IPython's prompts, as well as
162.244 +# a few additional ones which are IPython-specific. All valid prompt escapes
162.245 +# are described in detail in the Customization section of the IPython HTML/PDF
162.246 +# manual.
162.247 +
162.248 +# Use \# to represent the current prompt number, and quote them to protect
162.249 +# spaces.
162.250 +prompt_in1 'In [\#]: '
162.251 +
162.252 +# \D is replaced by as many dots as there are digits in the
162.253 +# current value of \#.
162.254 +prompt_in2 ' .\D.: '
162.255 +
162.256 +prompt_out 'Out[\#]: '
162.257 +
162.258 +# Select whether to left-pad the output prompts to match the length of the
162.259 +# input ones. This allows you for example to use a simple '>' as an output
162.260 +# prompt, and yet have the output line up with the input. If set to false,
162.261 +# the output prompts will be unpadded (flush left).
162.262 +prompts_pad_left 1
162.263 +
162.264 +# Pylab support: when ipython is started with the -pylab switch, by default it
162.265 +# executes 'from matplotlib.pylab import *'. Set this variable to false if you
162.266 +# want to disable this behavior.
162.267 +
162.268 +# For details on pylab, see the matplotlib website:
162.269 +# http://matplotlib.sf.net
162.270 +pylab_import_all 1
162.271 +
162.272 +
162.273 +# quick 1 -> same as ipython -quick
162.274 +quick 0
162.275 +
162.276 +# Use the readline library (1) or not (0). Most users will want this on, but
162.277 +# if you experience strange problems with line management (mainly when using
162.278 +# IPython inside Emacs buffers) you may try disabling it. Not having it on
162.279 +# prevents you from getting command history with the arrow keys, searching and
162.280 +# name completion using TAB.
162.281 +
162.282 +readline 1
162.283 +
162.284 +# Screen Length: number of lines of your screen. This is used to control
162.285 +# printing of very long strings. Strings longer than this number of lines will
162.286 +# be paged with the less command instead of directly printed.
162.287 +
162.288 +# The default value for this is 0, which means IPython will auto-detect your
162.289 +# screen size every time it needs to print. If for some reason this isn't
162.290 +# working well (it needs curses support), specify it yourself. Otherwise don't
162.291 +# change the default.
162.292 +
162.293 +screen_length 0
162.294 +
162.295 +# Prompt separators for input and output.
162.296 +# Use \n for newline explicitly, without quotes.
162.297 +# Use 0 (like at the cmd line) to turn off a given separator.
162.298 +
162.299 +# The structure of prompt printing is:
162.300 +# (SeparateIn)Input....
162.301 +# (SeparateOut)Output...
162.302 +# (SeparateOut2), # that is, no newline is printed after Out2
162.303 +# By choosing these you can organize your output any way you want.
162.304 +
162.305 +separate_in \n
162.306 +separate_out 0
162.307 +separate_out2 0
162.308 +
162.309 +# 'nosep 1' is a shorthand for '-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'.
162.310 +# Simply removes all input/output separators, overriding the choices above.
162.311 +nosep 0
162.312 +
162.313 +# Wildcard searches - IPython has a system for searching names using
162.314 +# shell-like wildcards; type %psearch? for details. This variables sets
162.315 +# whether by default such searches should be case sensitive or not. You can
162.316 +# always override the default at the system command line or the IPython
162.317 +# prompt.
162.318 +
162.319 +wildcards_case_sensitive 1
162.320 +
162.321 +# Object information: at what level of detail to display the string form of an
162.322 +# object. If set to 0, ipython will compute the string form of any object X,
162.323 +# by calling str(X), when X? is typed. If set to 1, str(X) will only be
162.324 +# computed when X?? is given, and if set to 2 or higher, it will never be
162.325 +# computed (there is no X??? level of detail). This is mostly of use to
162.326 +# people who frequently manipulate objects whose string representation is
162.327 +# extremely expensive to compute.
162.328 +
162.329 +object_info_string_level 0
162.330 +
162.331 +# xmode - Exception reporting mode.
162.332 +
162.333 +# Valid modes: Plain, Context and Verbose.
162.334 +
162.335 +# Plain: similar to python's normal traceback printing.
162.336 +
162.337 +# Context: prints 5 lines of context source code around each line in the
162.338 +# traceback.
162.339 +
162.340 +# Verbose: similar to Context, but additionally prints the variables currently
162.341 +# visible where the exception happened (shortening their strings if too
162.342 +# long). This can potentially be very slow, if you happen to have a huge data
162.343 +# structure whose string representation is complex to compute. Your computer
162.344 +# may appear to freeze for a while with cpu usage at 100%. If this occurs, you
162.345 +# can cancel the traceback with Ctrl-C (maybe hitting it more than once).
162.346 +
162.347 +#xmode Plain
162.348 +xmode Context
162.349 +#xmode Verbose
162.350 +
162.351 +# multi_line_specials: if true, allow magics, aliases and shell escapes (via
162.352 +# !cmd) to be used in multi-line input (like for loops). For example, if you
162.353 +# have this active, the following is valid in IPython:
162.354 +#
162.355 +#In [17]: for i in range(3):
162.356 +# ....: mkdir $i
162.357 +# ....: !touch $i/hello
162.358 +# ....: ls -l $i
162.359 +
162.360 +multi_line_specials 1
162.361 +
162.362 +
162.363 +# System calls: When IPython makes system calls (e.g. via special syntax like
162.364 +# !cmd or !!cmd, or magics like %sc or %sx), it can print the command it is
162.365 +# executing to standard output, prefixed by a header string.
162.366 +
162.367 +system_header "IPython system call: "
162.368 +
162.369 +system_verbose 1
162.370 +
162.371 +# wxversion: request a specific wxPython version (used for -wthread)
162.372 +
162.373 +# Set this to the value of wxPython you want to use, but note that this
162.374 +# feature requires you to have the wxversion Python module to work. If you
162.375 +# don't have the wxversion module (try 'import wxversion' at the prompt to
162.376 +# check) or simply want to leave the system to pick up the default, leave this
162.377 +# variable at 0.
162.378 +
162.379 +wxversion 0
162.380 +
162.381 +#---------------------------------------------------------------------------
162.382 +# Section: Readline configuration (readline is not available for MS-Windows)
162.383 +
162.384 +# This is done via the following options:
162.385 +
162.386 +# (i) readline_parse_and_bind: this option can appear as many times as you
162.387 +# want, each time defining a string to be executed via a
162.388 +# readline.parse_and_bind() command. The syntax for valid commands of this
162.389 +# kind can be found by reading the documentation for the GNU readline library,
162.390 +# as these commands are of the kind which readline accepts in its
162.391 +# configuration file.
162.392 +
162.393 +# The TAB key can be used to complete names at the command line in one of two
162.394 +# ways: 'complete' and 'menu-complete'. The difference is that 'complete' only
162.395 +# completes as much as possible while 'menu-complete' cycles through all
162.396 +# possible completions. Leave the one you prefer uncommented.
162.397 +
162.398 +readline_parse_and_bind tab: complete
162.399 +#readline_parse_and_bind tab: menu-complete
162.400 +
162.401 +# This binds Control-l to printing the list of all possible completions when
162.402 +# there is more than one (what 'complete' does when hitting TAB twice, or at
162.403 +# the first TAB if show-all-if-ambiguous is on)
162.404 +readline_parse_and_bind "\C-l": possible-completions
162.405 +
162.406 +# This forces readline to automatically print the above list when tab
162.407 +# completion is set to 'complete'. You can still get this list manually by
162.408 +# using the key bound to 'possible-completions' (Control-l by default) or by
162.409 +# hitting TAB twice. Turning this on makes the printing happen at the first
162.410 +# TAB.
162.411 +readline_parse_and_bind set show-all-if-ambiguous on
162.412 +
162.413 +# If you have TAB set to complete names, you can rebind any key (Control-o by
162.414 +# default) to insert a true TAB character.
162.415 +
162.416 +
162.417 +#readline_parse_and_bind "\C-o": tab-insert
162.418 +readline_parse_and_bind "\C-o": operate-and-get-next
162.419 +
162.420 +
162.421 +# These commands allow you to indent/unindent easily, with the 4-space
162.422 +# convention of the Python coding standards. Since IPython's internal
162.423 +# auto-indent system also uses 4 spaces, you should not change the number of
162.424 +# spaces in the code below.
162.425 +readline_parse_and_bind "\M-i": " "
162.426 +readline_parse_and_bind "\M-o": "\d\d\d\d"
162.427 +readline_parse_and_bind "\M-I": "\d\d\d\d"
162.428 +
162.429 +# Bindings for incremental searches in the history. These searches use the
162.430 +# string typed so far on the command line and search anything in the previous
162.431 +# input history containing them.
162.432 +readline_parse_and_bind "\C-r": reverse-search-history
162.433 +readline_parse_and_bind "\C-s": forward-search-history
162.434 +
162.435 +# Bindings for completing the current line in the history of previous
162.436 +# commands. This allows you to recall any previous command by typing its first
162.437 +# few letters and hitting Control-p, bypassing all intermediate commands which
162.438 +# may be in the history (much faster than hitting up-arrow 50 times!)
162.439 +readline_parse_and_bind "\C-p": history-search-backward
162.440 +readline_parse_and_bind "\C-n": history-search-forward
162.441 +
162.442 +# I also like to have the same functionality on the plain arrow keys. If you'd
162.443 +# rather have the arrows use all the history (and not just match what you've
162.444 +# typed so far), comment out or delete the next two lines.
162.445 +readline_parse_and_bind "\e[A": history-search-backward
162.446 +readline_parse_and_bind "\e[B": history-search-forward
162.447 +
162.448 +# These are typically on by default under *nix, but not win32.
162.449 +readline_parse_and_bind "\C-k": kill-line
162.450 +readline_parse_and_bind "\C-u": unix-line-discard
162.451 +
162.452 +# (ii) readline_remove_delims: a string of characters to be removed from the
162.453 +# default word-delimiters list used by readline, so that completions may be
162.454 +# performed on strings which contain them.
162.455 +
162.456 +readline_remove_delims -/~
162.457 +
162.458 +# (iii) readline_merge_completions: whether to merge the result of all
162.459 +# possible completions or not. If true, IPython will complete filenames,
162.460 +# python names and aliases and return all possible completions. If you set it
162.461 +# to false, each completer is used at a time, and only if it doesn't return
162.462 +# any completions is the next one used.
162.463 +
162.464 +# The default order is: [python_matches, file_matches, alias_matches]
162.465 +
162.466 +readline_merge_completions 1
162.467 +
162.468 +# (iv) readline_omit__names: normally hitting <tab> after a '.' in a name
162.469 +# will complete all attributes of an object, including all the special methods
162.470 +# whose names start with single or double underscores (like __getitem__ or
162.471 +# __class__).
162.472 +
162.473 +# This variable allows you to control this completion behavior:
162.474 +
162.475 +# readline_omit__names 1 -> completion will omit showing any names starting
162.476 +# with two __, but it will still show names starting with one _.
162.477 +
162.478 +# readline_omit__names 2 -> completion will omit all names beginning with one
162.479 +# _ (which obviously means filtering out the double __ ones).
162.480 +
162.481 +# Even when this option is set, you can still see those names by explicitly
162.482 +# typing a _ after the period and hitting <tab>: 'name._<tab>' will always
162.483 +# complete attribute names starting with '_'.
162.484 +
162.485 +# This option is off by default so that new users see all attributes of any
162.486 +# objects they are dealing with.
162.487 +
162.488 +readline_omit__names 0
162.489 +
162.490 +#---------------------------------------------------------------------------
162.491 +# Section: modules to be loaded with 'import ...'
162.492 +
162.493 +# List, separated by spaces, the names of the modules you want to import
162.494 +
162.495 +# Example:
162.496 +# import_mod sys os
162.497 +# will produce internally the statements
162.498 +# import sys
162.499 +# import os
162.500 +
162.501 +# Each import is executed in its own try/except block, so if one module
162.502 +# fails to load the others will still be ok.
162.503 +
162.504 +import_mod
162.505 +
162.506 +#---------------------------------------------------------------------------
162.507 +# Section: modules to import some functions from: 'from ... import ...'
162.508 +
162.509 +# List, one per line, the modules for which you want only to import some
162.510 +# functions. Give the module name first and then the name of functions to be
162.511 +# imported from that module.
162.512 +
162.513 +# Example:
162.514 +
162.515 +# import_some IPython.genutils timing timings
162.516 +# will produce internally the statement
162.517 +# from IPython.genutils import timing, timings
162.518 +
162.519 +# timing() and timings() are two IPython utilities for timing the execution of
162.520 +# your own functions, which you may find useful. Just commment out the above
162.521 +# line if you want to test them.
162.522 +
162.523 +# If you have more than one modules_some line, each gets its own try/except
162.524 +# block (like modules, see above).
162.525 +
162.526 +import_some
162.527 +
162.528 +#---------------------------------------------------------------------------
162.529 +# Section: modules to import all from : 'from ... import *'
162.530 +
162.531 +# List (same syntax as import_mod above) those modules for which you want to
162.532 +# import all functions. Remember, this is a potentially dangerous thing to do,
162.533 +# since it is very easy to overwrite names of things you need. Use with
162.534 +# caution.
162.535 +
162.536 +# Example:
162.537 +# import_all sys os
162.538 +# will produce internally the statements
162.539 +# from sys import *
162.540 +# from os import *
162.541 +
162.542 +# As before, each will be called in a separate try/except block.
162.543 +
162.544 +import_all
162.545 +
162.546 +#---------------------------------------------------------------------------
162.547 +# Section: Python code to execute.
162.548 +
162.549 +# Put here code to be explicitly executed (keep it simple!)
162.550 +# Put one line of python code per line. All whitespace is removed (this is a
162.551 +# feature, not a bug), so don't get fancy building loops here.
162.552 +# This is just for quick convenient creation of things you want available.
162.553 +
162.554 +# Example:
162.555 +# execute x = 1
162.556 +# execute print 'hello world'; y = z = 'a'
162.557 +# will produce internally
162.558 +# x = 1
162.559 +# print 'hello world'; y = z = 'a'
162.560 +# and each *line* (not each statement, we don't do python syntax parsing) is
162.561 +# executed in its own try/except block.
162.562 +
162.563 +execute
162.564 +
162.565 +# Note for the adventurous: you can use this to define your own names for the
162.566 +# magic functions, by playing some namespace tricks:
162.567 +
162.568 +# execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
162.569 +
162.570 +# defines %pf as a new name for %profile.
162.571 +
162.572 +#---------------------------------------------------------------------------
162.573 +# Section: Pyhton files to load and execute.
162.574 +
162.575 +# Put here the full names of files you want executed with execfile(file). If
162.576 +# you want complicated initialization, just write whatever you want in a
162.577 +# regular python file and load it from here.
162.578 +
162.579 +# Filenames defined here (which *must* include the extension) are searched for
162.580 +# through all of sys.path. Since IPython adds your .ipython directory to
162.581 +# sys.path, they can also be placed in your .ipython dir and will be
162.582 +# found. Otherwise (if you want to execute things not in .ipyton nor in
162.583 +# sys.path) give a full path (you can use ~, it gets expanded)
162.584 +
162.585 +# Example:
162.586 +# execfile file1.py ~/file2.py
162.587 +# will generate
162.588 +# execfile('file1.py')
162.589 +# execfile('_path_to_your_home/file2.py')
162.590 +
162.591 +# As before, each file gets its own try/except block.
162.592 +
162.593 +execfile
162.594 +
162.595 +# If you are feeling adventurous, you can even add functionality to IPython
162.596 +# through here. IPython works through a global variable called __ip which
162.597 +# exists at the time when these files are read. If you know what you are doing
162.598 +# (read the source) you can add functions to __ip in files loaded here.
162.599 +
162.600 +# The file example-magic.py contains a simple but correct example. Try it:
162.601 +
162.602 +# execfile example-magic.py
162.603 +
162.604 +# Look at the examples in IPython/iplib.py for more details on how these magic
162.605 +# functions need to process their arguments.
162.606 +
162.607 +#---------------------------------------------------------------------------
162.608 +# Section: aliases for system shell commands
162.609 +
162.610 +# Here you can define your own names for system commands. The syntax is
162.611 +# similar to that of the builtin %alias function:
162.612 +
162.613 +# alias alias_name command_string
162.614 +
162.615 +# The resulting aliases are auto-generated magic functions (hence usable as
162.616 +# %alias_name)
162.617 +
162.618 +# For example:
162.619 +
162.620 +# alias myls ls -la
162.621 +
162.622 +# will define 'myls' as an alias for executing the system command 'ls -la'.
162.623 +# This allows you to customize IPython's environment to have the same aliases
162.624 +# you are accustomed to from your own shell.
162.625 +
162.626 +# You can also define aliases with parameters using %s specifiers (one per
162.627 +# parameter):
162.628 +
162.629 +# alias parts echo first %s second %s
162.630 +
162.631 +# will give you in IPython:
162.632 +# >>> %parts A B
162.633 +# first A second B
162.634 +
162.635 +# Use one 'alias' statement per alias you wish to define.
162.636 +
162.637 +# alias
162.638 +
162.639 +#************************* end of file <ipythonrc> ************************
163.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
163.2 +++ b/lab/srv-isi/root/.joe_state Mon Apr 26 11:16:23 2010 +0200
163.3 @@ -0,0 +1,59 @@
163.4 +# JOE state file v1.0
163.5 +search
163.6 + pattern "help"
163.7 + backwards 0
163.8 + ignore 1
163.9 + replace 0
163.10 + block_restrict 0
163.11 +done
163.12 +macros
163.13 +done
163.14 +files
163.15 + "/etc/inittab\n"
163.16 + "/etc/apt/sources.list\n"
163.17 + "/etc/apt/sources.list\n"
163.18 + "/etc/bash.bashrc\n"
163.19 + "/etc/apt/sources.list\n"
163.20 + "/etc/apt/sources.list\n"
163.21 + "/usr/sbin/isi-setup\n"
163.22 + "/etc/cron.d/hgetc\n"
163.23 + "/etc/etckeeper/etckeeper.conf\n"
163.24 + "/etc/cron.d/hgetc\n"
163.25 +done
163.26 +find
163.27 +done
163.28 +replace
163.29 +done
163.30 +run
163.31 +done
163.32 +build
163.33 +done
163.34 +grep
163.35 +done
163.36 +cmd
163.37 +done
163.38 +math
163.39 +done
163.40 +yank
163.41 + "\n"
163.42 + "\n1:2345:respawn:/sbin/getty 38400 tty1\n2:23:respawn:/sbin/getty 38400 tty2\n"
163.43 + "deb http://ftp.it.debian.org/debian/ lenny main non-free"
163.44 + "it."
163.45 + "deb http://ftp.it.debian.org/debian/ lenny main"
163.46 + "5C"
163.47 + ".it"
163.48 + "#deb http://ftp.it.debian.org/debian/ lenny main\n"
163.49 + "#deb http://ftp.it.debian.org/debian/ lenny main non-free\n"
163.50 + " http://www.backports.org/debian/pool/main/p/python-django/python-django_1.1.1-1~bpo50+1_all.deb"
163.51 + "# "
163.52 + "#"
163.53 +done
163.54 +file_pos
163.55 + 42 "/etc/inittab"
163.56 + 48 "/etc/bash.bashrc"
163.57 + 9 "/etc/apt/sources.list"
163.58 + 1199 "/usr/sbin/isi-setup"
163.59 + 1 "/etc/etckeeper/etckeeper.conf"
163.60 + 0 "* Startup Log *"
163.61 + 2 "/etc/cron.d/hgetc"
163.62 +done
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164.2 +++ b/lab/srv-isi/root/.lessfilter Mon Apr 26 11:16:23 2010 +0200
164.3 @@ -0,0 +1,33 @@
164.4 +#!/bin/sh
164.5 +
164.6 +file=$1
164.7 +if [ $(expr match $file '/') = 0 ] ; then
164.8 + # il file $file NON ha path completo
164.9 + file=$(pwd)/$file
164.10 +fi
164.11 +
164.12 +if [ $(expr match $file '/etc\|.*.conf') -gt 3 ] ; then
164.13 + # $file � un file di configurazione
164.14 + COLOR=1
164.15 +fi
164.16 +
164.17 +if [ ! `file $file|egrep 'shell script|\.php|\.awk' > /dev/null` ] ; then
164.18 + COLOR=1
164.19 +fi
164.20 +
164.21 +case "$COLOR" in
164.22 + 1)
164.23 + awk ' {
164.24 + gsub(/#.*/,"\033[31m&\033[0m",$0);
164.25 + print
164.26 + }' $1
164.27 +
164.28 + ;;
164.29 + *)
164.30 + # We don't handle this format.
164.31 + exit 1
164.32 +esac
164.33 +
164.34 + # No further processing by lesspipe necessary
164.35 +exit 0
164.36 +
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
165.2 +++ b/lab/srv-isi/root/.profile Mon Apr 26 11:16:23 2010 +0200
165.3 @@ -0,0 +1,9 @@
165.4 +# ~/.profile: executed by Bourne-compatible login shells.
165.5 +
165.6 +if [ "$BASH" ]; then
165.7 + if [ -f ~/.bashrc ]; then
165.8 + . ~/.bashrc
165.9 + fi
165.10 +fi
165.11 +
165.12 +mesg n
166.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166.2 +++ b/lab/srv-isi/root/.ssh/authorized_keys Mon Apr 26 11:16:23 2010 +0200
166.3 @@ -0,0 +1,1 @@
166.4 +ssh-dss AAAAB3NzaC1kc3MAAACBAPgNz70XAMBhdfcw6AOfjJIDB5hLt03dS3VN/BZYHKzVJq7c4FxRy+PeqOSXQjAxIp467Dt3eb4i7SqJ0W4AwjGpg6A35nKPgbLda+SEruv0ticeVYbYxkwbcBA1Vu07qN/pof8J6iJ6sUerPhRN2FP8I+zP8h4UcaOcfk/tiv/LAAAAFQCBiVzZiRBeaJNSv1cklANPKOdY3QAAAIAyGZjA5Nnr2jdTdeoadq2DRGhaIgIx00qxpFwc9oC9xSuwHGjsahaKfPsYdX4lcMHl5Jf3Di6255PN2/xsYuR2qaB4S5gxjkMhkB7GDQdKACXsSGyEKzPlKbMUl/qm3kRq1yQcHQlfQohj7LkpEX99YI7hrL5LAihCo+9Na3un0gAAAIBHy0XcUQkYFNWP7EhaBcgdOM7hYXmr8hWXSX6vVtcbHHRrwZfcb+V/zfKo0F5aYsOU8OczKru+/4mBa7TYv3pO9UMiTr6DpJjiKYfYY2rkCPStvaTzr1JBtXfG1Bu8VaghS2T5llR0ro/Pp/niSj0N/CoAytuYQrm8+9fZgOBkoQ== [email protected]
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167.2 +++ b/lab/srv-isi/var/lib/misc/leases Mon Apr 26 11:16:23 2010 +0200
167.3 @@ -0,0 +1,54 @@
167.4 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.5 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.6 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.7 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.8 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.9 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.10 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.11 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.12 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.13 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.14 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.15 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.16 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.17 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.18 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.19 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.20 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.21 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.22 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.23 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.24 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.25 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.26 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.27 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.28 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.29 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.30 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.31 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.32 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.33 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.34 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.35 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.36 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.37 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.38 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.39 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.40 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.41 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.42 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.43 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.44 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.45 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.46 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.47 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.48 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.49 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.50 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.51 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
167.52 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
167.53 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
167.54 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
167.55 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
167.56 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
167.57 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
168.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
168.2 +++ b/lib/isi/__init__.py Mon Apr 26 11:16:23 2010 +0200
168.3 @@ -0,0 +1,5 @@
168.4 +from srv import Manager, IsiConn, get_main_groups, get_logger
168.5 +from conf import defaults
168.6 +import conf
168.7 +import models
168.8 +import exc
169.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
169.2 +++ b/lib/isi/bulk_users.py Mon Apr 26 11:16:23 2010 +0200
169.3 @@ -0,0 +1,450 @@
169.4 +# coding: utf-8
169.5 +
169.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
169.7 +#
169.8 +# This program is free software: you can redistribute it and/or modify
169.9 +# it under the terms of the GNU General Public License as published by
169.10 +# the Free Software Foundation, either version 3 of the License, or
169.11 +# (at your option) any later version.
169.12 +#
169.13 +# This program is distributed in the hope that it will be useful,
169.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
169.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
169.16 +# GNU General Public License for more details.
169.17 +#
169.18 +# You should have received a copy of the GNU General Public License
169.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
169.20 +
169.21 +
169.22 +"""
169.23 +class Users that handles Users in bulk and can generate a .isi format list
169.24 +
169.25 +"""
169.26 +import os
169.27 +import re
169.28 +import srv
169.29 +from isi import models, exc
169.30 +from isi.conf import defaults, tools
169.31 +from parser import new_password
169.32 +
169.33 +class BulkUsers(object):
169.34 + """
169.35 + A set of users that must be added to the system.
169.36 + """
169.37 + user_format = None
169.38 + def __init__(self, maingroup, user_format=None, random_password=False):
169.39 + """
169.40 + :param maingroup: the maingroup for which we are inserting users
169.41 + :param user_format: the user format we want. Mainformat must be in the format of
169.42 + template strings %(attr_name)s, but 3 other formats are recognized:
169.43 + 'cf', and 'name', 'id-name'
169.44 + If user-format is not passed it's taken from defaults.py (cf for students and name for others)
169.45 + """
169.46 +
169.47 + self.random_password = random_password
169.48 + self.l = srv.Manager()
169.49 + self.maingroup = maingroup
169.50 + self.gid = self.l.get_group(maingroup).gid
169.51 + self.users = self.l.pumpkin_conn.search(models.PosixUser)
169.52 + self.user_list = [u.logname for u in self.users]
169.53 + self.cf_dict = {}
169.54 + self.users_dict = {}
169.55 + for u in self.users:
169.56 + self.cf_dict[u.cf] = u
169.57 + self.users_dict[u.logname] = u
169.58 + self.file_users = []
169.59 + self.file_users_dict = {}
169.60 + self.renamed = []
169.61 + self.used_lognames = []
169.62 + self.user_format = user_format
169.63 + self.filename = None
169.64 + self.file_users = []
169.65 +
169.66 + def read_file(self, filename, file_format=None):
169.67 + """
169.68 + read a file with a list of all users of the group for which BulkUsers was instantiated
169.69 +
169.70 + :param file_format: can be sissi or isi
169.71 +
169.72 + """
169.73 + assert file_format in ('isi', 'sissi'), "File format must in 'isi' or 'sissi'"
169.74 + self.filename = filename
169.75 + self.file_users = []
169.76 + first = True if file_format in ('sissi',) else False
169.77 + for line in self.get_lines(filename):
169.78 + if first == True:
169.79 + ## heading
169.80 + try:
169.81 + SissiUser.read_heading(line)
169.82 + except exc.WrongFileFormat, e:
169.83 + msg = """Forse il file '%s' non e' nel formato corretto (Sissi)
169.84 + Errore originale: KeyError %s""" % (filename, e.message)
169.85 + raise exc.WrongFileFormat(msg)
169.86 + first = False
169.87 + continue
169.88 + line = line.strip()
169.89 +
169.90 + if line:
169.91 + if file_format == 'sissi':
169.92 + self.file_users += [SissiUser(line, self)]
169.93 + elif file_format == 'isi':
169.94 + self.file_users += [IsiUser(line, self)]
169.95 + self.get_overlap()
169.96 +
169.97 + def get_lines(self, filename):
169.98 +
169.99 + if filename.endswith('.xls'):
169.100 + lines = tools.Xls(filename).xls2csv()
169.101 + return lines.split('\n')
169.102 +
169.103 + return open(filename)
169.104 +
169.105 + def get_new_users(self, logname=False):
169.106 + """
169.107 + return a list of users, not yet saved
169.108 + """
169.109 + new = set(u.logname for u in self.file_users)
169.110 + old = set(self.user_list)
169.111 + if logname:
169.112 + return set(new.difference(old))
169.113 + else:
169.114 + return [self.file_users_dict[name] for name in set(new.difference(old))]
169.115 +
169.116 + def get_updated_users(self, logname=False):
169.117 + """
169.118 + return a list of old users updated in this file
169.119 + """
169.120 + new = set(u.logname for u in self.file_users)
169.121 + old = set(self.user_list)
169.122 + if logname:
169.123 + return set(old.intersection(new))
169.124 + else:
169.125 + return [self.file_users_dict[name] for name in new.intersection(old)]
169.126 +
169.127 + def get_users_to_be_removed(self, logname=False):
169.128 + """
169.129 + return a list of users that need to be removed
169.130 +
169.131 + :param logname: if True return a set of lognames else a list of PosixUsersx
169.132 +
169.133 + """
169.134 + new = set(u.logname for u in self.file_users)
169.135 + old = set(u.logname for u in self.users if u.gid == self.gid)
169.136 + if logname:
169.137 + return old.difference(new)
169.138 + else:
169.139 + return [self.users_dict[name] for name in old.difference(new)]
169.140 +
169.141 + deleted = property(get_users_to_be_removed)
169.142 + def get_overlap(self):
169.143 + """
169.144 + return list of users that have same first and last name and do not have
169.145 + the same CF or have empty CF
169.146 + """
169.147 + overlap = []
169.148 + for u in self.file_users:
169.149 + unique = self.is_unique(u)
169.150 + if not unique:
169.151 + u.logname = self.get_unique_name(u.logname)
169.152 + self.renamed += [u]
169.153 + overlap += [u]
169.154 + self.used_lognames += [u.logname]
169.155 + self.file_users_dict[u.logname] = u
169.156 + return overlap
169.157 +
169.158 + def is_unique(self, user):
169.159 + """
169.160 + return a boolean saying if the name is unique. Uses CF
169.161 +
169.162 + :param user: a NewUser object
169.163 + """
169.164 + if user.logname not in (self.user_list + self.used_lognames):
169.165 + return True
169.166 + else:
169.167 + if user.cf and user.cf in self.cf_dict:
169.168 + return True
169.169 + return False
169.170 +
169.171 + def get_unique_name(self, username):
169.172 + """
169.173 + return a unique name for user according to already present users
169.174 + """
169.175 + print "get-unique-name", username
169.176 + for i in range(2, 20):
169.177 + name = "%s%2.2d" % (username, i)
169.178 + if not self.l.user_exists(name) and not name in self.used_lognames:
169.179 + return name
169.180 +
169.181 + def as_isi(self, filename=None, extended=False):
169.182 + """
169.183 + return a file in .isi format suitable to be fed to isi-addusers
169.184 +
169.185 + :param filename: write in filename
169.186 + """
169.187 + output = [u.as_isi(extended=extended) for u in self.file_users]
169.188 + output += ["-%s" % u.as_isi_format(extended=extended) for u in self.get_users_to_be_removed(logname=False)]
169.189 + if filename:
169.190 + open(filename, 'w').write("\n".join(output) + "\n")
169.191 + return
169.192 + return "\n".join(output)
169.193 +
169.194 + def renamed_as_text(self):
169.195 + """
169.196 + return a list of users renamed as text
169.197 + """
169.198 + output = []
169.199 + for u in self.renamed:
169.200 + output += ["\t".join([u.logname, u.last_name, u.first_name])]
169.201 + return "\n".join(output)
169.202 +
169.203 + def deleted_as_text(self):
169.204 + """
169.205 + return a list of users deleted as text
169.206 + """
169.207 + output = []
169.208 + for u in self.get_users_to_be_removed(logname=False):
169.209 + output += ["\t".join([u.logname, u.last_name, u.first_name])]
169.210 + return "\n".join(output)
169.211 +
169.212 + def _get_user_format(self):
169.213 +
169.214 + return self._user_format
169.215 +
169.216 + def _set_user_format(self, format):
169.217 +
169.218 + if format == 'cf':
169.219 + format = u'%(group_id)s_%(cf).11s'
169.220 + elif format == 'name':
169.221 + format = u'%(first_name)s.%(last_name)s'
169.222 + elif format == 'id-name':
169.223 + format = u'%(group_id)s_%(first_name)s.%(last_name)s'
169.224 +
169.225 + self._user_format = format
169.226 +
169.227 + user_format = property(_get_user_format, _set_user_format)
169.228 +
169.229 + def __str__(self):
169.230 + return "<BulkUser %s (%s)>" % (self.maingroup, self.filename)
169.231 +
169.232 +class NewUser(object):
169.233 +
169.234 + user_format = None
169.235 + def _get_logname(self):
169.236 + try:
169.237 + return self._logname
169.238 + except AttributeError:
169.239 + fmt = self.user_format or defaults.USER_FORMAT.get(self.maingroup, None) or defaults.USER_FORMAT.get('default')
169.240 + return (fmt % self).lower()
169.241 +
169.242 + def _set_logname(self, logname):
169.243 + self._logname = logname
169.244 +
169.245 + def _get_group_id(self):
169.246 + return defaults.GROUP_IDS[self.maingroup]
169.247 +
169.248 + group_id = property(_get_group_id)
169.249 + logname = property(_get_logname, _set_logname)
169.250 +
169.251 + def _get_password(self):
169.252 + if self.bulk_instance.random_password:
169.253 + return new_password()
169.254 + try:
169.255 + return self._password
169.256 + except AttributeError:
169.257 + return ''
169.258 +
169.259 + password = property(_get_password)
169.260 +
169.261 + def __getitem__(self, key):
169.262 + """
169.263 + Cast all None values to '' otherwise the lookup can be scattered with 'None'
169.264 + as %(field_name)s would render as 'None' a None value
169.265 + """
169.266 + return getattr(self, key, '') or ''
169.267 +
169.268 + def as_isi(self, extended=False):
169.269 + """
169.270 + return the user isi 'isi' format: ie. as used by isi-adduser
169.271 + """
169.272 + record = [self.logname, self.last_name, self.first_name or '', self.maingroup,
169.273 + self.classe or '', self.cf or '', self.password]
169.274 + if extended:
169.275 + city, pv = '', ''
169.276 + pattern = re.compile('^(?P<city>.*)\((?P<pv>..)\)')
169.277 + m = pattern.match(self.city or '')
169.278 + if m:
169.279 + city = cp.group('city').strip()
169.280 + pv = cp.group('pv')
169.281 +
169.282 +
169.283 + record += [self.sex or '', self.address or '', city, pv, self.zip_code or '', self.phone or '']
169.284 +
169.285 + return ";".join(record)
169.286 +
169.287 + def _get_classe(self):
169.288 + """
169.289 + return the school_class according to:
169.290 +
169.291 + * year (anno_corso)
169.292 + * corsi mapping
169.293 + * section
169.294 +
169.295 + """
169.296 + return (defaults.CLASSE_FORMAT % self).lower()
169.297 +
169.298 + classe = property(_get_classe)
169.299 +
169.300 + def __str__(self):
169.301 + return "%(first_name)s %(last_name)s" % self
169.302 +
169.303 + def __repr__(self):
169.304 + return "<NewUser: %(logname)s (%(first_name)s %(last_name)s - %(maingroup)s)>" % self
169.305 +
169.306 +def get_sissi_tabcorsi():
169.307 + """
169.308 + read /etc/isi/sissi-tabcorsi and produce a suitable class mapping object
169.309 + that returns an acronim
169.310 + """
169.311 + tabsissi = {}
169.312 + if not os.path.exists('/etc/isi/sissi-tabcorsi'):
169.313 + raise exc.MissingCourseMapping("Manca sissi-tabcorsi vecessario per tradurre i corsi in sigle")
169.314 +
169.315 + for line in open('/etc/isi/sissi-tabcorsi'):
169.316 + line = line.strip().split('=')
169.317 + if len(line) == 2:
169.318 + corso_def = line[0].strip().lower()
169.319 + corso_sigla = line[1].strip().lower()
169.320 + tabsissi[corso_def] = corso_sigla
169.321 +
169.322 + return tabsissi
169.323 +
169.324 +class SissiUser(NewUser):
169.325 + """
169.326 + A user object as described in the file, one attribute for each (needed) column
169.327 + Anno di corso;Sezione;Corso;Cognome;Nome;Data di nascita;Sesso;Comune di nascita;Prov. Nascita;
169.328 + Codice fiscale;Indirizzo;Comune di residenza;CAP;Prov. Residenza;Telefono 1;Telefono 2;
169.329 + Cognome padre;Nome padre;Cognome madre;Nome madre;Anno Sc.
169.330 +
169.331 + """
169.332 + cols = {}
169.333 + attrs = ['first_name', 'last_name', 'sex', 'cf']
169.334 + corsi_dict = get_sissi_tabcorsi()
169.335 + col_map = {
169.336 + 'anno_corso' : 'Anno di corso',
169.337 + 'sezione' : 'Sezione',
169.338 + 'last_name' : 'Cognome',
169.339 + 'first_name' : 'Nome',
169.340 + 'birth_date' : 'Data di nascita',
169.341 + 'sex' : 'Sesso',
169.342 + 'birth_city' : 'Comune di nascita',
169.343 + 'birth_pv' : 'Prov. Nascita',
169.344 + 'cf' : 'Codice fiscale',
169.345 + 'address' : 'Indirizzo',
169.346 + 'city' : 'Comune di residenza',
169.347 + 'zip_code' : 'CAP',
169.348 + 'pv' : 'Prov. Residenza',
169.349 + 'phone' : 'Telefono 1',
169.350 + 'phone2' : 'Telefono 2',
169.351 + 'father_last_name' : 'Cognome padre',
169.352 + 'father_first_name' : 'Nome padre',
169.353 + 'mother_last_name' : 'Cognome madre',
169.354 + 'mother_first_name' : 'Nome madre',
169.355 + 'shool_year' : 'Anno Sc.',
169.356 + }
169.357 +
169.358 + def __init__(self, line, bulk_instance):
169.359 +
169.360 + self.bulk_instance = bulk_instance
169.361 + self.user_format = bulk_instance.user_format
169.362 + if isinstance(line, basestring):
169.363 + line = line.split(';')
169.364 +
169.365 + self.maingroup = bulk_instance.maingroup
169.366 + for att_name, col_description in self.col_map.iteritems():
169.367 +
169.368 + try:
169.369 + key = self.cols[col_description]
169.370 + except KeyError, e:
169.371 + msg = """Forse il file di input non e' nel formato corretto (Sissi)
169.372 + Errore originale: KeyError: '%s'""" % (e.message)
169.373 + raise exc.WrongFileFormat(msg)
169.374 +
169.375 + try:
169.376 + setattr(self, att_name, line[key] or '')
169.377 + except IndexError:
169.378 + pass
169.379 +
169.380 + try:
169.381 + self.corso = self.corsi_dict[line[self.cols['Corso']].lower()]
169.382 + except KeyError:
169.383 + msg = u"Il corso '%s' non puo' essere tradotto in una sigla. Guarda /etc/isi/sissi-tabcorsi"
169.384 + raise exc.MissingCourseMapping(msg % line[self.cols['Corso']])
169.385 +
169.386 + self.last_name = self.last_name.title()
169.387 + self.first_name = self.first_name.title()
169.388 + self.birth_date = self.birth_date.title()
169.389 + self.city = self.city.title()
169.390 + self.pv = self.pv.upper()
169.391 + self.anno_corso = int(float(self.anno_corso)) # xls writes '3' as numeric,
169.392 +# self.school_year = int(float(self.school_year)) # so that it turns as 3.0
169.393 +
169.394 + @classmethod
169.395 + def read_heading(cls, line):
169.396 + for i, col_name in enumerate(line.strip().split(';')):
169.397 + cls.cols[col_name] = i
169.398 +
169.399 +class IsiUser(NewUser):
169.400 + """
169.401 + A User as described for .isi format:
169.402 + 1. logname
169.403 + 2. last_name
169.404 + 3. first_name
169.405 + 4. maingroup
169.406 + 5. more groups (i.e.: class)
169.407 + 6. cf (italian CF codice fiscale, any unique key will do - optional)
169.408 + 7. password (optional)
169.409 + """
169.410 +
169.411 + def __init__(self, line, bulk_instance):
169.412 +
169.413 + self.bulk_instance = bulk_instance
169.414 + self.user_format = bulk_instance.user_format
169.415 + if isinstance(line, basestring):
169.416 + line = line.split(';')
169.417 +
169.418 +
169.419 + self._logname = line[0].lower()
169.420 + self.last_name = line[1].title()
169.421 + self.first_name = line[2].title()
169.422 + self.maingroup = bulk_instance.maingroup
169.423 +
169.424 + try:
169.425 + self.groups = line[4].lower()
169.426 + except IndexError, e:
169.427 + self.groups = ''
169.428 +
169.429 + try:
169.430 + self.cf = line[5].upper()
169.431 + except IndexError, e:
169.432 + self.cf = ''
169.433 +
169.434 + try:
169.435 + self._password = line[6]
169.436 + except IndexError, e:
169.437 + self.password = None
169.438 +
169.439 +
169.440 + def _get_classe(self):
169.441 + """
169.442 + return the school_class according to:
169.443 +
169.444 + * year (anno_corso)
169.445 + * corsi mapping
169.446 + * section
169.447 +
169.448 + """
169.449 + if self.groups:
169.450 + return self.groups.split(',')[0]
169.451 + return None
169.452 +
169.453 + classe = property(_get_classe)
170.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
170.2 +++ b/lib/isi/conf/__init__.py Mon Apr 26 11:16:23 2010 +0200
170.3 @@ -0,0 +1,22 @@
170.4 +"""
170.5 +This module provide a way to handle configuration files related to the isi project:
170.6 +
170.7 + logon.conf
170.8 + dnsmasq.conf
170.9 +
170.10 +The latter has been split into 3 different conf files:
170.11 +
170.12 + * boot: with all boot related option *except dhcp-options*
170.13 + tjese are all options related to boot but NOT related to a single MAC
170.14 +
170.15 + * hosts.mac: with dhcp-options, i.e.: all options related to a host
170.16 + related or not to the boot phase
170.17 +
170.18 +tool.py provides a Class used by any ot the other modules
170.19 +logon.py + params.py is just for logon.conf
170.20 +dnsmasq.py is ok for dnsmasq.conf
170.21 +hosts.py is ok for /etc/hosts
170.22 +mac.py is ok for hosts.mac
170.23 +
170.24 +
170.25 +"""
171.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
171.2 +++ b/lib/isi/conf/defaults.py Mon Apr 26 11:16:23 2010 +0200
171.3 @@ -0,0 +1,80 @@
171.4 +#!/usr/bin/python
171.5 +# -*- coding: utf-8 -*-
171.6 +
171.7 +# This program is free software; you can redistribute it and/or modify
171.8 +# it under the terms of the GNU General Public License as published by
171.9 +# the Free Software Foundation; either version 2, or (at your option)
171.10 +# any later version.
171.11 +
171.12 +
171.13 +# AUTHORS: Sandro Dentella - Massimo Mancini
171.14 +
171.15 +"""
171.16 +These defaults will be overwritten by values in /etc/isi/defaults.py
171.17 +"""
171.18 +import os
171.19 +# struttura della /home
171.20 +GROUPS_PATH = '/home/users'
171.21 +CLASSES_PATH = '/home/shares/classi'
171.22 +COURSES_PATH = '/home/shares/corsi'
171.23 +
171.24 +# gruppi a cui vanno assegnati gli utenti se si vuole che possano
171.25 +# usare chiavette e audio dei client linux
171.26 +#EXTRA_GROUPS = []
171.27 +EXTRA_GROUPS = ['plugdev','audio', 'fuse']
171.28 +
171.29 +
171.30 +# usato da isi2-adduser per l'imput interattivo
171.31 +DATI_USER = "USER_ID COGNOME NOME GRUPPO GRUPPI COD.FISC. PASSWORD SESSO INDIRIZZO COMUNE CAP PROVINCIA TELEFONO"
171.32 +
171.33 +# configurazione del logger
171.34 +LOG_FILE = '/var/log/users_error.log'
171.35 +LOG_MODE = 'w'
171.36 +LOG_FORMAT = '%(asctime)s %(name)-8s %(levelname)-8s %(message)s'
171.37 +LOG_DATE_FORMAT='%y-%m-%d %H:%M'
171.38 +
171.39 +# configurazione del backup ldap
171.40 +BAK_LDAP_FILE = '/etc/isi/slapcat.ldif'
171.41 +
171.42 +# QUOTA
171.43 +QUOTA_S1 = 0
171.44 +QUOTA_S2 = 0
171.45 +QUOTA_F1 = 0
171.46 +QUOTA_F2 = 0
171.47 +QUOTA_REP = '/tmp/repquota.txt'
171.48 +
171.49 +# PERMESSI DI DEFAULT SU HOME E FILE (indipendenti da acl)
171.50 +# alunni ed esterni
171.51 +PERMS_HOME_ALU = '2770'
171.52 +PERMS_FILE_ALU = '660'
171.53 +# tutti gli altri
171.54 +PERMS_HOME_ALL = '2700'
171.55 +PERMS_FILE_ALL = '600'
171.56 +
171.57 +# NUMERI INIZIALI LDAP
171.58 +UID_MIN = 1000
171.59 +GID_MIN = 1000
171.60 +UID_MAX = 30000
171.61 +GID_MAX = 30000
171.62 +
171.63 +## User's logname format
171.64 +
171.65 +GROUP_IDS = {
171.66 + 'alunni' : 'a',
171.67 + 'docenti' : 'd',
171.68 + 'admins' : 'ad',
171.69 + 'esterni' : 'e',
171.70 + 'segreteria' : 's',
171.71 + 'ata' : 'at',
171.72 + }
171.73 +
171.74 +USER_FORMAT = {
171.75 + 'default' : u'%(group_id)s_%(cf).8s',
171.76 + 'docenti' : u'%(first_name)s.%(last_name)s',
171.77 + }
171.78 +
171.79 +CLASSE_FORMAT = u"%(corso)s%(anno_corso)s%(sezione)s"
171.80 +
171.81 +if os.path.exists('/etc/isi/defaults.py'):
171.82 + execfile('/etc/isi/defaults.py')
171.83 +
172.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
172.2 +++ b/lib/isi/conf/dnsmasq.py Mon Apr 26 11:16:23 2010 +0200
172.3 @@ -0,0 +1,177 @@
172.4 +# -*- coding: utf-8 -*-
172.5 +
172.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
172.7 +#
172.8 +# This program is free software: you can redistribute it and/or modify
172.9 +# it under the terms of the GNU General Public License as published by
172.10 +# the Free Software Foundation, either version 3 of the License, or
172.11 +# (at your option) any later version.
172.12 +#
172.13 +# This program is distributed in the hope that it will be useful,
172.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
172.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
172.16 +# GNU General Public License for more details.
172.17 +#
172.18 +# You should have received a copy of the GNU General Public License
172.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
172.20 +
172.21 +
172.22 +"""
172.23 +domain-needed
172.24 +bogus-priv
172.25 +server=208.67.222.222
172.26 +server=208.67.220.220
172.27 +filterwin2k
172.28 +expand-hosts
172.29 +domain=isi.lan
172.30 +dhcp-range=192.168.96.130,192.168.96.140,255.255.255.0,8h
172.31 +dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1
172.32 +dhcp-host=00:0c:29:5e:69:b5,192.168.96.191,vm-ltsp02,net:ns2 # client2
172.33 +dhcp-option=3,192.168.96.1
172.34 +dhcp-option=6,192.168.96.254
172.35 +dhcp-authoritative
172.36 +cache-size=1024
172.37 +conf-dir=/etc/isi/dns/dnsmasq
172.38 +addn-hosts=/etc/isi/dns/hosts
172.39 +# comment
172.40 +"""
172.41 +import re
172.42 +import time
172.43 +import datetime
172.44 +import urllib
172.45 +from isi.conf import tools
172.46 +
172.47 +SIMPLE_PARAMS = "domain-needed bogus-priv filterwin2k expand-hosts dhcp-authoritative log-queries log-dhcp".split()
172.48 +PARAMS = "server domain dhcp-range dhcp-host dhcp-option dhcp-boot dhcp-vendorclass".split() + \
172.49 + "cache-size conf-dir addn-hosts conf-file conf-dir".split()
172.50 +
172.51 +
172.52 +class UnknownParamName(tools.ValidationError): pass
172.53 +class ParamRequireValue(tools.ValidationError): pass
172.54 +
172.55 +class Line(tools.Line):
172.56 +
172.57 + VAR_PATTERN = re.compile(r"""
172.58 + (?P<comment>\s*\#\s*)? # a possible comment of the line
172.59 + (?P<param_name>[\w-]+) # the variable name
172.60 + \s*=* # ok, that's an assignement
172.61 + (?P<value>.*?) # got the value!, non greedy
172.62 + (?P<final_comment>\s*(\#.*)?) # a possible final comment
172.63 + $""", re.VERBOSE)
172.64 + param_name = None
172.65 + value = ''
172.66 + str_format = "%(param_name)s=%(value)s"
172.67 +
172.68 +
172.69 + def validate(self):
172.70 + if self.is_comment:
172.71 + return True
172.72 + if self.param_name not in (PARAMS + SIMPLE_PARAMS):
172.73 + raise UnknownParamName("Param is not valid: %s" % self.param_name)
172.74 + if self.param_name in PARAMS and not self.value:
172.75 + raise ParamRequireValue("Param %s requires a value" % self.param_name)
172.76 + return True
172.77 +
172.78 + def __str__(self):
172.79 + if self.is_comment:
172.80 + return self.line
172.81 + if self.param_name in PARAMS:
172.82 + return "%s=%s" % (self.param_name, self.value)
172.83 + else:
172.84 + return "%s" % (self.param_name)
172.85 +
172.86 +
172.87 +class Conf(tools.Conf):
172.88 + line_class = Line
172.89 + search_value = None
172.90 +
172.91 + gw = '3'
172.92 + dns = '6'
172.93 + wins = '44'
172.94 +
172.95 + def get_option(self, option=None, tag=False, ip=True):
172.96 + """option may be gw, dns or wins"""
172.97 +
172.98 + assert option in ('gw', 'dns', 'wins'), "Option must be one of gw, dns or wins"
172.99 +
172.100 + option_id = getattr(self, option)
172.101 + lines = [l for l in self.get_param('dhcp-option') if
172.102 + l.value.startswith(option_id)]
172.103 +
172.104 + if tag:
172.105 + line = [l for l in lines if l.value.endswith("net:%s" % tag)]
172.106 +
172.107 + if lines:
172.108 + if ip:
172.109 + return get_ip(lines[0].value, option_id, tag)
172.110 + else:
172.111 + return lines
172.112 +
172.113 + def set_option(self, option=None, value=None, tag=False, ):
172.114 + """option may be gw, dns or wins"""
172.115 +
172.116 + lines = self.get_option(option, tag, ip=False)
172.117 + option_id = getattr(self, option)
172.118 + tag_str = ",net:%s" if tag else ''
172.119 + new_value = "%s,%s%s" % (option_id, value, tag_str)
172.120 +
172.121 + if lines:
172.122 + line = lines[0] ## FIXME
172.123 + line.value = new_value
172.124 + else:
172.125 + self.lines += [Line('dhcp-option=%s' % new_value)]
172.126 +
172.127 +def get_ip(value, option_id, tag=None):
172.128 +
172.129 + PATTERN = '%s,(?P<ip>[0-9.]*)(,net:(?P<tag>.*))?$' % option_id
172.130 + m = re.search(PATTERN, value)
172.131 +
172.132 + if m:
172.133 + if tag:
172.134 + if m.group('tag') == tag:
172.135 + return m.group('ip')
172.136 + else:
172.137 + return m.group('ip')
172.138 + return None
172.139 +
172.140 +class Lease(object):
172.141 + """
172.142 + A simple object that stores info on leases:
172.143 +
172.144 + mac
172.145 + ip
172.146 + hostname
172.147 + extra
172.148 + """
172.149 + def __init__(self, mac, ip, hostname, client_id, lease):
172.150 + self.mac = mac
172.151 + self.ip = ip
172.152 + self.hostname = hostname if hostname != '*' else None
172.153 + self.client_id = client_id if client_id != '*' else None
172.154 + self.lease_datetime = datetime.datetime(*time.localtime(int(lease))[:6])
172.155 +
172.156 + def __repr__(self):
172.157 + return u"<Lease: %s %s %s>" % (self.mac, self.ip, self.hostname)
172.158 +
172.159 +def get_leases(filename='/var/lib/misc/dnsmasq.leases'):
172.160 + """
172.161 + fill and return a list of Lease instances using the dnsmasq.leases
172.162 + file's informations
172.163 +
172.164 + 1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
172.165 + 1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
172.166 + file format:
172.167 + http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2006q2/000734.html
172.168 +
172.169 + """
172.170 + COMMENT = re.compile('^\s*#\s*.+$|^\s*$')
172.171 + leases = {}
172.172 +
172.173 + for line in open(filename):
172.174 + if not re.match(COMMENT, line):
172.175 + m = re.match('\s*(.+)\s*', line)
172.176 + lease_time, mac, ip, hostname, client_id = m.group().split()
172.177 + leases[mac] = Lease(mac, ip, hostname, client_id, lease_time)
172.178 +
172.179 + return leases.values()
172.180 +
173.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
173.2 +++ b/lib/isi/conf/hosts.py Mon Apr 26 11:16:23 2010 +0200
173.3 @@ -0,0 +1,59 @@
173.4 +# -*- coding: utf-8 -*-
173.5 +
173.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
173.7 +#
173.8 +# This program is free software: you can redistribute it and/or modify
173.9 +# it under the terms of the GNU General Public License as published by
173.10 +# the Free Software Foundation, either version 3 of the License, or
173.11 +# (at your option) any later version.
173.12 +#
173.13 +# This program is distributed in the hope that it will be useful,
173.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
173.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173.16 +# GNU General Public License for more details.
173.17 +#
173.18 +# You should have received a copy of the GNU General Public License
173.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
173.20 +
173.21 +
173.22 +"""
173.23 +127.0.0.1 localhost
173.24 +127.0.1.1 ISI-PDC
173.25 +192.168.96.222 srv-ltsp
173.26 +192.168.96.210 ISI-PDC
173.27 +192.168.96.22 www.tin.it
173.28 +192.168.96.199 vm-client-ltsp1
173.29 +192.168.96.44 srv-prova srv # questi sono dei commenti
173.30 +"""
173.31 +import re
173.32 +import urllib
173.33 +from isi.conf import tools
173.34 +
173.35 +class WrongIPError(tools.ValidationError): pass
173.36 +
173.37 +class Line(tools.Line):
173.38 +
173.39 + VAR_PATTERN = re.compile(r"""
173.40 + (?P<comment>\s*\#\s*)? # a possible comment of the line
173.41 + (?P<param_name>[\w.]+) # the variable name
173.42 + \s+ # ok, that's an assignement
173.43 + (?P<value>.+?) # got the value!, non greedy
173.44 + (?P<final_comment>\s*(\#.*)?) # a possible final comment
173.45 + $""", re.VERBOSE)
173.46 + param_name = None
173.47 + name = None
173.48 + str_format = "%(param_name)s %(value)s"
173.49 +
173.50 + def validate(self):
173.51 + if tools.is_ip_address(self.param_name) and self.value:
173.52 + return True
173.53 + raise WrongIPError("%s is not a valid IP" % self.param_name)
173.54 +
173.55 +class Hosts(tools.Conf):
173.56 + line_class = Line
173.57 +
173.58 + def set_param(self, param_name, value=None):
173.59 +
173.60 + return tools.Conf.set_param(self, param_name, value=value)
173.61 +
173.62 +
174.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
174.2 +++ b/lib/isi/conf/logon.py Mon Apr 26 11:16:23 2010 +0200
174.3 @@ -0,0 +1,232 @@
174.4 +# -*- coding: utf-8 -*-
174.5 +
174.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
174.7 +#
174.8 +# This program is free software: you can redistribute it and/or modify
174.9 +# it under the terms of the GNU General Public License as published by
174.10 +# the Free Software Foundation, either version 3 of the License, or
174.11 +# (at your option) any later version.
174.12 +#
174.13 +# This program is distributed in the hope that it will be useful,
174.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
174.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
174.16 +# GNU General Public License for more details.
174.17 +#
174.18 +# You should have received a copy of the GNU General Public License
174.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
174.20 +
174.21 +
174.22 +"""
174.23 +Start__Page = www.google.it #
174.24 +Start__Page[admins] = www.google.it
174.25 +ProxyServer = XXX.XXX.XXX:8128 # DansGuardian
174.26 +ProxyServer[admins] = XXX.XXX.XXX:3128 # Squid (FW permettendo)
174.27 +ProxyOverride = www.XXX.XXX,<local>
174.28 +"""
174.29 +import re
174.30 +class MultipleParamError(Exception): pass
174.31 +class UnknownParamError(Exception): pass
174.32 +from params import PARAMS
174.33 +import urllib
174.34 +
174.35 +class Line(object):
174.36 +
174.37 + VAR_PATTERN = re.compile(r"""
174.38 + (?P<comment>\s*\#\s*)? # a possible comment of the line
174.39 + (?P<name>\w+) # the variable name
174.40 + ((\[
174.41 + (?P<drive>.:)? # if it's a share we may have a 'drive'
174.42 + (?P<group>\w+)
174.43 + \])?)? # can be Start__Page[admin] in which case I need just Start__Page
174.44 + \s*=\s* # ok, that's an assignement
174.45 + (?P<value>.+?) # got the value!, non greedy
174.46 + (?P<final_comment>\s*(\#.*)?) # a possible final comment
174.47 + $""", re.VERBOSE)
174.48 +
174.49 + def __init__(self, line=None, param_name=None, group=None, value=None, drive=None):
174.50 + """
174.51 + create a line of the conf file. Comment line can be created passing line arg only::
174.52 +
174.53 + Line('Start__Page = www.google.it')
174.54 + Line('ProxyServer[admins] = XXX.XXX.XXX:3128 # Squid (FW permettendo)')
174.55 +
174.56 + """
174.57 +
174.58 + if line is None:
174.59 + self.param_name = param_name
174.60 + self.group = group
174.61 + self.value = value or ''
174.62 + self.final_comment = ''
174.63 + self.is_comment = False
174.64 + self.drive = drive
174.65 + self.line = str(self)
174.66 + else:
174.67 + self.line = line
174.68 + m = self.VAR_PATTERN.match(line.strip())
174.69 + if m:
174.70 + comm = m.group('comment')
174.71 + self.is_comment = True if (comm and '#' in comm) else False
174.72 + self.param_name = m.group('name')
174.73 + self.value = m.group('value')
174.74 + self.final_comment = m.group('final_comment') or ''
174.75 + self.group = m.group('group')
174.76 + self.drive = m.group('drive') and re.sub(':', '', m.group('drive'))
174.77 + ## let's fix the parser for drive w/o group
174.78 + ## _NetFolder[K] = classi: K would be put in group and drive empty
174.79 + if self.group and len(self.group) == 1 and not self.drive:
174.80 + self.drive = self.group
174.81 + self.group = None
174.82 +
174.83 + else:
174.84 + self.is_comment = True
174.85 +
174.86 + def variable(self):
174.87 + if self.group:
174.88 + if self.drive:
174.89 + return "%s[%s:%s]" % (self.param_name, self.drive, self.group)
174.90 + else:
174.91 + return "%s[%s]" % (self.param_name, self.group)
174.92 + else:
174.93 + if self.drive:
174.94 + return "%s[%s]" % (self.param_name, self.drive)
174.95 +
174.96 + return self.param_name
174.97 +
174.98 + def __str__(self):
174.99 + if self.is_comment:
174.100 + return self.line
174.101 + return "%s = %s%s" % (self.variable(), self.value or '',
174.102 + self.final_comment and (" " + self.final_comment))
174.103 +
174.104 + def __repr__(self):
174.105 + if self.is_comment:
174.106 + return self.line[:10]
174.107 + return "<%s>" % vars(self)
174.108 +
174.109 + def _url(self):
174.110 + """
174.111 + return the url as used in web application
174.112 + """
174.113 + if self.is_comment:
174.114 + return ''
174.115 + add = ''
174.116 + url = u"/%s/?param_name=%s&" % ((self.param_name,) *2)
174.117 + if self.group:
174.118 + url += "group=%s" % self.group
174.119 + add = '&'
174.120 + if self.drive:
174.121 + url += "%sdrive=%s" % (add, self.drive)
174.122 + return url
174.123 + url = property(_url)
174.124 +
174.125 + def _url_del(self):
174.126 + """
174.127 + return an url w/ valu suitable for del
174.128 + """
174.129 + return self.url + "&value=" + (urllib.quote(self.value) or '')
174.130 +
174.131 + url_del = property(_url_del)
174.132 +
174.133 +class Logon(object):
174.134 +
174.135 + def __init__(self, filename=None, text=None):
174.136 +
174.137 + assert filename or text, "You must set filename or text"
174.138 + self.filename = filename
174.139 + if filename:
174.140 + self.lines = [Line(l) for l in open(filename)]
174.141 + else:
174.142 + self.lines = [Line(l) for l in text.split('\n')]
174.143 +
174.144 + def set_param(self, param_name, value=None, group=None, drive=None):
174.145 + """
174.146 + set a value that can only have one value as e.g.:
174.147 + _debug
174.148 + """
174.149 + if param_name not in PARAMS:
174.150 + raise UnknownParamError("%s is not a valid ParamName" % param_name)
174.151 +
174.152 + lines = self.get_param(param_name, group=group, drive=drive)
174.153 +
174.154 + if len(lines) > 1:
174.155 + raise MultipleParamError("Param %s is present %d times" % (param_name, len(lines)))
174.156 +
174.157 + if lines:
174.158 + line = lines[0]
174.159 + line.param_name = param_name
174.160 + line.value = value
174.161 + line.group = group
174.162 + else:
174.163 + line = Line(param_name=param_name, value=value, group=group, drive=drive)
174.164 + l = self.get_param(param_name, group=False, drive=False)
174.165 + if len(l) == 0:
174.166 + idx = len(self.lines)
174.167 + else:
174.168 + idx = self.lines.index(l[-1])
174.169 +
174.170 + self.lines.insert(idx + 1, line)
174.171 +
174.172 + return line
174.173 +
174.174 + def get_param(self, param_name, group=False, drive=False, value=False):
174.175 + """
174.176 + return the (possible) Line objects that have param_name and possibly group
174.177 + """
174.178 + ret = []
174.179 + for l in self.lines:
174.180 + if not l.is_comment and l.param_name == param_name:
174.181 + ret += [l]
174.182 + if group is not False:
174.183 + ret = [l for l in ret if l.group == group]
174.184 + if drive is not False:
174.185 + ret = [l for l in ret if l.drive == drive]
174.186 + if value is not False:
174.187 + ret = [l for l in ret if l.value == value]
174.188 + return ret
174.189 +
174.190 + def del_param(self, param_name, group=None, drive=None, value=None):
174.191 + """
174.192 + delete a parameter
174.193 + """
174.194 + kw = { 'group' :group, 'drive' :drive,}
174.195 + if value:
174.196 + kw['value'] = value
174.197 + try:
174.198 + l = self.get_param(param_name, **kw)[0]
174.199 + except IndexError, e:
174.200 + return
174.201 +
174.202 + self.lines.remove(l)
174.203 + return l
174.204 +
174.205 + def __str__(self):
174.206 + return "\n".join([str(l).strip() for l in self.lines])
174.207 +
174.208 + def __len__(self):
174.209 + return len(self.lines)
174.210 +
174.211 + def len(self):
174.212 + """Return the number of non-comment lines"""
174.213 + return len([l for l in self.lines if not l.is_comment])
174.214 +
174.215 + def diff(self, other, this_file='this.conf', other_file='other.conf'):
174.216 + """return a diff between self and other"""
174.217 +
174.218 + assert isinstance(other, Logon), "other must be a Logon instance (is %s)" % oter.__class__
174.219 + import difflib
174.220 + diff = []
174.221 +
174.222 + for line in difflib.unified_diff(["%s\n" % l for l in str(self).split('\n')],
174.223 + ["%s\n" % l for l in str(other).split('\n')],
174.224 + this_file, other_file):
174.225 + diff += [line]
174.226 + return "".join(diff)
174.227 +
174.228 + def save(self, filename=None):
174.229 +
174.230 + filename = filename or self.filename
174.231 +
174.232 + f = open(filename, 'w')
174.233 + f.write(str(self) + '\n')
174.234 + f.close()
174.235 +
175.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
175.2 +++ b/lib/isi/conf/mac.py Mon Apr 26 11:16:23 2010 +0200
175.3 @@ -0,0 +1,106 @@
175.4 +# -*- coding: utf-8 -*-
175.5 +
175.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
175.7 +#
175.8 +# This program is free software: you can redistribute it and/or modify
175.9 +# it under the terms of the GNU General Public License as published by
175.10 +# the Free Software Foundation, either version 3 of the License, or
175.11 +# (at your option) any later version.
175.12 +#
175.13 +# This program is distributed in the hope that it will be useful,
175.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
175.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
175.16 +# GNU General Public License for more details.
175.17 +#
175.18 +# You should have received a copy of the GNU General Public License
175.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
175.20 +
175.21 +
175.22 +"""
175.23 +### sample : hosts_mac (vecchio formato, da non supportare!)
175.24 +dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1 # commento1
175.25 +dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2
175.26 +
175.27 +### sample : hosts_mac (nuovo formato che prevede anche l'uso dei tag)
175.28 +dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1
175.29 +dhcp-host=00:0c:29:5e:69:b5,192.168.96.191,vm-ltsp02,net:ns2
175.30 +"""
175.31 +import re
175.32 +import urllib
175.33 +from isi.conf import tools
175.34 +
175.35 +class WrongMACError(tools.ValidationError): pass
175.36 +class WrongValueError(tools.ValidationError): pass
175.37 +
175.38 +### DISCLAIMER: this parser is seriously incomplete and only meant for ReteISI Project!!!!
175.39 +###
175.40 +class Line(tools.Line):
175.41 +
175.42 + VAR_PATTERN = re.compile(r"""
175.43 + (?P<comment>\s*\#\s*)? # a possible comment of the line
175.44 + (?P<param_name>[\w-]+) # the variable name
175.45 + \s*=\s* # ok, that's an assignement
175.46 + (?P<value>.+?) # got the value!, non greedy
175.47 + (?P<final_comment>\s*(\#.*)?) # a possible final comment
175.48 + $""", re.VERBOSE)
175.49 + param_name = None
175.50 + name = None
175.51 + str_format = "%(param_name)s=%(value)s"
175.52 + ip = ''
175.53 + tag = ''
175.54 + mac = None
175.55 + hostname = ''
175.56 +
175.57 + def validate(self):
175.58 + if self.mac and (self.ip or self.tag or self.hostname):
175.59 + return True
175.60 + raise WrongMACError("%s is not a valid MAC Address" % self.param_name)
175.61 +
175.62 + def parse_value(self):
175.63 + """
175.64 + this is NOT a complete parser for dnsmasq. It's rather a usefull parser
175.65 + for the values that ReteISI project wants to use
175.66 + """
175.67 +
175.68 + for tk in self.value.split(','):
175.69 + if tools.is_mac_address(tk):
175.70 + self.mac = tk
175.71 + elif tools.is_ip_address(tk):
175.72 + self.ip = tk
175.73 + elif tk.startswith('net:'):
175.74 + self.tag = tk
175.75 + else:
175.76 + self.hostname = tk
175.77 +
175.78 +class Mac(tools.Conf):
175.79 + line_class = Line
175.80 +
175.81 + def get_param(self, param_name, value=None, ip=None, mac=None, tag=None):
175.82 +
175.83 + if mac:
175.84 + value = None
175.85 +
175.86 + ret = tools.Conf.get_param(self, param_name, value=value)
175.87 +
175.88 + if ip:
175.89 + ret = [l for l in ret if l.ip == ip]
175.90 +
175.91 + if mac:
175.92 + ret = [l for l in ret if l.mac == mac]
175.93 +
175.94 + if tag:
175.95 + ret = [l for l in ret if l.tag == tag]
175.96 +
175.97 + return ret
175.98 +
175.99 + def set_param(self, param_name, value=None, mac=None, ip=None, tag=None, hostname=None):
175.100 +
175.101 + if value and not mac:
175.102 + mac = value.split(',')[0]
175.103 +
175.104 + if not value:
175.105 + self.value = ",".join([locals()[at] for at in ('mac', 'ip', 'hostname', 'tag')
175.106 + if locals()[at]])
175.107 +
175.108 + return tools.Conf.set_param(self, param_name, value=value, mac=mac, ip=ip, tag=tag)
175.109 +
176.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
176.2 +++ b/lib/isi/conf/misc.py Mon Apr 26 11:16:23 2010 +0200
176.3 @@ -0,0 +1,108 @@
176.4 +import re
176.5 +import os
176.6 +import StringIO
176.7 +import ConfigParser
176.8 +from dry.functions import execute, ExecuteError
176.9 +import re
176.10 +from isi import models, exc
176.11 +
176.12 +def get_samba_conf():
176.13 + """
176.14 + test if a share is present in 'testparm -s'
176.15 + """
176.16 + ret_code, out, err = execute('testparm -s')
176.17 + if ret_code:
176.18 + raise ExecuteError("Error while testing samba configuration: %s" % err)
176.19 +
176.20 + testparm = StringIO.StringIO("\n".join(l.strip() for l in out.split('\n')))
176.21 + c = ConfigParser.ConfigParser()
176.22 + c.readfp(testparm)
176.23 + return c
176.24 +
176.25 +
176.26 +def get_shares(descr=True, all=False):
176.27 + """
176.28 + return a dict of samba shares
176.29 +
176.30 + :param descr: yield a description rather that path
176.31 + :param all: if False (default) only some shares are returned
176.32 + """
176.33 + shares = {}
176.34 + c = get_samba_conf()
176.35 + for sec in c.sections():
176.36 + if sec in ('print$', 'home', 'netlogon', 'printers') and not all:
176.37 + continue
176.38 + try:
176.39 + path = c.get(sec, 'path')
176.40 + if re.match('/home/shares/(classi|corsi)/.*', path) and not all:
176.41 + continue
176.42 + shares[sec] = path
176.43 + except ConfigParser.NoOptionError:
176.44 + pass
176.45 + if descr:
176.46 + return [(key, "%s (%s)" % (key, shares[key])) for key in sorted(shares.keys())]
176.47 + else:
176.48 + return [(key, shares[key]) for key in sorted(shares.keys())]
176.49 +
176.50 +
176.51 +def get_printers_with_rpcclient():
176.52 + """
176.53 + return a list of Printer objects initialized from the
176.54 + """
176.55 + printers = []
176.56 + passwd = file('/etc/ldap.secret').read().strip()
176.57 + u = models.get_samba_user('administrator')
176.58 + if not u.test_samba_password(passwd):
176.59 + if os.path.exists('/etc/administrator.secret'):
176.60 + passwd = file('/etc/administrator.secret').read().strip()
176.61 +
176.62 + if not u.test_samba_password(passwd):
176.63 + raise exc.AuthenticationError("Administrator could not authenticate with correct secret (looking ldap.secret and administrator.secret)")
176.64 +
176.65 + cmd = ["rpcclient", "-U", 'administrator%%%s' % passwd,
176.66 + '-c', 'enumprinters 2', '127.0.0.1', '-d0']
176.67 +
176.68 + ret_code, output, err = execute(cmd)
176.69 + if ret_code:
176.70 + raise exc.ExecutionError("failed cmd: %s" % " ".join(cmd))
176.71 + if output.startswith('No printers returned'):
176.72 + return []
176.73 + for prn in output.split("\n\n"):
176.74 + if prn.strip():
176.75 + printers += [Printer(prn)]
176.76 + return printers
176.77 +
176.78 +
176.79 +def get_samba_printers(driver=False):
176.80 +
176.81 + ret_code, out, err = execute('smbclient -N -L localhost')
176.82 + printers = {}
176.83 + if out:
176.84 + for line in out.split('\n'):
176.85 + tokens = line.split()
176.86 + if len(tokens)> 1 and tokens[1] == 'Printer':
176.87 + printers[tokens[0]] = " ".join(tokens[2:])
176.88 + if not driver:
176.89 + return [(key, printers[key]) for key in printers]
176.90 + else:
176.91 + return
176.92 +
176.93 +class Printer(object):
176.94 +
176.95 + def __init__(self, definition):
176.96 +
176.97 + for line in definition.split('\n'):
176.98 + try:
176.99 + name, value = line.strip().split(':')
176.100 + setattr(self, name, value.replace('[', '').replace(']',''))
176.101 + except:
176.102 + pass
176.103 +
176.104 + def __str__(self):
176.105 + return "%s (%s)" % (self.sharename, self.drivername)
176.106 +
176.107 + def __repr__(self):
176.108 + return "<Printer: %s>" % self
176.109 +
176.110 +
176.111 +
177.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
177.2 +++ b/lib/isi/conf/params.py Mon Apr 26 11:16:23 2010 +0200
177.3 @@ -0,0 +1,61 @@
177.4 +PARAMS = [
177.5 + 'DaysToKeep',
177.6 + 'ExcludeProfileDirs',
177.7 + 'LegalNoticeCaption',
177.8 + 'LegalNoticeText',
177.9 + 'My__Picture',
177.10 + 'My__Video',
177.11 + 'My__Music',
177.12 + 'MustBeValidated',
177.13 + 'NoAdminPage',
177.14 + 'NoConfigPage',
177.15 + 'NoDevMgrPage',
177.16 + 'NoDispAppearancePage',
177.17 + 'NoDispBackgroundPage',
177.18 + 'NoDispCPL',
177.19 + 'NoDispScrSavPage',
177.20 + 'NoDispSettingsPage',
177.21 + 'NoFileSysPage',
177.22 + 'NoProfilePage',
177.23 + 'NoVirtMemPage',
177.24 + 'Personal',
177.25 + 'ProxyOverride',
177.26 + 'ProxyServer',
177.27 + 'Start__Page',
177.28 + 'UseHomeDirectory',
177.29 + 'UserProfiles',
177.30 + 'UserPrinter',
177.31 + 'PcPrinter',
177.32 + '_DebugLevel',
177.33 + '_DebugUsers',
177.34 + '_DebugClients',
177.35 + '_DebugShare',
177.36 + '_EnvWin98',
177.37 + '_EnvWinXP',
177.38 + '_NetFolder',
177.39 + '_NetTime',
177.40 + '_NoAppWiz',
177.41 + '_NoDispLastUser',
177.42 + '_NoDispLastUser9X',
177.43 + '_NoSync',
177.44 + '_OkParanoia',
177.45 + '_ProfileDirs',
177.46 + '_RestrictActiveDesktop',
177.47 + '_RestrictCpan',
177.48 + '_RestrictDrive',
177.49 + '_RestrictDriveC',
177.50 + '_RestrictFind',
177.51 + '_RestrictHistory',
177.52 + '_RestrictIEPasswordCaching',
177.53 + '_RestrictLogon',
177.54 + '_RestrictNet',
177.55 + '_RestrictOldApp',
177.56 + '_RestrictPasswd',
177.57 + '_RestrictPrinter',
177.58 + '_RestrictRegTools',
177.59 + '_RestrictRun',
177.60 + '_RestrictSaveSettings',
177.61 + '_RestrictScreen',
177.62 + '_RestrictSystem',
177.63 + '_SetIECache',
177.64 + '_Versione']
178.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
178.2 +++ b/lib/isi/conf/tools.py Mon Apr 26 11:16:23 2010 +0200
178.3 @@ -0,0 +1,300 @@
178.4 +# -*- coding: utf-8 -*-
178.5 +
178.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
178.7 +#
178.8 +# This program is free software: you can redistribute it and/or modify
178.9 +# it under the terms of the GNU General Public License as published by
178.10 +# the Free Software Foundation, either version 3 of the License, or
178.11 +# (at your option) any later version.
178.12 +#
178.13 +# This program is distributed in the hope that it will be useful,
178.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
178.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
178.16 +# GNU General Public License for more details.
178.17 +#
178.18 +# You should have received a copy of the GNU General Public License
178.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
178.20 +
178.21 +
178.22 +"""
178.23 +Classes to manage a configuration file adding and removing parameters
178.24 +
178.25 +Line
178.26 +----
178.27 +
178.28 +The module is based on Line, a class that holds the data of the single line and the
178.29 +information if it's a comment or not and handles the representation via str()
178.30 +
178.31 +It possible to build the line from a tring (when reading conf files) or by
178.32 +supplying paramteres param_name and value to the constructor.
178.33 +
178.34 +It's normal to need to customize deeply
178.35 +
178.36 +
178.37 +Conf
178.38 +----
178.39 +
178.40 +The class that represent the conf file, it's build from a real filename but
178.41 +can be fed a text (mainly for test purposes)
178.42 +
178.43 +it has these useful methods:
178.44 +
178.45 + * get_param(param_name)
178.46 + * set_param(param_name, value)
178.47 + * del_param(param_name, value=None)
178.48 + * len() # number of non-comment lines
178.49 + * len(obj) # number of physical lines
178.50 + * diff(other) # prints a unified diff format file of self and other
178.51 + * save() # save
178.52 +
178.53 +"""
178.54 +
178.55 +import re
178.56 +import xlrd
178.57 +
178.58 +class ValidationError(Exception): pass
178.59 +class UnknownParamName(ValidationError): pass
178.60 +class ParamRequireValue(ValidationError): pass
178.61 +
178.62 +class Line(object):
178.63 +
178.64 + VAR_PATTERN = re.compile(r"""
178.65 + (?P<comment>\s*\#\s*)? # a possible comment of the line
178.66 + (?P<param_name>[\w-]+) # the variable name
178.67 + \s*=* # ok, that's an assignement
178.68 + (?P<value>.*?) # got the value!, non greedy
178.69 + (?P<final_comment>\s*(\#.*)?) # a possible final comment
178.70 + $""", re.VERBOSE)
178.71 + param_name = None
178.72 + value = ''
178.73 + str_format = "%(param_name)s %(value)s"
178.74 + repr_format = "<%(param_name)s %(value)s>"
178.75 +
178.76 + def __init__(self, line=None, param_name=None, value=None, **kw):
178.77 + """
178.78 + create a line of the conf file. Comment line can be created passing line arg only::
178.79 +
178.80 + Line(domain-needed)
178.81 + Line(server=208.67.222.222)
178.82 + Line(param_name=..., value=...)
178.83 +
178.84 + """
178.85 + if line is None:
178.86 + self.param_name = param_name
178.87 + self.value = value
178.88 + self.final_comment = ''
178.89 + self.is_comment = False
178.90 + self.line = str(self)
178.91 + for key, val in kw.iteritems():
178.92 + setattr(self, key, val)
178.93 + else:
178.94 + self.line = line
178.95 + m = self.VAR_PATTERN.match(line.strip())
178.96 + if m:
178.97 + comm = m.group('comment')
178.98 + self.is_comment = True if (comm and '#' in comm) else False
178.99 + self.param_name = m.group('param_name')
178.100 + self.value = m.group('value')
178.101 + self.final_comment = m.group('final_comment') or ''
178.102 +
178.103 + else:
178.104 + self.is_comment = True
178.105 +
178.106 + if not self.is_comment:
178.107 + self.parse_value()
178.108 + self.validate()
178.109 +
178.110 + def parse_value(self):
178.111 + """
178.112 + parse the value and possibly assign istance attributes
178.113 + """
178.114 + return
178.115 +
178.116 + def validate(self):
178.117 + """
178.118 + raise ValidationError if value is not valid
178.119 + """
178.120 + return True
178.121 +
178.122 + def __str__(self):
178.123 + if self.is_comment:
178.124 + return self.line
178.125 + return self.str_format % vars(self)
178.126 +
178.127 + def __repr__(self):
178.128 + if self.is_comment:
178.129 + return self.line
178.130 + return self.repr_format % vars(self)
178.131 +
178.132 +class Conf(object):
178.133 +
178.134 + line_class = Line
178.135 + search_value = None
178.136 +
178.137 + def __init__(self, filename=None, text=None):
178.138 + """
178.139 + :param filename: the conf filename to be read
178.140 + :param text: a text to be used (test purpose)
178.141 + """
178.142 +
178.143 + assert filename or text, "You must set filename or text"
178.144 + self.filename = filename
178.145 + if filename:
178.146 + self.lines = [self.line_class(l) for l in open(filename)]
178.147 + else:
178.148 + self.lines = [self.line_class(l) for l in text.split('\n')]
178.149 +
178.150 + def get_param(self, param_name, value=None):
178.151 + """
178.152 + return the (possible) Line objects that have param_name
178.153 + """
178.154 + ret = []
178.155 + for l in self.lines:
178.156 + if not l.is_comment and l.param_name == param_name:
178.157 + ret += [l]
178.158 + if value:
178.159 + ret = [l for l in ret if l.value == value]
178.160 + return ret
178.161 +
178.162 + def set_param(self, param_name, value=None, **kw):
178.163 + """
178.164 + set a param/value
178.165 + if a row already exists for that param, it is used
178.166 + Kw: may be other params specific for Line
178.167 + """
178.168 + if self.search_value:
178.169 + lines = self.get_param(param_name, value=value, **kw)
178.170 + else:
178.171 + lines = self.get_param(param_name, **kw)
178.172 +
178.173 + if lines:
178.174 + line = lines[0]
178.175 + line.value = value
178.176 + for key, val in kw.iteritems():
178.177 + setattr(line, key, val)
178.178 + else:
178.179 +
178.180 + line = self.line_class(param_name=param_name, value=value, **kw)
178.181 + l = self.get_param(param_name)
178.182 + if len(l) == 0:
178.183 + idx = len(self.lines)
178.184 + else:
178.185 + idx = self.lines.index(l[-1])
178.186 +
178.187 + self.lines.insert(idx + 1, line)
178.188 +
178.189 + return line
178.190 +
178.191 + def del_param(self, param_name, value=None):
178.192 + """
178.193 + delete a parameter
178.194 + """
178.195 + kw = {}
178.196 + if value:
178.197 + kw['value'] = value
178.198 + try:
178.199 + l = self.get_param(param_name, **kw)[0]
178.200 + except IndexError, e:
178.201 + return
178.202 +
178.203 + self.lines.remove(l)
178.204 + return l
178.205 +
178.206 + def __str__(self):
178.207 + return "\n".join([str(l).strip() for l in self.lines])
178.208 +
178.209 + def __len__(self):
178.210 + return len(self.lines)
178.211 +
178.212 + def len(self):
178.213 + """Return the number of non-comment lines"""
178.214 + return len([l for l in self.lines if not l.is_comment])
178.215 +
178.216 + def diff(self, other, this_file='this.conf', other_file='other.conf'):
178.217 + """return a diff between self and other"""
178.218 +
178.219 + assert isinstance(other, self.__class__), "other must be a Logon instance (is %s)" % oter.__class__
178.220 + import difflib
178.221 + diff = []
178.222 +
178.223 + for line in difflib.unified_diff(["%s\n" % l for l in str(self).split('\n')],
178.224 + ["%s\n" % l for l in str(other).split('\n')],
178.225 + this_file, other_file):
178.226 + diff += [line]
178.227 + return "".join(diff)
178.228 +
178.229 + def save(self, filename=None):
178.230 + """
178.231 + saves the file
178.232 +
178.233 + :param filename: name of the file where to save (default: self.filename)
178.234 + """
178.235 + filename = filename or self.filename
178.236 +
178.237 + f = open(filename, 'w')
178.238 + f.write(str(self) + "\n")
178.239 + f.close()
178.240 +
178.241 +class Xls(object):
178.242 +
178.243 + def __init__(self, filename):
178.244 + try:
178.245 + self.book = xlrd.open_workbook(filename)
178.246 + except IOError, e:
178.247 + print e
178.248 +
178.249 + def xls2csv(self):
178.250 + "Really poor version of csv file just aimed at .isi format"
178.251 + output = []
178.252 + for i in self.get_sheet_as_list():
178.253 + output += [";".join([unicode(x.value) for x in i])]
178.254 + return "\n".join(output)
178.255 +
178.256 + def get_sheet_as_list(self, sheet_name=None, all_sheets=True):
178.257 + "get named sheet or all sheets"
178.258 + rows = []
178.259 + if sheet_name:
178.260 + try:
178.261 + sheet = self.book.sheet_by_name(sheet_name)
178.262 + except Exception, e:
178.263 + raise
178.264 +
178.265 + rows += self.get_rows(sheet)
178.266 +
178.267 + elif all_sheets is True and sheet_name is None:
178.268 + for index in range(self.book.nsheets):
178.269 + sheet = self.book.sheet_by_index(index)
178.270 + rows += self.get_rows(sheet)
178.271 + else:
178.272 + sheet = self.book.sheet_by_index(0)
178.273 + rows += self.get_rows(sheet)
178.274 +
178.275 + return rows
178.276 +
178.277 + def get_rows(self, sheet):
178.278 + if isinstance(sheet, int):
178.279 + sheet = self.book.sheet_by_index(sheet)
178.280 + rows = []
178.281 + for nrow in range(sheet.nrows):
178.282 + rows += [sheet.row(nrow)]
178.283 + return rows
178.284 +
178.285 +
178.286 +
178.287 +def is_mac_address(mac):
178.288 + pattern = '([a-f0-9]{2}[:|\-]?){6}'
178.289 + m = re.compile(pattern, re.I).search(mac)
178.290 + if m:
178.291 + return True
178.292 + return False
178.293 +
178.294 +def is_ip_address(ip):
178.295 +
178.296 + try:
178.297 + for token in ip.split('.'):
178.298 + if int(token) > 255:
178.299 + return False
178.300 + except ValueError:
178.301 + return False
178.302 + return True
178.303 +
179.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
179.2 +++ b/lib/isi/exc.py Mon Apr 26 11:16:23 2010 +0200
179.3 @@ -0,0 +1,39 @@
179.4 +from dry.functions import ExecuteError
179.5 +
179.6 +class MultipleMatch(Exception): pass
179.7 +class MissingClass(Exception): pass
179.8 +class MissingCourse(Exception): pass
179.9 +class MissingCourseMapping(Exception): pass
179.10 +class MissingMatch(Exception): pass
179.11 +class MissingPassword(Exception): pass
179.12 +class AuthenticationError(Exception): pass
179.13 +class MissingCF(Exception): pass
179.14 +class MissingMainGroup(Exception):
179.15 + def __init__(self, message, maingroup, user):
179.16 + super(MissingMainGroup, self).__init__(message)
179.17 + self.maingroup = maingroup
179.18 + self.user = user
179.19 +
179.20 +class MissingOrVoidGroup(Exception): pass
179.21 +
179.22 +class MultipleErrors(Exception): pass
179.23 +class AlreadyExistingUser(Exception):
179.24 + def __init__(self, message, logname):
179.25 + super(AlreadyExistingUser, self).__init__(message)
179.26 + self.logname = logname
179.27 +
179.28 +class AlreadyExistingGroup(Exception):
179.29 + def __init__(self, message, name):
179.30 + super(AlreadyExistingGroup, self).__init__(message)
179.31 + self.name = name
179.32 +
179.33 +class WrongParameters(Exception): pass
179.34 +class WrongOperation(Exception): pass
179.35 +
179.36 +class WrongLineFormat(Exception): pass
179.37 +class WrongFileFormat(Exception): pass
179.38 +
179.39 +class QuotaError(Exception): pass
179.40 +class DuplicateUid(Exception): pass
179.41 +class InvalidValue(Exception): pass
179.42 +
180.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180.2 +++ b/lib/isi/filesystem.py Mon Apr 26 11:16:23 2010 +0200
180.3 @@ -0,0 +1,305 @@
180.4 +#!/usr/bin/python
180.5 +# -*- coding: utf-8 -*-
180.6 +
180.7 +# This program is free software; you can redistribute it and/or modify
180.8 +# it under the terms of the GNU General Public License as published by
180.9 +# the Free Software Foundation; either version 2, or (at your option)
180.10 +# any later version.
180.11 +
180.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
180.13 +
180.14 +
180.15 +
180.16 +"""
180.17 +interaction with os system
180.18 +
180.19 +"""
180.20 +
180.21 +import os
180.22 +import sys
180.23 +from dry.functions import execute, ExecuteError
180.24 +from isi.conf import defaults, misc
180.25 +from isi import exc
180.26 +import isi
180.27 +import pexpect
180.28 +import shutil
180.29 +from glob import glob
180.30 +
180.31 +CLASS_SHARE = """
180.32 +
180.33 +[%(share_name)s]
180.34 + comment = Classe %(share_name)s
180.35 + path = %(share_path)s
180.36 + guest ok = no
180.37 + writable = yes
180.38 + browseable = no
180.39 +"""
180.40 +
180.41 +def samba_version():
180.42 + """le versioni successive alla 3.0.24 gestiscono
180.43 + in altro modo la scadenza password
180.44 + """
180.45 + ret = "3.0.24"
180.46 + try:
180.47 + r, o, e = execute("smbd -V")
180.48 + ret = o.replace('Version ', '')
180.49 + except:
180.50 + pass
180.51 + return ret
180.52 +
180.53 +def samba_domain():
180.54 + """restituisce il nome del dominio samba"""
180.55 + domain = None
180.56 + try:
180.57 + for line in open('/etc/samba/smb.conf'):
180.58 + line = line.strip('\n')
180.59 + line = line.strip()
180.60 + if "workgroup" in line:
180.61 + ll = line.split('=')
180.62 + if not '#' in ll[0] or ';' in ll[0]:
180.63 + domain = ll[1].strip()
180.64 + break
180.65 + except:
180.66 + pass
180.67 + return domain
180.68 +
180.69 +
180.70 +def show_file(out_file):
180.71 + ret = raw_input("Vuoi vedere %s (S/n)? " % out_file)
180.72 + if not ret: ret = 's'
180.73 + if ret in 'sS':
180.74 + cmd = 'less %s' % out_file
180.75 + c = pexpect.spawn(cmd)
180.76 + try:
180.77 + c.interact()
180.78 + except OSError, e:
180.79 + pass
180.80 +
180.81 +def has_acl_support(directory='/home'):
180.82 + """ return True if /home has acl support """
180.83 +
180.84 + ret_code, out, err = execute("df %s" % directory)
180.85 + info = out.split('\n')[1] # first line are headers
180.86 + partition = info.split()[0]
180.87 + ret_code, out, err = execute("grep -w %s /etc/mtab" % partition)
180.88 + if not ret_code:
180.89 + # /dev/sda8 /home xfs rw,usrquota,grpquota 0 0
180.90 + # /dev/sda8 /home ext3 defaults,rw,acl,usrquota,grpquota 0 0
180.91 + part, directory, fs, opts, j1, j2 = out.split()
180.92 + if fs == 'xfs':
180.93 + return True
180.94 + if 'acl' in opts:
180.95 + return True
180.96 +
180.97 + return False
180.98 +
180.99 +
180.100 +def home_delete(user, home=None, mode='tar', dry_run=False):
180.101 + """delete home. 'mode' can be: rm | tar | none"""
180.102 +
180.103 + if mode == 'none' or not os.path.exists(home):
180.104 + return
180.105 +
180.106 + if mode == 'tar':
180.107 + dest_file = "%s/%s.tgz" % (os.path.dirname(home), user)
180.108 + cmd = 'tar -czvf %s %s' % (dest_file, home)
180.109 + if os.path.exists(home):
180.110 + if dry_run:
180.111 + sys.stderr.write("DRY-RUN: else: %s\n" % cmd)
180.112 + else:
180.113 + ret_code, out, err = execute(cmd)
180.114 + if ret_code:
180.115 + raise ExecuteError("Error while tarring %s:\n %s" % (
180.116 + home, err))
180.117 + else:
180.118 + sys.stderr.write("Info: No %s to delete\n" % home)
180.119 +
180.120 + if dry_run:
180.121 + sys.stderr.write("DRY-RUN: else: %s\n" % "rm -Rf %s" % (home))
180.122 + else:
180.123 + try:
180.124 + shutil.rmtree(home)
180.125 + except Exception, e:
180.126 + raise ExecuteError("Error while deleting %s:\n %s" %
180.127 + (home, e))
180.128 +
180.129 +
180.130 +def home_create(user, home):
180.131 +
180.132 + shutil.copytree('/etc/skel', home)
180.133 + ret_code, out, err = execute('chown -R %s %s' % (user, home))
180.134 + if ret_code:
180.135 + raise Exception(err)
180.136 + home_perms(home, user)
180.137 +
180.138 +def create_class(name, course=False, samba_reload=True, manager=None):
180.139 + """
180.140 + create a class
180.141 +
180.142 + :param course: create a course instead
180.143 + :param samba_restart: restart samba so that it immediately make
180.144 + the class available to samba users
180.145 +
180.146 + """
180.147 + manager = manager or isi.Manager()
180.148 + try:
180.149 + group = manager.get_group(name)
180.150 + except exc.MissingMatch, e:
180.151 + group = manager.add_group(name)
180.152 +
180.153 + share_path = "%s/%s" % (defaults.COURSES_PATH if course else defaults.CLASSES_PATH, name)
180.154 + students = 'alunni' if not course else 'esterni'
180.155 + if not os.path.exists(share_path):
180.156 + os.mkdir(share_path)
180.157 + os.chown(share_path, -1, group.gid)
180.158 + os.chmod(share_path, 0755)
180.159 + cmd1 = "setfacl -R -m g:%s:rwx,g:%s:--- %s"
180.160 + cmd2 = "setfacl -R -d -m g:%s:rwx,g:%s:--- %s"
180.161 +
180.162 + for cmd in (cmd1, cmd2):
180.163 + ret_code, out, err = execute(cmd % (name, students, share_path))
180.164 + if ret_code:
180.165 + raise ExecuteError("Error while executing %s: %s" %(cmd, err))
180.166 +
180.167 + conf = misc.get_samba_conf()
180.168 + if not name in conf.sections():
180.169 + create_samba_class_share(name, share_path)
180.170 +
180.171 + if samba_reload:
180.172 + execute("/etc/init.d/samba reload")
180.173 +
180.174 +
180.175 +def create_samba_class_share(share_name, share_path, course=False):
180.176 + """
180.177 + Create a samba share for the class
180.178 +
180.179 + :param course: it's a course rathre that class
180.180 +
180.181 + """
180.182 +
180.183 + conf_file = "/etc/isi/samba/smb_%s.conf" % ('corsi' if course else 'classi')
180.184 + f = open(conf_file, 'a+')
180.185 + f.write(CLASS_SHARE % locals() + '\n')
180.186 +
180.187 +
180.188 +def home_move(user, old_home, new_home, maingroup, dry_run=False):
180.189 + """ sposta la homedir e riassegna i permessi"""
180.190 + if old_home == new_home: return
180.191 + cmd = "mv %s %s" % (old_home, new_home)
180.192 + if dry_run:
180.193 + sys.stderr.write("DRY-RUN: else: %s\n" % cmd)
180.194 + else:
180.195 + ret_code, out, err = execute(cmd)
180.196 + if ret_code:
180.197 + raise ExecuteError("Error while moving %s in %s:\n %s" %
180.198 + (old_home, new_home, err))
180.199 + home_perms(new_home)
180.200 +
180.201 +def home_perms(home, user):
180.202 +
180.203 + maingroup = home.split('/')[-2]
180.204 +
180.205 + # ownership
180.206 +# cmd = "chown -R %s:%s %s" % (user, maingroup, home)
180.207 +# cmd = "chown -R %s %s" % (user, home)
180.208 +# ret_code, out, err = execute(cmd)
180.209 +# if ret_code:
180.210 +# raise ExecuteError( \
180.211 +# "Error while assign ownership to %s at %s:\n %s" % \
180.212 +# (user, home, err))
180.213 +
180.214 + if maingroup in ('alunni', 'esterni'):
180.215 + cmd = "chgrp -R %s %s" % ('docenti', home)
180.216 + else:
180.217 + cmd = "chgrp -R %s %s" % (maingroup, home)
180.218 + ret_code, out, err = execute(cmd)
180.219 + if ret_code:
180.220 + raise ExecuteError( \
180.221 + "Error while assign group ownership to %s at %s:\n %s" % \
180.222 + (maingroup, home, err))
180.223 +
180.224 + # default permissions con o senza acl
180.225 + if maingroup in ('alunni', 'esterni'):
180.226 + cmd1 = "find %s -type d -exec chmod %s {} ;" % (home, defaults.PERMS_HOME_ALU)
180.227 + cmd2 = "find %s -type f -exec chmod %s {} ;" % (home, defaults.PERMS_FILE_ALU)
180.228 + else:
180.229 + cmd1 = "find %s -type d -exec chmod %s {} ;" % (home, defaults.PERMS_HOME_ALL)
180.230 + cmd2 = "find %s -type f -exec chmod %s {} ;" % (home, defaults.PERMS_FILE_ALL)
180.231 + ret_code, out, err = execute(cmd1)
180.232 + if ret_code:
180.233 + raise ExecuteError( \
180.234 + "Error while assign permission to dir in %s:\n %s" % (home, err))
180.235 + ret_code, out, err = execute(cmd2)
180.236 + if ret_code:
180.237 + raise ExecuteError( \
180.238 + "Error while assign permission to file in %s:\n %s" % (home, err))
180.239 + if has_acl_support('/home'):
180.240 + cmd = "setfacl -R -m u:%s:rwx %s" % (user, home)
180.241 + ret_code, out, err = execute(cmd)
180.242 + if ret_code:
180.243 + raise ExecuteError("Error while setfacl to %s\n %s\n %s" % (home, err, cmd))
180.244 +
180.245 + # cosa può fare www-data
180.246 + cmd = "setfacl -m u:www-data:x-- %s" % (home)
180.247 + ret_code, out, err = execute(cmd)
180.248 + if ret_code:
180.249 + raise ExecuteError("Error while setfacl to %s\n %s" % (home, err))
180.250 +
180.251 + public_html = home+'/public_html'
180.252 + if os.path.exists(public_html):
180.253 + cmd = "setfacl -R -m u:www-data:rx %s" % (public_html)
180.254 + ret_code, out, err = execute(cmd)
180.255 + if ret_code:
180.256 + raise ExecuteError("Error while setfacl to %s\n %s" %
180.257 + (public_html, err))
180.258 + cmd = "setfacl -dR -m u:www-data:rx %s" % (public_html)
180.259 + ret_code, out, err = execute(cmd)
180.260 + if ret_code:
180.261 + raise ExecuteError("Error while setfacl to %s\n %s" %
180.262 + (public_html, err))
180.263 +
180.264 +
180.265 +def create_alulink(classes, manager=None, group=None):
180.266 + """
180.267 + Create links of students belonging to classes
180.268 + :param classes: all classe or course for which alulink must be run
180.269 + :param group: the models.PosixGroup for which the links must be created
180.270 + :param manager: the isi.Manager() if group is not passed
180.271 +
180.272 + The difference is that courses have a separate share
180.273 + (COURSES_PATH rather that CLASSES_PATH)
180.274 +
180.275 + """
180.276 +
180.277 + if group:
180.278 + assert len(classes) < 2, "When setting group arg classes must have just 1 element"
180.279 +
180.280 + if not classes:
180.281 + return
180.282 +
180.283 + for cls in classes:
180.284 + if not group:
180.285 + group = manager.get_group(cls)
180.286 + members = group.members_as_users()
180.287 + if not members:
180.288 + continue
180.289 +
180.290 + PATH = defaults.COURSES_PATH if members[0].maingroup == 'esterni' else defaults.CLASSES_PATH
180.291 + class_path = '%s/%s' % (PATH, cls)
180.292 + if not os.path.exists(class_path):
180.293 + raise exc.MissingClass("The directory %s is not present" % class_path)
180.294 +
180.295 + alulink_path = '%s/alulink' % class_path
180.296 + if not os.path.exists(alulink_path):
180.297 + os.mkdir(alulink_path, 0755)
180.298 +
180.299 + for f in glob(alulink_path + '/*'):
180.300 + os.remove(f)
180.301 +
180.302 + for user in members:
180.303 + if isinstance(user, basestring):
180.304 + continue
180.305 + link_name = '%s/%s_%s' % (alulink_path, user.logname, user.full_name.replace(' ', '_'))
180.306 + os.symlink(user.home, link_name)
180.307 +
180.308 + group = None
181.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
181.2 +++ b/lib/isi/models.py Mon Apr 26 11:16:23 2010 +0200
181.3 @@ -0,0 +1,674 @@
181.4 +# -*- coding: utf-8 -*-
181.5 +
181.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
181.7 +#
181.8 +# This program is free software: you can redistribute it and/or modify
181.9 +# it under the terms of the GNU General Public License as published by
181.10 +# the Free Software Foundation, either version 3 of the License, or
181.11 +# (at your option) any later version.
181.12 +#
181.13 +# This program is distributed in the hope that it will be useful,
181.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
181.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
181.16 +# GNU General Public License for more details.
181.17 +#
181.18 +# You should have received a copy of the GNU General Public License
181.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
181.20 +
181.21 +
181.22 +import re
181.23 +import os
181.24 +import time
181.25 +import pumpkin
181.26 +from pumpkin import fields, filters
181.27 +from pumpkin.resource import LDAPResource
181.28 +from pumpkin.directory import Directory
181.29 +from pumpkin.base import Model
181.30 +import smbpasswd
181.31 +from dry.functions import execute, ExecuteError
181.32 +import exc
181.33 +import isi
181.34 +#from isi import filesystem
181.35 +from isi.conf import defaults
181.36 +import ldap
181.37 +import hashlib
181.38 +
181.39 +
181.40 +def get_conn(isiconn):
181.41 +
181.42 + LDAP_RES = LDAPResource()
181.43 + LDAP_RES.server = isiconn.uri
181.44 + LDAP_RES.login = isiconn.rootdn
181.45 + LDAP_RES.password = isiconn.passwd
181.46 + LDAP_RES.TLS = False
181.47 + LDAP_RES.basedn = isiconn.base
181.48 + LDAP_RES.method = pumpkin.resource.AUTH_SIMPLE
181.49 +
181.50 + LDAP_CONN = Directory()
181.51 + LDAP_CONN.connect(LDAP_RES)
181.52 + return LDAP_CONN
181.53 +
181.54 +def get_user(username, conn=None):
181.55 + if not conn:
181.56 + conn = isi.Manager().pumpkin_conn
181.57 +
181.58 + return conn.get(PosixUser, search_filter=filters.eq('uid', username))
181.59 +
181.60 +def get_samba_user(username, conn=None):
181.61 + if not conn:
181.62 + conn = isi.Manager().pumpkin_conn
181.63 + return conn.get(SambaUser, search_filter=filters.eq('uid', username))
181.64 +
181.65 +def get_user_by_cf(cf, conn):
181.66 + try:
181.67 + user = conn.get(PosixUser, search_filter=filters.eq('employeeNumber', cf))
181.68 + except Exception, e:
181.69 + if e.message == 'Multiple objects found':
181.70 + raise exc.MultipleMatch("CF %s is not unique!" % cf)
181.71 +
181.72 +def get_group(group_name, conn):
181.73 +
181.74 + g = conn.get(PosixGroup, search_filter=filters.eq('name', group_name))
181.75 + if not g:
181.76 + raise exc.MissingMatch("No group with name '%s'" % group_name)
181.77 + return g
181.78 +
181.79 +def get_domain(domain_name, conn):
181.80 + d = conn.get(SambaDomain, search_filter=filters.eq('sambaDomainName', domain_name))
181.81 + if not d:
181.82 + raise exc.MissingMatch("No domain with name '%s'" % domain_name)
181.83 + return d
181.84 +
181.85 +def get_samba_group(group_name, conn):
181.86 + g = conn.get(SambaGroup, search_filter=filters.eq('name', group_name))
181.87 + if not g:
181.88 + raise exc.MissingMatch("No group with name '%s'" % group_name)
181.89 + return g
181.90 +
181.91 +def get_group_by_gid(gidNumber, conn):
181.92 + g = conn.get(PosixGroup, search_filter=filters.eq('gidNumber', gidNumber))
181.93 + if not g:
181.94 + raise exc.MissingMatch("No group with gid = %s" % gidNumber)
181.95 + return g
181.96 +
181.97 +class StringField(fields.StringField):
181.98 + """Unicode string
181.99 + """
181.100 + default = None
181.101 +
181.102 + def validate(self, values):
181.103 + """Check if new value is unicode
181.104 + """
181.105 + if isinstance(values, unicode):
181.106 + return values
181.107 + elif isinstance(values, basestring):
181.108 + return unicode(values)
181.109 + else:
181.110 + raise ValueError, "Not a unicode value: %s" % values
181.111 +
181.112 +class PosixUser(Model):
181.113 +
181.114 + """This is my custom model"""
181.115 +
181.116 + _object_class_ = ['posixAccount', 'inetOrgPerson', 'shadowAccount', 'organizationalPerson']
181.117 +
181.118 + _rdn_ = 'logname'
181.119 +
181.120 + __base_data__ = ['classe','first_name', 'last_name', 'cf']
181.121 + __extended_data__ = ['sex', 'address', 'city', 'zip_code', 'phone']
181.122 + # __orphan__ = ['password', 'full_name', 'logname', 'uid', 'gid']
181.123 + logname = StringField('uid')
181.124 + _classe = StringField('departmentNumber')
181.125 + uid = fields.IntegerField('uidNumber')
181.126 + gid = fields.IntegerField('gidNumber')
181.127 + full_name = StringField('cn')
181.128 + first_name = StringField('givenName')
181.129 + last_name = StringField('sn')
181.130 + shell = StringField('loginShell')
181.131 + home = StringField('homeDirectory')
181.132 + mail = fields.StringListField('mail')
181.133 + cf = StringField('employeeNumber')
181.134 + password = StringField('userPassword')
181.135 +
181.136 + sex = StringField('employeeType')
181.137 + address = StringField('postalAddress')
181.138 + city = StringField('postOfficeBox')
181.139 + zip_code = StringField('postalCode')
181.140 + phone = StringField('telephoneNumber')
181.141 +
181.142 +
181.143 + def url(self, text=None):
181.144 + return u'<a href="/users/user/detail/%s">%s</a>' % (self.logname, text or self.logname)
181.145 +
181.146 + ### password
181.147 + def test_password(self, pwd):
181.148 + """
181.149 + controlla la validità delle credenziali
181.150 + """
181.151 + if not pwd:
181.152 + return False
181.153 + conn = ldap.initialize(self.directory._ldapconn._uri)
181.154 + try:
181.155 + conn.bind_s(self.dn, pwd, ldap.AUTH_SIMPLE)
181.156 + return True
181.157 + except ldap.INVALID_CREDENTIALS, e:
181.158 + return False
181.159 +
181.160 + def set_password(self, password, force_change=False):
181.161 + """set password for user.
181.162 + :param password: the new password
181.163 + :param force_change: set force_change_password
181.164 + """
181.165 + if not password:
181.166 + return
181.167 +
181.168 + self.password = make_pass(password)
181.169 +
181.170 + if force_change:
181.171 + self.expire_password()
181.172 + self.save()
181.173 +
181.174 + def expire_password(self, gg=0):
181.175 + """
181.176 + Forza la scandenza password. Al momento disabilitato causa probelmi con gdm
181.177 + """
181.178 + # shadowLastChange al momento non funziona con X
181.179 + #self.srv.modify(user,'shadowLastChange','0')
181.180 + return
181.181 +
181.182 + def get_my_groups(self, as_text=False, as_plain_list=False):
181.183 + """
181.184 + return the groups the user belongs to
181.185 + :param as_test: as text string to be shown
181.186 + """
181.187 +
181.188 + filter_cond = filters.opand(filters.eq('memberUid', self.logname),
181.189 + filters.eq('objectClass', 'posixGroup'))
181.190 + groups = self.directory.search(PosixGroup, search_filter=filter_cond)
181.191 + if not isinstance(groups, list):
181.192 + groups = [groups]
181.193 + if as_text:
181.194 + return ",".join(g.name for g in groups)
181.195 + if as_plain_list:
181.196 + return [g.name for g in groups]
181.197 + return groups
181.198 +
181.199 + def _get_maingroup(self):
181.200 + try:
181.201 + return self._maingroup
181.202 + except AttributeError:
181.203 + try:
181.204 + return get_group_by_gid(self.gid, self.directory).name
181.205 + except:
181.206 + return self.gid
181.207 +
181.208 + def _set_maingroup(self, group_name):
181.209 + group = get_group(group_name, self.directory)
181.210 + self._maingroup = group_name
181.211 + self.gid = group.gid
181.212 +
181.213 + maingroup = property(_get_maingroup, _set_maingroup)
181.214 +
181.215 + def _get_classe(self):
181.216 + return self._classe
181.217 +
181.218 + def _set_classe(self, classe):
181.219 +
181.220 + if self.maingroup not in ('alunni', 'esterni'):
181.221 + return
181.222 +
181.223 + if self.classe == classe:
181.224 + ## nothing to do
181.225 + return
181.226 +
181.227 + old_class_name = self.classe
181.228 + try:
181.229 + old_class = get_group(old_class_name, self.directory)
181.230 + old_class.remove_member(self.logname)
181.231 + except exc.MissingMatch, e:
181.232 + pass
181.233 +
181.234 + self._classe = classe
181.235 + classe = get_group(classe, self.directory)
181.236 + classe.add_member(self.logname)
181.237 +
181.238 + classe = property(_get_classe, _set_classe)
181.239 +
181.240 + def set_groups(self, new_groups, posix_groups=None):
181.241 + """
181.242 + set membership of groups to reflect that of 'new_groups'
181.243 +
181.244 + :param new_groups: a set of groups that should be set
181.245 + :param posix_groups: for efficiency reason, a dict of group items
181.246 + can be passed
181.247 + """
181.248 + posix_groups = posix_groups or {}
181.249 + old_groups = set(self.get_my_groups(as_plain_list=True))
181.250 + if not isinstance(new_groups, set):
181.251 + new_groups = set(new_groups)
181.252 +
181.253 + for group_name in old_groups.union(new_groups):
181.254 + if group_name not in posix_groups:
181.255 + group = get_group(group_name, self.directory)
181.256 + if group:
181.257 + posix_groups[group_name] = group
181.258 + else:
181.259 + raise
181.260 +
181.261 + ## remove from groups no longer needed
181.262 + for group_name in old_groups.difference(new_groups):
181.263 + posix_groups[group_name].remove_member(self.logname, save=True)
181.264 +
181.265 + ## add membership to new groups
181.266 + for group_name in new_groups.difference(old_groups):
181.267 + posix_groups[group_name].add_member(self.logname, save=True)
181.268 +
181.269 +
181.270 + def delete(self, home_mode='tar'):
181.271 + self.home_mode = home_mode
181.272 + Model.delete(self)
181.273 +
181.274 + def _hook_post_delete(self):
181.275 + """
181.276 + Delete the personal group if it exists
181.277 + """
181.278 + ## delete personal group
181.279 + try:
181.280 + personal_group = get_group(self.logname, self.directory)
181.281 + personal_group.delete()
181.282 + except Exception:
181.283 + pass
181.284 +
181.285 + ### membership
181.286 + for g in self.get_my_groups():
181.287 + g.remove_member(self.logname)
181.288 +
181.289 + ### delete the home
181.290 + if self.home_mode:
181.291 + filesystem.home_delete(self.logname, self.home, mode=self.home_mode)
181.292 +
181.293 + def set_quota(self, soft_space, hard_space, soft_files, hard_files, fs='/home'):
181.294 + """ imposta la quota di un utente
181.295 +
181.296 + :param soft_space: soft disc space limit
181.297 + :param hard_space: hard disc space limit
181.298 + :param soft_files: soft file number limit
181.299 + :param hard_files: hard file number limit
181.300 + :param fs: the filesystem for which quota must be set
181.301 + """
181.302 +
181.303 + cmd = "setquota -u %s %s %s %s %s %s" % (self.logname, soft_space, hard_space, soft_files, hard_files, fs)
181.304 +
181.305 + ret, out, err = execute(cmd)
181.306 + if ret:
181.307 + raise exc.QuotaError(err)
181.308 +
181.309 + def as_isi_format(self, extended=False):
181.310 + """
181.311 + return the user isi 'isi' format: ie. as used by isi-adduser
181.312 + """
181.313 +
181.314 + record = [self.logname, self.last_name, self.first_name or '', self.maingroup,
181.315 + self.classe or '', self.cf or '', '']
181.316 + if extended:
181.317 + city, pv = '', ''
181.318 + pattern = re.compile('^(?P<city>.*)\((?P<pv>..)\)')
181.319 + m = pattern.match(self.city or '')
181.320 + if m:
181.321 + city = cp.group('city').strip()
181.322 + pv = cp.group('pv')
181.323 +
181.324 +
181.325 + record += [self.sex or '', self.address or '', city, pv, self.zip_code or '', self.phone or '']
181.326 +
181.327 + return ";".join(record)
181.328 +
181.329 + def as_dict(self):
181.330 + """return a dict with all attributes of the user if non empty
181.331 + used in django views to fill forms"""
181.332 +
181.333 + user_dict = {}
181.334 + for attr in self.__base_data__ + self.__extended_data__ + [
181.335 + 'logname', 'uid', 'full_name', 'home', 'maingroup', 'gid']:
181.336 + if getattr(self, attr):
181.337 + user_dict[attr] = getattr(self, attr)
181.338 + user_dict['groups'] = self.get_my_groups(as_text=True)
181.339 + return user_dict
181.340 +
181.341 + def get_quota(self, fs='/home'):
181.342 + """
181.343 + return (used, quota, limit) for space limits
181.344 + """
181.345 +
181.346 + ret_code, out, err = execute("quota -v %s " % self.logname)
181.347 + if ret_code:
181.348 + raise exc.MissingQuotaSupport()
181.349 + info = out.split('\n')[-1]
181.350 +
181.351 + filesystem, self.used, self.quota, self.limit = info.split()[:3]
181.352 + return (self.used, self.quota, self.limit)
181.353 +
181.354 + def __str__(self):
181.355 + return u'%s' % (self.logname, )
181.356 +
181.357 + def __repr__(self):
181.358 + return u'<PosixUser %s>' % (self.logname, )
181.359 +
181.360 +class SambaUser(PosixUser):
181.361 + _object_class_ = ['sambaSamAccount',]
181.362 +
181.363 + nthash = StringField('sambaNTPassword')
181.364 + lmhash = StringField('sambaLMPassword')
181.365 + logon = StringField('sambaLogonScript')
181.366 + sambaHomePath = StringField('sambaHomePath')
181.367 + sambamax = fields.IntegerField('shadowMax')
181.368 + sambaPwdMustChange = fields.IntegerField('sambaPwdMustChange')
181.369 + sambaPwdLastSet = fields.IntegerField('sambaPwdLastSet')
181.370 + flags = StringField('sambaAcctFlags')
181.371 +
181.372 + def test_samba_password(self, pwd, client=False):
181.373 + """
181.374 + controlla la validità delle credenziali
181.375 + :param client: use an external client (smbclient)
181.376 + the problem is that a password that has been forced to expire
181.377 + would not validate
181.378 + """
181.379 + if not pwd:
181.380 + return False
181.381 + if client:
181.382 + ret_code, out, err = execute('smbclient -L localhost -U %s%%%s' % (self.logname, pwd))
181.383 + return not bool(ret_code)
181.384 + else:
181.385 + return (self.lmhash, self.nthash) == smbpasswd.hash(pwd)
181.386 +
181.387 + def expire_password(self, gg=0):
181.388 + """
181.389 + force the password to expire
181.390 +
181.391 + :param gg: termine entro il quale deve essere fatta scadere la password (non implementato)
181.392 + """
181.393 +
181.394 + PosixUser.expire_password(self, gg=gg)
181.395 +
181.396 + self.sambaPwdLastSet = 0
181.397 + # for samba < 3.0.24
181.398 + #self.srv.modify(user,'sambaPwdMustChange','0')
181.399 +
181.400 + def set_password(self, password, force_change=False):
181.401 + """
181.402 + force the password to expire
181.403 + """
181.404 + if not password:
181.405 + return
181.406 + self.lmhash, self.nthash = [unicode(s) for s in smbpasswd.hash(password)]
181.407 + self.sambaPwdLastSet = int(time.time())
181.408 + PosixUser.set_password(self, password, force_change=force_change)
181.409 +
181.410 +class PosixGroup(Model):
181.411 + _object_class_ = ['posixGroup', ]
181.412 + _rdn_ = 'name'
181.413 + name = StringField('cn')
181.414 + gid = fields.IntegerField('gidNumber')
181.415 + members = fields.StringListField('memberUid')
181.416 + description = StringField('description')
181.417 +
181.418 + def __repr__(self):
181.419 + return u'<%s %s >' % (self.__class__.__name__, self.name)
181.420 +
181.421 + def __str__(self):
181.422 + return u'%s' % (self.name)
181.423 +
181.424 + def url(self, text=None):
181.425 + return u'<a href="/users/group/%s">%s</a>' % (self.name, text or self.name)
181.426 +
181.427 + def is_class(self):
181.428 + "return true if a directory exists in CLASSES_PATH with this name"
181.429 + return os.path.exists(os.path.join(defaults.CLASSES_PATH, self.name))
181.430 +
181.431 + def is_course(self):
181.432 + "return true if a directory exists in COURSES_PATH with this name"
181.433 + return os.path.exists(os.path.join(defaults.COURSES_PATH, self.name))
181.434 +
181.435 + def create_links(self):
181.436 + """
181.437 + run alulink if this is a aclass or course
181.438 + """
181.439 + from isi import filesystem
181.440 + if self.is_class() or self.is_course():
181.441 + filesystem.create_alulink((self.name,), group=self)
181.442 +
181.443 + def _get_my_share(self):
181.444 + """
181.445 + return class or course path if group is class or course
181.446 + return None otherwise
181.447 + """
181.448 + try:
181.449 + return self._share
181.450 + except AttributeError:
181.451 + if self.is_class():
181.452 + self._share = os.path.join(defaults.CLASSES_PATH, self.name)
181.453 + elif self.is_course():
181.454 + self._share = os.path.join(defaults.COURSES_PATH, self.name)
181.455 + return self._share
181.456 + return None
181.457 +
181.458 + share = property(_get_my_share)
181.459 +
181.460 +
181.461 + def members_info(self):
181.462 + if self.members:
181.463 + return "members: %s (%s)" % (len(self.members), ",".join(self.members[:8]))
181.464 + return ''
181.465 +
181.466 + def ismember(self, uid):
181.467 + """Return True if given uid is member of this group.
181.468 + """
181.469 + return uid in self.members
181.470 +
181.471 + def members_as_users(self, fake=False, order_by=None, samba=True):
181.472 + """
181.473 + :param fake: get also fake users as unicode strings
181.474 + A fake user is a user that no more exists but is still referenced as a member
181.475 + :param ordered: return members in alfabetical order on the last_name (only if fake=False)
181.476 + """
181.477 +
181.478 + members = sorted(self.members)
181.479 + if fake:
181.480 + return [get_user(u, self.directory) or u for u in members]
181.481 + else:
181.482 + if samba:
181.483 + members = filter(None, [get_samba_user(u, self.directory) for u in members])
181.484 + else:
181.485 + members = filter(None, [get_user(u, self.directory) for u in members])
181.486 +
181.487 + if order_by:
181.488 + return sorted(members, key=lambda x: getattr(x, order_by))
181.489 + else:
181.490 + return members
181.491 +
181.492 + def get_zombie_users(self):
181.493 + """check that each member is a system user, returns a list of
181.494 + user that are not system users (fake users)"""
181.495 +
181.496 + return [u for u in self.members_as_users(fake=True) if not u]
181.497 +
181.498 + def add_member(self, name, save=True):
181.499 + """
181.500 + add a user as mamber of this group
181.501 + """
181.502 + if name not in self.members:
181.503 + self.members += [unicode(name)]
181.504 + if save:
181.505 + self.save()
181.506 +
181.507 + def remove_member(self, member, save=True):
181.508 + """
181.509 + Remove a member from the group. The user is not deleted
181.510 + :param member: the member to remove: string or PosixUser
181.511 + :param save: (boolean) save the group after removeing the user
181.512 + """
181.513 + # Note! members.pop() doesn't work!
181.514 +
181.515 + if isinstance(member, basestring):
181.516 + logname = member
181.517 + else:
181.518 + logname = member.logname
181.519 +
181.520 + if logname in self.members:
181.521 + self.members = [u for u in self.members if not u == logname]
181.522 + if save:
181.523 + self.save()
181.524 +
181.525 + def delete_members(self, save=True, home_mode='tar', maingroup=True):
181.526 + """
181.527 + Delete all members of this group
181.528 + :param maingroup: delete also people that have this as maingroup
181.529 + """
181.530 + for u in self.members_as_users(fake=True):
181.531 + self.remove_member(u, save=True)
181.532 + try:
181.533 + u.delete(home_mode=home_mode)
181.534 + except AttributeError: # fake users
181.535 + pass
181.536 + self.members = []
181.537 +
181.538 + if maingroup:
181.539 + others = self.directory.search(PosixUser, search_filter=filters.eq('gidNumber', self.gid))
181.540 + for user in others:
181.541 + user.delete(home_mode=home_mode)
181.542 +
181.543 + if save:
181.544 + self.save()
181.545 +
181.546 + def expire_password(self, gg=0, samba=True):
181.547 +
181.548 + for user in self.members_as_users(samba=samba):
181.549 + user.expire_password(gg=gg)
181.550 +
181.551 + def get_www(self):
181.552 +
181.553 + return 'nowww' in (self.description or '')
181.554 +
181.555 + def as_isi_format(self, extended=False):
181.556 + """
181.557 + return all members in 'isi' format
181.558 + """
181.559 + records = [u.as_isi_format(extended) for u in self.members_as_users() if u]
181.560 + return "\n".join(records)
181.561 +
181.562 + def set_www(self, www):
181.563 + """
181.564 + inhibit internet browsing to all users
181.565 + """
181.566 + wgroup = get_group('nowww', self.directory)
181.567 +
181.568 + if www: # permetti navigazioe
181.569 + self.description = re.sub('nowww', '', self.description or '')
181.570 + for name in self.members:
181.571 + wgroup.remove_member(name)
181.572 +
181.573 + else: # inhibit browsing
181.574 + self.description = u"%s nowww" % (self.description or '')
181.575 + for name in self.members:
181.576 + wgroup.members += [name]
181.577 + self.save()
181.578 + wgroup.save()
181.579 +
181.580 + def set_quota(self, soft_space, hard_space, soft_files, hard_files, fs='/home'):
181.581 + """ imposta la quota di un utente
181.582 +
181.583 + :param soft_space: soft disc space limit
181.584 + :param hard_space: hard disc space limit
181.585 + :param soft_files: soft file number limit
181.586 + :param hard_files: hard file number limit
181.587 + :param fs: the filesystem for which quota must be set (default: /home)
181.588 + """
181.589 +
181.590 + cmd = "setquota -g %s %s %s %s %s %s" % (self.logname, soft_space, hard_space, soft_files, hard_files, fs)
181.591 +
181.592 + ret_code, out, err = execute(cmd)
181.593 + if ret_code:
181.594 + raise exc.QuotaError(err)
181.595 +
181.596 + def set_members_quota(self, soft_space, hard_space, soft_files, hard_files, fs='/home'):
181.597 + """ setta la quota di tutti i membri di un gruppo """
181.598 +
181.599 + for user in self.members_as_users(fake=False):
181.600 +
181.601 + touch_file = '%s/touch.%s' % (fs, u)
181.602 + open(touch_file).close()
181.603 + os.chown(touch_file, user.logname, gruppo.name)
181.604 + user.set_quota(soft_space, hard_space, soft_files, hard_files, fs)
181.605 +
181.606 +
181.607 + # setta la quota di gruppo come somma delle quote dei membri
181.608 +# n = len(self.members)
181.609 +# cmd = "setquota -g %s %s %s %s %s %s" % (self.name, soft_space*n, hard_space*n,
181.610 +# soft_files*n, hard_files*n, fs)
181.611 +# ret, out, err = execute(cmd)
181.612 +# if ret:
181.613 +# raise QuotaError(err)
181.614 +
181.615 + ## a che serve?
181.616 +# execute('repquota -au', stdout='/tmp/repquota.txt')
181.617 +# execute('repquota -ag', stdout='>>/tmp/repquota.txt')
181.618 + execute('rm %s/touch.*' % fs)
181.619 +
181.620 +
181.621 +class SambaGroup(PosixGroup):
181.622 + _object_class_ = ['posixGroup', 'sambaGroupMapping' ]
181.623 + sid = StringField('sambaSID')
181.624 +
181.625 + def members_as_users(self):
181.626 +
181.627 + return [get_samba_user(u, self.directory) for u in sorted(self.members)]
181.628 +
181.629 +class SambaDomain(Model):
181.630 + _object_class_ = ['sambaUnixIdPool', 'sambaDomain' ]
181.631 + domain_name = StringField('sambaDomainName')
181.632 + sid = StringField('sambaSID')
181.633 + next_gid = fields.IntegerField('gidNumber')
181.634 + next_uid = fields.IntegerField('uidNumber')
181.635 + sambaPwdHistoryLength = fields.IntegerField('sambaPwdHistoryLength')
181.636 + sambaMinPwdLength = fields.IntegerField('sambaMinPwdLength')
181.637 + sambaMinPwdAge = fields.IntegerField('sambaMinPwdAge')
181.638 + sambaMaxPwdAge = fields.IntegerField('sambaMaxPwdAge')
181.639 + sambaLogonToChgPwd = fields.IntegerField('sambaLogonToChgPwd')
181.640 +
181.641 + def get_next_uid(self):
181.642 + """return the next uid and increments it"""
181.643 +
181.644 + next = self.next_uid
181.645 + self.next_uid += 1
181.646 + self.save()
181.647 + return next
181.648 +
181.649 + def get_next_gid(self):
181.650 + """return the next uid and increments it"""
181.651 +
181.652 + next = self.next_gid
181.653 + self.next_gid += 1
181.654 + self.save()
181.655 + return next
181.656 +
181.657 +def make_pass(password):
181.658 + """
181.659 + generate a pass suitable for openldap
181.660 + """
181.661 + # http://www.openldap.org/faq/data/cache/347.html
181.662 + from base64 import encodestring as encode
181.663 + salt = os.urandom(4)
181.664 + h = hashlib.sha1(password)
181.665 + h.update(salt)
181.666 + return u"{SSHA}" + encode(h.digest() + salt)
181.667 +
181.668 +def check_pass(challenge_password, password):
181.669 +
181.670 + from base64 import decodestring as decode
181.671 +
181.672 + challenge_bytes = decode(challenge_password[6:])
181.673 + digest = challenge_bytes[:20]
181.674 + salt = challenge_bytes[20:]
181.675 + hr = hashlib.sha1(password)
181.676 + hr.update(salt)
181.677 + return digest == hr.digest()
182.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
182.2 +++ b/lib/isi/parser.py Mon Apr 26 11:16:23 2010 +0200
182.3 @@ -0,0 +1,172 @@
182.4 +# -*- coding: utf-8 -*-
182.5 +
182.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
182.7 +#
182.8 +# This program is free software: you can redistribute it and/or modify
182.9 +# it under the terms of the GNU General Public License as published by
182.10 +# the Free Software Foundation, either version 3 of the License, or
182.11 +# (at your option) any later version.
182.12 +#
182.13 +# This program is distributed in the hope that it will be useful,
182.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
182.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
182.16 +# GNU General Public License for more details.
182.17 +#
182.18 +# You should have received a copy of the GNU General Public License
182.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
182.20 +
182.21 +
182.22 +import re
182.23 +import exc
182.24 +import string
182.25 +import random
182.26 +
182.27 +class UserParser(object):
182.28 +
182.29 +
182.30 + action = None
182.31 + "action may be: add, delete, update"
182.32 +
182.33 + def __init__(self,
182.34 + manager,
182.35 + definition_string,
182.36 + interactive = False,
182.37 + update_user = True,
182.38 + no_filesystem = False,
182.39 + run_alulink = True,
182.40 +
182.41 + default_passwd = None,
182.42 + update_passwd = True,
182.43 + force_passwd_change = True,
182.44 + passwd_random = False,
182.45 + use_cf=None,
182.46 + ):
182.47 + """
182.48 + Definition string may have 6, 7 or 13 fields
182.49 + logname last_name, first_name, maingroup, minor_groups, cf, [password]
182.50 + extended fields:
182.51 + sesso, indirizzo, comune_residenza, cap, provincia, tel1
182.52 +
182.53 + :param no_filesystem: opts.no_filesystem,
182.54 + :param update_user: if the user exists must be updated,
182.55 + :param update_passwd: opts.update_passwd,
182.56 + :param home_mode: 'tar' if not opts.home_zap or 'rm',
182.57 + :param force_passwd_change: opts.force_change_passwd
182.58 +
182.59 +
182.60 + logname;last;name;maingrp;other_grp1,othergrp2...;CF;PASS;list_ext_flds
182.61 + If password is missing, password is set from cf
182.62 + If cf is missing password MUST be set
182.63 +
182.64 + """
182.65 + self.manager = manager
182.66 + self.interactive = interactive
182.67 + self.manager = manager
182.68 + self.update_user = update_user
182.69 + self.no_filesystem = no_filesystem
182.70 + self.run_alulink = run_alulink
182.71 +
182.72 + ### password related options
182.73 + self.update_passwd = update_passwd
182.74 + self.force_passwd_change = force_passwd_change
182.75 + self.default_passwd = default_passwd
182.76 + self.passwd_random = passwd_random
182.77 + self.use_cf = use_cf
182.78 +
182.79 + ## parsing the definition_string
182.80 + self.definition_string = definition_string.strip()
182.81 + fields = [x.strip() for x in self.definition_string.split(';')]
182.82 +
182.83 + self.action, self.logname = self.guess_action(fields[0])
182.84 +
182.85 + if self.action == 'delete':
182.86 + return
182.87 +
182.88 + self.last_name = fields[1].title()
182.89 + self.first_name = fields[2].title()
182.90 + self.maingroup = fields[3].lower()
182.91 + self.groups = [x for x in fields[4].split(',') if x]
182.92 + self.classe = self.groups and self.groups[0] or None
182.93 + try:
182.94 + self.cf = fields[5].upper()
182.95 + except IndexError:
182.96 + self.cf = ''
182.97 +
182.98 + self.passwd = self.create_passwd(fields)
182.99 + if len(fields) >= 13:
182.100 + self.sex, self.address, self.city, self.zip, self.pv, self.phone = fields[7:13]
182.101 + else:
182.102 + self.sex, self.address, self.city, self.zip, self.pv, self.phone = [None] * 6
182.103 +
182.104 + self.extended_attrs = {}
182.105 +
182.106 +
182.107 + def guess_action(self, logname):
182.108 + """
182.109 + guess which action should be taken from the logname depending on +, -, * or None
182.110 + """
182.111 +
182.112 + m = re.match('(?P<mode>[-*+])?(?P<logname>.*)', logname)
182.113 + mode = m.group('mode')
182.114 + logname = m.group('logname').lower()
182.115 +
182.116 + if mode == '-':
182.117 + action = 'delete'
182.118 + return action, logname
182.119 +
182.120 + user_exists = self.manager.user_exists(logname)
182.121 + if user_exists and not self.update_user:
182.122 + raise exc.AlreadyExistingUser("User %s already exists" % logname, logname)
182.123 +
182.124 + if mode == '*' or user_exists:
182.125 + action = 'update'
182.126 + else:
182.127 + action = 'add'
182.128 +
182.129 + return action, logname
182.130 +
182.131 + def create_passwd(self, fields):
182.132 +
182.133 + if not self.update_passwd and self.action == 'update':
182.134 + return None
182.135 +
182.136 + if self.use_cf:
182.137 + passwd = self.cf[:8].title()
182.138 + elif self.passwd_random:
182.139 + passwd = new_password()
182.140 + elif self.default_passwd:
182.141 + passwd = self.default_passwd
182.142 + else:
182.143 + try:
182.144 + passwd = fields[6]
182.145 + except IndexError:
182.146 + raise exc.MissingPassword("Missing password for user %s defined by\n%s" %
182.147 + (self.logname, self.definition_string))
182.148 +
182.149 + return passwd
182.150 +
182.151 + def get_opts(self):
182.152 +
182.153 + user_opts = {
182.154 + 'interactive' : self.interactive,
182.155 + 'no_filesystem' : self.no_filesystem,
182.156 + 'run_alulink' : self.run_alulink,
182.157 + 'force_passwd_change' : self.force_passwd_change,
182.158 + 'last_name' : self.last_name,
182.159 + 'first_name' : self.first_name,
182.160 + 'groups' : self.groups,
182.161 + 'passwd' : self.passwd,
182.162 + 'classe' : self.classe,
182.163 + 'cf' : self.cf,
182.164 + 'sex' : self.sex,
182.165 + 'address' : self.address,
182.166 + 'city' : self.city,
182.167 + 'zip_code' : self.zip,
182.168 + 'phone' : self.phone,
182.169 + }
182.170 + return user_opts
182.171 +
182.172 +def new_password(length=8, chars=string.letters + string.digits):
182.173 + """ genera una password casuale """
182.174 + return ''.join([random.choice(chars) for i in range(length)])
182.175 +
183.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183.2 +++ b/lib/isi/srv.py Mon Apr 26 11:16:23 2010 +0200
183.3 @@ -0,0 +1,1182 @@
183.4 +#!/usr/bin/python
183.5 +# -*- coding: utf-8 -*-
183.6 +
183.7 +# This program is free software; you can redistribute it and/or modify
183.8 +# it under the terms of the GNU General Public License as published by
183.9 +# the Free Software Foundation; either version 2, or (at your option)
183.10 +# any later version.
183.11 +
183.12 +
183.13 +# AUTHORS: Sandro Dentella - Massimo Mancini
183.14 +
183.15 +
183.16 +"""module to perform all basic operations with ldap server
183.17 +"""
183.18 +
183.19 +import ldap
183.20 +import re, string, random
183.21 +import sys
183.22 +import os
183.23 +import logging
183.24 +from logging import handlers
183.25 +from pprint import pprint
183.26 +#import subprocess as sub
183.27 +import datetime
183.28 +from dry.functions import execute, ExecuteError
183.29 +from isi import filesystem, exc
183.30 +from isi.conf import defaults
183.31 +from time import mktime, localtime, strftime
183.32 +from parser import UserParser
183.33 +import models
183.34 +
183.35 +SCOPE = ldap.SCOPE_SUBTREE
183.36 +
183.37 +## logger generico
183.38 +def get_logger(web=False):
183.39 + if web:
183.40 + # create logger
183.41 + logger = logging.getLogger("IdraWeb")
183.42 + logger.setLevel(logging.DEBUG)
183.43 +
183.44 + # create syslog handler and set level to debug
183.45 + sl = handlers.SysLogHandler(address='/dev/log')
183.46 + sl.setLevel(logging.DEBUG)
183.47 +
183.48 + # create formatter
183.49 + formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
183.50 + sl.setFormatter(formatter)
183.51 +
183.52 + logger.addHandler(sl)
183.53 +
183.54 + else:
183.55 + logging.basicConfig(filename=defaults.LOG_FILE,
183.56 + filemode=defaults.LOG_MODE,
183.57 + format=defaults.LOG_FORMAT,
183.58 + datefmt=defaults.LOG_DATE_FORMAT)
183.59 +
183.60 + logger = logging.getLogger('isi')
183.61 + return logger
183.62 +
183.63 +
183.64 +### Definizione classi ###
183.65 +
183.66 +class IsiConn(object):
183.67 + """
183.68 + Allows ANONYMOUS BIND passing dn="", passwd="" to __init__ method
183.69 + """
183.70 + def __init__(self, uri='ldap://localhost', conf='/etc/ldap/slapd.conf',
183.71 + dry_run=False, dn=None, passwd=None, test_runnning=False, web=False):
183.72 + """
183.73 + :param uri: the ldap server to connect to (default: ldap://localhost)
183.74 + :param conf: the con file for slapd (default: /etc/ldap/slapd.conf
183.75 + :param dry_run: don't really change the ldap server
183.76 + :param dn: bind with this user
183.77 + :param passwd: authenticate with this password
183.78 + :param test_running: we are running tests, don't make backup copies
183.79 + so that tests are faster
183.80 + """
183.81 + self.uri = uri
183.82 + self.conf = conf
183.83 + self.dry_run = dry_run
183.84 + self.base = self.get_base()
183.85 + self.conn = ldap.initialize(uri)
183.86 +
183.87 + self.rootdn = dn
183.88 + self.passwd = passwd
183.89 +
183.90 + if dn is None: self.rootdn = self.get_rootdn()
183.91 + if passwd is None: self.passwd = self.get_rootdn_passwd()
183.92 +
183.93 + self.bind()
183.94 + self.test_running = test_runnning
183.95 + self.logger = get_logger(web=web)
183.96 +
183.97 + def bind(self, dn=None, passwd=None):
183.98 + """
183.99 + make a syncronous connection to the server for ``self.conn``
183.100 + """
183.101 + if dn is None: dn = self.rootdn
183.102 + if passwd is None: passwd = self.passwd
183.103 + try:
183.104 + self.conn.bind_s(dn, passwd, ldap.AUTH_SIMPLE)
183.105 + except ldap.INVALID_CREDENTIALS, e:
183.106 + raise
183.107 +
183.108 + def test_password(self, uid, pwd):
183.109 + """
183.110 + controlla la validità delle credenziali
183.111 + """
183.112 + if not pwd: return False
183.113 + dn = self.get_dn(uid, search_type='uid')
183.114 + conn = ldap.initialize(self.uri)
183.115 + try:
183.116 + conn.bind_s(dn, pwd, ldap.AUTH_SIMPLE)
183.117 + return True
183.118 + except ldap.INVALID_CREDENTIALS, e:
183.119 + return False
183.120 +
183.121 + def get_rootdn(self):
183.122 + """
183.123 + should be implemented reading just slapd.conf...
183.124 + I don't want to depend on smbldap_tools.
183.125 + """
183.126 +
183.127 + return "cn=admin,%s" % self.base
183.128 +
183.129 + def get_rootdn_passwd(self):
183.130 + """
183.131 + return password in ldap.secret
183.132 + """
183.133 + f= open('/etc/ldap.secret')
183.134 + passwd = f.readline()
183.135 + f.close()
183.136 + return passwd.rstrip('\n')
183.137 +
183.138 + def set_rootdn_passwd(self, password):
183.139 + """cambia la pass di rootbinddn"""
183.140 +
183.141 + self.set_smbldap_bind_passwd(password)
183.142 +
183.143 + cmd = 'slappasswd -s %s' % password
183.144 + ret_code, newpwd, err = execute(cmd)
183.145 + if ret_code:
183.146 + raise ExecuteError("OUT: %s\nERR: %s" % (out, err))
183.147 +
183.148 + self.modify(self.rootdn,'userPassword',newpwd)
183.149 + try:
183.150 + self.bind(passwd=password)
183.151 + self.passwd = password
183.152 + except:
183.153 + raise ExecuteError("I can't get auth bind: %s" % err)
183.154 +
183.155 + secrets = ( '/etc/ldap.secret',
183.156 + '/etc/libnss-ldap.secret',
183.157 + '/etc/pam_ldap.secret')
183.158 +
183.159 + for f in secrets:
183.160 + if not os.path.islink(f):
183.161 + f = open(f, 'w')
183.162 + f.write("%s\n" % password)
183.163 + f.close()
183.164 +
183.165 + cmd = "smbpasswd -w %s" % password
183.166 + ret_code, out, err = execute(cmd)
183.167 + if ret_code:
183.168 + raise ExecuteError("could not change password in secret.tdb: %s" % err)
183.169 +
183.170 +
183.171 + def set_smbldap_bind_passwd(self, password):
183.172 + """
183.173 + replace pwd in file /etc/smbldap-tools/smbldap_bind.conf
183.174 + that looks like::
183.175 +
183.176 + slaveDN="cn=admin,dc=isi,dc=lan"
183.177 + slavePw="xxxxxx"
183.178 + masterDN="cn=admin,dc=isi,dc=lan"
183.179 + masterPw="xxxxxx"
183.180 + """
183.181 + conf_file = '/etc/smbldap-tools/smbldap_bind.conf'
183.182 + PATTERN = re.compile('(slavePw|masterPw)="(.*)"', re.M)
183.183 + content = open(conf_file).read()
183.184 + content = re.sub(PATTERN, r'\1="%s"' % password, content)
183.185 + f = open(conf_file, 'w')
183.186 + f.write(content)
183.187 + f.close()
183.188 +
183.189 + def get_base(self):
183.190 + """
183.191 + return samba conf for basedn
183.192 + look for 'ldap suffix' in the output of samba's ``testparm -s``
183.193 + """
183.194 +
183.195 + try:
183.196 + ret, out, err = execute('testparm -s')
183.197 + except e:
183.198 + print e
183.199 + sys.exit(1)
183.200 +
183.201 + smbconf = out.replace('\t','').split('\n')
183.202 +
183.203 + for l in smbconf:
183.204 + if not 'ldap suffix = ' in l: continue
183.205 + key, value = l.split(' = ')
183.206 +
183.207 + if not value:
183.208 + raise InvalidValue
183.209 + sys.exit(1)
183.210 + else:
183.211 + return value
183.212 +
183.213 + def show_conf(self):
183.214 + """
183.215 + show the configurazione of this server: uri, base, conf, rootdn, passwd
183.216 + """
183.217 + for i in ('uri', 'base', 'conf','rootdn', 'passwd'):
183.218 + print "%s: %s" % (i, getattr(self, i))
183.219 +
183.220 + try:
183.221 + ret = self.bind()
183.222 + except Exception, e:
183.223 +# print "Error: could not bind", e
183.224 + raise
183.225 +
183.226 + def search(self, filterstr, *args, **kw):
183.227 + """
183.228 + perform a serach_s (syncronous) and return the result
183.229 + """
183.230 + return self.conn.search_s(self.base, SCOPE, filterstr, *args, **kw)
183.231 +
183.232 + def delete(self, dn):
183.233 + "delete an object"
183.234 +
183.235 + if self.dry_run:
183.236 + sys.stderr.write("DRY-RUN: else I'd delete %s\n" % dn)
183.237 + else:
183.238 + return self.conn.delete_s(dn)
183.239 +
183.240 + def get(self, filterstr, attrlist=None, null_ok=False, **kw):
183.241 + """
183.242 + search an object and raise a MultipleMatch error if more than one
183.243 + record is found. It also raise a MissingMatch if norecord is found and
183.244 + 'null_ok' is False (default)
183.245 + """
183.246 +
183.247 + records = self.search(filterstr, attrlist=attrlist, **kw)
183.248 + if len(records) == 0:
183.249 + if null_ok == False:
183.250 + raise exc.MissingMatch('filter is: %s' % filterstr)
183.251 + else:
183.252 + return (None, None)
183.253 +
183.254 + if len(records) == 1:
183.255 + return records[0]
183.256 +
183.257 + elif len(records) > 1:
183.258 + raise MultipleMatch(filterstr)
183.259 +
183.260 + def gets(self, filterstr, attrlist=None, null_ok=False, **kw):
183.261 + """search an object and NOT raise a MultipleMatch error if more than one
183.262 + record is found. It also raise a MissingMatch if norecord is found and
183.263 + 'null_ok' is False (default)"""
183.264 +
183.265 + records = self.search(filterstr, attrlist=attrlist, **kw)
183.266 + return records
183.267 +
183.268 + def modify(self, uid_or_dn, attr, newvalue,
183.269 + search_type='uid', quiet=False, add=False, rem=False):
183.270 + """
183.271 + modify an attribute by name or dn. add or remove (rem)
183.272 + """
183.273 +
183.274 + if self.dry_run:
183.275 + print "DRY-RUN:change %s to %s in %s" % (uid_or_dn, attr,newvalue)
183.276 + return
183.277 +
183.278 + dn = self.get_dn(uid_or_dn, search_type=search_type)
183.279 +
183.280 + if newvalue == None:
183.281 + try:
183.282 + self.conn.modify_s(dn, [(ldap.MOD_DELETE, attr, None)])
183.283 + except ldap.NO_SUCH_ATTRIBUTE:
183.284 + pass
183.285 + else:
183.286 + if add:
183.287 + ## be quiet if adding a value, the value is already there
183.288 + try:
183.289 + self.conn.modify_s(dn, [(ldap.MOD_ADD, attr, newvalue)])
183.290 + except ldap.TYPE_OR_VALUE_EXISTS, e:
183.291 + pass
183.292 + if rem:
183.293 + try:
183.294 + self.conn.modify_s(dn, [(ldap.MOD_ADD, attr, newvalue)])
183.295 + except ldap.TYPE_OR_VALUE_EXISTS, e:
183.296 + pass
183.297 +
183.298 + else:
183.299 + try:
183.300 + self.conn.modify_s(dn, [(ldap.MOD_REPLACE, attr, newvalue)])
183.301 + except ldap.NO_SUCH_ATTRIBUTE, e:
183.302 + if not quiet:
183.303 + raise
183.304 +
183.305 + def get_dn(self, uid, search_type='uid'):
183.306 + """
183.307 + return a dn when given a uid (changeable with attribute). It searches
183.308 + adding base. If given a dn, returns it unchaged
183.309 + """
183.310 +
183.311 + if uid.startswith("dn: ") or uid.startswith("cn="):
183.312 + return uid
183.313 +
183.314 + dn, data = self.get("%s=%s" % (search_type, uid))
183.315 + return dn
183.316 +
183.317 + def backup(self):
183.318 + """save a slapcat.ldif file of the situation, suitable for restoring.
183.319 + The file is saved in /etc/isi/slapcat.ldif and is overwritte each call
183.320 + but is handled by a mercurial repository that is commited each time
183.321 + """
183.322 + if self.test_running:
183.323 + return
183.324 + out_file = defaults.BAK_LDAP_FILE
183.325 + execute("slapcat", None, out_file)
183.326 + ret_code, out, err = execute('hg add %s' % out_file, None, cwd='/etc')
183.327 +
183.328 + #ret_code, out, err = execute('hg status', None, cwd='/etc')
183.329 +
183.330 + date = datetime.datetime.now().strftime("%H:%M %d/%m/%y")
183.331 + cmd = ['hg', 'commit', '-m' 'isi bk automatico %s' % date, out_file]
183.332 + ret_code, out, err = execute(cmd, cwd='/etc')
183.333 + if ret_code:
183.334 + raise ExecuteError(err)
183.335 +# TODO: policies
183.336 + def get_pwd_domain_policies(self, domain=None):
183.337 + """
183.338 + recupera le politiche di dominio
183.339 + """
183.340 + if not domain: domain = filesystem.samba_domain()
183.341 + plist = {
183.342 + 'sambaPwdHistoryLength':0,
183.343 + 'sambaMinPwdLength':5,
183.344 + 'sambaMinPwdAge':0,
183.345 + 'sambaMaxPwdAge':-1,
183.346 + 'sambaLogonToChgPwd':0,
183.347 + }
183.348 + pol = self.get('sambaDomainName=%s' % domain,plist.keys())
183.349 + plist['sambaPwdHistoryLength'] = int(pol[1]['sambaPwdHistoryLength'][0])
183.350 + plist['sambaMinPwdLength'] = int(pol[1]['sambaMinPwdLength'][0])
183.351 + plist['sambaMinPwdAge'] = int(pol[1]['sambaMinPwdAge'][0])
183.352 + plist['sambaMaxPwdAge'] = int(pol[1]['sambaMaxPwdAge'][0])
183.353 + plist['sambaLogonToChgPwd'] = int(pol[1]['sambaLogonToChgPwd'][0])
183.354 + return plist
183.355 +
183.356 + def get_ugnums(self, domain):
183.357 + """
183.358 + get uidNumber and gidNumber for domain
183.359 + """
183.360 + nums = self.get('sambaDomainName=%s' % domain,['uidNumber','gidNumber'])
183.361 + uidNumber = int(nums[1]['uidNumber'][0])
183.362 + gidNumber = int(nums[1]['gidNumber'][0])
183.363 + return {'uidNumber':int(uidNumber), 'gidNumber':int(gidNumber)}
183.364 +
183.365 + def set_ugnums(self, domain, uidNumber=None, gidNumber=None):
183.366 + """
183.367 + set uidNumber and gidNumber for domain
183.368 + """
183.369 + if uidNumber: self.modify(domain,'uidNumber',
183.370 + uidNumber,search_type='sambaDomainName')
183.371 + if gidNumber: self.modify(domain,'gidNumber',
183.372 + gidNumber,search_type='sambaDomainName')
183.373 +
183.374 +class Manager(object):
183.375 + def __init__(self, isiconn=None, verbose=False, web=False):
183.376 +
183.377 + self.srv = isiconn or IsiConn(web=web)
183.378 + self.pumpkin_conn = models.get_conn(self.srv)
183.379 +
183.380 + self.home_mode = None
183.381 + """home_mode may be rm or tar"""
183.382 + self.verbose = verbose
183.383 + self.sambaHome = None
183.384 + self.sambavers = filesystem.samba_version()
183.385 + self.logger = self.srv.logger
183.386 + self.groups = {}
183.387 + self.domain = self.get_samba_domain(filesystem.samba_domain())
183.388 +### check
183.389 + def user_in_group(self, user, group):
183.390 + "test if user is in group"
183.391 +
183.392 + filterstr = "(&(memberUid=%s)(cn=%s))" % (user, group)
183.393 + ret = self.srv.search(filterstr)
183.394 + return bool(ret)
183.395 +
183.396 + def user_exists(self, user):
183.397 + """test if user is a system user"""
183.398 +
183.399 + filterstr = "(&(uid=%s)(objectClass=posixAccount))" % (user)
183.400 + dn, data = self.srv.get(filterstr, null_ok=True)
183.401 + return bool(dn)
183.402 +
183.403 + def group_exists(self, group):
183.404 + """test if group is a system group"""
183.405 + filterstr = "(&(cn=%s)(objectClass=posixGroup))" % (group)
183.406 + dn, data = self.srv.get(filterstr, null_ok=True)
183.407 + return bool(dn)
183.408 +
183.409 + def add_missing_groups(self, groups):
183.410 + """to be overloaded by isi-adduser for efficency """
183.411 + for group in groups:
183.412 + if group and not self.group_exists(group):
183.413 + self.add_group(group)
183.414 +
183.415 + def add_classes(self, user, maingroup, interactive, groups):
183.416 + """ controlla esistenza gruppi dell'utente """
183.417 + if maingroup in ('alunni', 'esterni'):
183.418 + class_ = groups and groups[0] or None
183.419 + if not class_:
183.420 + return
183.421 + ## the first group, if exists is the class
183.422 + if maingroup == 'alunni':
183.423 + add_class_share([class_], course=False, interactive=interactive)
183.424 + elif maingroup == 'esterni':
183.425 +
183.426 + add_class_share([class_], course=True, interactive=interactive)
183.427 +
183.428 + return class_
183.429 +
183.430 + def test_password(self, uid, pwd):
183.431 + """
183.432 + controlla la validità delle credenziali
183.433 + """
183.434 + return self.srv.test_password(uid, pwd)
183.435 +
183.436 + def test_samba_password(self, uid, pwd, client=False):
183.437 + """
183.438 + controlla la validità delle credenziali
183.439 + """
183.440 + if not pwd:
183.441 + return False
183.442 + user = self.get_samba_user(uid)
183.443 + return user.test_samba_password(pwd, client=client)
183.444 +
183.445 +### get pumpkin objects
183.446 + def get_user(self, name, quiet=False):
183.447 + """
183.448 + Return a User object (pumpkin module)
183.449 + """
183.450 + user = models.get_user(name, self.pumpkin_conn)
183.451 + if not user and not quiet:
183.452 + raise exc.MissingMatch("User %s does not exists" % user)
183.453 + else:
183.454 + return user
183.455 +
183.456 + def get_samba_user(self, name, quiet=False):
183.457 + """
183.458 + Return a User object (pumpkin module)
183.459 + """
183.460 + user = models.get_samba_user(name, self.pumpkin_conn)
183.461 + if not user and not quiet:
183.462 + raise exc.MissingMatch("User %s does not exists" % user)
183.463 + else:
183.464 + return user
183.465 +
183.466 + def get_user_by_cf(self, cf):
183.467 + """
183.468 + Return a User object (pumpkin module)
183.469 + """
183.470 + return models.get_user_by_cf(cf, self.pumpkin_conn)
183.471 +
183.472 + def get_group(self, name, quiet=False):
183.473 + """
183.474 + Return a User object (pumpkin module)
183.475 + """
183.476 + try:
183.477 + return models.get_group(name, self.pumpkin_conn)
183.478 +
183.479 + except exc.MissingMatch, e:
183.480 + if quiet:
183.481 + return
183.482 + raise exc.MissingMatch("Group %s does not exists" % name)
183.483 +
183.484 + def get_samba_group(self, name, quiet=False):
183.485 + """
183.486 + Return a User object (pumpkin module)
183.487 + """
183.488 + try:
183.489 + return models.get_samba_group(name, self.pumpkin_conn)
183.490 +
183.491 + except exc.MissingMatch, e:
183.492 + if quiet:
183.493 + return
183.494 + raise exc.MissingMatch("Group %s does not exists" % name)
183.495 +
183.496 + def get_samba_domain(self, name):
183.497 + """
183.498 + Return a User object (pumpkin module)
183.499 + """
183.500 + return models.get_domain(name, self.pumpkin_conn)
183.501 +
183.502 +### get
183.503 + def get_group_dn_by_name(self, name):
183.504 + """return the dn of a group reference by it's posix name"""
183.505 +
183.506 + filterstr = "(&(cn=%s)(objectClass=posixGroup))" % name
183.507 + dn, data = self.srv.get(filterstr, attrlist=['cn'])
183.508 + return dn
183.509 +
183.510 + def get_user_dn_by_name(self, name):
183.511 + """return the dn of a user reference by it's posix name"""
183.512 +
183.513 + filterstr = "(&(uid=%s)(objectClass=posixAccount))" % name
183.514 + dn, data = self.srv.get(filterstr, attrlist=['cn'])
183.515 + return dn
183.516 +
183.517 + def get_home(self, user):
183.518 + """get homeDirectory of a user"""
183.519 + return self.get_ldap_field(user, 'homeDirectory')
183.520 +
183.521 + def get_ldap_field(self, user, field):
183.522 + """get value of one ldap field"""
183.523 + filterstr = "(&(uid=%s)(objectClass=posixAccount))" % (user)
183.524 + dn, data = self.srv.get(filterstr, attrlist=[field])
183.525 + field = find_in(field, data.keys())
183.526 + if field: # in data:
183.527 + return data[field][0]
183.528 + else:
183.529 + return ""
183.530 +
183.531 + def get_ldap_data(self, user, attrlist):
183.532 + """get all data in attrlist"""
183.533 +
183.534 + filterstr = "(&(uid=%s)(objectClass=posixAccount))" % (user)
183.535 + dn, data = self.srv.get(filterstr, attrlist=attrlist)
183.536 + return data
183.537 +
183.538 + def get_user_groups(self, user):
183.539 + "return all posix group of a user"
183.540 +
183.541 + filterstr = "(&(memberUid=%s)(objectClass=posixGroup))" % user
183.542 +
183.543 + ret = self.srv.search(filterstr, attrlist=['cn'])
183.544 + groups = []
183.545 + for dn, data in ret:
183.546 + groups += data['cn']
183.547 + return groups
183.548 +
183.549 + def get_domain(self):
183.550 + """get the sambaDomainName attribute of sambaDomain object"""
183.551 +
183.552 + dn, data = self.srv.get("objectClass=sambaDomain")
183.553 + return data['sambaDomainName'][0]
183.554 +
183.555 + def get_attr(self, user, name):
183.556 + """return attribut 'name' of *user* 'user'. NOTE returns a list!! """
183.557 +
183.558 + filterstr = "(&(uid=%s)(objectClass=posixAccount))" % (user)
183.559 + dn, data = self.srv.get(filterstr, [name])
183.560 + name = find_in(name, data.keys())
183.561 + if name: # in data:
183.562 + return data[name]
183.563 + else:
183.564 + return []
183.565 +
183.566 + def get_members(self, name, checkuid=True):
183.567 + """return members of a group"""
183.568 + g = self.get_group(name)
183.569 + return g.members
183.570 +
183.571 + def get_computers(self):
183.572 + """return members of ou=Computers"""
183.573 +
183.574 + filterstr = "(&(gidNumber=515)(objectClass=posixAccount))"
183.575 + computers = self.srv.gets(filterstr, attrlist=['uid'])
183.576 + return computers
183.577 +
183.578 +### del
183.579 + def del_computer(self, uid):
183.580 + """ delete a joined computer"""
183.581 + # i nomi delle macchine windows terminano con un $
183.582 + if uid[-1] != '$': uid += '$'
183.583 + dn = self.get_user_dn_by_name(uid)
183.584 + if dn:
183.585 + self.srv.delete(dn)
183.586 + if self.verbose:
183.587 + sys.stdout.write("%s DELETED\n" % (uid))
183.588 +
183.589 + def del_member_from_group(self, uid, group, quiet=True):
183.590 + """delete membership. Don't complain if user is not in the group
183.591 + unless quiet=False"""
183.592 +
183.593 + dn = self.get_group_dn_by_name(group)
183.594 + if self.srv.dry_run:
183.595 + return
183.596 + try:
183.597 + self.srv.conn.modify_s(dn, [(ldap.MOD_DELETE, 'memberUid', uid)])
183.598 + except ldap.NO_SUCH_ATTRIBUTE:
183.599 + if not quiet:
183.600 + raise
183.601 +
183.602 + def del_user(self, name, quiet=False):
183.603 + """delete a user, all its membership and the personal group.
183.604 + If quiet=True does not complain even if the user does not exists"""
183.605 +
183.606 + try:
183.607 + user = self.get_user(name)
183.608 + except exc.MissingMatch, e:
183.609 + if quiet:
183.610 + return
183.611 + else:
183.612 + raise exc.MissingMatch("User %s does not exists" % name)
183.613 +
183.614 + ### delete the user
183.615 + user.delete(home_mode=self.home_mode)
183.616 + self.logger.info("Deleting user " + user.logname)
183.617 +
183.618 + def del_group(self, name, quiet=False):
183.619 + """delete a group
183.620 + If quiet=True does not complain even if the group does not exists"""
183.621 +
183.622 + try:
183.623 + group = self.get_group(name)
183.624 + except exc.MissingMatch, e:
183.625 + if not quiet:
183.626 + raise exc.MissingMatch("Group %s does not exists" % name)
183.627 + else:
183.628 + return
183.629 +
183.630 + ### delete the user
183.631 + group.delete()
183.632 + self.logger.info("Deleting group " + group.name)
183.633 +
183.634 +
183.635 +### add
183.636 + def add_user(self, name, maingroup, no_filesystem=False, force_passwd_change=False,
183.637 + interactive=False, run_alulink=True, **kw):
183.638 + """add a user with all 'normal' defaults
183.639 + The groups[0], if it exists is the class and will be set to
183.640 + departmentNumber attribute. This is used to connect the class.
183.641 + Interactive indicates a user is listening and can decide to add
183.642 + the class.
183.643 + """
183.644 +
183.645 + cls = self.add_classes(name, maingroup, interactive, kw['groups'])
183.646 + self.add_missing_groups(kw['groups'])
183.647 + user = models.PosixUser(self.pumpkin_conn)
183.648 + user.set_parent('ou=People,dc=isi,dc=lan')
183.649 + user.logname = name
183.650 + user.shell = '/bin/bash'
183.651 + self.user_configure(user, maingroup, no_filesystem, force_passwd_change,
183.652 + run_alulink=run_alulink, mode='Adding', **kw)
183.653 +
183.654 + user = self.get_samba_user(name)
183.655 +
183.656 + if run_alulink and user.classe:
183.657 + filesystem.create_alulink((user.classe,), self)
183.658 +
183.659 + return user
183.660 +
183.661 + def add_samba_staff(self, user, invalidate_cache=True):
183.662 +
183.663 + if invalidate_cache:
183.664 + execute('nscd -i passwd')
183.665 + ret_code, out, err = execute('smbpasswd -a -n %s' % user)
183.666 + if ret_code:
183.667 + self.logger.debug('smbpasswd failed: OUT: %s - ERR: %s' % (out, err))
183.668 +
183.669 + raise Exception("Sambapasswd problems: %s - OUT: %s" % (err, out))
183.670 + user = self.get_samba_user(user)
183.671 + if not user:
183.672 + raise Exception("Samba user not created")
183.673 + user.drive = u'H:'
183.674 + user.logon = u'logon.bat'
183.675 + if self.sambaHome:
183.676 + user.sambaHomePath = ur'\\%s\%s\\.\\.profili\\WinXP' % (self.sambaHome, name)
183.677 + user.flags = u"[U ]"
183.678 + user.save()
183.679 + return user
183.680 +
183.681 + def modify_user(self, name, maingroup, no_filesystem=True, force_passwd_change=False,
183.682 + interactive=False, run_alulink=True, **kw):
183.683 + """ modifica un utente esistente """
183.684 +
183.685 + user = self.get_samba_user(name)
183.686 +
183.687 + new_cls = self.add_classes(name, maingroup, interactive, kw['groups'])
183.688 + user.classe = new_cls
183.689 +
183.690 + self.add_missing_groups(kw['groups'])
183.691 + self.user_configure(user, maingroup, no_filesystem, force_passwd_change,
183.692 + run_alulink=run_alulink, mode='Modifying', **kw)
183.693 + return user
183.694 +
183.695 + def user_configure(self, user, maingroup, no_filesystem, force_passwd_change, mode='Adding', **kw):
183.696 + """Crea l'utente
183.697 + :param user: a models.PosixUser or models.SambaUser object
183.698 + :param maingroup: the maingroup it must belog to
183.699 + :param no_filesystem: (boolean) indicates it the homedir must be prepared
183.700 + :param kw: a dict as prepared by UserParser.get_opts() with
183.701 + """
183.702 + if maingroup not in self.groups:
183.703 + try:
183.704 + group = self.get_group(maingroup)
183.705 + except exc.MissingMatch:
183.706 + raise exc.MissingMainGroup("Maingroup %s is not defined" % maingroup, maingroup, user)
183.707 + self.groups[maingroup] = group
183.708 +
183.709 + user.gid = self.groups[maingroup].gid
183.710 +
183.711 + for key in user.__base_data__ + user.__extended_data__:
183.712 + value = kw.get(key, None)
183.713 + # change value or set to None an existent value but don't set to None a non-existent
183.714 + if value or getattr(user, key):
183.715 + setattr(user, key, value)
183.716 +
183.717 +
183.718 + user.full_name = u"%s %s" % (kw['first_name'], kw['last_name'])
183.719 +
183.720 + if not user.uid: # it's a new one
183.721 + user.uid = self.domain.get_next_uid()
183.722 +
183.723 + homedir = u"%s/%s/%s" % (defaults.GROUPS_PATH, maingroup, user.logname)
183.724 + user.home = homedir
183.725 +
183.726 + user.save()
183.727 + self.logger.info('%s user %s' %(mode, user.logname))
183.728 + samba_user = self.add_samba_staff(user)
183.729 + # gestione password
183.730 + samba_user.set_password(kw['passwd'], force_passwd_change)
183.731 +
183.732 + if not no_filesystem and not os.path.exists(homedir):
183.733 + filesystem.home_create(user, homedir)
183.734 +
183.735 + user_groups = set([maingroup] + kw['groups'] + defaults.EXTRA_GROUPS)
183.736 + user.set_groups(user_groups, self.groups)
183.737 +
183.738 + def parse_user_definition_string(self, string, action=True, interactive=False, home_mode='tar', **kw):
183.739 +
183.740 + """split the user definition string and call user creation functions
183.741 + the (compact) format is in 7 fields, logname,last name,first name and
183.742 + maingroup being the only mandatory ones.
183.743 + The fields are separated by ';' and secondary groups are separated by ','
183.744 +
183.745 + :param action: boolean. Take the action
183.746 + :param no_filesystem: opts.no_filesystem,
183.747 + :param update_user: if the user exists must be updated,
183.748 + :param update_passwd: opts.update_passwd,
183.749 + :param home_mode: 'tar' if not opts.home_zap or 'rm',
183.750 + :param force_passwd_change: opts.force_change_passwd
183.751 +
183.752 +
183.753 + logname;last;name;maingrp;other_grp1,othergrp2...;CF;PASS;list_ext_flds
183.754 +
183.755 + list_ext_flds: sex;address;city;cap;prov;tel
183.756 + """
183.757 + self.home_mode = home_mode
183.758 +
183.759 + proxy = UserParser(self, string, interactive=interactive, **kw )
183.760 +
183.761 + if action:
183.762 + return self.proxy_action(proxy, interactive=interactive)
183.763 +
183.764 + return proxy
183.765 +
183.766 + def proxy_action(self, proxy, interactive=True):
183.767 + """
183.768 + act on user_proxy according to action in it
183.769 + """
183.770 +
183.771 + if proxy.action == 'add':
183.772 + return self.add_user(proxy.logname, proxy.maingroup, **proxy.get_opts())
183.773 +
183.774 + elif proxy.action == 'delete':
183.775 + self.del_user(proxy.logname)
183.776 +
183.777 + else:
183.778 + return self.modify_user(proxy.logname, proxy.maingroup, **proxy.get_opts())
183.779 +
183.780 + def add_group(self, group_name, gid=None, quiet=True, system=False, invalidate_cache=True):
183.781 + """add a group
183.782 +
183.783 + :param group_name: the name of the group
183.784 + :param gid: use gid (default is to get the next free number from Domain
183.785 + :param quiet: don't complain if it already exists, just retun it
183.786 + :param system: add a system group, possibile with same gid as existent
183.787 + :param invalidate_cache: if True (default) nscd -i group is called
183.788 + """
183.789 +
183.790 + if not group_name:
183.791 + raise WrongParameters("Missing group in add_group")
183.792 +
183.793 + try:
183.794 + ## check if it alreay exists
183.795 + g = self.get_group(group_name)
183.796 +
183.797 + if quiet:
183.798 + return g
183.799 + else:
183.800 + raise exc.AlreadyExistingGroup("Group %s already exists" % group_name, group_name)
183.801 +
183.802 + except exc.MissingMatch:
183.803 + pass
183.804 +
183.805 + ## opt -a adds SID
183.806 + if system:
183.807 + ret_code, out, err = execute("getent group %s" % group_name)
183.808 + if out: # plugdev:x:46:sandro
183.809 + group_name, pwd, gid, members = out.split(':')
183.810 + else:
183.811 + for gid in xrange(120, 150):
183.812 + try:
183.813 + models.get_group_by_gid(gid, self.pumpkin_conn)
183.814 + except Exception:
183.815 + break
183.816 +
183.817 + self.logger.info("Adding group %s" % group_name)
183.818 +
183.819 + g = models.PosixGroup(self.pumpkin_conn)
183.820 + g.set_parent('ou=Groups,dc=isi,dc=lan')
183.821 + g.gid = gid and int(gid) or self.domain.get_next_gid()
183.822 + g.name = group_name
183.823 + g.save()
183.824 + if invalidate_cache:
183.825 + execute('nscd -i group')
183.826 + return g
183.827 +
183.828 +### tools
183.829 +
183.830 + def check_and_add(self, classes, courses):
183.831 + """if a class/course is missing, prompt for a confirm and create it"""
183.832 +
183.833 + ## classes
183.834 + missing_classes = []
183.835 + for grp in classes.keys():
183.836 + if grp not in get_classes():
183.837 + missing_classes += [grp]
183.838 + if missing_classes:
183.839 + interactive_add_classes(missing_classes)
183.840 +
183.841 + ## courses
183.842 + missing_courses = []
183.843 + for grp in courses.keys():
183.844 + if grp not in get_courses():
183.845 + missing_courses += [grp]
183.846 + if missing_courses:
183.847 + interactive_add_classes(missing_courses, opt='course')
183.848 +
183.849 +
183.850 + def read_file(self, file_name, interactive=True, run_alulink=True, **kw):
183.851 + """
183.852 + read an '.isi' file and add/delete/modify the user accordingly to specs in it
183.853 +
183.854 + :param file_name: can be a file name or a file handler
183.855 + :param run_alulink: (boolean) run/don't run isi-alulink
183.856 + :param interactive: (boolean) ask/don't ask confirmation to create classes
183.857 + :param home_mode: (rm|tar|none) how should homes be removed
183.858 + :param no_filesystem: (boolean) don't touch filesystem (used in tests, run faster)
183.859 +
183.860 + """
183.861 + main_groups, other_groups, classes, courses = set(), set(), set(), set()
183.862 + users = []
183.863 +
183.864 + f = open(file_name) if isinstance(file_name, basestring) else file_name
183.865 + for line in f:
183.866 +
183.867 + user_proxy = self.parse_user_definition_string(line, action=False,
183.868 + run_alulink=False, **kw)
183.869 + users += [user_proxy]
183.870 +
183.871 + if not user_proxy.action == 'delete':
183.872 + main_groups.add(user_proxy.maingroup)
183.873 + other_groups.update(set(user_proxy.groups))
183.874 +
183.875 + if user_proxy.classe:
183.876 +
183.877 + if user_proxy.maingroup == 'alunni': # this is a class
183.878 + classes.add(user_proxy.classe)
183.879 +
183.880 + elif user_proxy.maingroup == 'esterni':
183.881 + courses.add(user_proxy.classe)
183.882 +
183.883 +
183.884 + wrong_groups = main_groups.difference( set(get_main_groups()))
183.885 + if wrong_groups:
183.886 + raise exc.MissingMainGroup("Group not present in maingroups: %s" % wrong_groups, None, None)
183.887 +
183.888 + self.add_missing_groups( other_groups )
183.889 + add_class_share(classes, course=False, interactive=interactive)
183.890 + add_class_share(courses, course=True, interactive=interactive)
183.891 +
183.892 + for proxy in users:
183.893 + try:
183.894 + self.proxy_action(proxy, interactive=False)
183.895 + except exc.MissingMatch, e:
183.896 + self.logger.warning(e)
183.897 +
183.898 + if run_alulink:
183.899 + self.logger.info('Starting alulink for %s' % ','.join(list(classes.union(courses))))
183.900 + for cls in classes.union(courses):
183.901 + filesystem.create_alulink(classes, self)
183.902 + return len(users)
183.903 +
183.904 + def check_file(self, file_name):
183.905 + """
183.906 + returna tuple of three lists of user to be added, deleted and modified according to
183.907 + content of file_name
183.908 +
183.909 + :param file_name: a file in .isi format
183.910 + """
183.911 +
183.912 + add, delete, modify = [], [], []
183.913 + users = []
183.914 +
183.915 + f = open(file_name) if isinstance(file_name, basestring) else file_name
183.916 + for line in f:
183.917 +
183.918 + user_proxy = self.parse_user_definition_string(line, action=False,)
183.919 +
183.920 + if user_proxy.action == 'update':
183.921 + modify += [user_proxy]
183.922 +
183.923 + elif user_proxy.action == 'delete':
183.924 + delete += [user_proxy]
183.925 +
183.926 + elif user_proxy.action == 'add':
183.927 + add += [user_proxy]
183.928 +
183.929 + return add, delete, modify
183.930 +
183.931 + def pwd_must_change(self, name, gg=0):
183.932 + """ forza il rinnovo password per i membri di un gruppo
183.933 + se gg > 0 fissa la data di scadenza a mktime()+gg
183.934 + """
183.935 + group = self.get_group(name)
183.936 +
183.937 + if gg:
183.938 + ggs = str(int(mktime(localtime()))+24*3600*gg)
183.939 + else:
183.940 + ggs = '0'
183.941 +
183.942 + for uid in group.members:
183.943 + if self.verbose:
183.944 + print "elaboro %s" % uid
183.945 + if self.sambavers > "3.0.24":
183.946 + self.srv.modify(uid,'sambaPwdLastSet',ggs)
183.947 + else:
183.948 + self.srv.modify(uid,'sambaPwdMustChange',ggs)
183.949 +
183.950 + def pwd_can_change(self, gruppo, gg=-7):
183.951 + """ stabilisce da quando i membri del gruppo possono cambiare password """
183.952 + uu = self.get_members(gruppo)
183.953 + ggs = str(int(mktime(localtime()))+24*3600*gg)
183.954 + if uu:
183.955 + for uid in uu:
183.956 + if self.verbose:
183.957 + print "elaboro %s" % uid
183.958 + self.srv.modify(uid,'sambaPwdCanChange',ggs)
183.959 + self.srv.modify(uid,'sambaPwdLastSet',ggs)
183.960 + else:
183.961 + raise exc.MissingOrVoidGroup
183.962 +
183.963 + def pwd_when(self, gruppo, outf=None):
183.964 + """ date delle passwords """
183.965 +
183.966 + def print_msg(msg):
183.967 + if outf:
183.968 + outf.write(msg+'\n')
183.969 + else:
183.970 + print msg
183.971 +
183.972 + # legge le policies di dominio
183.973 + plist = self.srv.get_pwd_domain_policies()
183.974 +
183.975 + uu = self.get_members(gruppo)
183.976 + if uu:
183.977 + print_msg('-'*75)
183.978 + print "POLITICHE DI DOMINIO"
183.979 + for k, v in plist.iteritems():
183.980 + print "%25s = %s" % (k, v)
183.981 +# print plist
183.982 + print_msg('-'*75)
183.983 + print_msg("%-15s %-15s %s %s" %
183.984 + ('UserId',
183.985 + 'PwdLastSet',
183.986 + 'PwdExpiration [days]',
183.987 + 'PwdCanChange'))
183.988 + print_msg('-'*75)
183.989 + for uid in uu:
183.990 + x1 = float(self.get_attr(uid, 'sambaPwdLastSet')[0])
183.991 + lsd = strftime('%Y-%m-%d',localtime(x1))
183.992 +
183.993 + if self.sambavers > "3.0.24":
183.994 + if plist['sambaMaxPwdAge'] == -1:
183.995 + x2 = 0
183.996 + else:
183.997 + x2 = x1 + plist['sambaMaxPwdAge']
183.998 + else:
183.999 + x2 = float(self.get_attr(uid, 'sambaPwdMustChange')[0])
183.1000 +
183.1001 + x3 = float(self.get_attr(uid, 'sambaPwdCanChange')[0])
183.1002 + if x2 > x1:
183.1003 + try:
183.1004 + exd = strftime('%Y-%m-%d',localtime(x2))
183.1005 + exg = "[%s]" % str(int((x2-x1)/3600/24))
183.1006 + except:
183.1007 + exd = "Never expire"
183.1008 + exg = ''
183.1009 + else:
183.1010 + exg = ''
183.1011 + if self.sambavers > "3.0.24":
183.1012 + if plist['sambaMaxPwdAge'] == -1:
183.1013 + if x1>x2:
183.1014 + exd = "Never expire"
183.1015 + else:
183.1016 + exd = "Expired"
183.1017 +
183.1018 + else:
183.1019 + exd = strftime('%Y-%m-%d',localtime(x2))
183.1020 + else:
183.1021 + exd = 'Expired'
183.1022 + cch = strftime('%Y-%m-%d',localtime(x3))
183.1023 + print_msg("%-15s %-15s %-10s %-10s %s" %
183.1024 + (uid, lsd, exd, exg, cch))
183.1025 + else:
183.1026 + raise esc.MissingOrVoidGroup
183.1027 +
183.1028 +
183.1029 + def rename_user(self, old_uid, new_uid, cf):
183.1030 + """ modifica il logname e quel che ne consegue """
183.1031 +
183.1032 + if self.user_exists(new_uid):
183.1033 + raise exc.DuplicateUid('ERRORE: %s duplicato!!!' % new_uid)
183.1034 +
183.1035 + if self.user_exists(old_uid):
183.1036 + old_home = self.get_home(old_uid)
183.1037 + old_dati = self.get_ldap_data(old_uid, ['cn','sn'])
183.1038 + cn = old_dati['cn'][0]
183.1039 + sn = old_dati['sn'][0]
183.1040 + new_home = "%s/%s" % (os.path.dirname(old_home), new_uid)
183.1041 + groups = self.get_user_groups(old_uid)
183.1042 + if self.verbose:
183.1043 + print "elaboro %s -> %s %s %s" % (old_uid,new_uid, new_home, cf)
183.1044 +
183.1045 + cmd = ['smbldap-usermod']
183.1046 +
183.1047 + cmd += ['-r', new_uid]
183.1048 + cmd += ['-d', new_home]
183.1049 + cmd += ['-G', ",".join(groups)]
183.1050 +
183.1051 +# cmd += ['-N', cn ] # cn
183.1052 +# cmd += ['-S', sn ] # sn
183.1053 +
183.1054 + # FIXME: sambaHomePath con doppia
183.1055 +# if self.sambaHome:
183.1056 +# cmd += ['-C',r'\\%s\%s\\.\\.profili\\WinXP'%(self.sambaHome,user)]
183.1057 +# cmd+= ['-F', r'\\%s\%s\\.profili\\WinXP' % (self.sambaHome,user)]
183.1058 +
183.1059 + cmd += [old_uid]
183.1060 + ret_code, out, err = execute(cmd)
183.1061 + if ret_code:
183.1062 + raise ExecuteError("OUT: %s\nERR: %s" % (out, err))
183.1063 + # smbldap-usermod non sembra modificare correttamente sn e cn in abbinamento all'opzione -r
183.1064 +
183.1065 + self.srv.modify(new_uid, 'cn', cn)
183.1066 + self.srv.modify(new_uid, 'sn', sn)
183.1067 + # rinomino home dir
183.1068 + os.rename(old_home, new_home)
183.1069 + # cambio cf, se cf='' viene cancellato, se cf=None resta inalterato
183.1070 + if not cf is None:
183.1071 + self.srv.modify(new_uid, 'employeeNumber', cf)
183.1072 +
183.1073 +
183.1074 +### Definizione funzioni ###
183.1075 +
183.1076 +def find_parm_value(conf_file, parm):
183.1077 + """trova il valore di un parametro in un file di conf or None"""
183.1078 + content = open(conf_file).read()
183.1079 + pat = '(.*%s.*?)=\s*"*\s*(.*)\s*"' % parm
183.1080 + ret = re.search(pat, content)
183.1081 + if ret:
183.1082 + return ret.group(2)
183.1083 + else:
183.1084 + return None
183.1085 +
183.1086 +def find_in(x, ylist):
183.1087 + ret = None
183.1088 + for y in ylist:
183.1089 + if x.lower() == y.lower():
183.1090 + ret = y
183.1091 + break
183.1092 + return ret
183.1093 +
183.1094 +def get_main_groups():
183.1095 + """
183.1096 + return official list of maingroups, now os.listdir('/home/users')
183.1097 + after performing a group existence check.
183.1098 + """
183.1099 +
183.1100 + srv = IsiConn(dn="", passwd="")
183.1101 + isi_user = Manager(srv)
183.1102 +
183.1103 + groups_list_raw = os.listdir(defaults.GROUPS_PATH)
183.1104 + groups_list = [g for g in groups_list_raw if isi_user.group_exists(g) ]
183.1105 +
183.1106 + return groups_list
183.1107 +
183.1108 +def get_classes(as_groups=False):
183.1109 + """
183.1110 + return official list of classes, now os.listdir('/home/shares/classi')
183.1111 + after performing a group existence check.
183.1112 + """
183.1113 + srv = IsiConn(dn="", passwd="")
183.1114 + l = Manager(srv)
183.1115 +
183.1116 + classes_list_raw = os.listdir(defaults.CLASSES_PATH)
183.1117 + if as_groups:
183.1118 + classes_list = [l.get_group(g) for g in classes_list_raw if l.group_exists(g) ]
183.1119 + else:
183.1120 + classes_list = [g for g in classes_list_raw if l.group_exists(g) ]
183.1121 +
183.1122 + return classes_list
183.1123 +
183.1124 +
183.1125 +def get_courses():
183.1126 + """
183.1127 + return official list of courses, now os.listdir('/home/shares/courses')
183.1128 + after performing a group existence check.
183.1129 + """
183.1130 +
183.1131 + srv = IsiConn(dn="", passwd="")
183.1132 + isi_user = Manager(srv)
183.1133 +
183.1134 + courses_list_raw = os.listdir(defaults.COURSES_PATH)
183.1135 + courses_list = [g for g in courses_list_raw if isi_user.group_exists(g) ]
183.1136 +
183.1137 + return courses_list
183.1138 +
183.1139 +def add_class_share(classes, course=False, interactive=True):
183.1140 + """
183.1141 + add classes if user confirms
183.1142 +
183.1143 + :param course: boolean. Add a course not a class
183.1144 + """
183.1145 + logger = get_logger(web=True)
183.1146 +
183.1147 + if course:
183.1148 + CLASSES = get_courses()
183.1149 + else:
183.1150 + CLASSES = get_classes()
183.1151 +
183.1152 + missing_classes = set(classes).difference(set(CLASSES))
183.1153 +
183.1154 + if missing_classes and interactive:
183.1155 + msg = "Queste classi non sono definite:\n %s\ndevo definirle? [S/n]\n"
183.1156 + response = raw_input(msg % " ".join(list(missing_classes)))
183.1157 + if response and response in 'nN':
183.1158 + sys.stderr.write("Non aggiungo utenti in classi inesistenti. Esco\n")
183.1159 + return False
183.1160 +
183.1161 + if missing_classes:
183.1162 + logger.info("Aggiungo le classi mancanti: %s" % missing_classes)
183.1163 +
183.1164 + for cl in missing_classes:
183.1165 + logger.info('Aggiungo classe: ' + cl)
183.1166 + filesystem.create_class(cl, course=course, samba_reload=False, manager=None)
183.1167 +
183.1168 + if missing_classes:
183.1169 + execute('/etc/init.d/samba reload')
183.1170 +
183.1171 +def maingroup_byprefix(logname):
183.1172 + '''cerca di determinare il maingroup dal logname'''
183.1173 + #FIXME:la clausola or .... è dovuta a una mia necessità specifica
183.1174 + main_group = ''
183.1175 + if logname.startswith('a_') or logname.startswith('aa'):
183.1176 + main_group = 'alunni'
183.1177 + if logname.startswith('e_') or logname.startswith('ee'):
183.1178 + main_group = 'esterni'
183.1179 + if logname.startswith('d_') or logname.startswith('dd'):
183.1180 + main_group = 'docenti'
183.1181 + if logname.startswith('ad_') or logname.startswith('ad'):
183.1182 + main_group = 'admins'
183.1183 + return main_group
183.1184 +
183.1185 +
184.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
184.2 +++ b/lib/isi/test.py Mon Apr 26 11:16:23 2010 +0200
184.3 @@ -0,0 +1,58 @@
184.4 +import functions
184.5 +import subprocess
184.6 +import StringIO
184.7 +
184.8 +class InputStream(object):
184.9 + """ Simple Wrapper for File-like objects. [c]StringIO doesn't provide
184.10 + a readline function for use with generate_tokens.
184.11 + Using a iterator-like interface doesn't succeed, because the readline
184.12 + function isn't used in such a context. (see <python-lib>/tokenize.py)
184.13 + """
184.14 + def __init__(self, data):
184.15 + self.__data = [ '%s\n' % x for x in data.splitlines() ]
184.16 + self.__lcount = 0
184.17 +
184.18 + def readline(self):
184.19 + try:
184.20 + line = self.__data[self.__lcount]
184.21 + self.__lcount += 1
184.22 + except IndexError:
184.23 + line = ''
184.24 + self.__lcount = 0
184.25 + return line
184.26 +
184.27 + def fileno(self):
184.28 + return self.__lcount
184.29 +
184.30 +cmd = ['/home/sandro/sd/sandro_echo']
184.31 +#cmd = ['sort']
184.32 +def set_password(user, password):
184.33 + """set password fo user"""
184.34 +
184.35 +#p1 = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell='/bin/bash')
184.36 +
184.37 + #Input = InputStream('%s\n%s' % (password, password))
184.38 + #Input = StringIO.StringIO('%s\n%s' % (password, password))
184.39 +
184.40 + #p = subprocess.Popen(..., stdin=subprocess.PIPE)
184.41 + #p.stdin.write('%s\n%s' % (password, password))
184.42 + #p.stdin.close() # signal end of file
184.43 +
184.44 + PWD = '<%s\na%s' % (password, password)
184.45 + #PWD = InputStream('%s\n%s' % (password, password))
184.46 + ret_code, out, err = functions.execute(cmd, stdin=PWD )
184.47 + return "OUTPUT: %s" % out
184.48 +
184.49 +
184.50 +print set_password('abc', 'xyz')
184.51 +
184.52 +#p = subprocess.Popen(cmd,stdin=subprocess.PIPE, stdout=subprocess.PIPE)
184.53 +#print p.communicate(input='uno\ndue\n')
184.54 +
184.55 +#p.stdin.write('uno\ndue\n')
184.56 +#p.stdin.close()
184.57 +#p.wait()
184.58 +
184.59 +
184.60 +#print p.communicate()
184.61 +
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/lib/isi/tests/runtest.py Mon Apr 26 11:16:23 2010 +0200
185.3 @@ -0,0 +1,16 @@
185.4 +#!/usr/bin/env python
185.5 +
185.6 +import sys
185.7 +import doctest
185.8 +
185.9 +sys.path.insert(0, "../../")
185.10 +
185.11 +files = (
185.12 + 'srv.txt',
185.13 + 'user.txt',
185.14 + )
185.15 +for filename in files:
185.16 + doctest.testfile(filename)
185.17 +
185.18 +
185.19 +
186.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186.2 +++ b/lib/isi/tests/srv.txt Mon Apr 26 11:16:23 2010 +0200
186.3 @@ -0,0 +1,21 @@
186.4 +# -*- mode: python -*-
186.5 +
186.6 +This doctest only works if slapd is already working
186.7 +
186.8 +>>> from isi import IsiConn
186.9 +>>> c = IsiConn()
186.10 +>>> c.get_rootdn()
186.11 +'cn=admin,dc=saraceno,dc=lan'
186.12 +>>> c.get('cn=admin')[0]
186.13 +'cn=admin,dc=saraceno,dc=lan'
186.14 +
186.15 +## simple way to check hat no more than one domain is defined:
186.16 +## useless
186.17 +>>> len(c.get("objectClass=sambaDomain"))
186.18 +2
186.19 +
186.20 +>>> c.backup()
186.21 +>>>
186.22 +
186.23 +
186.24 +
187.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187.2 +++ b/lib/isi/tests/user.txt Mon Apr 26 11:16:23 2010 +0200
187.3 @@ -0,0 +1,38 @@
187.4 +# -*- mode: python -*-
187.5 +
187.6 +This doctest only works if slapd is already working
187.7 +
187.8 +>>> from isi import IsiConn, IsiUser
187.9 +>>> c = IsiConn()
187.10 +>>> l = IsiUser(c)
187.11 +
187.12 + #print l.get_domain()
187.13 + #print l.get_group_dn_by_name('geo1a')
187.14 + #u, g = ('a_spnclr93l50', 'geo1a')
187.15 + #print "%s is in group %s: %s" % (u, g, l.user_in_group(u, g))
187.16 +
187.17 + #u, g = ('aspnclr93l50', 'geo1a')
187.18 + #print "%s is in group %s: %s" % (u, g, l.user_in_group(u, g))
187.19 + #print l.get_user_dn_by_name(u)
187.20 + #print l.get_home(u)
187.21 + #u = 'a_dlcsfn92s05'
187.22 + #u =
187.23 + #l.del_member_from_group(u, g)
187.24 + #print l.get_user_dn_by_name('a_cllfba93m07')
187.25 + #l.del_user('a_cllfba93m07', quiet=True)
187.26 + g = 'c4c1'
187.27 + print "alunni: %s, %s: %s" % (len(l.get_members('alunni')), g,
187.28 + len(l.get_members(g)))
187.29 + #print l.get_members(g)
187.30 + #l.del_users_of_group('alunni')
187.31 + #print l.get_members(g)
187.32 + #print l.get_attr('admancini', 'homeDirectory')[0]
187.33 + #print l.get_home('admancini')
187.34 + #l.del_user('admancini', quiet=True)
187.35 + #l.srv.backup()
187.36 + #l.del_users_of_group('alunni')
187.37 + #l.eliminate_member_from_group('a_spnclr93l50', 'geo1a')
187.38 + #u = 'a_trnlcu93h23'
187.39 + #print l.get_user_groups(u)
187.40 + #for i in l.get_members('geo1a'):
187.41 + # l.user_in_group(i, 'geo1a')
188.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188.2 +++ b/setup.py Mon Apr 26 11:16:23 2010 +0200
188.3 @@ -0,0 +1,20 @@
188.4 +#!/usr/bin/env python
188.5 +
188.6 +
188.7 +from setuptools import setup, find_packages
188.8 +import os
188.9 +#from distutils.core import setup, find_packages
188.10 +
188.11 +setup(name='isi',
188.12 + version='0.2.4',
188.13 + description='Python module for reteisi',
188.14 + author='Alessandro Dentella',
188.15 + author_email='[email protected]',
188.16 + url='http://www.e-den.it/',
188.17 + package_dir={'':'lib'},
188.18 +# packages=find_packages('lib', exclude=['ez_setup', 'examples', 'tests']),
188.19 + packages=find_packages('lib', exclude='isi.egg-info'),
188.20 +# scripts=['bin/' + s for s in os.listdir('bin')]
188.21 + zip_safe=False,
188.22 + )
188.23 +
189.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
189.2 +++ b/tests/README Mon Apr 26 11:16:23 2010 +0200
189.3 @@ -0,0 +1,45 @@
189.4 +Tests
189.5 +=====
189.6 +
189.7 +
189.8 +Questa cartella contiene alcuni test di verifica del corretto funzionamento
189.9 +della libreria. Sono in due formati differenti:
189.10 +
189.11 + * doctest
189.12 + * nosetests
189.13 +
189.14 +i doctest possono essere lanciati da qualunque macchina che abbia installato
189.15 +python e dalla cartella stessa dei test con il comando: ./runtests.py
189.16 +
189.17 +I nosetest devono essere lanciati nella macchina virtuale. Nella loro
189.18 +esecuzione cancellano e creano utenti, eliminano cartelle e fanno altre
189.19 +operazioni che su un server reale creerebbero grossi scompensi.
189.20 +
189.21 +Copia dell'ultima versione
189.22 +==========================
189.23 +
189.24 +Il filesystem netkit ha una versione dei pacchetti isi non costantemente
189.25 +aggiornata. Per eseguire i test è necessario aggiornare:
189.26 +
189.27 + * la libreria python isi
189.28 + * gli eseguibili isi-*
189.29 + * creare una cartella con i test in /tmp/
189.30 +
189.31 +Tutto questo può esere fatto con questi comandi::
189.32 +
189.33 + rsync -a lib/isi [email protected]:/var/lib/python-support/python2.5/
189.34 + rsync -a usr/sbin [email protected]:/usr/
189.35 + rsync -a tests [email protected]:/tmp
189.36 +
189.37 +Ovviamente è suggeribile aggiornare all'ultima versione di sorgente
189.38 +
189.39 +
189.40 +Lanciare i test
189.41 +===============
189.42 +
189.43 +cd /tmp/tests
189.44 +nosetests -v
189.45 +
189.46 +
189.47 +
189.48 +
190.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
190.2 +++ b/tests/convert_test.py Mon Apr 26 11:16:23 2010 +0200
190.3 @@ -0,0 +1,195 @@
190.4 +import os
190.5 +import re
190.6 +import isi
190.7 +import glob
190.8 +import datetime
190.9 +import unittest
190.10 +from dry.functions import execute
190.11 +from nose import tools
190.12 +import shutil
190.13 +from isi import bulk_users
190.14 +import logging
190.15 +
190.16 +
190.17 +l = isi.Manager()
190.18 +#l.logger.setLevel(logging.critical)
190.19 +class Res: pass
190.20 +res = Res()
190.21 +
190.22 +def setup():
190.23 + print "killing nscd"
190.24 + execute('killall nscd')
190.25 + execute('rm -Rf /home/users/alunni/*')
190.26 + execute('cp data/convert/sissi-tabcorsi /etc/isi')
190.27 + crea_classe('geo3a')
190.28 + crea_classe('ige3a')
190.29 + crea_classe('pro3a')
190.30 +
190.31 +def crea_classe(classe):
190.32 + l.add_group(classe, quiet=True)
190.33 + path = '/home/shares/classi/%s' % classe
190.34 + if not os.path.exists(path):
190.35 + os.mkdir(path)
190.36 +
190.37 +class BulkUsers(unittest.TestCase):
190.38 +
190.39 + def execute(self, cmd):
190.40 + ret_code, out, err = execute(cmd)
190.41 + assert ret_code == 0, "ret_code: %s: OUT=%s, ERR=%s" % (ret_code, out, err)
190.42 + return out, err
190.43 +
190.44 + def diff(self, this, other, ):
190.45 + """return a diff between self and other"""
190.46 +
190.47 + import difflib
190.48 + diff = []
190.49 +
190.50 + for line in difflib.unified_diff([l for l in open(this).readlines()],
190.51 + [l for l in open(other).readlines()],
190.52 + this, other):
190.53 + diff += [line]
190.54 + return "".join(diff)
190.55 +
190.56 + def are_files_equal(self, f1, f2):
190.57 + assert self.diff(f1, f2) == '', self.diff(f1, f2)
190.58 +
190.59 + def del_classe(self, classe):
190.60 + l.del_group(classe)
190.61 + execute('rm -Fr /home/shares/classi/%s' % classe)
190.62 +
190.63 + def prepare_01(self):
190.64 + for f in glob.glob('/root/users-*'):
190.65 + os.remove(f)
190.66 + l.get_group('alunni').delete_members(home_mode='rm')
190.67 +
190.68 + ## Anno 0
190.69 + ## generazione FORMATO STANDARD
190.70 + def test_01a_alunni_anno0_std(self):
190.71 + self.prepare_01()
190.72 + res.b1 = bulk_users.BulkUsers('alunni', user_format='cf')
190.73 + res.b1.read_file('data/convert/sissi-0.csv', file_format='sissi')
190.74 +
190.75 + def test_01b_col_map(self):
190.76 + assert bulk_users.SissiUser.cols['Corso'] == 2, 'Corso = %' % bulk_users.SissiUser.cols['Corso']
190.77 +
190.78 + # esiste output
190.79 + def test_01b_generate_output(self):
190.80 + res.b1.as_isi(filename='/root/users-0-std.isi')
190.81 + assert os.path.exists('/root/users-0-std.isi')
190.82 +
190.83 + # e' corretto
190.84 + def test_01c_alunni_anno0_std(self):
190.85 + f1 = '/root/users-0-std.isi'
190.86 + f2 = 'data/convert/users-0-std.isi'
190.87 + self.are_files_equal(f1, f2)
190.88 +
190.89 + # FORMATO ESTESO
190.90 + def test_01d_alunni_anno0_std(self):
190.91 + res.b1.as_isi(filename='/root/users-0-extended.isi', extended=True)
190.92 + assert os.path.exists('/root/users-0-extended.isi')
190.93 +
190.94 + # e' corretto
190.95 + def test_01e_alunni_anno0_std_users_upd(self):
190.96 + f1 = '/root/users-0-extended.isi'
190.97 + f2 = 'data/convert/users-0-extended.isi'
190.98 + self.are_files_equal(f1, f2)
190.99 +
190.100 + def test_01f_alunni_anno0_renamed(self):
190.101 + assert not res.b1.renamed
190.102 +
190.103 + def test_01g_alunni_anno0_deleted(self):
190.104 + assert not res.b1.get_users_to_be_removed()
190.105 +
190.106 + ## logname con nome
190.107 + def test_01h_alunni_anno0_std(self):
190.108 + res.b1.user_format = 'name'
190.109 + res.b1.read_file('data/convert/sissi-0.csv', file_format='sissi')
190.110 + res.b1.as_isi(filename='/root/users-0-names.isi')
190.111 + assert os.path.exists('/root/users-0-names.isi')
190.112 +
190.113 + # e' corretto
190.114 + def test_01i_alunni_anno0_std_users_upd(self):
190.115 + f1 = '/root/users-0-names.isi'
190.116 + f2 = 'data/convert/users-0-names.isi'
190.117 + self.are_files_equal(f1, f2)
190.118 +
190.119 + ## logname con nome - collisioni
190.120 + def test_01l_alunni_anno0_collisioni(self):
190.121 + res.b1 = bulk_users.BulkUsers('alunni', user_format='cf')
190.122 + res.b1.user_format = 'name'
190.123 + res.b1.read_file('data/convert/sissi-0-collisioni.csv', file_format='sissi')
190.124 + res.b1.as_isi(filename='/root/users-0-collisioni.isi')
190.125 + assert os.path.exists('/root/users-0-names.isi')
190.126 +
190.127 + # e' corretto
190.128 + def test_01m_alunni_anno0_std_users_upd(self):
190.129 + f1 = '/root/users-0-collisioni.isi'
190.130 + f2 = 'data/convert/users-0-collisioni.isi'
190.131 + self.are_files_equal(f1, f2)
190.132 +
190.133 +
190.134 + ## da file .xls
190.135 + def test_01n_xls(self):
190.136 + xls = bulk_users.BulkUsers('alunni', user_format='cf')
190.137 + xls.read_file('data/convert/sissi-0.xls', file_format='sissi')
190.138 + assert len(xls.file_users) == 8
190.139 +
190.140 + ## missing columns xls
190.141 + def test_01o_alunni_anno0_collisioni(self):
190.142 + res.b1 = bulk_users.BulkUsers('alunni', user_format='name')
190.143 + res.b1.user_format = 'name'
190.144 + res.b1.read_file('data/convert/sissi-0-col-select.xls', file_format='sissi')
190.145 + res.b1.as_isi(filename='/root/users-0-names-cols.isi')
190.146 + assert os.path.exists('/root/users-0-names-cols.isi')
190.147 +
190.148 + def test_01p_alunni_anno0_std_users_upd(self):
190.149 + f1 = '/root/users-0-names-cols.isi'
190.150 + f2 = 'data/convert/users-0-names.isi'
190.151 + self.are_files_equal(f1, f2)
190.152 +
190.153 + def test_01q_alunni_anno0_collisioni(self):
190.154 + res.b1 = bulk_users.BulkUsers('alunni', user_format='id-name')
190.155 + res.b1.read_file('data/convert/sissi-0.csv', file_format='sissi')
190.156 + res.b1.as_isi(filename='/root/users-0-idnames.isi')
190.157 + assert os.path.exists('/root/users-0-idnames.isi')
190.158 +
190.159 + def test_01r_alunni_anno0_std_users_upd(self):
190.160 + f1 = '/root/users-0-idnames.isi'
190.161 + f2 = 'data/convert/users-0-idnames.isi'
190.162 + self.are_files_equal(f1, f2)
190.163 +
190.164 + ## ANNO 1
190.165 + # genera alunni anno 0 con nomi (per avere collisioni)
190.166 + def prepara_02(self):
190.167 + l.get_group('alunni').delete_members()
190.168 + l.read_file('data/convert/users-0-names.isi', run_alulink=False,
190.169 + no_filesystem=True, interactive=False, default_passwd='PASSWORD')
190.170 +
190.171 + def test_02a_alunni_anno1(self):
190.172 + self.prepara_02()
190.173 + # genera un db ldap da anno0
190.174 + res.b2 = bulk_users.BulkUsers('alunni', user_format='name')
190.175 + res.b2.read_file('data/convert/sissi-1.csv', file_format='sissi')
190.176 +
190.177 + # crea output standard
190.178 + def test_02b_alunni_standard(self):
190.179 + res.b2.as_isi('/root/users-1-names.isi')
190.180 + assert os.path.exists('/root/users-1-names.isi')
190.181 +
190.182 + def test_02c_removed(self):
190.183 + assert res.b2.get_users_to_be_removed()
190.184 + delenda = list(res.b2.get_users_to_be_removed())[0]
190.185 + assert res.b2.users_dict[delenda.logname].cf == 'CRBMHL94A58I829C'
190.186 +
190.187 + def test_02d_renamed(self):
190.188 + renamed = list(res.b2.renamed)[0]
190.189 + assert renamed.logname == 'michela.carboni02'
190.190 + assert renamed.cf == 'CRBLCU95E23A821X'
190.191 +
190.192 + # e' corretto
190.193 + def test_02h_alunni_anno1_users(self):
190.194 + f1 = '/root/users-1-names.isi'
190.195 + f2 = 'data/convert/users-1-names.isi'
190.196 + self.are_files_equal(f1, f2)
190.197 +
190.198 +
191.1 Binary file tests/data/convert/sissi-0-col-select.xls has changed
192.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
192.2 +++ b/tests/data/convert/sissi-0-collisioni.csv Mon Apr 26 11:16:23 2010 +0200
192.3 @@ -0,0 +1,9 @@
192.4 +Anno di corso;Sezione;Corso;Cognome;Nome;Data di nascita;Sesso;Comune di nascita;Prov. Nascita;Codice fiscale;Indirizzo;Comune di residenza;CAP;Prov. Residenza;Telefono 1;Telefono 2;Cognome padre;Nome padre;Cognome madre;Nome madre;Anno Sc.
192.5 +3;A;PROGETTO CINQUE;CARBONI;LUCA;08/02/1992;M;MILANO;MI;CRBLCU95E23A829H;VIA GARIBALDI, 60;COLICO;23823;LC;0341/123456;;ACQUISTINI;GERVASO;ALIPRANDI;MARISA;2009
192.6 +3;A;Indirizzo Giuridico Economico Aziendale;BERTOLDI;GIULIA;03/02/1993;F;MORBEGNO;SO;BRTGLI93B43F712B;VIA ROMA 103;TRAONA;23013;SO;0342/123456;888 123456; m;BERTOLDI;MARIO;GIGIONELLI;ANTONIA;2009
192.7 +3;A;PROGETTO CINQUE;ANTONI;LUCIA;29/02/1991;F;MORBEGNO;SO;ANTLCU91B69F712X;VIA BRIGLIA, 150/A;MORBEGNO;23017;SO;0342/123456;;ANTONI;ALBERTO;MANNOIA;ZOE;2009
192.8 +3;A;Indirizzo Giuridico Economico Aziendale;CARAPELLI;MARCO;18/02/1993;M;MORBEGNO;SO;CRPMRC93B18F712A;VIA RIBALDI, 4;COSIO VALTELLINO;23013;SO;0342 123456;M 999123456;CARAPELLI;GIUSEPPE;MARIOTTI;CRISTINA;2009
192.9 +3;A;Indirizzo Giuridico Economico Aziendale;AMARETTI;NICOLA;08/01/1993;M;SONDRIO;SO;MRTNCL93A08I829X;VIA MARCHETTI, 20;ARDENNO;23014;SO;0342 123456;0342 654321 lavoro;AMARETTI;CARLO;FRANZINA;MARTA;2009
192.10 +3;A;Programmatori Mercurio;CARBONI;LUCA;19/01/1993;F;MORBEGNO;SO;CRBLCU95E23A829G;VIA CARTIERA, 7;MANDELLO;23015;SO;0342 687521;335 5659780 p;TARGIOLI;ANDREA;AMBROSETTI;CARLA;2009
192.11 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;LUCA;23/01/1995;M;SONDRIO;SO;CRBLCU95E23A829F;Via LARIO, 32;MORBEGNO;23017;SO;0342/612620;333/5968693 m;CARBONI;MASSIMO;SELLA;SILVIA;2009
192.12 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;MICHELA;18/1/1994;F;SONDRIO;SO;CRBMHL94A58I829C;VIA ROCCA 5C;MORBEGNO;23017;SO;0342615240;P3406429865;CARBONI;MAURO;ARTONI;PAOLA;2009
193.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
193.2 +++ b/tests/data/convert/sissi-0.csv Mon Apr 26 11:16:23 2010 +0200
193.3 @@ -0,0 +1,9 @@
193.4 +Anno di corso;Sezione;Corso;Cognome;Nome;Data di nascita;Sesso;Comune di nascita;Prov. Nascita;Codice fiscale;Indirizzo;Comune di residenza;CAP;Prov. Residenza;Telefono 1;Telefono 2;Cognome padre;Nome padre;Cognome madre;Nome madre;Anno Sc.
193.5 +3;A;PROGETTO CINQUE;ACQUISTINI;FRANCESCO;08/02/1992;M;MILANO;MI;CQSFRN92B08A745Z;VIA GARIBALDI, 60;COLICO;23823;LC;0341/123456;;ACQUISTINI;GERVASO;ALIPRANDI;MARISA;2009
193.6 +3;A;Indirizzo Giuridico Economico Aziendale;BERTOLDI;GIULIA;03/02/1993;F;MORBEGNO;SO;BRTGLI93B43F712B;VIA ROMA 103;TRAONA;23013;SO;0342/123456;888 123456; m;BERTOLDI;MARIO;GIGIONELLI;ANTONIA;2009
193.7 +3;A;PROGETTO CINQUE;ANTONI;LUCIA;29/02/1991;F;MORBEGNO;SO;ANTLCU91B69F712X;VIA BRIGLIA, 150/A;MORBEGNO;23017;SO;0342/123456;;ANTONI;ALBERTO;MANNOIA;ZOE;2009
193.8 +3;A;Indirizzo Giuridico Economico Aziendale;CARAPELLI;MARCO;18/02/1993;M;MORBEGNO;SO;CRPMRC93B18F712A;VIA RIBALDI, 4;COSIO VALTELLINO;23013;SO;0342 123456;M 999123456;CARAPELLI;GIUSEPPE;MARIOTTI;CRISTINA;2009
193.9 +3;A;Indirizzo Giuridico Economico Aziendale;AMARETTI;NICOLA;08/01/1993;M;SONDRIO;SO;MRTNCL93A08I829X;VIA MARCHETTI, 20;ARDENNO;23014;SO;0342 123456;0342 654321 lavoro;AMARETTI;CARLO;FRANZINA;MARTA;2009
193.10 +3;A;Programmatori Mercurio;TARGIOLI;MARIELLA;19/01/1993;F;MORBEGNO;SO;TRGMRL93A59F712X;VIA CARTIERA, 7;MANDELLO;23015;SO;0342 687521;335 5659780 p;TARGIOLI;ANDREA;AMBROSETTI;CARLA;2009
193.11 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;LUCA;23/01/1995;M;SONDRIO;SO;CRBLCU95E23A829F;Via LARIO, 32;MORBEGNO;23017;SO;0342/612620;333/5968693 m;CARBONI;MASSIMO;SELLA;SILVIA;2009
193.12 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;MICHELA;18/1/1994;F;SONDRIO;SO;CRBMHL94A58I829C;VIA ROCCA 5C;MORBEGNO;23017;SO;0342615240;P3406429865;CARBONI;MAURO;ARTONI;PAOLA;2009
194.1 Binary file tests/data/convert/sissi-0.xls has changed
195.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
195.2 +++ b/tests/data/convert/sissi-1.csv Mon Apr 26 11:16:23 2010 +0200
195.3 @@ -0,0 +1,9 @@
195.4 +Anno di corso;Sezione;Corso;Cognome;Nome;Data di nascita;Sesso;Comune di nascita;Prov. Nascita;Codice fiscale;Indirizzo;Comune di residenza;CAP;Prov. Residenza;Telefono 1;Telefono 2;Cognome padre;Nome padre;Cognome madre;Nome madre;Anno Sc.
195.5 +3;A;PROGETTO CINQUE;ACQUISTINI;FRANCESCO;08/02/1992;M;MILANO;MI;CQSFRN92B08A745Z;VIA GARIBALDI, 60;COLICO;23823;LC;0341/123456;;ACQUISTINI;GERVASO;ALIPRANDI;MARISA;2009
195.6 +3;A;Indirizzo Giuridico Economico Aziendale;BERTOLDI;GIULIA;03/02/1993;F;MORBEGNO;SO;BRTGLI93B43F712B;VIA ROMA 103;TRAONA;23013;SO;0342/123456;888 123456; m;BERTOLDI;MARIO;GIGIONELLI;ANTONIA;2009
195.7 +3;A;PROGETTO CINQUE;ANTONI;LUCIA;29/02/1991;F;MORBEGNO;SO;ANTLCU91B69F712X;VIA BRIGLIA, 150/A;MORBEGNO;23017;SO;0342/123456;;ANTONI;ALBERTO;MANNOIA;ZOE;2009
195.8 +3;A;Indirizzo Giuridico Economico Aziendale;CARAPELLI;MARCO;18/02/1993;M;MORBEGNO;SO;CRPMRC93B18F712A;VIA RIBALDI, 4;COSIO VALTELLINO;23013;SO;0342 123456;M 999123456;CARAPELLI;GIUSEPPE;MARIOTTI;CRISTINA;2009
195.9 +3;A;Indirizzo Giuridico Economico Aziendale;AMARETTI;NICOLA;08/01/1993;M;SONDRIO;SO;MRTNCL93A08I829X;VIA MARCHETTI, 20;ARDENNO;23014;SO;0342 123456;0342 654321 lavoro;AMARETTI;CARLO;FRANZINA;MARTA;2009
195.10 +3;A;Programmatori Mercurio;TARGIOLI;MARIELLA;19/01/1993;F;MORBEGNO;SO;TRGMRL93A59F712X;VIA CARTIERA, 7;MANDELLO;23015;SO;0342 687521;335 5659780 p;TARGIOLI;ANDREA;AMBROSETTI;CARLA;2009
195.11 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;LUCA;23/01/1995;M;SONDRIO;SO;CRBLCU95E23A829F;Via LARIO, 32;MORBEGNO;23017;SO;0342/612620;333/5968693 m;CARBONI;MASSIMO;SELLA;SILVIA;2009
195.12 +3;A;Indirizzo Giuridico Economico Aziendale;CARBONI;MICHELA;18/1/1994;F;SONDRIO;SO;CRBLCU95E23A821X;VIA ROCCA 5C;MORBEGNO;23017;SO;0342615240;P3406429865;CARBONI;MAURO;ARTONI;PAOLA;2009
196.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
196.2 +++ b/tests/data/convert/sissi-tabcorsi Mon Apr 26 11:16:23 2010 +0200
196.3 @@ -0,0 +1,5 @@
196.4 +progetto cinque = geo
196.5 +geometri = geo
196.6 +indirizzo giuridico economico aziendale = ige
196.7 +programmatori mercurio = pro
196.8 +
197.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
197.2 +++ b/tests/data/convert/users-0-collisioni.isi Mon Apr 26 11:16:23 2010 +0200
197.3 @@ -0,0 +1,8 @@
197.4 +luca.carboni;Carboni;Luca;alunni;geo3a;CRBLCU95E23A829H;
197.5 +giulia.bertoldi;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;
197.6 +lucia.antoni;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;
197.7 +marco.carapelli;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;
197.8 +nicola.amaretti;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;
197.9 +luca.carboni02;Carboni;Luca;alunni;pro3a;CRBLCU95E23A829G;
197.10 +luca.carboni03;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;
197.11 +michela.carboni;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;
198.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
198.2 +++ b/tests/data/convert/users-0-extended.isi Mon Apr 26 11:16:23 2010 +0200
198.3 @@ -0,0 +1,8 @@
198.4 +a_cqsfrn92b08;Acquistini;Francesco;alunni;geo3a;CQSFRN92B08A745Z;;M;VIA GARIBALDI, 60;;;23823;0341/123456
198.5 +a_brtgli93b43;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;;F;VIA ROMA 103;;;23013;0342/123456
198.6 +a_antlcu91b69;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;;F;VIA BRIGLIA, 150/A;;;23017;0342/123456
198.7 +a_crpmrc93b18;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;;M;VIA RIBALDI, 4;;;23013;0342 123456
198.8 +a_mrtncl93a08;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;;M;VIA MARCHETTI, 20;;;23014;0342 123456
198.9 +a_trgmrl93a59;Targioli;Mariella;alunni;pro3a;TRGMRL93A59F712X;;F;VIA CARTIERA, 7;;;23015;0342 687521
198.10 +a_crblcu95e23;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;;M;Via LARIO, 32;;;23017;0342/612620
198.11 +a_crbmhl94a58;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;;F;VIA ROCCA 5C;;;23017;0342615240
199.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
199.2 +++ b/tests/data/convert/users-0-idnames.isi Mon Apr 26 11:16:23 2010 +0200
199.3 @@ -0,0 +1,8 @@
199.4 +a_francesco.acquistini;Acquistini;Francesco;alunni;geo3a;CQSFRN92B08A745Z;
199.5 +a_giulia.bertoldi;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;
199.6 +a_lucia.antoni;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;
199.7 +a_marco.carapelli;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;
199.8 +a_nicola.amaretti;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;
199.9 +a_mariella.targioli;Targioli;Mariella;alunni;pro3a;TRGMRL93A59F712X;
199.10 +a_luca.carboni;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;
199.11 +a_michela.carboni;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;
200.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
200.2 +++ b/tests/data/convert/users-0-names.isi Mon Apr 26 11:16:23 2010 +0200
200.3 @@ -0,0 +1,8 @@
200.4 +francesco.acquistini;Acquistini;Francesco;alunni;geo3a;CQSFRN92B08A745Z;
200.5 +giulia.bertoldi;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;
200.6 +lucia.antoni;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;
200.7 +marco.carapelli;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;
200.8 +nicola.amaretti;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;
200.9 +mariella.targioli;Targioli;Mariella;alunni;pro3a;TRGMRL93A59F712X;
200.10 +luca.carboni;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;
200.11 +michela.carboni;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;
201.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
201.2 +++ b/tests/data/convert/users-0-std.isi Mon Apr 26 11:16:23 2010 +0200
201.3 @@ -0,0 +1,8 @@
201.4 +a_cqsfrn92b08;Acquistini;Francesco;alunni;geo3a;CQSFRN92B08A745Z;
201.5 +a_brtgli93b43;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;
201.6 +a_antlcu91b69;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;
201.7 +a_crpmrc93b18;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;
201.8 +a_mrtncl93a08;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;
201.9 +a_trgmrl93a59;Targioli;Mariella;alunni;pro3a;TRGMRL93A59F712X;
201.10 +a_crblcu95e23;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;
201.11 +a_crbmhl94a58;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;
202.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
202.2 +++ b/tests/data/convert/users-1-names.isi Mon Apr 26 11:16:23 2010 +0200
202.3 @@ -0,0 +1,9 @@
202.4 +francesco.acquistini;Acquistini;Francesco;alunni;geo3a;CQSFRN92B08A745Z;
202.5 +giulia.bertoldi;Bertoldi;Giulia;alunni;ige3a;BRTGLI93B43F712B;
202.6 +lucia.antoni;Antoni;Lucia;alunni;geo3a;ANTLCU91B69F712X;
202.7 +marco.carapelli;Carapelli;Marco;alunni;ige3a;CRPMRC93B18F712A;
202.8 +nicola.amaretti;Amaretti;Nicola;alunni;ige3a;MRTNCL93A08I829X;
202.9 +mariella.targioli;Targioli;Mariella;alunni;pro3a;TRGMRL93A59F712X;
202.10 +luca.carboni;Carboni;Luca;alunni;ige3a;CRBLCU95E23A829F;
202.11 +michela.carboni02;Carboni;Michela;alunni;ige3a;CRBLCU95E23A821X;
202.12 +-michela.carboni;Carboni;Michela;alunni;ige3a;CRBMHL94A58I829C;
203.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
203.2 +++ b/tests/data/etc/dnsmasq.conf Mon Apr 26 11:16:23 2010 +0200
203.3 @@ -0,0 +1,102 @@
203.4 +# -*- mode: conf -*-
203.5 +# non inoltrare mai ai server dns esterni
203.6 +# query senza nome dominio
203.7 +domain-needed
203.8 +
203.9 +# Tutti i reverse lookup per la subnet privata
203.10 +# non presenti in /etc/hosts o nei lease dhcp
203.11 +# ottengono "host not found"
203.12 +# invece di essere inoltrati ai dns esterni
203.13 +bogus-priv
203.14 +
203.15 +# Filtra le ricorrenti richieste SOA, SRV e altre,
203.16 +# provenienti da macchine windows
203.17 +# serve in particolare a non attivare
203.18 +# per sbaglio il link quando si
203.19 +# hanno connessioni "on demand"
203.20 +filterwin2k
203.21 +
203.22 +# server dns esterni di riferimento
203.23 +# inserire i server dns uno per riga
203.24 +# usati in questo caso i server di opendns.org
203.25 +server=208.67.222.222
203.26 +server=208.67.220.220
203.27 +
203.28 +# aggiunge sempre il nome dominio al nome host
203.29 +expand-hosts
203.30 +
203.31 +# nome del mio dominio
203.32 +domain=isi.lan
203.33 +
203.34 +# Se si intende passare ai client un dominio differente
203.35 +# dhcp-option=option:domain-name,isi.lan
203.36 +
203.37 +# range dei lease dhcp: indirizzo iniziale, indirizzo finale, netmask, durata del lease
203.38 +dhcp-range=192.168.96.130,192.168.96.140,255.255.255.0,8h
203.39 +
203.40 +# Range dhcp per-tag
203.41 +# ~~~~~~~~~~~~~~~~~~~
203.42 +# E` anche possibile riservare un determinato range filtrando per TAG.
203.43 +# I tag possono essere associati anche ad un'intera famiglia di indirizzi MAC
203.44 +# Ciò risulta utilissimo, ad esempio, per limitare le macchine virtuali vmware
203.45 +# ad un certo range.
203.46 +#
203.47 +# Settare il tag "macchinevmware" per le macchine con mac iniziante per
203.48 +# 00:0c:29:*:*:* (gruppo di indirizzi mac riservati a vmware)
203.49 +#
203.50 +# dhcp-mac=macchinevmware,00:0c:29:*:*:*
203.51 +#
203.52 +# Sintassi ::
203.53 +#
203.54 +# dhcp-range=[[net:]network-id,]<start-addr>,<end-addr>[[,<net‐netmask>],<broadcast>][,<lease time>]
203.55 +#
203.56 +# Esempio ::
203.57 +#
203.58 +# dhcp-range=net:macchinevmware,192.168.150,160,255.255.255.0,8h
203.59 +
203.60 +
203.61 +# Esempio di ip-reservation per client
203.62 +#
203.63 +# MAC address, indirizzo, nome host, tag(utile per associare a più server)
203.64 +#
203.65 +# dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1
203.66 +# dhcp-host=00:0c:29:5e:69:b5,192.168.96.191,vm-ltsp02,net:ns2 # client2
203.67 +#
203.68 +# le associazioni vengono definite esternamente, vedi inclusioni a fine file.
203.69 +# il file usato è /etc/isi/dns/dnsmasq/hosts.mac
203.70 +
203.71 +# dnsmasq supporta la maggior parte delle
203.72 +# opzioni dhcp e bootp specificate in
203.73 +# http://www.faqs.org/rfcs/rfc2132.html
203.74 +# la sintassi e':
203.75 +# dhcp-option=[numero relativo all'opzione],parametro
203.76 +
203.77 +# GATEWAY di default (3)
203.78 +dhcp-option=3,192.168.96.1
203.79 +
203.80 +# DNS da passare ai client (6)
203.81 +dhcp-option=6,192.168.96.254
203.82 +
203.83 +# WINS da passare ai client (44)
203.84 +dhcp-option=44,192.168.96.253
203.85 +#
203.86 +# Il server dhcp sarà AUTORITATIVO.
203.87 +dhcp-authoritative
203.88 +cache-size=1024
203.89 +### LOG
203.90 +# da usare per debug
203.91 +# log-queries
203.92 +
203.93 +# Da abilitare *solo* in caso di debug, logga tutte le transazioni che avvengono
203.94 +# tra servente DHCP e i client.
203.95 +#
203.96 +# log-dhcp
203.97 +
203.98 +# Configurazione aggiuntiva per isi.
203.99 +conf-dir=/etc/isi/dns/dnsmasq
203.100 +addn-hosts=/etc/isi/dns/hosts
203.101 +
203.102 +# Per includere ulteriori configurazioni...
203.103 +# conf-file=/etc/dnsmasq.more.conf
203.104 +# conf-dir=/etc/dnsmasq.d
203.105 +dhcp-boot=/ltsp/i386/nbi.img,ltsp-server,192.168.96.222
204.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
204.2 +++ b/tests/data/etc/hosts Mon Apr 26 11:16:23 2010 +0200
204.3 @@ -0,0 +1,7 @@
204.4 +127.0.0.1 localhost
204.5 +127.0.1.1 ISI-PDC
204.6 +192.168.96.222 srv-ltsp
204.7 +192.168.96.210 ISI-PDC
204.8 +192.168.96.22 www.tin.it
204.9 +192.168.96.199 vm-client-ltsp1
204.10 +192.168.96.44 srv-prova srv # questi sono dei commenti
205.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
205.2 +++ b/tests/data/etc/hosts.mac Mon Apr 26 11:16:23 2010 +0200
205.3 @@ -0,0 +1,2 @@
205.4 +dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1
205.5 +dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1
206.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
206.2 +++ b/tests/data/etc/isi/dns/dnsmasq/ltsp Mon Apr 26 11:16:23 2010 +0200
206.3 @@ -0,0 +1,27 @@
206.4 +# le prossime sono quelle che servono
206.5 +# in particolare ai thin client
206.6 +# root-path (17)
206.7 +# percorso dove montare la partizione root
206.8 +dhcp-option=17,"/opt/ltsp/i386"
206.9 +
206.10 +# file di boot (percorso relativo alla root del server tftp),
206.11 +# nome tftp server, ip tftp server
206.12 +# l'indirizzo e il nome del server
206.13 +# devono essere inseriti in /etc/hosts
206.14 +dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
206.15 +
206.16 +# file di boot (percorso relativo alla root del server tftp),
206.17 +# nome tftp server, ip tftp server
206.18 +# l'indirizzo e il nome del server
206.19 +# devono essere inseriti in /etc/hosts
206.20 +#dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
206.21 +
206.22 +# PXE / Etherboot
206.23 +dhcp-vendorclass=pxe,PXEClient
206.24 +dhcp-vendorclass=eth,Etherboot
206.25 +# dhcp-option=vendor:PXEClient,1,0.0.0.0
206.26 +dhcp-boot=net:pxe,/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
206.27 +dhcp-boot=net:eth,/ltsp/i386/pxelinux.0,ltsp-server, 192.168.96.222
206.28 +
206.29 +# other
206.30 +dhcp-boot=/ltsp/i386/nbi.img,ltsp-server,192.168.96.222
207.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
207.2 +++ b/tests/data/leases Mon Apr 26 11:16:23 2010 +0200
207.3 @@ -0,0 +1,6 @@
207.4 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
207.5 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
207.6 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
207.7 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
207.8 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
207.9 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
208.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
208.2 +++ b/tests/data/logon.conf Mon Apr 26 11:16:23 2010 +0200
208.3 @@ -0,0 +1,248 @@
208.4 +# +-------------------------------------------------+
208.5 +# � 2002-2005 ReteIsi / www.reteisi.org
208.6 +# +-------------------------------------------------+
208.7 +# $Id: logon.conf,v 1.4 2021/09/02 17:23:43 max Exp $
208.8 +
208.9 +###-----------------------------------------------------------------------
208.10 +### Le variabili dichiarate in questo file sono di due tipi
208.11 +### quelle che iniziano con un _ sono variabili interne e servono
208.12 +### ad abilitare (1) o disabilitare (0) la funzionalita`corrispondente
208.13 +### oppure a passare variabili di configurazione specifiche di
208.14 +### ISI-logon; le altre DEVONO corrispondere a voci di registro a cui
208.15 +### si vuole assegnare il valore scritto di seguito (es. 0x00000001).
208.16 +### Per ottenere una differente impostazione per uno specifico gruppo
208.17 +### basta specificare il gruppo come nell'esempio:
208.18 +### Start__Page[alunni] = www.google.com
208.19 +### Quando i nomi usati per le variabili sono quelli del registro di
208.20 +### windows, se il nome della variabile di registro contiene uno
208.21 +### spazio, sostituirlo con due _ (.Es "Start Page" = Start__Page)
208.22 +
208.23 +### sulle variabili prefissate con underscore in generale
208.24 +### 1 applica la restrizione
208.25 +### 0 rimuove la restrizione
208.26 +### il valore delle variabili di registro va espresso
208.27 +### coerentemente con il TIPO (se REG_DWORD, 0x......)
208.28 +
208.29 +### NOTA: Le variabili sono *case sensitive*
208.30 +###-----------------------------------------------------------------------
208.31 +
208.32 +### versione di logon.conf - DA INCREMENTARE AD OGNI MODIFICA di logon.conf
208.33 +### per attivare l'aggiornamento degli user.dat (agisce sui client win98)
208.34 +
208.35 +_Versione = 0;
208.36 +
208.37 +### DEBUG (0,1,2,3)
208.38 +### 0 = nessun debug
208.39 +### 1 = solo console su video o su file (se valorizzato _DebugFile)
208.40 +### 2 = su schermo (in box grafici: lungo, completo e noioso ;-)
208.41 +### 3 = sul file locale DBG_macchina.TXT nella HOME
208.42 +
208.43 +
208.44 +_DebugLevel = 1
208.45 +
208.46 +### opzioni aggiuntive se _DebugLevel=3
208.47 +### _DebugShare share samba in cui centralizzare
208.48 +### _DebugUsers lista degli utenti da sottoporre a debug
208.49 +### _DebugClients lista dei clients da sottoporre a debug
208.50 +
208.51 +_DebugShare =
208.52 +_DebugUsers =
208.53 +_DebugClients=
208.54 +
208.55 +
208.56 +### WinSet sezione 'start_page'
208.57 +Start__Page = www.google.it
208.58 +Start__Page[admins] = www.google.it
208.59 +
208.60 +### WinSet sezione 'proxy'
208.61 +ProxyServer = XXX.XXX.XXX:8128 # DansGuardian
208.62 +ProxyServer[admins] = XXX.XXX.XXX:3128 # Squid (FW permettendo)
208.63 +ProxyOverride = www.XXX.XXX,<local>
208.64 +
208.65 +### WinSet sezione 'no_profile' (solo XP)
208.66 +ExcludeProfileDirs = Impostazioni locali;Temporary Internet Files;Cronologia;Temp;Documenti;Cookies;SendTo
208.67 +
208.68 +### WinSet sezione 'document_folder'
208.69 +Personal = H:\Documenti
208.70 +My__Picture =
208.71 +My__Music =
208.72 +My__Video =
208.73 +
208.74 +### WinSet sezione 'paranoia_folders' solo per win9x
208.75 +### se _OkParanoia = 1 vengono ripuliti ad ogni logon il Desktop e il cestino di default.
208.76 +_OkParanoia = 0
208.77 +
208.78 +
208.79 +### WinSet sezione 'iepasswordcache' - non salva le password digitate quando si accede a siti web
208.80 +
208.81 +_RestrictIEPasswordCaching = 0
208.82 +
208.83 +### WinSet sezione 'sync' (solo WinXP)
208.84 +### per disabilitare la sincronizzazione delle cartelle non in linea
208.85 +### � necessario porre a 1 la seguente variabile
208.86 +_NoSync = 1
208.87 +
208.88 +### WinSet sezione 'last-user' (WinXP)
208.89 +### gli utenti normali non hanno permessi sufficenti
208.90 +### gli amministratori (admins) invece possono
208.91 +### questa situazione viene gestita eliminando
208.92 +### il default
208.93 +
208.94 +_NoDispLastUser[admins] = 0
208.95 +
208.96 +### WinPol9x sezione 'last-user' (Win9X solo con Tweakui installato)
208.97 +_NoDispLastUser9X = 1
208.98 +
208.99 +### parametri validi per Win9x - default molto restrittivo
208.100 +
208.101 +### di seguito sono specifate tutte e solo le cartelle che possono essere messe in roaming
208.102 +### separare le cartelle con un ; per default tutte le cartelle sono in roaming
208.103 +
208.104 +#_ProleDirs = AppData;Cache;Cookies;Desktop;Favorites;History;NetHood;Programs;Recent;Start Menu;Startup
208.105 +_ProfileDirs = AppData;Temporary Internet Files;Cookies;Desktop;Favorites;History;NetHood;Programs;Recent;Start Menu;Startup
208.106 +
208.107 +### se le cartelle vengono messe in roaming possono anche essere rimappate sul server in modo
208.108 +### da salvare i documenti durante la sessione ed evitare "traffico" all'uscita,
208.109 +### se non si specifica alcun percorso vengono messe in roaming nel modo "classico"
208.110 +### con il salvataggio sul server all'uscita
208.111 +
208.112 +#esempi di percorsi:
208.113 +#Desktop = H:\.profili\Win95\Desktop
208.114 +#Cookies=H:\.profili\Win95\Cookies
208.115 +#Favorites=H:\.profili\Win95\Favorites
208.116 +
208.117 +
208.118 +### WinPol9x sezione 'access'
208.119 +_RestrictLogon = 1
208.120 +_RestrictLogon[admins] = 1
208.121 +# valori di registro
208.122 +UserProfiles = 1 #0x00000001 # si vogliono i roaming profiles
208.123 +UseHomeDirectory = 1 #0x00000001
208.124 +MustBeValidated = 1 #0x00000001 # si vuole l'autenticazione ldap
208.125 +MustBeValidated[admins] = 1 #0x00000000
208.126 +LegalNoticeCaption = XXX.XXX
208.127 +LegalNoticeText = accesso riservato agli utenti autorizzati.
208.128 +
208.129 +### WinPol9x sezione 'nocpan' - fa sparire dal pannello di controllo
208.130 +_RestrictCpan = 0
208.131 +
208.132 +### WinPol9x sezione 'appwiz' - fa sparire dal pannello di controllo
208.133 +### l'applet Installa/Rimuovi applicazioni
208.134 +_NoAppWiz = 0
208.135 +
208.136 +### WinPol9x sezione 'nodrive' - fa sparire le periferiche dalle risorse del computer
208.137 +_RestrictDrive = 0
208.138 +_RestrictDrive[admins] = 0
208.139 +
208.140 +###WinPol9x sezione 'nodrivec' - fa sparire il disco C dalle risorse del computer
208.141 +_RestrictDriveC = 1
208.142 +_RestrictDriveC[admins] = 0
208.143 +
208.144 +### WinPol9x sezione 'nofind' - fa sparire la voce trova dal menu avvio
208.145 +_RestrictFind = 1
208.146 +_RestrictFind[admins] = 0
208.147 +
208.148 +### WinPol9x sezione 'nohistory' - cancella la cronologia
208.149 +_RestrictHistory = 0
208.150 +
208.151 +### WinPol9x sezione 'iecachedays' - se _SetIECache � settato a 1
208.152 +### con la variabile successiva DaysToKeep � possibile impostare per
208.153 +### quanti giorni restano nella cache le pagine web visitate
208.154 +### Con DaysToKeep = 0x00000000 le pagine non vengono salvate
208.155 +_SetIECache = 0
208.156 +DaysToKeep = 0x00000000
208.157 +
208.158 +
208.159 +
208.160 +### WinPol9x sezione 'nosavesettings' - non salva i cambiamenti al Desktop all'uscita
208.161 +_RestrictSaveSettings = 0
208.162 +
208.163 +### WinPol9x sezione 'noactivedesktop' - disattiva l'Active Desktop
208.164 +_RestrictActiveDesktop = 0
208.165 +
208.166 +### WinPol9x sezione 'screen' - abilita le restrizioni dello schermo
208.167 +_RestrictScreen = 1
208.168 +_RestrictScreen[admins] = 0
208.169 +
208.170 +# opzioni restrizioni screen
208.171 +NoDispAppearancePage = 0 #0x00000000
208.172 +NoDispBackgroundPage = 0 #0x00000000
208.173 +NoDispCPL = 0 #0x00000000
208.174 +NoDispScrSavPage = 0 #0x00000000
208.175 +NoDispSettingsPage = 1 #0x00000001
208.176 +
208.177 +# opzioni altre applet del pannello di controllo
208.178 +NoAdminPage = 1
208.179 +NoConfigPage = 1
208.180 +NoDevMgrPage = 1
208.181 +NoFileSysPage = 1
208.182 +NoProfilePage = 1
208.183 +NoVirtMemPage = 1
208.184 +
208.185 +### WinPol9x sezione 'net' - Risorse di rete Propriet�
208.186 +_RestrictNet = 0
208.187 +_RestrictNet[admins] = 0
208.188 +
208.189 +### WinPol9x sezione 'passwd' = Pannello di controllo Password
208.190 +_RestrictPasswd = 1
208.191 +_RestrictPasswd[admins] = 0
208.192 +
208.193 +### WinPol9x sezione 'printer' - Impostazioni stampanti
208.194 +_RestrictPrinter = 1
208.195 +_RestrictPrinter[admins] = 0
208.196 +
208.197 +### WinPol9x sezione 'system' - Restrizioni varie sul sistema
208.198 +_RestrictSystem = 1
208.199 +_RestrictSystem[admins] = 0
208.200 +
208.201 +### WinPol9x sezione 'shell-run' - Start Esegui
208.202 +_RestrictRun = 0
208.203 +_RestrictRun[admins] = 0
208.204 +
208.205 +### WinPol9x sezione 'shell-noregtools' - tools per la modifica del registro
208.206 +_RestrictRegTools = 0
208.207 +_RestrictRegTools[admins] = 0
208.208 +
208.209 +### WinPol9x sezione 'shell-winoldapp' - vecchie applicazioni
208.210 +_RestrictOldApp = 0
208.211 +_RestrictOldApp[admins] = 0
208.212 +
208.213 +
208.214 +### connessioni di rete oltre a quelle attivate
208.215 +### automaticamente, che sono:
208.216 +### H: -> homedir
208.217 +### L: -> classe (solo per gli alunni)
208.218 +### la sintassi e'la seguente:
208.219 +### NetFolder[unita'[:gruppo]] = nome della condivisione
208.220 +### esempio _NetFolder[U:admins]=util
208.221 +
208.222 +_NetFolder[W] = mioweb
208.223 +#_NetFolder[Z:admins] = zoftware
208.224 +_NetFolder[Z] = software
208.225 +_NetFolder[S] = area_alunni
208.226 +_NetFolder[K:docenti] = classi
208.227 +_NetFolder[K:admins] = classi
208.228 +_NetFolder[X:admins] = dati
208.229 +
208.230 +### sincronizzazione orologio
208.231 +
208.232 +_NetTime = 1
208.233 +
208.234 +### forzatura ambiente di default (desktop, menu avvio ecc.ecc.)
208.235 +### la si ottiene copiando la seguente cartella
208.236 +
208.237 +### [netlogon]\env_$os_$gruppo\* -> C:\Windows\All Users (Win9x)
208.238 +### [netlogon]\env_$os_gruppo\* -> C:\Documents and Settings\All Users (WinXP)
208.239 +
208.240 +### dove os = $ENV{OSCLIENT} e'la versione di windows che gira sul client
208.241 +### cioe'una delle seguenti: Win95,Win98,WinME,WinNT,Win2K,WinXP
208.242 +
208.243 +_EnvWin98 = 1
208.244 +_EnvWin98[admins] = 0
208.245 +
208.246 +### ATTENZIONE: per WinXP,Win2K occorre che la cartella di destinazione sia
208.247 +### scrivibile dagli utenti di dominio il che normalmente non e'; si
208.248 +### consiglia di non attivare questa funzionalita, Se il client e'
208.249 +### correttamente configurato si rivela sostanzialmente inutile
208.250 +
208.251 +_EnvWinXP = 0
209.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
209.2 +++ b/tests/data/users_misc.isi Mon Apr 26 11:16:23 2010 +0200
209.3 @@ -0,0 +1,4 @@
209.4 +a_test;alunno;test;alunni;classe_test2;DNTLSN63D07z404a;isi
209.5 +-a_test2;alunno;test;alunni;3b;DNTLSN63D07z404a;isi
209.6 +d_test;doc;test;docenti;;DNTLSN63D07z404b;isi2
209.7 +ad_test;adm;test;admins;;DNTLSN63D07z404c;isi2
210.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
210.2 +++ b/tests/data/users_test.isi Mon Apr 26 11:16:23 2010 +0200
210.3 @@ -0,0 +1,7 @@
210.4 +a_test;alunno;test;alunni;classe_test;DNTLSN63D07z404a;isi
210.5 +a_test2;alunno;test;alunni;3b;DNTLSN63D07z404a;isi
210.6 +d_test;doc;test;docenti;;DNTLSN63D07z404b;isi
210.7 +ad_test;adm;test;admins;;DNTLSN63D07z404c;isi
210.8 +at_test;ata;test;ata;;DNTLSN63D07z405;isi
210.9 +s_test;doc;test;segreteria;;DNTLSN63D07z406;isi
210.10 +e_test;doc;test;esterni;;DNTLSN63D07z407;isi
211.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
211.2 +++ b/tests/data/var/lib/misc/dnsmasq.leases Mon Apr 26 11:16:23 2010 +0200
211.3 @@ -0,0 +1,2 @@
211.4 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
211.5 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
212.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
212.2 +++ b/tests/dnsmasq.txt Mon Apr 26 11:16:23 2010 +0200
212.3 @@ -0,0 +1,107 @@
212.4 +# -*- mode: python -*-
212.5 +### test Hosts
212.6 +
212.7 +>>> import sys
212.8 +>>> sys.path.insert(0, '..')
212.9 +>>> from isi.conf import dnsmasq
212.10 +
212.11 +>>> l = dnsmasq.Line('# comment')
212.12 +>>> l.is_comment
212.13 +True
212.14 +
212.15 +## Building a line from a string
212.16 +>>> l = dnsmasq.Line('bogus-param')
212.17 +Traceback (most recent call last):
212.18 +...
212.19 +UnknownParamName: Param is not valid: bogus-param
212.20 +
212.21 +>>> l = dnsmasq.Line('dhcp-authoritative')
212.22 +>>> l.validate()
212.23 +True
212.24 +
212.25 +>>> l = dnsmasq.Line('domain=isi.lan')
212.26 +>>> l.param_name
212.27 +'domain'
212.28 +
212.29 +>>> l = dnsmasq.Line('dhcp-range=192.168.96.130,192.168.96.140,255.255.255.0,8h')
212.30 +>>> l.param_name
212.31 +'dhcp-range'
212.32 +
212.33 +>>> l = dnsmasq.Line('dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1')
212.34 +>>> l.param_name
212.35 +'dhcp-host'
212.36 +
212.37 +>>> l = dnsmasq.Line('dhcp-option=3,192.168.96.1')
212.38 +>>> l.param_name
212.39 +'dhcp-option'
212.40 +>>> l.value
212.41 +'3,192.168.96.1'
212.42 +
212.43 +## Building a line from parameters
212.44 +>>> print dnsmasq.Line(param_name='dhcp-range', value='192.168.96.130,192.168.96.140,255.255.255.0,8h')
212.45 +dhcp-range=192.168.96.130,192.168.96.140,255.255.255.0,8h
212.46 +
212.47 +>>> print dnsmasq.Line(param_name='dhcp-authoritative')
212.48 +dhcp-authoritative
212.49 +
212.50 +############
212.51 +## Conf file
212.52 +############
212.53 +
212.54 +>>> conf = dnsmasq.Conf('data/etc/dnsmasq.conf')
212.55 +>>> len(conf.lines)
212.56 +102
212.57 +
212.58 +>>> lines = conf.get_param(param_name='dhcp-authoritative')
212.59 +>>> len(lines)
212.60 +1
212.61 +
212.62 +>>> l = conf.del_param('dhcp-authoritative')
212.63 +>>> print l
212.64 +dhcp-authoritative
212.65 +
212.66 +>>> conf2 = dnsmasq.Conf('data/etc/dnsmasq.conf')
212.67 +>>> print conf2.diff(conf)
212.68 +--- this.conf
212.69 ++++ other.conf
212.70 +@@ -81,7 +81,6 @@
212.71 + dhcp-option=44,192.168.96.253
212.72 + #
212.73 + # Il server dhcp sarà AUTORITATIVO.
212.74 +-dhcp-authoritative
212.75 + cache-size=1024
212.76 + ### LOG
212.77 + # da usare per debug
212.78 +<BLANKLINE>
212.79 +
212.80 +>>> conf = dnsmasq.Conf('data/etc/dnsmasq.conf')
212.81 +>>> l = conf.del_param(param_name='server', value='208.67.222.222')
212.82 +>>> print l
212.83 +server=208.67.222.222
212.84 +
212.85 +>>> print conf2.diff(conf)
212.86 +--- this.conf
212.87 ++++ other.conf
212.88 +@@ -19,7 +19,6 @@
212.89 + # server dns esterni di riferimento
212.90 + # inserire i server dns uno per riga
212.91 + # usati in questo caso i server di opendns.org
212.92 +-server=208.67.222.222
212.93 + server=208.67.220.220
212.94 +<BLANKLINE>
212.95 + # aggiunge sempre il nome dominio al nome host
212.96 +<BLANKLINE>
212.97 +
212.98 +>>> dnsmasq.get_ip('dhcp-option=6,192.168.96.254', '6')
212.99 +'192.168.96.254'
212.100 +
212.101 +>>> dnsmasq.get_ip('dhcp-option=6,192.168.96.254,net:ns', '6', tag='ns')
212.102 +'192.168.96.254'
212.103 +
212.104 +>>> dnsmasq.get_ip('dhcp-option=6,192.168.96.254,net:ns', '6', tag='ns2')
212.105 +
212.106 +>>> conf.get_option('gw')
212.107 +'192.168.96.1'
212.108 +
212.109 +>>> sorted([x.hostname for x in dnsmasq.get_leases('data/leases') if x.hostname])
212.110 +['colinux', 'vm-client-ltsp1', 'wdt']
213.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
213.2 +++ b/tests/hosts.txt Mon Apr 26 11:16:23 2010 +0200
213.3 @@ -0,0 +1,84 @@
213.4 +# -*- mode: python -*-
213.5 +### test Hosts
213.6 +
213.7 +>>> import sys
213.8 +>>> sys.path.insert(0, '..')
213.9 +>>> from isi.conf import hosts
213.10 +
213.11 +## a Line from a line
213.12 +>>> l = hosts.Line('127.0.0.1 localhost')
213.13 +>>> l.param_name
213.14 +'127.0.0.1'
213.15 +
213.16 +>>> l.value
213.17 +'localhost'
213.18 +
213.19 +## a lien from values
213.20 +>>> l = hosts.Line(param_name='127.0.0.1', value='localhost')
213.21 +>>> print l
213.22 +127.0.0.1 localhost
213.23 +
213.24 +>>> l = hosts.Line(param_name='127.0.0.300', value='localhost')
213.25 +Traceback (most recent call last):
213.26 +...
213.27 +WrongIPError: 127.0.0.300 is not a valid IP
213.28 +
213.29 +
213.30 +###########
213.31 +## a file
213.32 +###########
213.33 +
213.34 +>>> h = hosts.Hosts('data/etc/hosts')
213.35 +>>> len(h.lines) == 7
213.36 +True
213.37 +
213.38 +>>> lines = h.get_param(param_name='127.0.0.1')
213.39 +>>> len(lines)
213.40 +1
213.41 +
213.42 +>>> lines = h.get_param(param_name='192.168.96.222', value='srv-ltsp')
213.43 +>>> len(lines)
213.44 +1
213.45 +
213.46 +>>> lines[0].param_name
213.47 +'192.168.96.222'
213.48 +
213.49 +>>> print h.set_param('192.168.96.222', value='srv-isi')
213.50 +192.168.96.222 srv-isi
213.51 +
213.52 +## line number has not increased
213.53 +>>> len(h.lines)
213.54 +7
213.55 +
213.56 +>>> h1 = hosts.Hosts('data/etc/hosts')
213.57 +>>> print h1.diff(h)
213.58 +--- this.conf
213.59 ++++ other.conf
213.60 +@@ -1,6 +1,6 @@
213.61 + 127.0.0.1 localhost
213.62 + 127.0.1.1 ISI-PDC
213.63 +-192.168.96.222 srv-ltsp
213.64 ++192.168.96.222 srv-isi
213.65 + 192.168.96.210 ISI-PDC
213.66 + 192.168.96.22 www.tin.it
213.67 + 192.168.96.199 vm-client-ltsp1
213.68 +<BLANKLINE>
213.69 +
213.70 +>>> print h.set_param('192.168.96.254', value='gw')
213.71 +192.168.96.254 gw
213.72 +
213.73 +>>> h1 = hosts.Hosts('data/etc/hosts')
213.74 +>>> print h1.diff(h)
213.75 +--- this.conf
213.76 ++++ other.conf
213.77 +@@ -1,7 +1,8 @@
213.78 + 127.0.0.1 localhost
213.79 + 127.0.1.1 ISI-PDC
213.80 +-192.168.96.222 srv-ltsp
213.81 ++192.168.96.222 srv-isi
213.82 + 192.168.96.210 ISI-PDC
213.83 + 192.168.96.22 www.tin.it
213.84 + 192.168.96.199 vm-client-ltsp1
213.85 + 192.168.96.44 srv-prova srv
213.86 ++192.168.96.254 gw
213.87 +<BLANKLINE>
214.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
214.2 +++ b/tests/logon.txt Mon Apr 26 11:16:23 2010 +0200
214.3 @@ -0,0 +1,247 @@
214.4 +# -*- mode: python -*-
214.5 +
214.6 +>>> from isi.conf import logon
214.7 +
214.8 +### Line
214.9 +>>> line_dict = {'drive': None,
214.10 +... 'final_comment': '',
214.11 +... 'group': None,
214.12 +... 'is_comment': False,
214.13 +... 'line': 'Start__Page = www.google.it',
214.14 +... 'param_name': 'Start__Page',
214.15 +... 'value': 'www.google.it'}
214.16 +
214.17 +## parsing a simple line (w/o comment, w/o group)
214.18 +>>> line = logon.Line('Start__Page = www.google.it')
214.19 +>>> vars(line) == line_dict
214.20 +True
214.21 +
214.22 +## parsing a line with group & comment
214.23 +>>> line = logon.Line('Start__Page[admins] = www.google.it')
214.24 +>>> line_dict.update({
214.25 +... 'group' : 'admins',
214.26 +... 'line': 'Start__Page[admins] = www.google.it'
214.27 +... })
214.28 +>>> vars(line) == line_dict
214.29 +True
214.30 +
214.31 +## parsing a line with final comment
214.32 +>>> line = logon.Line('Start__Page[admins] = www.google.it # comment')
214.33 +>>> line_dict.update({
214.34 +... 'group' : 'admins',
214.35 +... 'line': 'Start__Page[admins] = www.google.it # comment',
214.36 +... 'final_comment' : ' # comment',
214.37 +... })
214.38 +>>> vars(line) == line_dict
214.39 +True
214.40 +
214.41 +## parsing a line with ";"
214.42 +>>> line = logon.Line('ExcludeProfileDirs = Impostazioni locali;Temporary Internet Files;Cronologia;Temp;Documenti;Cookies;SendTo')
214.43 +>>> line.group is None
214.44 +True
214.45 +>>> print line.param_name
214.46 +ExcludeProfileDirs
214.47 +>>> print line.value
214.48 +Impostazioni locali;Temporary Internet Files;Cronologia;Temp;Documenti;Cookies;SendTo
214.49 +
214.50 +## parsing a line with only driver
214.51 +>>> line = logon.Line('_NetFolder[Z] = software')
214.52 +>>> line.group is None
214.53 +True
214.54 +
214.55 +>>> line.drive
214.56 +'Z'
214.57 +
214.58 +## parsing a comment line
214.59 +>>> line = logon.Line('#_NetFolder[Z] = software')
214.60 +>>> line.is_comment
214.61 +True
214.62 +
214.63 +>>> line = logon.Line(' # _NetFolder[Z] = software')
214.64 +>>> line.is_comment
214.65 +True
214.66 +
214.67 +## building a line w/o value
214.68 +>>> line = logon.Line(param_name='Start__Page')
214.69 +>>> print line
214.70 +Start__Page =
214.71 +
214.72 +## building a line w/o group
214.73 +>>> line = logon.Line(param_name='Start__Page', value='www.google.it', group=None)
214.74 +>>> str(line) == 'Start__Page = www.google.it'
214.75 +True
214.76 +
214.77 +## building a line with group
214.78 +>>> line = logon.Line(param_name='Start__Page', value='www.google.it', group='admins')
214.79 +>>> str(line) == 'Start__Page[admins] = www.google.it'
214.80 +True
214.81 +
214.82 +## building a line with group
214.83 +>>> line = logon.Line(param_name='Start__Page', group='alunni', value='facebook.it', )
214.84 +>>> str(line) == 'Start__Page[alunni] = facebook.it'
214.85 +True
214.86 +
214.87 +## building a line with drive
214.88 +>>> line = logon.Line(param_name='_NetFolder', value='software', group='admins', drive='S')
214.89 +>>> str(line) == '_NetFolder[S:admins] = software'
214.90 +True
214.91 +
214.92 +## building a line from args
214.93 +>>> line = logon.Line(param_name='_NetFolder', value='software', drive='S')
214.94 +>>> str(line) == '_NetFolder[S] = software'
214.95 +True
214.96 +
214.97 +### URL generation
214.98 +>>> line = logon.Line(param_name='_NetFolder', value='software', drive='S')
214.99 +>>> print line.url
214.100 +/_NetFolder/?param_name=_NetFolder&drive=S
214.101 +
214.102 +>>> line = logon.Line(param_name='_NetFolder', value='software', group='docenti', drive='S')
214.103 +>>> print line.url
214.104 +/_NetFolder/?param_name=_NetFolder&group=docenti&drive=S
214.105 +
214.106 +>>> line = logon.Line(param_name='Start__Page', value='www.google.it', group='admins')
214.107 +>>> print line.url
214.108 +/Start__Page/?param_name=Start__Page&group=admins
214.109 +
214.110 +####################################
214.111 +#### Logon: reading a conf file
214.112 +####################################
214.113 +
214.114 +>>> conf = logon.Logon(text=logon.__doc__)
214.115 +>>> sp = conf.get_param('Start__Page', 'admins')
214.116 +>>> len(sp)
214.117 +1
214.118 +
214.119 +## group=None: group is not defined
214.120 +>>> sp = conf.get_param('Start__Page', group=None)
214.121 +>>> for l in sp: print l
214.122 +Start__Page = www.google.it #
214.123 +
214.124 +## group=False: any group or group not defined
214.125 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.126 +>>> sp = c1.get_param('Start__Page', group=False)
214.127 +>>> for l in sp: print l
214.128 +Start__Page = www.google.it
214.129 +Start__Page[admins] = www.google.it
214.130 +
214.131 +>>> sp = c1.get_param('_NetFolder', drive='Z')
214.132 +>>> for l in sp: print l
214.133 +_NetFolder[Z] = software
214.134 +
214.135 +## DebugShare
214.136 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.137 +>>> param = c1.get_param('_DebugUsers', group=False)
214.138 +
214.139 +
214.140 +### change a Start__Page for admins
214.141 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.142 +>>> c2 = logon.Logon(filename='data/logon.conf')
214.143 +>>> param = c2.set_param('Start__Page', value='http://www.istruzione.it', group='admins')
214.144 +>>> len(c1), len(c2)
214.145 +(248, 248)
214.146 +
214.147 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.148 +--- c1.conf
214.149 ++++ c2.conf
214.150 +@@ -52,7 +52,7 @@
214.151 +<BLANKLINE>
214.152 + ### WinSet sezione 'start_page'
214.153 + Start__Page = www.google.it
214.154 +-Start__Page[admins] = www.google.it
214.155 ++Start__Page[admins] = http://www.istruzione.it
214.156 +<BLANKLINE>
214.157 + ### WinSet sezione 'proxy'
214.158 + ProxyServer = XXX.XXX.XXX:8128 # DansGuardian
214.159 +<BLANKLINE>
214.160 +
214.161 +### add a Start__Page for docenti
214.162 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.163 +>>> c2 = logon.Logon(filename='data/logon.conf')
214.164 +>>> param = c2.set_param('Start__Page', value='http://www.istruzione.it', group='docenti')
214.165 +>>> len(c1), len(c2)
214.166 +(248, 249)
214.167 +
214.168 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.169 +--- c1.conf
214.170 ++++ c2.conf
214.171 +@@ -53,6 +53,7 @@
214.172 + ### WinSet sezione 'start_page'
214.173 + Start__Page = www.google.it
214.174 + Start__Page[admins] = www.google.it
214.175 ++Start__Page[docenti] = http://www.istruzione.it
214.176 +<BLANKLINE>
214.177 + ### WinSet sezione 'proxy'
214.178 + ProxyServer = XXX.XXX.XXX:8128 # DansGuardian
214.179 +<BLANKLINE>
214.180 +
214.181 +### add a _NetFolder for docenti
214.182 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.183 +>>> c2 = logon.Logon(filename='data/logon.conf')
214.184 +>>> param = c2.set_param('_NetFolder', value='software', group='docenti', drive="Z")
214.185 +>>> len(c1), len(c2)
214.186 +(248, 249)
214.187 +
214.188 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.189 +--- c1.conf
214.190 ++++ c2.conf
214.191 +@@ -223,6 +223,7 @@
214.192 + _NetFolder[K:docenti] = classi
214.193 + _NetFolder[K:admins] = classi
214.194 + _NetFolder[X:admins] = dati
214.195 ++_NetFolder[Z:docenti] = software
214.196 +<BLANKLINE>
214.197 + ### sincronizzazione orologio
214.198 +<BLANKLINE>
214.199 +<BLANKLINE>
214.200 +
214.201 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.202 +>>> c2 = logon.Logon(filename='data/logon.conf')
214.203 +>>> param = c2.del_param('_NetTime')
214.204 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.205 +--- c1.conf
214.206 ++++ c2.conf
214.207 +@@ -226,7 +226,6 @@
214.208 +<BLANKLINE>
214.209 + ### sincronizzazione orologio
214.210 +<BLANKLINE>
214.211 +-_NetTime = 1
214.212 +<BLANKLINE>
214.213 + ### forzatura ambiente di default (desktop, menu avvio ecc.ecc.)
214.214 + ### la si ottiene copiando la seguente cartella
214.215 +<BLANKLINE>
214.216 +
214.217 +>>> c1 = logon.Logon(filename='data/logon.conf')
214.218 +>>> c2 = logon.Logon(filename='data/logon.conf')
214.219 +>>> param = c2.del_param('_NetTime', value='1')
214.220 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.221 +--- c1.conf
214.222 ++++ c2.conf
214.223 +@@ -226,7 +226,6 @@
214.224 +<BLANKLINE>
214.225 + ### sincronizzazione orologio
214.226 +<BLANKLINE>
214.227 +-_NetTime = 1
214.228 +<BLANKLINE>
214.229 + ### forzatura ambiente di default (desktop, menu avvio ecc.ecc.)
214.230 + ### la si ottiene copiando la seguente cartella
214.231 +<BLANKLINE>
214.232 +
214.233 +>>> param = c2.set_param('_NetTime', 1, group='admins')
214.234 +>>> print c1.diff(c2, 'c1.conf', 'c2.conf')
214.235 +--- c1.conf
214.236 ++++ c2.conf
214.237 +@@ -226,7 +226,6 @@
214.238 +<BLANKLINE>
214.239 + ### sincronizzazione orologio
214.240 +<BLANKLINE>
214.241 +-_NetTime = 1
214.242 +<BLANKLINE>
214.243 + ### forzatura ambiente di default (desktop, menu avvio ecc.ecc.)
214.244 + ### la si ottiene copiando la seguente cartella
214.245 +@@ -246,3 +245,4 @@
214.246 + ### correttamente configurato si rivela sostanzialmente inutile
214.247 +<BLANKLINE>
214.248 + _EnvWinXP = 0
214.249 ++_NetTime[admins] = 1
214.250 +<BLANKLINE>
215.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
215.2 +++ b/tests/mac.txt Mon Apr 26 11:16:23 2010 +0200
215.3 @@ -0,0 +1,108 @@
215.4 +# -*- mode: python -*-
215.5 +### test Mac
215.6 +
215.7 +>>> import sys
215.8 +>>> sys.path.insert(0, '..')
215.9 +>>> from isi.conf import mac, tools
215.10 +
215.11 +## a Line from a line
215.12 +>>> l = mac.Line('dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2 # comment')
215.13 +>>> l.param_name
215.14 +'dhcp-host'
215.15 +
215.16 +>>> l.value
215.17 +'00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2'
215.18 +
215.19 +
215.20 +## a lien from values
215.21 +>>> l = mac.Line(param_name='dhcp-host', value='00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2')
215.22 +>>> print l
215.23 +dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2
215.24 +
215.25 +>>> l.mac
215.26 +'00:0c:29:c0:d7:9e'
215.27 +
215.28 +>>> l = mac.Line('dhcp-host=00:0c,192.168.96.198,vm-client-ltsp2 # comment')
215.29 +Traceback (most recent call last):
215.30 +...
215.31 +WrongMACError: dhcp-host is not a valid MAC Address
215.32 +
215.33 +>>> l = mac.Line(param_name='dhcp-host', value='00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2')
215.34 +>>> l.ip, l.hostname, l.tag
215.35 +('192.168.96.198', 'vm-client-ltsp2', '')
215.36 +
215.37 +>>> l = mac.Line(param_name='dhcp-host', value='00:0c:29:c0:d7:9e,vm-client-ltsp2')
215.38 +>>> l.ip, l.hostname, l.tag
215.39 +('', 'vm-client-ltsp2', '')
215.40 +
215.41 +>>> l = mac.Line(param_name='dhcp-host', value='00:0c:29:c0:d7:9e,net:ns1')
215.42 +>>> l.ip, l.hostname, l.tag
215.43 +('', '', 'net:ns1')
215.44 +
215.45 +
215.46 +>>> l = mac.Line(param_name='dhcp-host', value='00:0c:29:c0:d7:9e,192.168.1.1')
215.47 +>>> l.ip, l.hostname, l.tag
215.48 +('192.168.1.1', '', '')
215.49 +
215.50 +
215.51 +###########
215.52 +## a file
215.53 +###########
215.54 +
215.55 +>>> h0 = mac.Mac('data/etc/hosts.mac')
215.56 +>>> len(h0.lines)
215.57 +2
215.58 +
215.59 +>>> lines = h0.get_param(param_name='dhcp-host')
215.60 +>>> len(lines)
215.61 +2
215.62 +
215.63 +>>> lines = h0.get_param(param_name='dhcp-host', value='00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1')
215.64 +>>> len(lines)
215.65 +1
215.66 +
215.67 +>>> h0.get_param(param_name='dhcp-host', mac='00:0c:29:10:a6:45')
215.68 +[<dhcp-host 00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1>]
215.69 +
215.70 +>>> h0.get_param(param_name='dhcp-host', ip='192.168.96.199')
215.71 +[<dhcp-host 00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1>]
215.72 +
215.73 +>>> h0.get_param(param_name='dhcp-host', tag='net:ns0')
215.74 +[]
215.75 +
215.76 +>>> h0.get_param(param_name='dhcp-host', tag='net:ns1')
215.77 +[<dhcp-host 00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1>]
215.78 +
215.79 +>>> lines[0].param_name
215.80 +'dhcp-host'
215.81 +
215.82 +>>> h1 = mac.Mac('data/etc/hosts.mac')
215.83 +>>> print h1.set_param('dhcp-host', value='00:0c:29:10:a6:46,192.168.96.200,vm-client-ltsp4')
215.84 +dhcp-host=00:0c:29:10:a6:46,192.168.96.200,vm-client-ltsp4
215.85 +
215.86 +>>> print h0.diff(h1)
215.87 +--- this.conf
215.88 ++++ other.conf
215.89 +@@ -1,2 +1,3 @@
215.90 + dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1
215.91 + dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1
215.92 ++dhcp-host=00:0c:29:10:a6:46,192.168.96.200,vm-client-ltsp4
215.93 +<BLANKLINE>
215.94 +
215.95 +## this should *change* the previous rather than adding as we cannot have 2 identical MACs
215.96 +>>> h1 = mac.Mac('data/etc/hosts.mac')
215.97 +>>> print h1.set_param('dhcp-host', value='00:0c:29:10:a6:45,192.168.96.190,vm-client-ltsp1')
215.98 +dhcp-host=00:0c:29:10:a6:45,192.168.96.190,vm-client-ltsp1
215.99 +
215.100 +>>> print h0.diff(h1)
215.101 +--- this.conf
215.102 ++++ other.conf
215.103 +@@ -1,2 +1,2 @@
215.104 +-dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1
215.105 ++dhcp-host=00:0c:29:10:a6:45,192.168.96.190,vm-client-ltsp1
215.106 + dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1
215.107 +<BLANKLINE>
215.108 +
215.109 +>>> tools.is_mac_address('00:0c:29:10:a6:46')
215.110 +True
215.111 +
216.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
216.2 +++ b/tests/ntests.sh Mon Apr 26 11:16:23 2010 +0200
216.3 @@ -0,0 +1,4 @@
216.4 +#!/bin/bash
216.5 +
216.6 +
216.7 +nosetests --pdb-failure -v
217.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
217.2 +++ b/tests/runtests.py Mon Apr 26 11:16:23 2010 +0200
217.3 @@ -0,0 +1,33 @@
217.4 +#!/usr/bin/python
217.5 +
217.6 +import os
217.7 +import sys
217.8 +import doctest
217.9 +import sys
217.10 +
217.11 +os.environ['LANG'] = 'C'
217.12 +sys.path.insert(0, os.path.join(os.path.dirname(os.getcwd()), 'lib'))
217.13 +
217.14 +files = (
217.15 + 'logon.txt',
217.16 + 'hosts.txt',
217.17 + 'dnsmasq.txt',
217.18 + 'mac.txt',
217.19 + )
217.20 +
217.21 +if sys.argv[1:]:
217.22 + files = sys.argv[1:]
217.23 +
217.24 +for filename in files:
217.25 + print filename
217.26 + doctest.testfile(filename)
217.27 +
217.28 +
217.29 +#nosetests --pdb-failure --with-doctest --doctest-extension=txt filename
217.30 +#nosetests --pdb-failure
217.31 +
217.32 +
217.33 +
217.34 +
217.35 +
217.36 +
218.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
218.2 +++ b/tests/user_isi_adduser.py Mon Apr 26 11:16:23 2010 +0200
218.3 @@ -0,0 +1,227 @@
218.4 +import os
218.5 +import re
218.6 +import isi
218.7 +import unittest
218.8 +from dry.functions import execute
218.9 +from nose import tools
218.10 +import shutil
218.11 +
218.12 +def setup():
218.13 + print "killing nscd"
218.14 + execute('killall nscd')
218.15 + os.system('rm -Rf /home/users/docenti/*')
218.16 + l = isi.Manager()
218.17 + for name in ('d_test100', 'd_test101', 'd_test102'):
218.18 + try:
218.19 + l.del_user(name, )
218.20 + except isi.exc.MissingMatch:
218.21 + pass
218.22 +
218.23 +class AddDelUser(unittest.TestCase):
218.24 + __test__ = False
218.25 + #__test__ = True
218.26 + def setUp(self):
218.27 + self.conn = isi.IsiConn()
218.28 + self.l = isi.Manager(self.conn)
218.29 + self.l.home_mode = 'rm'
218.30 +
218.31 + def execute(self, cmd):
218.32 + ret_code, out, err = execute(cmd)
218.33 + assert ret_code == 0, "ret_code: %s: OUT=%s, ERR=%s" % (ret_code, out, err)
218.34 + return out, err
218.35 +
218.36 + def execute_ko(self, cmd):
218.37 + ret_code, out, err = execute(cmd)
218.38 + assert ret_code != 0, "ret_code: %s: OUT=%s, ERR=%s" % (ret_code, out, err)
218.39 + return out, err
218.40 +
218.41 + def test_01a_del_user_group(self):
218.42 + ## clear any user from docenti
218.43 + self.execute('isi-deluser -g docenti --home rm')
218.44 +
218.45 + def test_01b_del_home(self):
218.46 + ## clear any user from docenti
218.47 + assert not os.path.exists('/home/users/docenti/d_test100')
218.48 + assert not os.path.exists('/home/users/docenti/d_test101')
218.49 + assert not os.path.exists('/home/users/docenti/d_test102')
218.50 + assert not os.path.exists('/home/users/docenti/d_test100.tgz')
218.51 + assert not os.path.exists('/home/users/docenti/d_test101.tgz')
218.52 + assert not os.path.exists('/home/users/docenti/d_test102.tgz')
218.53 +
218.54 + def test_02_isi_adduser(self):
218.55 + ## add d_test100
218.56 + self.execute(['isi-adduser', '-T', '-t', 'd_test100;docenti;isi'])
218.57 +
218.58 + def test_03_isi_groupcat(self):
218.59 + # verify it's in group docenti
218.60 + out, err = self.execute('isi-groupcat docenti')
218.61 + assert 'd_test100' in out.split()
218.62 +
218.63 + def test_03b_user_exists(self):
218.64 + assert self.l.user_exists('d_test100')
218.65 +
218.66 + def test_04_del_user(self):
218.67 + ## default: deletes the home directory, leaves the .tar.gz
218.68 + self.execute('isi-deluser d_test100')
218.69 + assert not os.path.exists('/home/users/docenti/d_test100')
218.70 + assert os.path.exists('/home/users/docenti/d_test100.tgz')
218.71 +
218.72 + ## again isi-addusers but normal -s "string_definition"
218.73 + def test_05_isi_addusers(self):
218.74 + assert not self.l.user_exists('d_test101')
218.75 + assert not self.l.user_exists('d_test102')
218.76 + self.execute(['isi-adduser', '-T', '-s', "d_test101;Test;Docente;docenti;;CF1;isi"])
218.77 + self.execute(['isi-adduser', '-T', '-s', "d_test102;Test;Docente;docenti;;CF2;isi"])
218.78 +
218.79 + def test_06_isi_groupcat(self):
218.80 + out, err = self.execute('isi-groupcat docenti')
218.81 + assert 'd_test101' in out.split()
218.82 +
218.83 + def test_07a_password_ok(self):
218.84 + assert self.l.test_password('d_test101', 'isi')
218.85 +
218.86 + def test_07b_password_ko(self):
218.87 + assert not self.l.test_password('d_test101', 'isi_ko')
218.88 +
218.89 + def test_08a_smb_password_ok(self):
218.90 + assert self.l.test_samba_password('d_test101', 'isi')
218.91 +
218.92 + def test_08b_smb_password_ko(self):
218.93 + assert not self.l.test_samba_password('d_test101', 'isi_ko')
218.94 +
218.95 + def test_08c_set_passwd(self):
218.96 + assert not self.l.test_password('d_test101', 'new_pwd')
218.97 + assert not self.l.test_samba_password('d_test101', 'new_pwd')
218.98 +
218.99 + def test_09_groupcat_r(self):
218.100 + OUT = """d_test101;Test;Docente;docenti;;CF1;\nd_test102;Test;Docente;docenti;;CF2;\n"""
218.101 +
218.102 + out, err = self.execute('isi-groupcat -r docenti')
218.103 + assert OUT == out
218.104 +
218.105 + def test_09a_del_no_home(self):
218.106 + self.execute('isi-deluser --zap-home d_test101')
218.107 + assert not os.path.exists('/home/users/docenti/d_test101')
218.108 + assert not os.path.exists('/home/users/docenti/d_test101.tgz')
218.109 +
218.110 + def test_09b_del_leave_home(self):
218.111 + self.execute('isi-deluser -H none d_test102')
218.112 + assert os.path.exists('/home/users/docenti/d_test102')
218.113 +
218.114 + ## again isi-addusers but normal -s "string_definition", using -p _cf
218.115 + def test_10a_isi_addusers_pass_cf(self):
218.116 + self.execute('rm -Rf /home/users/docenti/d_test102')
218.117 + self.execute(['isi-adduser', '-T', '--use-cf', '-s', "d_test101;Test;Docente;docenti;;DNTLSN63D07Z404Z;isi"])
218.118 + self.execute(['isi-adduser', '-T', '--use-cf', '-s', "d_test102;Test;Docente;docenti;;CCCNMN73F4ZP404Z;isi"])
218.119 +
218.120 + def test_10b_password_cf(self):
218.121 + assert self.l.test_password('d_test101', 'Dntlsn63')
218.122 +
218.123 + def test_10b_samba_password_cf(self):
218.124 + assert self.l.test_samba_password('d_test101', 'Dntlsn63')
218.125 +
218.126 + def test_11a_isi_passwd(self):
218.127 + self.execute('isi-passwd -p isi2 d_test101')
218.128 +
218.129 + def test_11b_test_passwd(self):
218.130 + assert self.l.test_password('d_test101', 'isi2')
218.131 +
218.132 + def test_11b_test_samba_passwd(self):
218.133 + assert self.l.test_samba_password('d_test101', 'isi2')
218.134 +
218.135 +
218.136 +class IsiUserFromFile(unittest.TestCase):
218.137 + __test__ = True
218.138 +
218.139 + def setUp(self):
218.140 + self.conn = isi.IsiConn()
218.141 + self.l = isi.Manager(self.conn)
218.142 + self.l.home_mode = 'rm'
218.143 +
218.144 + def execute(self, cmd):
218.145 + ret_code, out, err = execute(cmd)
218.146 + assert ret_code == 0, "ret_code: %s: OUT=%s, ERR=%s" % (ret_code, out, err)
218.147 + return out, err
218.148 +
218.149 + def test_00_delete(self):
218.150 + self.execute('isi-deluser -T -f data/users_test.isi -z')
218.151 +
218.152 +
218.153 + ## utenti da file - password in file
218.154 + def test_01a_isi_addusers_file(self):
218.155 + self.execute('isi-adduser -T -f data/users_test.isi --non-interactive')
218.156 + assert self.l.user_exists('a_test')
218.157 +
218.158 + def test_01a_passwd(self):
218.159 + assert self.l.test_password('a_test', 'isi')
218.160 +
218.161 + def test_01b_samba_passwd(self):
218.162 + assert self.l.test_samba_password('a_test', 'isi', client=False)
218.163 +
218.164 + def test_01c_isi_addusers_file(self):
218.165 + assert self.l.user_exists('a_test')
218.166 +
218.167 + def test_01d_update_samba_passwd(self):
218.168 + assert self.l.user_exists('a_test')
218.169 + self.execute('isi-adduser -T -f data/users_test.isi --default-passwd ok --update-passwd')
218.170 + assert self.l.test_samba_password('a_test', 'ok', client=False)
218.171 +
218.172 + def test_13a_del_file(self):
218.173 + self.execute('isi-deluser -T -f data/users_test.isi -z')
218.174 +
218.175 + def test_13b_del_home(self):
218.176 + assert not os.path.exists('/home/users/docenti/d_test')
218.177 + assert not os.path.exists('/home/users/docenti/d_test.tgz')
218.178 +
218.179 + def test_13c_del_user(self):
218.180 + assert not self.l.user_exists('d_test')
218.181 + assert not self.l.user_exists('ad_test')
218.182 + assert not self.l.user_exists('at_test')
218.183 +
218.184 + ## utenti da file - password _cf
218.185 + def test_14a_isi_addusers_file(self):
218.186 + self.execute('isi-adduser -ZT --use-cf --default-passwd blabla -f data/users_test.isi')
218.187 +
218.188 + def test_14a_passwd(self):
218.189 + assert self.l.test_password('d_test', 'Dntlsn63')
218.190 + assert self.l.test_password('ad_test', 'Dntlsn63')
218.191 + assert self.l.test_password('at_test', 'Dntlsn63')
218.192 +
218.193 + def test_14b_samba_passwd(self):
218.194 + assert self.l.test_samba_password('d_test', 'Dntlsn63')
218.195 + assert self.l.test_samba_password('ad_test', 'Dntlsn63')
218.196 + assert self.l.test_samba_password('at_test', 'Dntlsn63')
218.197 +
218.198 + def test_15b_del_user(self):
218.199 + assert self.l.user_exists('d_test')
218.200 + assert self.l.user_exists('ad_test')
218.201 + assert self.l.user_exists('at_test')
218.202 +
218.203 + def test_16a_modify(self):
218.204 + "fails becouse update is not allowed if not explicitly required"
218.205 + ret_code, out, err = execute('isi-adduser -T -f data/users_misc.isi -z -Z')
218.206 + assert ret_code
218.207 +
218.208 + def test_16b_modify(self):
218.209 + self.l.get_samba_user('ad_test').set_password('xxx')
218.210 + self.execute('isi-adduser -T -f data/users_misc.isi -z --update-user -Z')
218.211 +
218.212 + def test_16c_changed_group(self):
218.213 + assert self.l.user_in_group('a_test', 'classe_test2')
218.214 +
218.215 + def test_16d_changed_group2(self):
218.216 + assert not self.l.user_in_group('a_test', 'classe_test')
218.217 +
218.218 + def test_16e_deleted(self):
218.219 + assert not self.l.user_exists('a_tests')
218.220 + assert not os.path.exists('/home/users/alunni/a_test2')
218.221 + assert not os.path.exists('/home/users/alunni/a_test2.tgz')
218.222 +
218.223 + def test_16f_unmodified(self):
218.224 + "update-user doesn't change password"
218.225 + assert self.l.user_exists('ad_test')
218.226 + assert not self.l.test_password('ad_test', 'isi2')
218.227 + assert self.l.test_password('ad_test', 'xxx')
218.228 +
218.229 + def test_16g_del_file(self):
218.230 + self.execute('isi-deluser -T -f data/users_test.isi -z')
219.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
219.2 +++ b/tests/user_lib_test.py Mon Apr 26 11:16:23 2010 +0200
219.3 @@ -0,0 +1,339 @@
219.4 +import os
219.5 +import re
219.6 +import isi
219.7 +import unittest
219.8 +from dry.functions import execute
219.9 +from nose import tools
219.10 +import shutil
219.11 +import logging
219.12 +from isi.parser import UserParser
219.13 +
219.14 +def setup():
219.15 + global l
219.16 + conn = isi.IsiConn()
219.17 + l = isi.Manager()
219.18 + l.logger.setLevel(logging.critical)
219.19 +
219.20 + print "killing nscd"
219.21 + execute('killall nscd')
219.22 + execute('rm -Rf /home/users/docenti/*')
219.23 +
219.24 +class ParserUser(unittest.TestCase):
219.25 +
219.26 +# __test__ = False
219.27 + __test__ = True
219.28 +
219.29 + def setUp(self):
219.30 + self.opts = {
219.31 + 'no_filesystem' : None,
219.32 + 'update_user' : None,
219.33 + 'update_passwd' : None,
219.34 + 'force_passwd_change' : None,
219.35 + 'default_passwd' : None,
219.36 + 'use_cf' : None,
219.37 + 'passwd_random' : None,
219.38 + 'run_alulink' : None,
219.39 + }
219.40 +
219.41 + def test_00_del_user_group(self):
219.42 + ## clear any user from docenti
219.43 + docenti = l.get_group('docenti')
219.44 + docenti.delete_members(home_mode='rm')
219.45 +
219.46 + docenti = l.get_group('alunni')
219.47 + docenti.delete_members(home_mode='rm')
219.48 +
219.49 + def test_01a_action_add(self):
219.50 + proxy = UserParser(l, 'd_test;Docente;Test;docenti;;DNTLSN63D07;isi', **self.opts)
219.51 + assert proxy.action == 'add'
219.52 +
219.53 + def test_01b_action_del(self):
219.54 + proxy = UserParser(l, '-d_test;Docente;Test;docenti;;DNTLSN63D07;isi', **self.opts)
219.55 + assert proxy.action == 'delete'
219.56 +
219.57 + @tools.raises(isi.exc.AlreadyExistingUser)
219.58 + def test_02a_action_update(self):
219.59 + ## create a user
219.60 + l.parse_user_definition_string("d_test;Test;Docente;docenti;;DNTLSN63D07;isi")
219.61 + proxy = UserParser(l, 'd_test;Docente;Test;docenti;;DNTLSN63D07;isi', **self.opts)
219.62 +
219.63 + def test_02a_action_update(self):
219.64 + l.parse_user_definition_string("d_test;Test;Docente;docenti;;DNTLSN63D07;isi")
219.65 + self.opts['update_user'] = True
219.66 + proxy = UserParser(l, 'd_test;Docente;Test;docenti;;DNTLSN63D07;isi', **self.opts)
219.67 + assert proxy.action == 'update'
219.68 +
219.69 + # attributi
219.70 + def test_03b_logname(self):
219.71 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.72 + assert proxy.logname == 'd_test1'
219.73 +
219.74 + def test_03c_first_name(self):
219.75 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.76 + assert proxy.first_name == 'Test'
219.77 +
219.78 + def test_03d_last_name(self):
219.79 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.80 + assert proxy.last_name == 'Docente'
219.81 +
219.82 + def test_03e_maingrop(self):
219.83 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.84 + assert proxy.maingroup == 'docenti'
219.85 +
219.86 + def test_03f_classe(self):
219.87 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.88 + assert proxy.classe == None
219.89 +
219.90 + def test_03g_cf(self):
219.91 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;dntlsn63d07;isi', **self.opts)
219.92 + assert proxy.cf == 'DNTLSN63D07'
219.93 +
219.94 + def test_03g_password(self):
219.95 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.96 + assert proxy.passwd == 'isi'
219.97 +
219.98 + def test_03h_password_cf(self):
219.99 + self.opts['use_cf'] = True
219.100 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07', **self.opts)
219.101 + assert proxy.passwd == 'Dntlsn63'
219.102 +
219.103 + def test_03h_password_cf_password_present(self):
219.104 + self.opts['use_cf'] = True
219.105 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.106 + assert proxy.passwd == 'Dntlsn63'
219.107 +
219.108 + def test_03h_password_random(self):
219.109 + self.opts['passwd_random'] = True
219.110 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.111 + ## well, at least is none of these...
219.112 + assert proxy.passwd not in ('Dntlsn63', 'isi', None)
219.113 +
219.114 + def test_04a_passwd_update_false(self):
219.115 + ## even if you have use_cf, since d_test is already present (=> action is update)
219.116 + ## passwd is not updated
219.117 + self.opts['use_cf'] = True
219.118 + self.opts['update_user'] = True
219.119 + self.opts['update_passwd'] = False
219.120 + proxy = UserParser(l, 'd_test;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.121 + ## well, at least is none of these...
219.122 + assert proxy.passwd == None
219.123 +
219.124 + def test_04b_passwd_update_true(self):
219.125 + ## even if you have use_cf, since d_test is already present (=> action is update)
219.126 + ## passwd is not updated
219.127 + self.opts['use_cf'] = True
219.128 + self.opts['update_user'] = True
219.129 + self.opts['update_passwd'] = True
219.130 + proxy = UserParser(l, 'd_test;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.131 + ## well, at least is none of these...
219.132 + assert proxy.passwd == 'Dntlsn63'
219.133 +
219.134 + def test_04c_cf_wins_over_default(self):
219.135 + self.opts['use_cf'] = True
219.136 + self.opts['default_passwd'] = 'ciao'
219.137 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.138 + ## well, at least is none of these...
219.139 + assert proxy.passwd == 'Dntlsn63'
219.140 +
219.141 + def test_04d_default_passwd(self):
219.142 + self.opts['default_passwd'] = 'ciao'
219.143 + proxy = UserParser(l, 'd_test1;docente;test;docenti;;DNTLSN63D07;isi', **self.opts)
219.144 + ## well, at least is none of these...
219.145 + assert proxy.passwd == 'ciao'
219.146 +
219.147 + # classe
219.148 + def test_05a_classe_in_proxy(self):
219.149 + """user class attributes gets correctly set"""
219.150 + self.opts.update({'default_passwd' : 'ciao', 'interactive' : False})
219.151 + proxy = UserParser(l, 'a_test;Alunno;test;alunni;classe_test;DNTLSN63D07;isi', **self.opts)
219.152 + ## well, at least is none of these...
219.153 + assert proxy.classe == 'classe_test'
219.154 +
219.155 +class Extended(unittest.TestCase):
219.156 +
219.157 + def setUp(self):
219.158 + self.opts = {
219.159 + 'no_filesystem' : None,
219.160 + 'update_user' : None,
219.161 + 'update_passwd' : None,
219.162 + 'force_passwd_change' : None,
219.163 + 'default_passwd' : None,
219.164 + 'use_cf' : None,
219.165 + 'passwd_random' : None,
219.166 + 'run_alulink' : None,
219.167 + }
219.168 +
219.169 +
219.170 + def test_06a_extended(self):
219.171 + l.del_user('a_test_ext', quiet=True)
219.172 + definition = "a_test_ext;carboni;michela;alunni;ige3a;crbmhl94a58i829c;XPWDX;f;" +\
219.173 + "via rocca 5c;morbegno;23017;so;0342615240;p3406429865;18/1/1994;sondrio;" +\
219.174 + "so;3;carboni;mauro;artoni;paola"
219.175 + self.opts.update({'default_passwd' : 'ciao', 'interactive' : False})
219.176 + self.proxy = UserParser(l, definition, **self.opts)
219.177 + assert self.proxy
219.178 + assert self.proxy.address == 'via rocca 5c'
219.179 + assert self.proxy.city == 'morbegno'
219.180 + assert self.proxy.zip == '23017'
219.181 + assert self.proxy.phone == '0342615240'
219.182 + assert self.proxy.sex == 'f'
219.183 +
219.184 + def test_06b_extended_user(self):
219.185 + l.del_user('a_test_ext', quiet=True)
219.186 + definition = "a_test_ext;carboni;michela;alunni;ige3a;crbmhl94a58i829c;XPWDX;f;" +\
219.187 + "via rocca 5c;morbegno;23017;so;0342615240;p3406429865;18/1/1994;sondrio;" +\
219.188 + "so;3;carboni;mauro;artoni;paola"
219.189 + self.opts.update({'default_passwd' : 'ciao', 'interactive' : False})
219.190 + l.parse_user_definition_string(definition, force_passwd_change=False)
219.191 +
219.192 + def test_06c_extended_user2(self):
219.193 + user = l.get_user('a_test_ext')
219.194 + assert user.sex == u'f'
219.195 + assert user.address == u'via rocca 5c'
219.196 + assert user.city == u'morbegno'
219.197 + assert user.zip_code == u'23017'
219.198 + assert user.phone == u'0342615240'
219.199 +
219.200 +
219.201 +class ParserMethod(unittest.TestCase):
219.202 +
219.203 + def setUp(self):
219.204 + self.conn = isi.IsiConn()
219.205 + l = isi.Manager(self.conn)
219.206 + self.conn.logger.setLevel(logging.critical)
219.207 + self.opts = {
219.208 + 'no_filesystem' : None,
219.209 + 'update_user' : None,
219.210 + 'update_passwd' : None,
219.211 + 'force_passwd_change' : None,
219.212 + 'default_passwd' : None,
219.213 + 'use_cf' : None,
219.214 + 'passwd_random' : None,
219.215 + 'run_alulink' : None,
219.216 + }
219.217 +
219.218 +
219.219 + def test_01_del_user_group(self):
219.220 + ## clear any user from docenti
219.221 + docenti = l.get_group('docenti')
219.222 + docenti.delete_members(home_mode='rm')
219.223 + alunni = l.get_group('alunni')
219.224 + alunni.delete_members(home_mode='rm')
219.225 +
219.226 + def test_10d_add_from_string(self):
219.227 + l.parse_user_definition_string("d_test111;Test;Docente;docenti;;DNTLSN63D07;isi", force_passwd_change=False)
219.228 +
219.229 + def test_10e_path_exists(self):
219.230 + assert os.path.exists('/home/users/docenti/d_test111')
219.231 +
219.232 + def test_10f_test_pass(self):
219.233 + assert l.test_password('d_test111', 'isi')
219.234 +
219.235 + def test_10g_test_samba_pass(self):
219.236 + assert l.test_samba_password('d_test111', 'isi', client=False)
219.237 + assert l.test_samba_password('d_test111', 'isi', client=True)
219.238 +
219.239 + def test_11d_add_from_string(self):
219.240 + l.parse_user_definition_string("d_test112;Test;Docente;docenti;;DNTLSN63D07;isi", force_passwd_change=True)
219.241 +
219.242 + def test_11e_path_exists(self):
219.243 + assert os.path.exists('/home/users/docenti/d_test112')
219.244 +
219.245 + def test_11f_test_pass(self):
219.246 + assert l.test_password('d_test112', 'isi')
219.247 +
219.248 + def test_11g_test_samba_pass(self):
219.249 + assert l.test_samba_password('d_test112', 'isi', client=False)
219.250 + assert not l.test_samba_password('d_test112', 'isi', client=True)
219.251 +
219.252 + def test_11h_force_passwd_change(self):
219.253 + user = l.get_samba_user('d_test112')
219.254 + assert user.sambaPwdLastSet == 0
219.255 +
219.256 + def test_12d_add_from_string(self):
219.257 + l.parse_user_definition_string("d_test122;Test;Docente;docenti;;DNTLSN63D07;isi", use_cf=True)
219.258 +
219.259 + def test_12e_path_exists(self):
219.260 + assert os.path.exists('/home/users/docenti/d_test122')
219.261 +
219.262 + def test_12f_test_pass(self):
219.263 + assert l.test_password('d_test122', 'Dntlsn63')
219.264 +
219.265 + def test_12g_samba_test_pass(self):
219.266 + assert l.test_samba_password('d_test122', 'Dntlsn63', client=False)
219.267 +
219.268 + # classe
219.269 + def test_12h_classe_in_user(self):
219.270 + self.opts.update({'default_passwd' : 'ciao', 'interactive' : False})
219.271 + proxy = l.parse_user_definition_string('a_test;Alunno;test;alunni;classe_test;DNTLSN63D07;isi', **self.opts)
219.272 + a = l.get_user('a_test')
219.273 + assert a.classe == 'classe_test'
219.274 +
219.275 + # delete
219.276 + def test_12j_delete_user_by_string(self):
219.277 + l.parse_user_definition_string("-d_test122;Test;Docente;docenti;;DNTLSN63D07;isi")
219.278 + assert not l.user_exists('d_test122')
219.279 +
219.280 + def test_12j_deleted_home(self):
219.281 + assert not os.path.exists('/home/users/docenti/d_test122')
219.282 +
219.283 + def test_12k_tgz(self):
219.284 + assert os.path.exists('/home/users/docenti/d_test122.tgz')
219.285 +
219.286 + def test_12m_dn(self):
219.287 + a = l.get_user('a_test')
219.288 + assert a.dn == u'uid=a_test,ou=People,dc=isi,dc=lan'
219.289 +
219.290 + def test_12n_deleted_from_group_when_deleted(self):
219.291 + l.del_user('a_test')
219.292 + assert not l.user_in_group('a_test', 'classe_test')
219.293 +
219.294 + # delete zapping home
219.295 + def test_13h_delete_user_by_string(self):
219.296 + l.parse_user_definition_string("d_test123;Test;Docente;docenti;;DNTLSN63D07;isi")
219.297 + l.parse_user_definition_string("-d_test123;Test;Docente;docenti;;DNTLSN63D07;isi",
219.298 + home_mode='rm')
219.299 + assert not l.user_exists('d_test123')
219.300 +
219.301 + def test_13i_deleted_home(self):
219.302 + assert not os.path.exists('/home/users/docenti/d_test123')
219.303 +
219.304 + def test_13j_tgz(self):
219.305 + assert not os.path.exists('/home/users/docenti/d_test123.tgz')
219.306 +
219.307 + @tools.raises(isi.exc.MissingMainGroup)
219.308 + def test_14a_missing_maingroup(self):
219.309 + l.parse_user_definition_string("d_test124;Test;Docente;docente;;DNTLSN63D07;isi")
219.310 +
219.311 +
219.312 +class Modify(unittest.TestCase):
219.313 +
219.314 + def preparazione_16(self):
219.315 + ## clear any user from docenti
219.316 + l.get_group('docenti').delete_members(home_mode='rm')
219.317 + l.get_group('alunni').delete_members(home_mode='rm')
219.318 + l.del_group('classe_test', quiet=True)
219.319 + l.del_group('classe_test2', quiet=True)
219.320 +
219.321 +
219.322 + ## modifica
219.323 + def test_16b_add_alunno(self):
219.324 + self.preparazione_16()
219.325 + kw = {'interactive': False, 'update_user' : True}
219.326 + def_string = "a_test;Test;Alunno;alunni;classe_test;DNTLSN63D07;isi"
219.327 + def_string2 = "a_test;Test;Alunno;alunni;classe_test2;DNTLSN63D07;isi"
219.328 +
219.329 + u = l.parse_user_definition_string(def_string, **kw)
219.330 + assert l.user_in_group('a_test', 'classe_test')
219.331 + assert not l.user_in_group('a_test', 'classe_test2')
219.332 + u = l.parse_user_definition_string(def_string2, **kw)
219.333 + assert not l.user_in_group('a_test', 'classe_test')
219.334 + assert l.user_in_group('a_test', 'classe_test2')
219.335 +
219.336 +
219.337 +
219.338 +setup.__test__ = False
219.339 +#Extended = False
219.340 +#ParserUser.__test__ = False
219.341 +#Modify.__test__ = False
219.342 +#ParserMethod.__test__ = False
220.1 Binary file usr/bin/crackcheck has changed
221.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
221.2 +++ b/usr/bin/isi-gnome-menu Mon Apr 26 11:16:23 2010 +0200
221.3 @@ -0,0 +1,338 @@
221.4 +#!/usr/bin/python
221.5 +# -*- coding: utf-8 -*-
221.6 +"""
221.7 +Crea se non presente o modifica il file ``$UTENTE/.gtk-bookmarks``,
221.8 +aggiungendo i riferimenti alle share ISI definite per l'utente
221.9 +in ``/etc/isi/logon.conf``
221.10 +
221.11 +E' possibile lavorare su singoli utenti, gruppi o tutti gli utenti.
221.12 +
221.13 +Senza opzioni lavora sull'utente corrente. In un contesto LTSP cio'
221.14 +permette, usando opportunamente ``$UTENTE/.xsessionrc``, di risettare
221.15 +le share ad inizio sessione-grafica dell'utente.
221.16 +
221.17 + usage: %prog [options] [user | group]
221.18 + -u, --user=user: lavora su un singolo utente
221.19 + -g, --group=group: lavora per un gruppo di utenti
221.20 + -a, --all: lavora su tutti gli utenti, ad eccezione di root
221.21 + -v, --verbose: modo verboso
221.22 +"""
221.23 +
221.24 +import isi
221.25 +
221.26 +from dry import optionparse
221.27 +from dry.functions import execute
221.28 +
221.29 +import ConfigParser
221.30 +import os
221.31 +import sys
221.32 +import re
221.33 +import commands
221.34 +
221.35 +### Classes Definition
221.36 +class NoValidUser(Exception):
221.37 + def __init__(self):
221.38 + print 'Utente non valido'
221.39 + sys.exit(1)
221.40 +
221.41 +class NoExistingIsiUser(Exception):
221.42 + def __init__(self):
221.43 + print 'Utente ISI inesistente'
221.44 +
221.45 +class RequireRootPrivileges(Exception):
221.46 + def __init__(self):
221.47 + print 'Privilegi di root richiesti'
221.48 + sys.exit(1)
221.49 +
221.50 +class InputStream(object):
221.51 + """
221.52 + Simple Wrapper for File-like objects. [c]StringIO doesn't provide
221.53 + a readline function for use with generate_tokens.
221.54 + Using a iterator-like interface doesn't succeed, because the readline
221.55 + function isn't used in such a context. (see <python-lib>/tokenize.py)
221.56 + """
221.57 + def __init__(self, filename=None, data=None):
221.58 + if filename:
221.59 + f = open(file)
221.60 + data = f.read()
221.61 + f.close()
221.62 + data = re.sub(':(.*=)', r'|\1', data)
221.63 + self.__data = [ '%s\n' % x for x in data.splitlines() ]
221.64 + self.__lcount = 0
221.65 +
221.66 + def readline(self):
221.67 + try:
221.68 + line = self.__data[self.__lcount]
221.69 + self.__lcount += 1
221.70 + except IndexError:
221.71 + line = ''
221.72 + self.__lcount = 0
221.73 + line = re.sub(r'^ +', '', line)
221.74 + line = re.sub(r'^\t+', '', line)
221.75 + line = re.sub(r'#.*', '', line)
221.76 + return line
221.77 +
221.78 +class UserInfo(object):
221.79 + """
221.80 + UserInfo, an object to share user infos ...
221.81 + """
221.82 + def __init__(self, user):
221.83 + self.Manager = Manager
221.84 + self.user = user
221.85 + posix_user = self.Manager.get_user(user)
221.86 +
221.87 + self.main_groups = MAIN_GROUPS
221.88 +
221.89 + self.user_home = posix_user.home
221.90 + self.user_groups = [x.name for x in posix_user.get_my_groups()]
221.91 + self.user_maingroup = posix_user.maingroup
221.92 +
221.93 + self.classe = posix_user.classe
221.94 + self.mioweb_path = '%s/public_html' % (posix_user.home)
221.95 +
221.96 + self.links_cfg_path = '%s/.gtk-bookmarks' % posix_user.home
221.97 + self.logon_conf = '/etc/isi/logon.conf'
221.98 +
221.99 +
221.100 +class SambaUserShare(object):
221.101 + """
221.102 + samba
221.103 + """
221.104 + def __init__(self, UI):
221.105 + self.UI = UI
221.106 +
221.107 + def _get_share_path(self, share):
221.108 + """
221.109 + Parse the "test_parm -s" samba command output putting share info (name and path)
221.110 + in a dict {share-name : share-path} .
221.111 + Returns the PATH of given share-name.
221.112 + """
221.113 + shares_path_dict = {}
221.114 + ret_code, sambaconf, err = execute('testparm -s')
221.115 + f = InputStream(data=sambaconf)
221.116 + parser = ConfigParser.ConfigParser()
221.117 + parser.readfp(f, 'cfg')
221.118 + sections = parser.sections()
221.119 +
221.120 + for section in parser.sections():
221.121 + items = parser.items(section)
221.122 + #print items
221.123 + item_with_path = ([item[1] for item in items if 'path' in item])
221.124 + # filtering env variable elements
221.125 + if re.search('%', str(item_with_path)):
221.126 + continue
221.127 + for path in item_with_path:
221.128 + share_name = path.split('/')[-1]
221.129 + shares_path_dict[share_name] = path
221.130 +
221.131 + try:
221.132 + return shares_path_dict[share]#share_path = shares_path_dict[share]
221.133 + except KeyError, e:
221.134 + print 'Impossibile trovare la share samba "%s".\
221.135 + Lancia "isi-checkup"!' % (share)
221.136 +# print ' Le share samba attualmente attive sul tuo server sono le seguenti:'
221.137 +# for key in shares_path_dict.keys():
221.138 +# print ' ', key
221.139 +
221.140 + def get_my_shares_path(self):
221.141 + """
221.142 + Parse "/etc/isi/logon.conf" and returns a list of shares's path that user should
221.143 + see in his/her own gnome menu.
221.144 + "/etc/isi/logon.conf" sample ::
221.145 +
221.146 + _NetFolder[T:docenti] = area_docenti
221.147 + _NetFolder[T:admins] = area_docenti
221.148 +
221.149 + _NetFolder[Z:docenti] = area_alunni
221.150 + _NetFolder[Z:admins] = area_alunni
221.151 + _NetFolder[Z:alunni] = area_alunni
221.152 + _NetFolder[U] = didattica
221.153 + #_NetFolder[W] = mio_web
221.154 +
221.155 + """
221.156 + UI = self.UI
221.157 + user_maingroup = UI.user_groups[0]
221.158 +
221.159 + # FIXME Cambiare modo di prendere il gruppo principale
221.160 + # per admins user_maingroup[0] == 'Domain Admins', non 'admins'
221.161 + if user_maingroup == 'Domain Admins':
221.162 + user_maingroup = 'admins'
221.163 +
221.164 + my_shares = []
221.165 + my_shares_path = []
221.166 + group_shares = {}
221.167 +
221.168 + GROUP_RESTRICTION = re.compile(r'''
221.169 + ([^[]+) # tutto fino alla quadra [
221.170 + (?:\[ # ?: non lo vogliamo in m.groups()
221.171 + (?:(?:[A-Z]:)? # per NetFolder e ammessa sintassi: [S:admins]
221.172 + ([a-z]+) # il gruppo principale
221.173 + )
221.174 + ])?
221.175 + ''', re.VERBOSE)
221.176 +
221.177 + f = open(LOGON_CONF)
221.178 + for line in f.readlines():
221.179 + #debug
221.180 + #for line in __doc__.split('\n'):
221.181 + if re.match('^$', line) or \
221.182 + re.match('^\s*#', line) or \
221.183 + '_NetFolder' not in line:
221.184 + continue
221.185 +
221.186 + m = re.search(GROUP_RESTRICTION, line)
221.187 + if m:
221.188 + smb_share_name = line.split('=')[1].strip()
221.189 + opt, group = m.groups()
221.190 + # Adding group's share name
221.191 + if not group in group_shares.keys():
221.192 + group_shares[group] = [smb_share_name]
221.193 + else:
221.194 + group_shares[group].append(smb_share_name)
221.195 +
221.196 + #
221.197 + # ``group_shares`` content es.:
221.198 + #
221.199 + # >>> print group_shares
221.200 + # {None: ['software'], \
221.201 + # 'admins': ['classi', 'software', 'area_docenti', 'area_alunni', 'didattica'],\
221.202 + # 'alunni': ['area_alunni', 'didattica'], \
221.203 + # 'docenti': ['classi', 'area_docenti', 'area_alunni', 'didattica', 'area_educatori']}
221.204 + #
221.205 + if user_maingroup in group_shares.keys():
221.206 + my_shares = group_shares[user_maingroup]
221.207 +
221.208 + # all-group shares
221.209 + if None in group_shares:
221.210 + my_shares += group_shares[None]
221.211 +
221.212 + if UI.classe:
221.213 + my_shares += [UI.classe]
221.214 +
221.215 + for share in my_shares:
221.216 + # settaggio manuale path di mio_web
221.217 + if share == 'mioweb':
221.218 + my_shares_path += [UI.mioweb_path]
221.219 + else:
221.220 + my_shares_path += [self._get_share_path(share)]
221.221 +
221.222 + return my_shares_path
221.223 +
221.224 +class MenuManager(object):
221.225 + """
221.226 + Menu manager class, provides functions to manage user's menu
221.227 +
221.228 + TODO
221.229 + replace _add_link function with _update_link function that
221.230 + removes share no longer defined for the user's group in
221.231 + logon.conf
221.232 + """
221.233 + def __init__(self, UI):
221.234 + self.UI = UI
221.235 + self.uri_list_old = []
221.236 + self.uri_list_new = []
221.237 +
221.238 + def _check_link_existance(self, uri):
221.239 + """
221.240 + Returns TRUE if link exists
221.241 + Returns FALSE if link doesn't exist
221.242 + """
221.243 + if uri in self.uri_list_old:
221.244 + return True
221.245 + return False
221.246 +
221.247 + def _add_link(self, uri):
221.248 + """
221.249 + Adds the link's uri given to the user's gnome menu
221.250 + """
221.251 + if VERBOSE:
221.252 + print 'ADDING\n "%s" to "%s"' % (uri, self.UI.links_cfg_path)
221.253 +
221.254 + self.uri_list_new.append(uri)
221.255 +
221.256 + def setup_menu_links(self):
221.257 + """
221.258 + Main function.
221.259 + Checks the link's uri presence in the user's gnome-menu config file and adds
221.260 + missing shares defined as needed by the user.
221.261 +
221.262 + """
221.263 + S = SambaUserShare(self.UI)
221.264 + share_path_list = S.get_my_shares_path()
221.265 +
221.266 +# print share_path_list
221.267 +# import ipdb; ipdb.set_trace()
221.268 +
221.269 + if os.path.exists(self.UI.links_cfg_path):
221.270 + try:
221.271 + f = open(self.UI.links_cfg_path, 'r')
221.272 + self.uri_list_old = [ line.strip('\n') for line in f.readlines() if '://' in line ]
221.273 + except Exception, e:
221.274 + print e
221.275 +
221.276 + for path in share_path_list:
221.277 + uri = 'file://%s' % path
221.278 + if self._check_link_existance(uri) == True:
221.279 + continue
221.280 + self._add_link(uri)
221.281 +
221.282 + uri_list = []
221.283 + uri_list = self.uri_list_old + self.uri_list_new
221.284 +
221.285 + try:
221.286 + f = open(self.UI.links_cfg_path, 'w')
221.287 + f.writelines("\n".join(uri_list))
221.288 + f.close()
221.289 + except Exception, e:
221.290 + print 'Errore ', e
221.291 +
221.292 + # chown user
221.293 + ret, out, err = execute('chown %s %s' % (self.UI.user, self.UI.links_cfg_path))
221.294 +
221.295 +def work_on_user(user):
221.296 + if not Manager.user_exists(user): raise NoExistingIsiUser
221.297 +
221.298 + print 'working on %s ...' % user
221.299 +
221.300 + UI = UserInfo(user)
221.301 + M = MenuManager(UI)
221.302 + M.setup_menu_links()
221.303 +
221.304 +def work_on_group(group):
221.305 + USERS = Manager.get_members(group)
221.306 + for user in USERS:
221.307 + work_on_user(user)
221.308 +
221.309 +def work_on_all():
221.310 + for group in MAIN_GROUPS:
221.311 + work_on_group(group)
221.312 +
221.313 +
221.314 +opts, args = optionparse.parse(__doc__)
221.315 +
221.316 +LOGON_CONF = '/etc/isi/logon.conf'
221.317 +
221.318 +Manager = isi.Manager(isi.IsiConn(dn="", passwd=""))
221.319 +MAIN_GROUPS = isi.srv.get_main_groups()
221.320 +
221.321 +#LOGNAME = os.getlogin() # Damn bugged method always returning root !?!?
221.322 +LOGNAME = os.getenv('LOGNAME') # env variable method
221.323 +
221.324 +USER = opts.user
221.325 +GROUP = opts.group
221.326 +VERBOSE = opts.verbose
221.327 +
221.328 +### Startup
221.329 +if USER:
221.330 + work_on_user(USER)
221.331 +elif GROUP:
221.332 + if LOGNAME != 'root':
221.333 + raise RequireRootPrivileges
221.334 + work_on_group(GROUP)
221.335 +elif opts.all:
221.336 + if LOGNAME != 'root':
221.337 + raise RequireRootPrivileges
221.338 + work_on_all()
221.339 +else:
221.340 + user = LOGNAME
221.341 + work_on_user(user)
222.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
222.2 +++ b/usr/bin/isi-passwd Mon Apr 26 11:16:23 2010 +0200
222.3 @@ -0,0 +1,94 @@
222.4 +#!/usr/bin/python
222.5 +# -*- coding: utf-8 -*-
222.6 +
222.7 +# This program is free software; you can redistribute it and/or modify
222.8 +# it under the terms of the GNU General Public License as published by
222.9 +# the Free Software Foundation; either version 2, or (at your option)
222.10 +# any later version.
222.11 +
222.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
222.13 +
222.14 +"""
222.15 +
222.16 +opt -A is not yet implemented
222.17 +
222.18 + usage: %prog [options] user
222.19 + -N, --dry-run: don't touch the ldap db or filesystem
222.20 + -w, --pwdroot: change root and slapd/samba password
222.21 + -A, --pwdslap: change only slapd/samba admin password
222.22 + -p, --passwd=password: use password
222.23 + -r, --random: assign a random password, print it in stdout
222.24 + -c, --codfis: password uguale ai primi 8 caratteri del codice fiscale con l'iniziale maiuscola
222.25 +
222.26 +"""
222.27 +
222.28 +import isi
222.29 +import sys
222.30 +# servono per identificare l'utente (vedi sotto)
222.31 +# import os, pwd
222.32 +import re
222.33 +from dry import optionparse
222.34 +from dry.functions import execute, ExecuteError
222.35 +from isi.parser import new_password
222.36 +from getpass import getpass
222.37 +opts, args = optionparse.parse(__doc__)
222.38 +
222.39 +c = isi.IsiConn(dry_run=opts.dry_run)
222.40 +l = isi.Manager(c)
222.41 +c.backup()
222.42 +
222.43 +# per saper chi è l'utente loggato
222.44 +# attuser = pwd.getpwuid(os.getuid())[0]
222.45 +
222.46 +
222.47 +if opts.pwdroot or opts.pwdslap:
222.48 + msg=''
222.49 + if opts.pwdroot:
222.50 + opts.pwdslap = True
222.51 + msg = '/root'
222.52 + if opts.pwdslap:
222.53 + passwd1 = getpass('Nuova password samba/ldap%s: '% msg)
222.54 + passwd2 = getpass('Ripeti password samba/ldap%s: '% msg)
222.55 + if passwd1 == passwd2:
222.56 + try:
222.57 + c.set_rootdn_passwd(passwd1)
222.58 + except:
222.59 + sys.exit(1)
222.60 + if opts.pwdroot:
222.61 + pwdr = "root:%s\n|" % passwd1
222.62 + ret_code, out, err = execute('chpasswd', stdin=pwdr )
222.63 + if ret_code:
222.64 + print "ERRORE nel cambiare la password di root:%s" % err
222.65 + msg=''
222.66 +
222.67 + print "password slap/samba%s cambiata con successo" % msg
222.68 + else:
222.69 + print "ERRORE: le password digitate non coincidono"
222.70 + sys.exit(0)
222.71 +
222.72 +
222.73 +if not len(args) == 1:
222.74 + print >>sys.stderr, "Need a user to change the password"
222.75 + sys.exit(1)
222.76 +else:
222.77 + user = args[0]
222.78 +
222.79 +
222.80 +if l.user_exists(user):
222.81 + if opts.random:
222.82 + opts.passwd = new_password()
222.83 + print "the random password for user %s is: %s" % (user, opts.passwd)
222.84 + if opts.codfis:
222.85 + cf = l.get_attr(user, 'employeeNumber')[0]
222.86 + if cf:
222.87 + opts.passwd = cf[0:8].title()
222.88 + print "the password for user %s is: %s " % (user, opts.passwd)
222.89 + else:
222.90 + print "ERRORE: codice fiscale mancante, inserire manualmente una password"
222.91 + if not opts.passwd:
222.92 + opts.passwd = raw_input('Nuova Password: ')
222.93 + user = l.get_samba_user(user)
222.94 + user.set_password(opts.passwd)
222.95 +else:
222.96 + print >>sys.stderr, "No user '%s'" % user
222.97 + sys.exit(1)
223.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
223.2 +++ b/usr/lib/cgi-bin/dglog.pl Mon Apr 26 11:16:23 2010 +0200
223.3 @@ -0,0 +1,827 @@
223.4 +#!/usr/bin/perl
223.5 +
223.6 +###########################################################################
223.7 +#
223.8 +# Program : Log Analyzer for DansGuardian
223.9 +# Author : Jimmy Myrick ([email protected])
223.10 +# Version : .1.1
223.11 +# Released : July 6, 2021
223.12 +#
223.13 +# This program is free software; you can redistribute it and/or modify
223.14 +# it under the terms of the GNU General Public License as published by
223.15 +# the Free Software Foundation; either version 2 of the License, or
223.16 +# (at your option) any later version.
223.17 +#
223.18 +# This program is distributed in the hope that it will be useful,
223.19 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
223.20 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
223.21 +# GNU General Public License for more details.
223.22 +#
223.23 +# Heck, if you like it though and want to send me something, that's
223.24 +# ok too.
223.25 +#
223.26 +# Change history is available here for now:
223.27 +# http://www.tiger.org/technology/dg
223.28 +#
223.29 +###########################################################################
223.30 +#
223.31 +# Modified by: Massimo Mancini <[email protected]>
223.32 +# for: query ldap about user data
223.33 +#
223.34 +###########################################################################
223.35 +
223.36 +###########################################################################
223.37 +#
223.38 +# Change to point to your DansGuardian log directory
223.39 +# NOTE: The trailing / IS REQUIRED!!
223.40 +#
223.41 +###########################################################################
223.42 +$logdir = '/var/log/dansguardian/';
223.43 +do "/etc/isi/dglog.conf.pl";
223.44 +
223.45 +
223.46 +###########################################################################
223.47 +#
223.48 +# Log filename. Change this to match the prefix of your log files
223.49 +# This defaults to access.log and should not have to be modified.
223.50 +#
223.51 +# Any logfiles in $logdir that match the prefix $logfile and are gzip'ed
223.52 +# with a .gz extension will also be read. The results will be printed in
223.53 +# reverse chronological filename order.
223.54 +#
223.55 +# Example:
223.56 +# If you have the files: access.log access.log.0.gz access.log.1.gz
223.57 +# where they are newest to oldest, then any matches in
223.58 +# access.log.1.gz will be printed first, followed by access.log.0.gz
223.59 +# and then access.log
223.60 +#
223.61 +# No sorting is done by the program and the results are displayed in logfile
223.62 +# order. If your results are out of sequence, check the filename/dates
223.63 +# to be sure they are compressed and rotated properly. If you use
223.64 +# the FreeBSD newsyslog.conf to rotate your logs, this will not be a
223.65 +# problem.
223.66 +#
223.67 +###########################################################################
223.68 +$logfile = 'access.log';
223.69 +
223.70 +
223.71 +###########################################################################
223.72 +#
223.73 +# If you need the perl modules below, download and untar them to a directory.
223.74 +# Then cd to the directory and enter the commands:
223.75 +# perl Makefile.PL; make; make test; make install
223.76 +#
223.77 +# If you need more instructions,
223.78 +# go here: http://www.cpan.org/modules/INSTALL.html
223.79 +#
223.80 +# Get it here: http://www.cpan.org/authors/id/LDS/CGI.pm-2.81.tar.gz
223.81 +#
223.82 +###########################################################################
223.83 +use CGI;
223.84 +
223.85 +###########################################################################
223.86 +#
223.87 +# This is needed to do gzip'ed log files on the fly
223.88 +# Get it here: http://www.cpan.org/authors/id/PMQS/Compress-Zlib-1.16.tar.gz
223.89 +#
223.90 +###########################################################################
223.91 +use Compress::Zlib;
223.92 +
223.93 +
223.94 +###########################################################################
223.95 +#
223.96 +# This should determine where the program is called from automagically.
223.97 +# If not, uncomment the first lane, change to your server name/path and
223.98 +# comment the second line. You can use Apache restrictions to block
223.99 +# access to this file if desired.
223.100 +#
223.101 +###########################################################################
223.102 +#$cgipath = 'http://your.server.com/cgi-bin/dglog/dglog.pl';
223.103 +$cgipath = $ENV{SCRIPT_NAME};
223.104 +
223.105 +
223.106 +###########################################################################
223.107 +# LDAP
223.108 +###########################################################################
223.109 +
223.110 +use Net::LDAP;
223.111 +$OK_LDAP=1;
223.112 +%usersfound=();
223.113 +# $ldap_server ='<name|ip server_ldap>';
223.114 +# $ldap_base ='<dc=isi,dc=lan>';
223.115 +# @ldap_fields=('gecos','departmentNumber');
223.116 +$ldap = Net::LDAP->new($ldap_server) or ($OK_LDAP=0);
223.117 +$ldap->bind if ($OK_LDAP);
223.118 +
223.119 +
223.120 +###########################################################################
223.121 +#
223.122 +# SHOULDN'T HAVE TO MODIFY ANYTHING BELOW THIS LINE
223.123 +#
223.124 +###########################################################################
223.125 +
223.126 +$q = new CGI;
223.127 +
223.128 +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
223.129 +$mon = $mon + 1; # mon starts at 0
223.130 +$year = $year + 1900; # year needs 1900 added
223.131 +$pagename = 'Log Analyzer for DansGuardian';
223.132 +
223.133 +$a = $q->param('a');
223.134 +
223.135 +if ($a eq 'i') { # Inquiry into logs
223.136 +
223.137 + # These are the values that can be sent by the user through the browser
223.138 + $sIP = "ALL"; # IP address
223.139 + $sUN = "ALL"; # Username
223.140 + $sURL = "ALL"; # URL to show or trace a denied site - this is the URL to trace
223.141 + $sSD = "ALL"; # Complete start date
223.142 + $sSDY = "ALL"; # Start date year
223.143 + $sSDM = "ALL"; # Start date month
223.144 + $sSDD = "ALL"; # Start date day
223.145 + $sED = "ALL"; # Complete end date
223.146 + $sEDY = "ALL"; # End date year
223.147 + $sEDM = "ALL"; # End date month
223.148 + $sEDD = "ALL"; # End date day
223.149 + $sA = "ALL"; # Action
223.150 + $sSumCnt = "20"; # Number of summary sites to show
223.151 + $sSumDen = "off"; # Show denied summary? on/off
223.152 + $sSumAlw = "off"; # Show allowed summary? on/off
223.153 + $sL = "off"; # Turn URL's into links? on/off
223.154 + $sZ = "off"; # Examine gziped files? on/off
223.155 +
223.156 + $sIP = &validateIP($q->param('sIP')) if $q->param('sIP') ne "";
223.157 + $sUN = $q->param('sUN') if $q->param('sUN') ne "";
223.158 + $sURL = $q->param('sURL') if $q->param('sURL') ne "";
223.159 +
223.160 + if ($q->param('sSDY') ne "" &&
223.161 + $q->param('sSDM') ne "" &&
223.162 + $q->param('sSDD') ne "" &&
223.163 + $q->param('sEDY') ne "" &&
223.164 + $q->param('sEDM') ne "" &&
223.165 + $q->param('sEDD') ne "") {
223.166 +
223.167 + $sSDY = $q->param('sSDY');
223.168 + $sSDM = $q->param('sSDM');
223.169 + $sSDD = $q->param('sSDD');
223.170 + $sEDY = $q->param('sEDY');
223.171 + $sEDM = $q->param('sEDM');
223.172 + $sEDD = $q->param('sEDD');
223.173 +
223.174 + $sSD = $sSDY.'.'.$sSDM.'.'.$sSDD;
223.175 + $sSD = convertDate($sSD);
223.176 + $sED = $sEDY.'.'.$sEDM.'.'.$sEDD;
223.177 + $sED = convertDate($sED);
223.178 +
223.179 + if ($sSD > $sED) {
223.180 + $msg = "End Date is greather than Start Date";
223.181 + &printMenu;
223.182 + }
223.183 + }
223.184 +
223.185 + $sA = &validateAction($q->param('sA')) if $q->param('sA') ne ""; # Action
223.186 +
223.187 + $sSumCnt = &validateSummary($q->param('sSumCnt'))
223.188 + if $q->param('sSumCnt') ne "";
223.189 + $sSumDen = $q->param('sSumDen') if $q->param('sSumDen') eq 'on';
223.190 + $sSumAlw = $q->param('sSumAlw') if $q->param('sSumAlw') eq 'on';
223.191 +
223.192 + $sL = $q->param('sL') if $q->param('sL') eq 'on';
223.193 + $sZ = $q->param('sZ') if $q->param('sZ') eq 'on';
223.194 +
223.195 +
223.196 + # Need a few global variables to keep from passing back and forth a bunch
223.197 + $linesRead, $allowTotal, $blockTotal, $grandTotal = 0;
223.198 +
223.199 + &searchLog;
223.200 +
223.201 +}
223.202 +elsif ($a eq 'h') {
223.203 + &displayHelp;
223.204 +}
223.205 +else {
223.206 + &printMenu;
223.207 +}
223.208 +
223.209 +#############
223.210 +sub searchLog
223.211 +#############
223.212 +{
223.213 + my $first = 0;
223.214 +
223.215 + &printHeader;
223.216 + print "<font face=arial,helvetica,sans-serif size=2>";
223.217 + print "Report information for:<br>
223.218 + Start Date: <b>$sSD</b> | End Date: <b>$sED</b> |
223.219 + Username : <b>$sUN</b> | IP: <b>$sIP</b> |
223.220 + Action: <b>$sA</b> | URL: <b>$sURL</b><hr></font>\n";
223.221 + print "<font face=arial,helvetica,sans-serif size=1>";
223.222 +
223.223 + opendir(D, $logdir);
223.224 + @files = grep {/^$logfile/} readdir(D);
223.225 + @files = sort {$b cmp $a} @files;
223.226 + closedir(D);
223.227 +
223.228 + foreach $file (@files) {
223.229 + if ($file =~ /\.gz/) {
223.230 + if ($sZ eq 'on') {
223.231 + if ($first == 0) {
223.232 + print "Ignoring gzip logfile(s) in $logdir: ";
223.233 + $first = 1;
223.234 + }
223.235 + print "$file | ";
223.236 + next;
223.237 + }
223.238 + $gz = gzopen($logdir.$file,r);
223.239 + if (!$gz) {
223.240 + $msg = "Cannot open $logdir$file. Check Permissions.";
223.241 + &printMenu;
223.242 + }
223.243 + while ($gz->gzreadline($line)) {
223.244 + &checkLine($line);
223.245 + }
223.246 + $gz->gzclose;
223.247 + }
223.248 + else {
223.249 + print "<p>";
223.250 + unless (open(F,$logdir.$file)) {
223.251 + $msg = "Cannot open $logdir$file. Check Permissions.";
223.252 + &printMenu;
223.253 + }
223.254 + while ($line = <F>) {
223.255 + &checkLine($line);
223.256 + }
223.257 + close(F);
223.258 + }
223.259 + }
223.260 +
223.261 + if ($sSumAlw eq "on" && $allowTotal != 0) {
223.262 + &showSummarySites($allowTotal,'ALLOWED',$sSumCnt,%topSites);
223.263 + }
223.264 + if ($sSumDen eq "on" && $blockTotal != 0) {
223.265 + &showSummarySites($blockTotal,'DENIED',$sSumCnt,%blockSites);
223.266 + }
223.267 +
223.268 + print "<center><hr noshade size=1 width=50%>
223.269 + <font size=2>Total matches: $grandTotal |
223.270 + Total ALL Requests: $linesRead</font>
223.271 + <hr noshade size=1 width=50%></font>";
223.272 + print "<center><a href=$cgipath>Return to Menu</a></center>";
223.273 +}
223.274 +
223.275 +#######################
223.276 +sub ldap_getuserinfo {
223.277 +#######################
223.278 +
223.279 + $uid=shift;
223.280 +
223.281 + return "...no ldap!" if (!$OK_LDAP);
223.282 +
223.283 + my $ret="",$gec,$dep,$flt,$ris,@info,$entry;
223.284 +
223.285 + if (defined($usersfound{$uid})){
223.286 + $ret = $usersfound{$uid};
223.287 + }else{
223.288 +
223.289 + $ris=$ldap->search( base => $ldap_base,
223.290 + filter => "uid=$uid",
223.291 + attrs => \@ldap_fields);
223.292 +
223.293 + @info = $ris->entries;
223.294 +
223.295 + foreach $entry (@info) {
223.296 + $gec = $entry->get_value($ldap_fields[0]);
223.297 + $gec =~ s/,//g;
223.298 + $dep = $entry->get_value($ldap_fields[1]);
223.299 + $ret = uc("<strong> : $gec - $dep</strong>");
223.300 + }
223.301 + $usersfound{$uid}=$ret;
223.302 + }
223.303 + return $ret;
223.304 +}
223.305 +
223.306 +
223.307 +#############
223.308 +sub checkLine
223.309 +#############
223.310 +{
223.311 + my ($line) = @_;
223.312 + $linesRead++;
223.313 +
223.314 + # Print out a '.' every 1000 log file lines read. Keep browser connect alive
223.315 + if (($linesRead % 1000) == 0) {
223.316 + print " ";
223.317 + }
223.318 + ($date,$time,$user,$ip,$url,$toeol) = split(/ /,$line,6);
223.319 +
223.320 + # query ldap
223.321 + $user .= ldap_getuserinfo($user);
223.322 +
223.323 +
223.324 + # Rule out the easy matches first
223.325 + return if ($sIP ne "ALL" && $sIP ne $ip);
223.326 + return if ($sUN ne "ALL" && $sUN ne $user);
223.327 +
223.328 + # Don't do a date comparison unless we are told to
223.329 + if ($sSD ne "ALL" || $sED ne "ALL") {
223.330 + $dgDate = &convertDate($date);
223.331 + return if (!($dgDate ge $sSD && $dgDate le $sED));
223.332 + }
223.333 +
223.334 + $url =~ /(\w+):\/\/([\w\.-]+)\/?(\S*)/;
223.335 + $protocol = $1; # HTTP, FTP
223.336 + $baseurl = $2; # domain part without http:// or ftp://
223.337 + return if ($sURL ne "ALL" && $sURL ne $baseurl);
223.338 + $toeol =~ /(\*.+\*)? ?(.+)? (\w+) (\d+)$/;
223.339 + $action = $1; # *DENIED# or *EXCEPTION* etc., if exists
223.340 + $reason = $2; # Reason for #1 if exists
223.341 + $method = $3; # method (GET POST)
223.342 + $size = $4; # size
223.343 + if ($sA ne "ALL") {
223.344 + return if ($sA eq "denAll" &&
223.345 + $action ne "*DENIED*");
223.346 + return if ($sA eq "excAll" &&
223.347 + $action ne "*EXCEPTION*");
223.348 + return if ($sA eq "denSite" &&
223.349 + !($reason =~ /^Banned site/));
223.350 + return if ($sA eq "denRegURL" &&
223.351 + !($reason =~ /^Banned Regular Expression URL/));
223.352 + return if ($sA eq "denPhrase" &&
223.353 + !($reason =~ /^Banned Phrase/));
223.354 + return if ($sA eq "denCombPhrase" &&
223.355 + !($reason =~ /^Banned combination phrase/));
223.356 + return if ($sA eq "denWeightPhrase" &&
223.357 + !($reason =~ /^Weighted phrase limit/));
223.358 + return if ($sA eq "denExt" &&
223.359 + !($reason =~ /^Banned extension/));
223.360 + return if ($sA eq "denMIME" &&
223.361 + !($reason =~ /^Banned MIME Type/));
223.362 + return if ($sA eq "denICRA" &&
223.363 + !($reason =~ /^ICRA/));
223.364 + return if ($sA eq "denBlanketIP" &&
223.365 + !($reason =~ /^Blanket IP Block/));
223.366 + return if ($sA eq "excSite" &&
223.367 + !($reason =~ /^Exception site/));
223.368 + return if ($sA eq "excPhrase" &&
223.369 + !($reason =~ /^Exception phrase/));
223.370 + return if ($sA eq "excCombPhrase" &&
223.371 + !($reason =~ /^Combination exception phrase/));
223.372 + }
223.373 +
223.374 + # Need to do a count for grandTotal if allowed OR denied summary selected
223.375 + if ($sSumAlw eq "on" || $sSumDen eq "on") {
223.376 + if ($action ne '*DENIED*') {
223.377 + $allowTotal++;
223.378 + $grandTotal++;
223.379 + # Don't waste memory if didn't want this, but need to count for grandTotal
223.380 + $topSites{$baseurl}++ if $sSumAlw eq "on";
223.381 + }
223.382 + else {
223.383 + $blockTotal++;
223.384 + $grandTotal++;
223.385 + # Don't waste memory if didn't want this, but need to count for grandTotal
223.386 + $blockSites{$baseurl}++ if $sSumDen eq "on";
223.387 + }
223.388 + }
223.389 + else {
223.390 + print "$date $time ";
223.391 + print "<a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sIP=$ip&sZ=$sZ&sL=$sL>$ip</a>
223.392 + $user<br>";
223.393 + if ($sL eq 'on') {
223.394 + print "<a href=\"$url\" target=_blank>$url</a> $method $size<br>";
223.395 + } else {
223.396 + print "$url $method $size<br>";
223.397 + }
223.398 + if ($action ne "" && $reason ne "") {
223.399 + print "<font color=red>$action : $reason</font><p>";
223.400 + } else {
223.401 + print "<p>";
223.402 + }
223.403 + $grandTotal++;
223.404 + }
223.405 +}
223.406 +
223.407 +####################
223.408 +sub showSummarySites {
223.409 +####################
223.410 + my ($subTotal, $whatToShow, $topNum, %sites) = @_;
223.411 + my $count = 1;
223.412 +
223.413 + print "<table border=0 cellpadding=2 cellspacing=2 align=center>
223.414 + <tr><th colspan=6>
223.415 + <b><center>
223.416 + <hr noshade width=50% size=1>
223.417 + Top $topNum $whatToShow Sites</b></td></tr>
223.418 + <hr noshade width=50% size=1>
223.419 + <tr><td align=center>Rank</td>
223.420 + <td align=center>URL</td>
223.421 + <td align=center>Count</td>
223.422 + <td align=right>\% of<br>$whatToShow</td>
223.423 + <td align=right>\% of<br>Total</td>
223.424 + <td align=center>Investigate</td></tr>";
223.425 +
223.426 + foreach $key (sort {$sites{$b} <=> $sites{$a}} keys %sites) {
223.427 + if ($count <= $topNum) {
223.428 + print "<tr>
223.429 + <td align=right>$count. </td>";
223.430 + print "<td align=right>";
223.431 + if ($sL eq 'on') {
223.432 + print "<a href=http://$key target=_blank>$key</a>";
223.433 + } else {
223.434 + print "$key";
223.435 + }
223.436 + print "</td><td align=right>$sites{$key}</td><td align=right>";
223.437 + printf(" %2.2f ",($sites{$key}/$subTotal)*100);
223.438 + print "</td><td align=right>";
223.439 + printf(" %2.2f",($sites{$key}/$grandTotal)*100);
223.440 + print "</td>";
223.441 + print "<td align=center>
223.442 + <a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sUN=$sUN&sIP=$sIP&sURL=$key&sZ=$sZ&sA=";
223.443 + if ($whatToShow eq "DENIED") { print "denAll"; } else { print ""; }
223.444 + print">Trace</a></td></tr>";
223.445 + $count++;
223.446 + }
223.447 + break;
223.448 + }
223.449 + print "<tr><td colspan=6 align=center>
223.450 + <hr noshade size=1 width=85% align=center>
223.451 + Total $whatToShow Requests (only top $topNum sites shown) : $subTotal
223.452 + <hr noshade size=1 width=85% align=center>
223.453 + </td></tr>";
223.454 + print "</table>
223.455 + <hr noshade width=100% size=1>";
223.456 +}
223.457 +
223.458 +###################
223.459 +sub validateSummary
223.460 +###################
223.461 +{
223.462 + my ($count) = @_;
223.463 + if ($count < 0 || $count > 100) {
223.464 + $count = 20;
223.465 + }
223.466 + return($count);
223.467 +}
223.468 +
223.469 +##############
223.470 +sub validateIP
223.471 +##############
223.472 +{
223.473 + my ($checkIP) = @_;
223.474 +
223.475 + if ($checkIP eq 'ALL') {
223.476 + return('ALL');
223.477 + }
223.478 + elsif ($checkIP =~ /^((2([0-4]\d|5[0-5])|1?\d{1,2})(\.|$)){4}/) {
223.479 + return ($checkIP);
223.480 + }
223.481 + else {
223.482 + $msg = "Invalid IP address entered.";
223.483 + &printMenu;
223.484 + }
223.485 +}
223.486 +
223.487 +##################
223.488 +sub validateAction {
223.489 +##################
223.490 + my ($action) = @_;
223.491 +
223.492 + # Need to make the actions a hash and reference them that way
223.493 + # Make it easier to add/modify and can validate that way too
223.494 + # Maybe later.
223.495 + if ($action eq "none") { return ("ALL"); }
223.496 +
223.497 + return ($action);
223.498 +}
223.499 +
223.500 +###############
223.501 +sub convertDate {
223.502 +###############
223.503 + my ($workDate) = @_;
223.504 + ($year, $mon, $day) = split(/\./,$workDate);
223.505 +
223.506 + if (length($mon) == 1) { $mon = '0'.$mon; }
223.507 + if (length($day) == 1) { $day = '0'.$day; }
223.508 + if (($mon ge "01" && $mon le "12") && ($day ge "01" && $day le "31") &&
223.509 + ($year ge "2000" && $year le "2035")) {
223.510 +
223.511 + $goodDate = $year.$mon.$day;
223.512 + return ($goodDate);
223.513 + } else {
223.514 + $msg = "Invalid Date Detected";
223.515 + &printMenu;
223.516 + }
223.517 +}
223.518 +
223.519 +###############
223.520 +sub buildSelect
223.521 +###############
223.522 +{
223.523 + my ($start, $end, $type) = @_;
223.524 + my $x = 0;
223.525 +
223.526 +## print "<option value=\"\">--$type--";
223.527 + print "<option value=\"\">--ALL--";
223.528 + for ($x = $start; $x <= $end; $x++) {
223.529 + if ($type eq 'Year' && $x == $year) {
223.530 + print "<option value=$x selected>$x";
223.531 + }
223.532 + elsif ($type eq 'Month' && $x == $mon) {
223.533 + print "<option value=$x selected>$x";
223.534 + }
223.535 + elsif ($type eq 'Day' && $x == $mday) {
223.536 + print "<option value=$x selected>$x";
223.537 + }
223.538 + else {
223.539 + print "<option value=$x>$x";
223.540 + }
223.541 + }
223.542 +}
223.543 +
223.544 +#############
223.545 +sub printMenu
223.546 +#############
223.547 +{
223.548 + &printHeader;
223.549 + print "
223.550 + <table align=center bgcolor=ffffff border=1 cellpadding=3 cellspacing=1>\n";
223.551 + if ($msg ne "") {
223.552 + print "<tr><td colspan=3 bgcolor=c80000 align=center>
223.553 + <font face=arial,helvetica,sans-serif size=3><b>$msg</b>
223.554 + </font></tr>\n";
223.555 + }
223.556 +
223.557 + # Menu items header row
223.558 + print "
223.559 + <tr bgcolor=f0f0f0>
223.560 + <th width=40%>
223.561 + Parameter
223.562 + </th>
223.563 + <th width=40%>
223.564 + Value
223.565 + </th>
223.566 + <th width=20%>
223.567 + Description
223.568 + </th></tr>\n";
223.569 +
223.570 + # Menu item for entering date ranges
223.571 + print "
223.572 + <tr><td align=left>
223.573 + Enter date range:
223.574 + <form action=$cgipath><input type=hidden name=a value=i>
223.575 + <br>
223.576 + </td>
223.577 + <td align=left>
223.578 + Start Date<br>
223.579 + <select name=sSDY>";
223.580 + &buildSelect(2002,2010,"Year");
223.581 + print "</select><select name=sSDM>";
223.582 + &buildSelect(01,12,"Month");
223.583 + print "</select><select name=sSDD>";
223.584 + &buildSelect(01,31,"Day");
223.585 + print "</select><br>
223.586 + End Date<br>
223.587 + <select name=sEDY>";
223.588 + &buildSelect(2002,2010,"Year");
223.589 + print "</select><select name=sEDM>";
223.590 + &buildSelect(01,12,"Month");
223.591 + print "</select><select name=sEDD>";
223.592 + &buildSelect(01,31,"Day");
223.593 + print "</select>
223.594 + </td>
223.595 + <td align=center>
223.596 + A start and end must be specified.
223.597 + </td></tr>\n";
223.598 +
223.599 + # Menu item for IP viewing
223.600 + print "
223.601 + <tr><td align=left>
223.602 + Enter IP Address
223.603 + </td>
223.604 + <td align=left>
223.605 + <input name=sIP maxlength=15 size=20>
223.606 + </td>
223.607 + <td align=center>
223.608 + ex: 10.0.0.1<br>
223.609 + </td></tr>\n";
223.610 +
223.611 + # Menu item for username viewing
223.612 + print "
223.613 + <tr><td align=left>
223.614 + Enter a Username
223.615 + </td>
223.616 + <td align=left>
223.617 + <input name=sUN maxlength=15 size=20>
223.618 + </td>
223.619 + <td align=center>
223.620 + (proxy auth must be enabled)<br>
223.621 + </td></tr>\n";
223.622 +
223.623 + # Menu item for URL viewing
223.624 + print "
223.625 + <tr><td align=left>
223.626 + Enter a URL (domain part only)
223.627 + </td>
223.628 + <td align=left>
223.629 + <input name=sURL maxlength=30 size=20>
223.630 + </td>
223.631 + <td align=center>
223.632 + Enter the www.domain.com part of a URL only<br>
223.633 + </td></tr>\n";
223.634 +
223.635 + # Menu item for ACTION
223.636 + print "
223.637 + <tr><td align=left>
223.638 + View activity by ACTION
223.639 + </td>
223.640 + <td align=left>
223.641 + <select name=sA>
223.642 + <option value=none>Show ALL
223.643 + <option value=none>---------------
223.644 + <option value=denAll>Show ALL Denied
223.645 + <option value=none>---------------
223.646 + <option value=excAll>Show ALL Exception
223.647 + <option value=none>---------------
223.648 + <option value=denSite>Banned Site
223.649 + <option value=denPhrase>Banned Phrase
223.650 + <option value=denRegURL>Banned Regular Expression URL
223.651 + <option value=denCombPhrase>Banned Combination Phrase
223.652 + <option value=denWeightPhrase>Weighted Phrase Limit
223.653 + <option value=denExt>Banned Extension
223.654 + <option value=denMIME>Banned MIME Type
223.655 + <option value=denICRA>ICRA Exceeded
223.656 + <option value=denBlanketIP>Blanket IP Block
223.657 + <option value=none>---------------
223.658 + <option value=excSite>Exception Site
223.659 + <option value=excPhrase>Exception Phrase
223.660 + <option value=excCombPhrase>Combination Exception Phrase
223.661 + </select>
223.662 +
223.663 + </td>
223.664 + <td align=center>
223.665 + Can only do one at a time.
223.666 + </td></tr>\n";
223.667 +
223.668 + # Menu item for selecting summary statistics
223.669 + print "
223.670 + <tr><td colspan=2 align=left>
223.671 + Show summary information for the top
223.672 + <input maxlength=3 size=5 name=sSumCnt value=20>
223.673 + <input type=checkbox name=sSumDen>DENIED
223.674 + <input type=checkbox name=sSumAlw>ALLOWED
223.675 + sites
223.676 + </td>
223.677 + <td align=center>
223.678 + Will summarize the top sites for the criteria specified.
223.679 + </td></tr>\n";
223.680 +
223.681 + print "
223.682 + <tr><td colspan=3 align=center>
223.683 + <table width=100% border=0 cellpadding=0 cellspacing=0 align=center>
223.684 + <tr><td>
223.685 + <input type=checkbox name=sL>Check to turn URL's in reports into links.<br>
223.686 + <input type=checkbox name=sZ>Check to <b>exclude</b> gzip log files.<br>
223.687 + <a href=$cgipath?a=h>View Usage Instructions</a><br>
223.688 + </td>
223.689 + <td align=center valign=middle>
223.690 + Click the \"Run Report\" Button to Start<p>
223.691 + <input type=submit value=\"Run Report\">
223.692 + <input type=reset value=\"Reset Values\"><br>
223.693 + </td></tr>
223.694 + </table>
223.695 + </td></tr>\n";
223.696 +
223.697 + print " </form> </td> </tr> </table> ";
223.698 + &printFooter;
223.699 + exit;
223.700 +}
223.701 +
223.702 +###############
223.703 +sub printHeader
223.704 +###############
223.705 +{
223.706 + print $q->header;
223.707 + print <<"(EOT)";
223.708 + <HTML><HEAD>
223.709 + <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
223.710 + <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
223.711 + <META HTTP-EQUIV="Expires" CONTENT="-1">
223.712 + <TITLE>$pagename</TITLE>
223.713 + <STYLE>
223.714 + <!--
223.715 + TABLE {margin-top: 0; padding-top: 0}
223.716 + TD {font-family: Serif; font-size: 10pt }
223.717 + TH {font-family: Serif; font-size: 12pt }
223.718 + -->
223.719 + </STYLE>
223.720 + </HEAD>
223.721 + <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#0000ff"
223.722 + alink="#0000ff">
223.723 + <center>
223.724 + <table width="600" border="0" cellspacing="0" cellpadding="0">
223.725 + <tr><th width=600 align=center>
223.726 + <font size="4" color="#000000" face="arial">
223.727 + <hr noshade size=1 width=90%>
223.728 + $pagename
223.729 + <hr noshade size=1 width=90%>
223.730 + </th></tr>
223.731 + </table>
223.732 + </center>
223.733 +
223.734 +(EOT)
223.735 +}
223.736 +
223.737 +###############
223.738 +sub printFooter
223.739 +###############
223.740 +{
223.741 + print <<"(EOT)";
223.742 + </BODY>
223.743 + </HTML>
223.744 +(EOT)
223.745 +}
223.746 +
223.747 +###############
223.748 +sub displayHelp
223.749 +###############
223.750 +{
223.751 + &printHeader;
223.752 + print<<"(EOF)";
223.753 + <table width=75% border=1 cellpadding=2 cellspacing=0 align=center>
223.754 + <tr><th bgcolor=f0f0f0><font face=arial,helvetica,sans-serif size=4>
223.755 + Instructions
223.756 + </th></tr>
223.757 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.758 + <b>Overview</b>
223.759 + <ul>
223.760 + This program will examine logs files created by DansGuardian filtering
223.761 + software (http://www.dansguardian.org).<p>
223.762 + Different search criteria can be specified. The search criteria are
223.763 + cummulatvie (added together). For example, specifying a date range
223.764 + and an IP address will only show entries that match BOTH criteria. If
223.765 + you want to see all log entries, do not specify any criteria.
223.766 + <p>
223.767 + Presently, no sorting is done on the results. This is to ensure a very
223.768 + fast search, use a small amount of memory, and "feed" the browser peridically with information
223.769 + so a timeout does not occur. What this means is that your log files
223.770 + must be in chronological sequence on your system by name. This will
223.771 + become important when using multiple log files is added. This feature
223.772 + is not currently implemented. Only the one file is examined now.
223.773 + </ul>
223.774 + </td></tr>
223.775 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.776 + <b>Dates</b>
223.777 + <ul>
223.778 +Select the range of dates to match. If dates are used, <b>both</b> a start and end date must be selected. Failure to select any part of a start or end date will result in no date range being used. The dates will match greater than or equal to start date - less than or equal to end date.
223.779 + </ul>
223.780 + </td></tr>
223.781 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.782 + <b>IP Address</b>
223.783 + <ul>
223.784 + Enter a IPv4 address to match. Example: 10.0.0.1
223.785 + </ul>
223.786 + </td></tr>
223.787 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.788 + <b>Username</b>
223.789 + <ul>
223.790 + Enter a username to match. Proxy auth must be enabled in DansGuardian for this to work. If usernames are not shown when matching without any criteria, then proxy auth is most likely not enabled. Refer to the appropriate instructions on how to do this.
223.791 + </ul>
223.792 + </td></tr>
223.793 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.794 + <b>Action</b>
223.795 + <ul>
223.796 + Enter an action to match.
223.797 + Use the drop-down list to select the ACTION to match. The ACTIONs are the
223.798 + special case requests logged by DansGuardian. To see ALL matches for
223.799 + DENIED and EXCEPTION, select "ALL DENIED" or "ALL EXCEPTIONS". Only one
223.800 + ACTION can be viewed at a time and it shows most restrictive. For example,
223.801 + if "Banned Site" is selected, then only DENIED requests that were DENIED because of a site being in a banned site list will be shown. No other DENIED requests will be shown.
223.802 + </ul>
223.803 + </td></tr>
223.804 + <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
223.805 + <b>Summary Information</b>
223.806 + <ul>
223.807 + Selecting these options will show a summary report for the number
223.808 + of sites entered. The top 1 to 100 sites may be selected.
223.809 + <p>
223.810 + Once the summary screen appears, you may "investigate" why a site was
223.811 + denied/allowed and who/what machine was visiting the site. Simply click
223.812 + on the "Trace" link under the "Investigate" column and the results will be
223.813 + shown.
223.814 + <p>
223.815 + Caution: If you select to filter for only DENIED and check to show
223.816 + a summary for allowed, there will not be any results. This is correct.
223.817 + If you don't see the results you expected, go back and check the
223.818 + criteria that was entered.
223.819 + <p>
223.820 + Turn URL's into links
223.821 + <ul>Checking this box will cause the URL's in the report to be clickable.
223.822 + </ul>
223.823 + </ul>
223.824 + </td></tr>
223.825 +(EOF)
223.826 + print "<tr><td align=center><font face=arial,helvetica,sans=serif size=2>
223.827 + <a href=$cgipath>Return to $pagename</a></tr></td>
223.828 + </table>\n";
223.829 +}
223.830 +
224.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
224.2 +++ b/usr/lib/cgi-bin/listlogon.pl Mon Apr 26 11:16:23 2010 +0200
224.3 @@ -0,0 +1,251 @@
224.4 +#!/usr/bin/perl -w
224.5 +
224.6 +# your httpd.conf should have something like this:
224.7 +
224.8 +# Alias /perl/ /real/path/to/perl-scripts/
224.9 +
224.10 +# <Location /perl>
224.11 +# SetHandler perl-script
224.12 +# PerlHandler Apache::Registry
224.13 +# PerlSendHeader On
224.14 +# Options +ExecCGI
224.15 +# </Location>
224.16 +
224.17 +my $cgipath = $ENV{SCRIPT_NAME};
224.18 +my $qry = $ENV{QUERY_STRING};
224.19 +my $logonFile = "";
224.20 +my $DOMAIN=`ldapsearch -xLLL sambaDomainName=* sambaDomainName | grep -v dn | sed 's/sambaDomainName: //'`;
224.21 +
224.22 +if (defined($qry)){
224.23 + my @aq=split(/&/,$qry);
224.24 + $aq[0] =~ s/logfile=//g;
224.25 + $logonFile=$aq[0];
224.26 + $aq[1] =~ s/ord=//g;
224.27 + $ordFile=$aq[1];
224.28 +}
224.29 +
224.30 +if ($logonFile) {
224.31 + &vediLogonFile($logonFile,$ordFile);
224.32 +}else{
224.33 + &listaLogonFiles;
224.34 +}
224.35 +
224.36 +
224.37 +sub listaLogonFiles {
224.38 + my $logondir="/var/www/sambalogon";
224.39 + opendir(LD, $logondir) or die "Errore fatale: $!";
224.40 + my @allf = readdir LD;
224.41 + my @allfiles = sort {$b cmp $a} @allf;
224.42 + closedir LD;
224.43 + $form="
224.44 + <form action $cgipath method=\"GET\">
224.45 + <center>
224.46 + <table>
224.47 + ";
224.48 +
224.49 + my $i=0;
224.50 + my $trclass;
224.51 + my $trjs;
224.52 +
224.53 + foreach $f (@allfiles) {
224.54 +
224.55 + next if ($f !~ m/logon-/);
224.56 +
224.57 + if ($i++ % 2) {
224.58 + $trclass="even";
224.59 + }else{
224.60 + $trclass="odd";
224.61 + }
224.62 +
224.63 + $trjs1=" onmouseover=\"this.className='surbrillance2'\" onmouseout=\"this.className='$trclass'\"";
224.64 + $trjs2=" onmousedown=\"document.location='listlogon.pl?logfile=$f&ord=time';\" ";
224.65 +
224.66 + $form .= "
224.67 + <tr class=$trclass $trjs1 $trjs2>
224.68 + <td>$f<br></td>
224.69 + </tr>
224.70 + ";
224.71 + }
224.72 +
224.73 + $form .= "
224.74 + </table></center></form>
224.75 + ";
224.76 + print "Content-type: text/html\n\n";
224.77 + &printHeader;
224.78 + print $form;
224.79 + #print "%ENV: <br>\n", map { "$_ = $ENV{$_} <br>\n" } keys %ENV;
224.80 + &printFooter;
224.81 +}
224.82 +
224.83 +
224.84 +sub vediLogonFile {
224.85 + my $lf = shift;
224.86 + my $ord= shift;
224.87 + my $logonFile="/var/www/sambalogon/$lf";
224.88 +# my $logonFile="/var/www/sambalogon/logon-051006";
224.89 + my $lst;
224.90 + my $r;
224.91 + my @ar;
224.92 +
224.93 + open(LL,"<$logonFile");
224.94 + my @aX=();
224.95 + my @aL=<LL>;
224.96 + my @aL1=();
224.97 + close LL;
224.98 + my $ot="↓";
224.99 + my $on="↓";
224.100 + if ($ord eq 'id'){
224.101 + @aL1=sort { substr($a,15,10) cmp substr($b,15,10) } @aL;
224.102 + @aX=@aL1;
224.103 + $ot="";
224.104 + }else{
224.105 + @aX=@aL;
224.106 + $on="";
224.107 + }
224.108 +
224.109 +
224.110 +
224.111 + my $trjs1=" onmouseover=\"this.className='surbrillance'\" onmouseout=\"this.className='normal'\"";
224.112 + my $trjs2=" onmousedown=\"document.location='listlogon.pl?logfile=$lf&ord=id';\" ";
224.113 + my $trjs3=" onmousedown=\"document.location='listlogon.pl?logfile=$lf&ord=time';\" ";
224.114 +
224.115 + $lst="$op<br>
224.116 + <center>
224.117 + <table>
224.118 + <th class='nobrd'>Data</th>
224.119 + <th class='nobrd' $trjs1 $trjs3>$ot Ora $ot</th>
224.120 + <th class='nobrd' $trjs1 $trjs2>$on UserID $on</th>
224.121 + <th class='nobrd'>Cognome</th>
224.122 + <th class='nobrd'>Nome</th>
224.123 + <th class='nobrd'>Classe</th>
224.124 + <th class='nobrd'>Quota</th>
224.125 + <th class='nobrd'>ClientID</th>
224.126 + <th class='nobrd'>op.su WLG</th>
224.127 + ";
224.128 + my $i=0;
224.129 + my $trclass;
224.130 + my $trjs;
224.131 +
224.132 + foreach $l (@aX) {
224.133 + chop();
224.134 + @ar=split(/;/,$l);
224.135 + if ($ar[5] !~ m/INQUOTA/){
224.136 + $ar[5]="*"
224.137 + }else{
224.138 + $ar[5]="";
224.139 + }
224.140 + if ($i++ % 2) {
224.141 + $trclass="even";
224.142 + }else{
224.143 + $trclass="odd";
224.144 + }
224.145 + $trjs=" onmouseover=\"this.className='surbrillance'\" onmouseout=\"this.className='$trclass'\"";
224.146 + $sn=`ldapsearch -xLLL uid=$ar[2] sn | grep -w sn | sed 's/sn: //g'`;
224.147 + chop($sn);
224.148 + $cn=`ldapsearch -xLLL uid=$ar[2] cn | grep -w cn | sed 's/cn: //g'`;
224.149 + chop($cn);
224.150 + $lst .= "
224.151 + <tr class=$trclass $trjs>
224.152 + <td>$ar[0]</td>
224.153 + <td >$ar[1]</td>
224.154 + <td>$ar[2]</td>
224.155 + <td>$sn</td>
224.156 + <td>$cn</td>
224.157 + <td>$ar[4]</td>
224.158 + <td align=\"center\">$ar[5]</td>
224.159 + <td>$ar[6]</td>
224.160 + <td>$ar[7]</td>
224.161 + </tr>
224.162 + ";
224.163 + }
224.164 +
224.165 + $lst .= "
224.166 + </table>
224.167 + </center>
224.168 + ";
224.169 +
224.170 + print "Content-type: text/html\n\n";
224.171 + &printHeader;
224.172 + print $lst;
224.173 + &printFooter;
224.174 +}
224.175 +
224.176 +sub printHeader {
224.177 +print "
224.178 +<HTML><HEAD>
224.179 +<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">
224.180 +<META HTTP-EQUIV=\"Cache-Control\" CONTENT=\"no-cache\">
224.181 +<META HTTP-EQUIV=\"Expires\" CONTENT=\"-1\">
224.182 +<TITLE>LISTA LOGON</TITLE>
224.183 +<STYLE>
224.184 +<!--
224.185 + TABLE {margin-top: 0; padding-top: 0}
224.186 + TD {font-family: Serif; font-size: 10pt }
224.187 + TH {font-family: Serif; font-size: 12pt }
224.188 +
224.189 + th.surbrillance {
224.190 + background:#FFFF9A;
224.191 + cursor:pointer;
224.192 + }
224.193 + th.normal {
224.194 + background:#C1DCF0;
224.195 + }
224.196 +
224.197 + tr.even {
224.198 + background: #FAFDFF;
224.199 + color: #000;
224.200 + }
224.201 +
224.202 + tr.odd {
224.203 + background: #E1E4E6;
224.204 + color: #000;
224.205 + }
224.206 +
224.207 + tr.surbrillance {
224.208 + background:#FFFF9A;
224.209 + }
224.210 + tr.surbrillance2 {
224.211 + background:#FFFF9A;
224.212 + cursor:pointer;
224.213 + }
224.214 + th.nobrd {
224.215 + background: #C1DCF0;
224.216 + border-bottom: 0px solid #D5A085;
224.217 + border-top: 0px solid #D5A085;
224.218 + border-left: 0px solid #D5A085;
224.219 + border-right: 0px solid #D5A085;
224.220 + text-align: center;
224.221 + }
224.222 +
224.223 +-->
224.224 +</STYLE>
224.225 +
224.226 +</script>
224.227 +
224.228 +</HEAD>
224.229 +<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" vlink=\"#0000ff\"
224.230 +alink=\"#0000ff\">
224.231 +<center>
224.232 +<table width=\"600\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">
224.233 +<tr><th width=\"600\" align=\"center\">
224.234 +<font size=\"4\" color=\"#000000\" face=\"arial\">
224.235 +<hr noshade size=1 width=90%>
224.236 +ACCESSI AL DOMINIO SAMBA: $DOMAIN
224.237 +<hr noshade size=1 width=90%>
224.238 +</th></tr>
224.239 +</table>
224.240 +</center>
224.241 +";
224.242 +
224.243 +}
224.244 +
224.245 +sub printFooter {
224.246 +print "
224.247 +</BODY>
224.248 +</HTML>
224.249 +";
224.250 +}
224.251 +
224.252 +
224.253 +
224.254 +
225.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
225.2 +++ b/usr/lib/isi/acl.conf Mon Apr 26 11:16:23 2010 +0200
225.3 @@ -0,0 +1,98 @@
225.4 +## Ogni modifica a questo file verrà sovrascritta al cambio di release.
225.5 +## modificare invece il file /etc/isi/acl-local.conf
225.6 +
225.7 +## i gruppi principali di default sono:
225.8 +## admins alunni ata docenti esterni ospiti segreteria grtest
225.9 +
225.10 +[alunni]
225.11 + path = /home/users/alunni
225.12 + grp = docenti
225.13 + u: = rxw # ogni permesso al proprietario
225.14 + g:docenti = rxw # il gruppo docenti deve poter fare tutto
225.15 + g:admins = rxw # anche gli admins
225.16 + g:alunni = --- # nessun alunno ha diritti
225.17 + o = --- # nessun altro ha diritto di fare qualche cosa
225.18 + public_html = true
225.19 +
225.20 +
225.21 +[docenti]
225.22 + path = /home/users/docenti
225.23 + grp = docenti
225.24 + u: = rxw # l'utente deve poter fare tutto
225.25 + g: = --- # il gruppo nulla (questo implica che nessun altro
225.26 + # gruppo può per via della risemantizzazione delle
225.27 + # groupship a "upper bound"
225.28 + o = ---
225.29 + public_html = true
225.30 +
225.31 +[ata]
225.32 + path = /home/users/ata
225.33 + grp = ata
225.34 + copy = docenti
225.35 + public_html = true
225.36 +
225.37 +[admins]
225.38 + path = /home/users/admins
225.39 + grp = admins
225.40 + copy = docenti
225.41 + g:admins = --- # gli admins non possono vedere altri admins
225.42 + public_html = true
225.43 +
225.44 +[segreteria]
225.45 + path = /home/users/segreteria
225.46 + grp = segreteria
225.47 + copy = docenti
225.48 + g:segreteria = ---
225.49 +
225.50 +[esterni]
225.51 + path = /home/users/esterni
225.52 + grp = esterni
225.53 + copy = docenti
225.54 + g:esterni = ---
225.55 + public_html = true
225.56 +
225.57 +[ospiti]
225.58 + path = /home/users/ospiti
225.59 + grp = ospiti
225.60 + copy = docenti
225.61 + g:ospiti = --- # gli utenti di ospiti entrano nella propria home
225.62 + public_html = true
225.63 +
225.64 +[classi]
225.65 + path = /home/shares/classi
225.66 + g:docenti = rxw
225.67 + g:admins = rxw
225.68 + g: = rxw # ogni classe deve poter fare tutto in questa area
225.69 +
225.70 +[area_segreteria]
225.71 + path = /home/shares/area_segreteria
225.72 + grp = segreteria
225.73 + g:segreteria = rxw
225.74 + g:alunni = ---
225.75 + o = rx
225.76 +
225.77 +[area_materiali]
225.78 + path = /home/shares/area_materiali
225.79 + g:docenti = rxw
225.80 + g:admins = rxw
225.81 + o = rx
225.82 +
225.83 +[area_docenti]
225.84 + path = /home/shares/area_docenti
225.85 + g:docenti = rxw
225.86 + g:admins = rxw
225.87 + o = ---
225.88 +
225.89 +[area_alunni]
225.90 + path = /home/shares/area_alunni
225.91 + copy = alunni # copia da /home/shares/classi le permission
225.92 + g:alunni = rxw # e modifica questo
225.93 +
225.94 +[post_exec]
225.95 + file = /etc/isi/acl-post-exec.sh
225.96 + ## non modificate la riga seguente se non sapete cosa fate!!!
225.97 + cmd01 = setfacl --set u::7,g::5,o:0 /home/users/*
225.98 + cmd02 = setfacl --set u::7,g::5,o:5 /home/users/alunni /home/shares/classi
225.99 + cmd03 = chmod 600 /root
225.100 + cmd04 = isi-classe -N # no samba
225.101 + cmd05 = isi-classe -C
225.102 \ No newline at end of file
226.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
226.2 +++ b/usr/lib/perl5/ISI/Conf.pm Mon Apr 26 11:16:23 2010 +0200
226.3 @@ -0,0 +1,95 @@
226.4 +# +-------------------------------------------------+
226.5 +# � 2002-2005 ReteIsi / www.reteisi.org
226.6 +# +-------------------------------------------------+
226.7 +# $Id: Conf.pm,v 1.1.1.3 2021/10/09 04:34:58 max Exp $
226.8 +
226.9 +package ISI::Conf;
226.10 +
226.11 +use strict;
226.12 +
226.13 +
226.14 +BEGIN {
226.15 + use Exporter ();
226.16 + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
226.17 +
226.18 + # set the version for version checking
226.19 + # if using RCS/CVS, this may be preferred
226.20 + $VERSION = sprintf "%d.%03d", q$Revision: 1.1.1.3 $ =~ /(\d+)/g;
226.21 +
226.22 + @ISA = qw(Exporter Autoload );
226.23 + @EXPORT = qw(&ReadLdapConf );
226.24 +# @EXPORT_OK = qw(%LdapConf);
226.25 +
226.26 +}
226.27 +# our @EXPORT_OK;
226.28 +# our %LdapConf;
226.29 +# %LdapConf = ();
226.30 +
226.31 +sub ReadLdapConf () {
226.32 + # this function fills the hash %LdapConf w/ parameters needed for
226.33 + # normal interaction w/ the LDAP db
226.34 + # base:
226.35 + # root_bind_dn
226.36 + # slapd_pwd
226.37 + # host
226.38 + my %LdapConf=();
226.39 +
226.40 + open CONF, "/etc/ldap/ldap.conf";
226.41 + while (<CONF>) {
226.42 + if ($_ =~ m/^\s*BASE\s*(\S+)/) {
226.43 + $LdapConf{'BASE'} = $1;
226.44 + }
226.45 + if ($_ =~ m/^\s*HOST\s*(\S+)/) {
226.46 + $LdapConf{'HOST'} = $1;
226.47 + }
226.48 + }
226.49 + close CONF;
226.50 + open CONF, "/etc/pam_ldap.conf";
226.51 + while (<CONF>) {
226.52 + if ($_ =~ m/^\s*rootbinddn\s*(\S+)/) {
226.53 + $LdapConf{'ROOT_BIND_DN'} = $1;
226.54 + }
226.55 + }
226.56 + close CONF;
226.57 +
226.58 + $LdapConf{'PWD'} = `cat /etc/ldap.secret`;
226.59 + chomp $LdapConf{'PWD'};
226.60 +
226.61 + return %LdapConf;
226.62 +}
226.63 +sub ReadFile {
226.64 + my $file = $_[0];
226.65 + my $delimiter="=";
226.66 + my %assoc_array;
226.67 + my $current_line;
226.68 + my @righe;
226.69 + my $riga;
226.70 + my @kv;
226.71 +
226.72 + if ( -T $file) {
226.73 + if(!open(CONF,"<$file")) {
226.74 + return -1;
226.75 + }
226.76 + } else {
226.77 + #print "Inexistent file: $file\n" ;
226.78 + return 0 ;
226.79 + }
226.80 +
226.81 + @righe=<CONF>;
226.82 + foreach $riga (@righe) {
226.83 + chop($riga);
226.84 + @kv=split(/=/,$riga);
226.85 + next if (!$kv[1]);
226.86 + $kv[0]=~s/ //g ;
226.87 + $kv[1]=~s/\"//g ;
226.88 + if ( $kv[0] ne "") {
226.89 + $assoc_array{$kv[0]}=$kv[1];
226.90 + }
226.91 + }
226.92 + close(CONF);
226.93 + return %assoc_array;
226.94 +}
226.95 +
226.96 +
226.97 +1;
226.98 +
227.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
227.2 +++ b/usr/lib/perl5/ISI/MkPasswd.pm Mon Apr 26 11:16:23 2010 +0200
227.3 @@ -0,0 +1,315 @@
227.4 +package ISI::MkPasswd;
227.5 +
227.6 +use 5.006001;
227.7 +use strict;
227.8 +use base qw(Exporter);
227.9 +
227.10 +use Carp qw(croak);
227.11 +
227.12 +# Defaults.
227.13 +use constant LENGTH => 8;
227.14 +use constant MINNUM => 1;
227.15 +use constant MINLOWER => 2;
227.16 +use constant MINUPPER => 2;
227.17 +use constant MINSPECIAL => 0;
227.18 +use constant DISTRIBUTE => "";
227.19 +use constant FATAL => "";
227.20 +
227.21 +our %EXPORT_TAGS = (
227.22 + all => [ qw(mkpasswd) ],
227.23 +);
227.24 +our @EXPORT_OK = @{ $EXPORT_TAGS{all} };
227.25 +our $VERSION = "0.02";
227.26 +our $FATAL = "";
227.27 +
227.28 +my %keys = (
227.29 + dist => {
227.30 + lkeys => [ qw(q w e r t a s d f g z x c v b) ],
227.31 + rkeys => [ qw(y u i o p h j k l n m) ],
227.32 + lnums => [ qw(1 2 3 4 5 6) ],
227.33 + rnums => [ qw(7 8 9 0) ],
227.34 + lspec => [ qw(! @ $ %), "#" ],
227.35 + rspec => [
227.36 + qw(^ & * ( ) - = _ + [ ] { } \ | ; : ' " < > . ? /), ","
227.37 + ],
227.38 + },
227.39 +
227.40 + undist => {
227.41 + lkeys => [
227.42 + qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)
227.43 + ],
227.44 + rkeys => [
227.45 + qw(a b c d e f g h i j k l m n o p q r s t u v w x y z)
227.46 + ],
227.47 + lnums => [ qw(0 1 2 3 4 5 6 7 8 9) ],
227.48 + rnums => [ qw(0 1 2 3 4 5 6 7 8 9) ],
227.49 + lspec => [
227.50 + qw(! @ $ % ~ ^ & * ( ) - = _ + [ ] { } \ | ; : ' " < > . ? /),
227.51 + "#", ","
227.52 + ],
227.53 + rspec => [
227.54 + qw(! @ $ % ~ ^ & * ( ) - = _ + [ ] { } \ | ; : ' " < > . ? /),
227.55 + "#", ","
227.56 + ],
227.57 + },
227.58 +);
227.59 +
227.60 +sub mkpasswd {
227.61 + my $class = shift if UNIVERSAL::isa $_[0], __PACKAGE__;
227.62 + my %args = @_;
227.63 +
227.64 + # Configuration.
227.65 + my $length = defined $args{"-length"}
227.66 + ? $args{"-length"}
227.67 + : LENGTH;
227.68 + my $minnum = defined $args{"-minnum"}
227.69 + ? $args{"-minnum"}
227.70 + : MINNUM;
227.71 + my $minlower = defined $args{"-minlower"}
227.72 + ? $args{"-minlower"}
227.73 + : MINLOWER;
227.74 + my $minupper = defined $args{"-minupper"}
227.75 + ? $args{"-minupper"}
227.76 + : MINUPPER;
227.77 + my $minspecial = defined $args{"-minspecial"}
227.78 + ? $args{"-minspecial"}
227.79 + : MINSPECIAL;
227.80 + my $distribute = defined $args{"-distribute"}
227.81 + ? $args{"-distribute"}
227.82 + : DISTRIBUTE;
227.83 + my $fatal = defined $args{"-fatal"}
227.84 + ? $args{"-fatal"}
227.85 + : FATAL;
227.86 +
227.87 + ++$length;
227.88 +
227.89 + if ( $minnum + $minlower + $minupper + $minspecial > $length ) {
227.90 + if ( $fatal || $FATAL ) {
227.91 + croak "Impossible to generate $length-character password with "
227.92 + . "$minnum numbers, $minlower lowercase letters, "
227.93 + . "$minupper uppercase letters and $minspecial special "
227.94 + . "characters";
227.95 + } else {
227.96 + return;
227.97 + }
227.98 + }
227.99 +
227.100 + # If there is any underspecification, use additional lowercase letters.
227.101 + $minlower = $length - ($minnum + $minupper + $minspecial);
227.102 +
227.103 + # Choose left or right starting hand.
227.104 + my $initially_left = my $isleft = int rand 2;
227.105 +
227.106 + # Select distribution of keys.
227.107 + my $lkeys = $distribute ? $keys{dist}{lkeys} : $keys{undist}{lkeys};
227.108 + my $rkeys = $distribute ? $keys{dist}{rkeys} : $keys{undist}{rkeys};
227.109 + my $lnums = $distribute ? $keys{dist}{lnums} : $keys{undist}{lnums};
227.110 + my $rnums = $distribute ? $keys{dist}{rnums} : $keys{undist}{rnums};
227.111 + my $lspec = $distribute ? $keys{dist}{lspec} : $keys{undist}{lspec};
227.112 + my $rspec = $distribute ? $keys{dist}{rspec} : $keys{undist}{rspec};
227.113 +
227.114 + # Generate password.
227.115 +
227.116 + my @lpass = (undef) x $length; # password chars typed by left hand
227.117 + my @rpass = (undef) x $length; # password chars typed by right hand
227.118 + my ($left, $right);
227.119 +
227.120 + ($left, $right) = &_psplit($minnum, \$isleft);
227.121 + for ( my $i = 0; $i < $left; $i++ ) {
227.122 + &_insert(\@lpass, $lnums->[rand @$lnums]);
227.123 + }
227.124 + for ( my $i = 0; $i < $right; $i++ ) {
227.125 + &_insert(\@rpass, $rnums->[rand @$rnums]);
227.126 + }
227.127 +
227.128 + ($left, $right) = &_psplit($minlower, \$isleft);
227.129 + for ( my $i = 0; $i < $left; $i++ ) {
227.130 + &_insert(\@lpass, $lkeys->[rand @$lkeys]);
227.131 + }
227.132 + for ( my $i = 0; $i < $right; $i++ ) {
227.133 + &_insert(\@rpass, $rkeys->[rand @$rkeys]);
227.134 + }
227.135 +
227.136 + ($left, $right) = &_psplit($minupper, \$isleft);
227.137 + for ( my $i = 0; $i < $left; $i++ ) {
227.138 + &_insert(\@lpass, uc $lkeys->[rand @$lkeys]);
227.139 + }
227.140 + for ( my $i = 0; $i < $right; $i++ ) {
227.141 + &_insert(\@rpass, uc $rkeys->[rand @$rkeys]);
227.142 + }
227.143 +
227.144 + ($left, $right) = &_psplit($minspecial, \$isleft);
227.145 + for ( my $i = 0; $i < $left; $i++ ) {
227.146 + &_insert(\@lpass, $lspec->[rand @$lspec]);
227.147 + }
227.148 + for ( my $i = 0; $i < $right; $i++ ) {
227.149 + &_insert(\@rpass, $rspec->[rand @$rspec]);
227.150 + }
227.151 +
227.152 + # Merge results together.
227.153 + my $lpass = join "", map { defined $_ ? $_ : () } @lpass;
227.154 + my $rpass = join "", map { defined $_ ? $_ : () } @rpass;
227.155 +
227.156 + return $initially_left ? "$lpass$rpass" : "$rpass$lpass";
227.157 +}
227.158 +
227.159 +# Insert $char into password at a random position, thereby spreading the
227.160 +# different kinds of characters throughout the password.
227.161 +sub _insert {
227.162 + my $pass = shift; # ref = ARRAY
227.163 + my $char = shift;
227.164 +
227.165 + my $pos;
227.166 + do {
227.167 + $pos = int rand(1 + @$pass);
227.168 + } while ( defined $pass->[$pos] );
227.169 +
227.170 + $pass->[$pos] = $char;
227.171 +}
227.172 +
227.173 +# Given a size, distribute between left and right hands, taking into account
227.174 +# where we left off.
227.175 +sub _psplit {
227.176 + my $max = shift;
227.177 + my $isleft = shift; # ref = SCALAR
227.178 +
227.179 + my ($left, $right);
227.180 +
227.181 + if ( $$isleft ) {
227.182 + $right = int($max / 2);
227.183 + $left = $max - $right;
227.184 + $$isleft = !($max % 2);
227.185 + } else {
227.186 + $left = int($max / 2);
227.187 + $right = $max - $left;
227.188 + $$isleft = !($max % 2);
227.189 + }
227.190 +
227.191 + return ($left, $right);
227.192 +}
227.193 +
227.194 +1;
227.195 +
227.196 +__END__
227.197 +
227.198 +=head1 NAME
227.199 +
227.200 +String::MkPasswd - random password generator
227.201 +
227.202 +=head1 SYNOPSIS
227.203 +
227.204 + use String::MkPasswd qw(mkpasswd);
227.205 +
227.206 + print mkpasswd();
227.207 +
227.208 + # for the masochisticly paranoid...
227.209 + print mkpasswd(
227.210 + -length => 27,
227.211 + -minnum => 5,
227.212 + -minlower => 1, # minlower is increased if necessary
227.213 + -minupper => 5,
227.214 + -minspecial => 5,
227.215 + -distribute => 1,
227.216 + );
227.217 +
227.218 +=head1 ABSTRACT
227.219 +
227.220 +This Perl library defines a single function, C<mkpasswd()>, to generate
227.221 +random passwords. The function is meant to be a simple way for
227.222 +developers and system administrators to easily generate a relatively
227.223 +secure password.
227.224 +
227.225 +=head1 DESCRIPTION
227.226 +
227.227 +The exportable C<mkpasswd()> function returns a single scalar: a random
227.228 +password. By default, this password is nine characters long with a
227.229 +random distribution of four lower-case characters, two upper-case
227.230 +characters, two digits, and one non-alphanumeric character. These
227.231 +parameters can be tuned by the user, as described in the L</"ARGUMENTS">
227.232 +section.
227.233 +
227.234 +=head2 ARGUMENTS
227.235 +
227.236 +The C<mkpasswd()> function takes an optional hash of arguments.
227.237 +
227.238 +=over 4
227.239 +
227.240 +=item -length
227.241 +
227.242 +The total length of the password. The default is 9.
227.243 +
227.244 +=item -minnum
227.245 +
227.246 +The minimum number of digits that will appear in the final password.
227.247 +The default is 2.
227.248 +
227.249 +=item -minlower
227.250 +
227.251 +The minimum number of lower-case characters that will appear in the
227.252 +final password. The default is 2.
227.253 +
227.254 +=item -minupper
227.255 +
227.256 +The minimum number of upper-case characters that will appear in the
227.257 +final password. The default is 2.
227.258 +
227.259 +=item -minspecial
227.260 +
227.261 +The minimum number of non-alphanumeric characters that will appear in
227.262 +the final password. The default is 1.
227.263 +
227.264 +=item -distribute
227.265 +
227.266 +If set to a true value, password characters will be distributed between
227.267 +the left- and right-hand sides of the keyboard. This makes it more
227.268 +difficult for an onlooker to see the password as it is typed. The
227.269 +default is false.
227.270 +
227.271 +=item -fatal
227.272 +
227.273 +If set to a true value, C<mkpasswd()> will L<Carp::croak()> rather than
227.274 +return C<undef> on error. The default is false.
227.275 +
227.276 +=back
227.277 +
227.278 +If B<-minnum>, B<-minlower>, B<-minupper>, and B<-minspecial> do not add
227.279 +up to B<-length>, B<-minlower> will be increased to compensate.
227.280 +However, if B<-minnum>, B<-minlower>, B<-minupper>, and B<-minspecial>
227.281 +add up to more than B<-length>, then C<mkpasswd()> will return C<undef>.
227.282 +See the section entitled L</"EXCEPTION HANDLING"> for how to change this
227.283 +behavior.
227.284 +
227.285 +=head2 EXCEPTION HANDLING
227.286 +
227.287 +By default, C<mkpasswd()> will return C<undef> if it cannot generate a
227.288 +password. Some people are inclined to exception handling, so
227.289 +B<String::MkPasswd> does its best to accomodate them. If the variable
227.290 +C<$String::MkPasswd::FATAL> is set to a true value, C<mkpasswd()> will
227.291 +L<Carp::croak()> with an error instead of returning C<undef>.
227.292 +
227.293 +=head2 EXPORT
227.294 +
227.295 +None by default. The C<mkpasswd()> method is exportable.
227.296 +
227.297 +=head1 SEE ALSO
227.298 +
227.299 +L<http://expect.nist.gov/#examples>, L<mkpasswd(1)>
227.300 +
227.301 +=head1 AKNOWLEDGEMENTS
227.302 +
227.303 +Don Libes of the National Institute of Standards and Technology, who
227.304 +wrote the Expect example, L<mkpasswd(1)>.
227.305 +
227.306 +=head1 AUTHOR
227.307 +
227.308 +Chris Grau E<lt>[email protected]<gt>
227.309 +
227.310 +=head1 COPYRIGHT AND LICENSE
227.311 +
227.312 +Copyright (C) 2003-2004 by Chris Grau
227.313 +
227.314 +This library is free software; you can redistribute it and/or modify it
227.315 +under the same terms as Perl itself, either Perl version 5.8.1 or, at
227.316 +your option, any later version of Perl 5 you may have available.
227.317 +
227.318 +=cut
228.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
228.2 +++ b/usr/lib/perl5/ISI/User.pm Mon Apr 26 11:16:23 2010 +0200
228.3 @@ -0,0 +1,152 @@
228.4 +# +-------------------------------------------------+
228.5 +# � 2002-2005 ReteIsi / www.reteisi.org
228.6 +# +-------------------------------------------------+
228.7 +# $Id: User.pm,v 1.1.1.3 2021/10/09 04:34:58 max Exp $
228.8 +
228.9 +package ISI::User;
228.10 +use Net::LDAP;
228.11 +use ISI::Conf;
228.12 +
228.13 +use strict;
228.14 +
228.15 +BEGIN {
228.16 + use Exporter ();
228.17 + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
228.18 +
228.19 + # set the version for version checking
228.20 + # if using RCS/CVS, this may be preferred
228.21 + $VERSION = sprintf "%d.%03d", q$Revision: 1.1.1.3 $ =~ /(\d+)/g;
228.22 +
228.23 + @ISA = qw(Exporter Autoload ISI::Conf Net::LDAP);
228.24 + @EXPORT = qw(&FindUser &Bind);
228.25 +
228.26 +}
228.27 +
228.28 +my %CONF = &ReadLdapConf();
228.29 +my $ldap;
228.30 +
228.31 +sub Bind() {
228.32 + my $ris;
228.33 +
228.34 + $ldap = Net::LDAP->new($CONF{'HOST'},
228.35 + port => 389,
228.36 + version => 3,
228.37 + timeout => 60)
228.38 + or die "ERRORE LDAP: non riesco a contattare il server ($@)";
228.39 +
228.40 + $ris = $ldap->bind($CONF{'ROOT_BIND_DN'}, password=>$CONF{'PWD'});
228.41 +
228.42 + if ( $ris->is_error ) {
228.43 + print STDERR "ERRORE LDAP: bind autenticato non riuscito\n";
228.44 + exit;
228.45 + }
228.46 + return $ris;
228.47 +}
228.48 +
228.49 +sub FindUser {
228.50 + # trova l'utente dato lo UID
228.51 + my $str = shift;
228.52 + my $campi = shift;
228.53 + my $txt ;
228.54 + my @fields;
228.55 + my $a;
228.56 + my $ris;
228.57 + my @info;
228.58 + my $filter = "(&(uid=$str)(objectClass=posixAccount))";
228.59 + if (defined($campi) ) {
228.60 + @fields = split /[,\s]/, $campi;
228.61 + } else {
228.62 + @fields = ('cn');
228.63 + }
228.64 + ## creaiamo una referenza perche' non possiamo mettere un array in
228.65 + ## uno hash (valore della chiave attrs)
228.66 + $a = \@fields ;
228.67 + $ris = $ldap->search(
228.68 + filter => $filter,
228.69 + base => $CONF{'BASE'},
228.70 + attrs => $a);
228.71 + @info = $ris->entries;
228.72 + $txt = "";
228.73 + foreach my $entry (@info) {
228.74 + foreach my $at (@fields) {
228.75 + $txt .= $entry->get_value($at)."\n";
228.76 + }
228.77 + }
228.78 + return $txt;
228.79 +}
228.80 +
228.81 +
228.82 +sub SearchUser {
228.83 + #trova l'utente in base a una condizione di filtro
228.84 + #il primo campo passato e' la chiave della risposta
228.85 + my $flt = shift;
228.86 + my $campi = shift;
228.87 + my $txt;
228.88 + my @fields;
228.89 + my $a;
228.90 + my $ris;
228.91 + my @info;
228.92 + my $filter = "(&($flt)(objectClass=posixAccount))";
228.93 + if (defined($campi) ) {
228.94 + @fields = split /[,\s]/, $campi;
228.95 + } else {
228.96 + @fields = ('cn');
228.97 + }
228.98 + ## creaiamo una referenza perche' non possiamo mettere un array in
228.99 + ## uno hash (valore della chiave attrs)
228.100 + $a = \@fields ;
228.101 + $ris = $ldap->search(
228.102 + filter => $filter,
228.103 + base => $CONF{'BASE'},
228.104 + attrs => $a);
228.105 + @info = $ris->entries;
228.106 + $txt = "";
228.107 + foreach my $entry (@info) {
228.108 + foreach my $at (@fields) {
228.109 + $txt .= $entry->get_value($at)."\n";
228.110 + }
228.111 + }
228.112 + return $txt;
228.113 +}
228.114 +
228.115 +sub SearchGroup {
228.116 + #trova l'utente in base a una condizione di filtro
228.117 + #il primo campo passato e' la chiave della risposta
228.118 + my $flt = shift;
228.119 + my $campi = shift;
228.120 + my $txt;
228.121 + my @fields;
228.122 + my $a;
228.123 + my $ris;
228.124 + my @info;
228.125 + my $filter = "(&($flt)(objectClass=posixGroup))";
228.126 +
228.127 + if (defined($campi) ) {
228.128 + @fields = split /[,\s]/, $campi;
228.129 + } else {
228.130 + @fields = ('cn'); my $ldap;
228.131 +
228.132 + }
228.133 + ## creaiamo una referenza perche' non possiamo mettere un array in
228.134 + ## uno hash (valore della chiave attrs)
228.135 + $a = \@fields ;
228.136 + $ris = $ldap->search(
228.137 + filter => $filter,
228.138 + base => $CONF{'BASE'},
228.139 + attrs => $a);
228.140 + @info = $ris->entries;
228.141 + $txt = "";
228.142 + foreach my $entry (@info) {
228.143 + foreach my $at (@fields) {
228.144 + $txt .= $entry->get_value($at)."\n";
228.145 + }
228.146 + }
228.147 + return $txt;
228.148 +}
228.149 +
228.150 +1;
228.151 +
228.152 +
228.153 +
228.154 +
228.155 +
229.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
229.2 +++ b/usr/sbin/isi-addgroup Mon Apr 26 11:16:23 2010 +0200
229.3 @@ -0,0 +1,52 @@
229.4 +#!/usr/bin/python
229.5 +# -*- coding: utf-8 -*-
229.6 +
229.7 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
229.8 +#
229.9 +# This program is free software: you can redistribute it and/or modify
229.10 +# it under the terms of the GNU General Public License as published by
229.11 +# the Free Software Foundation, either version 3 of the License, or
229.12 +# (at your option) any later version.
229.13 +#
229.14 +# This program is distributed in the hope that it will be useful,
229.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
229.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
229.17 +# GNU General Public License for more details.
229.18 +#
229.19 +# You should have received a copy of the GNU General Public License
229.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
229.21 +
229.22 +
229.23 +"""
229.24 +Adds a group to ldap system
229.25 +
229.26 + usage: %prog [options] group_name
229.27 + -g, --gid=GID: set gid GID
229.28 + -v, --verbose: be verbose
229.29 + -q, --quiet: be quiet if it already exists (exit with 0)
229.30 + -s, --system: add an ldap system group, possibly same gid as existent
229.31 +"""
229.32 +
229.33 +import isi
229.34 +import sys
229.35 +import re
229.36 +from dry import optionparse
229.37 +from isi.models import PosixGroup
229.38 +
229.39 +#### PROGRAM
229.40 +opts, args = optionparse.parse(__doc__)
229.41 +
229.42 +l = isi.Manager()
229.43 +
229.44 +
229.45 +for group_name in args:
229.46 + try:
229.47 + l.add_group(group_name, quiet=opts.quiet, system=opts.system)
229.48 + except Exception:
229.49 + print "Already existing group '%s'" % l.get_group(group_name)
229.50 +
229.51 +sys.exit(0)
229.52 +
229.53 +
229.54 +
229.55 +
230.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
230.2 +++ b/usr/sbin/isi-adduser Mon Apr 26 11:16:23 2010 +0200
230.3 @@ -0,0 +1,265 @@
230.4 +#!/usr/bin/python
230.5 +# -*- coding: utf-8 -*-
230.6 +
230.7 +# This program is free software; you can redistribute it and/or modify
230.8 +# it under the terms of the GNU General Public License as published by
230.9 +# the Free Software Foundation; either version 2, or (at your option)
230.10 +# any later version.
230.11 +
230.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
230.13 +
230.14 +"""
230.15 +Utility per aggiugere utenti. Puo' essere usata sia interattivamente sia in
230.16 +modo script leggendo da file (opzione -f) che passando la definizione dell'
230.17 +alunno da riga di comando.
230.18 +
230.19 +Il formato della riga deve essere almeno:
230.20 +
230.21 + logname;cognome;nome;gruppo_principale;classe;CF;password
230.22 +
230.23 +possono essere accodati altri campi rispettando il seguente formato:
230.24 +
230.25 + sesso;indirizzo;cap;comune;provincia;telefono
230.26 +
230.27 +ogni campo puo' essere vuoto tranne logname e gruppo principale
230.28 +la classe ha senso per alunni ed esterni e verra' usata per connettere la risorsa
230.29 +Viene memorizzata in ldap come departmentNumber
230.30 +
230.31 +ATTENZIONE: se logname inizia con un - (meno) l'utente viene cancellato, in questo
230.32 +caso l'opzione -z elimina la home dell'utente eliminato che altrimenti verra'
230.33 +semplicemente targizzata
230.34 +
230.35 +La forma [isi-adduser user gruppo] aggiunge l'utente al gruppo
230.36 +
230.37 + usage: %prog [options] [ -f file_name ]
230.38 + -N, --dry-run: non tocca il db ldap o il filesystem
230.39 + -d, --debug: Mostra i comandi mentre li esegue
230.40 + -B, --force-change-passwd: forza cambio password all'accesso
230.41 + -f, --file=FILE: legge gli utenti da file (record standard)
230.42 + -F, --file-extended: legge gli utenti da file (record esteso)
230.43 + -v, --verbose: aumenta i messaggi
230.44 + -i, --interactive: modo interattivo (default se manca file)
230.45 + -I, --interactive-extended: modo interattivo con dati estesi
230.46 + -s, --string=str-definition: usa str-definition come definizione alunno
230.47 + -t, --test=str-def: come -s ma basta logname;gruppo;pwd
230.48 + -S, --show-conf: mostra la configurazione
230.49 + -x, --no-filesystem: non crea le cartelle
230.50 + -H, --home=host: crea home dir su host1,2 (necessita ssh con chiave)
230.51 + -c, --check: controlla se gli utenti sono tutti da aggiungere (opt di -f)
230.52 + -p, --default-passwd=xx: imposta la password di default
230.53 + -P, --passwd-random=pwd_lenght: password casuale di lunghezza pwd_lenght (min.5)
230.54 + -u, --update-user: gli utenti riconosciuti come esistenti saranno aggiornati. Non tocca la password
230.55 + -U, --update-passwd: come -u ma con aggiornamento della password
230.56 + -z, --home-zap: elimina le homedirs degli utenti cancellati
230.57 + -L, --noalulink: NON esegue isi-alulink dopo l'inserimento degli alunni
230.58 + -C, --use-cf: password costruita da cf (primi 8 caratteru, prima lettera maiuscola, come -p _cf)
230.59 + -T, --test-mode: running tests - don't backup (go faster)
230.60 + -Z, --non-interactive: non chiedere nulla, fai e basta (quindi crea le classi...)
230.61 +
230.62 +NOTA: se il campo password contiene PASSWORD, la password non viene gestita.
230.63 +"""
230.64 +
230.65 +import isi
230.66 +import sys
230.67 +import re
230.68 +import pexpect
230.69 +from dry import optionparse
230.70 +from dry.functions import execute, ExecuteError
230.71 +from isi.filesystem import show_file
230.72 +from isi import srv, exc, parser
230.73 +from isi.conf import defaults
230.74 +
230.75 +MSG_ERR01 = "ERRORE: gli utenti del gruppo %s devono essere membri di %s\n%s come primo elemento del campo GRUPPI"
230.76 +
230.77 +# TODO: ma siamo certi che IsiUserAdd serva?
230.78 +class IsiUserAdd(isi.Manager):
230.79 + """ check all the group in one shot before starting. """
230.80 +
230.81 + def check_groups_and_add(self, groups):
230.82 + """to be overloaded by isi-adduser for efficency """
230.83 + pass
230.84 +
230.85 +def test2string(test):
230.86 + logname, main_group, pwd = [x.strip() for x in re.split('[;,]', test)]
230.87 + main_group = srv.maingroup_byprefix(logname)
230.88 + return "%s;%s;%s;%s;;cf;%s" % (logname, main_group.title(), logname,
230.89 + main_group, pwd)
230.90 +
230.91 +def go_interactive(isi_user):
230.92 + """prompt for interactive input of users to add"""
230.93 +
230.94 + print "-"*70
230.95 + print "ISI-ADDUSER-MODO INTERATTIVO: user_ID vuoto = FINE\nAl posto dello USER_ID, puoi scrivere una stringa unica nel formato std:"
230.96 + if opts.interactive_extended:
230.97 + print "userID;cogn;nome;gruppo;gruppi;cf;pwd;sesso;indir;comune;cap;prov;tel"
230.98 + interactive_attrs = defaults.DATI_USER.split()
230.99 + else:
230.100 + print "userID;cognome;nome;gruppo;gruppi;cf;passwd\n"
230.101 + interactive_attrs = defaults.DATI_USER.split()[:7]
230.102 + print "-"*70
230.103 +
230.104 + data = []
230.105 + system_main_groups = srv.get_main_groups()
230.106 + for att in interactive_attrs:
230.107 + valdef = delim1 = delim2 = ""
230.108 + if att == 'GRUPPO':
230.109 + valdef = main_group
230.110 + delim1 = ' ['
230.111 + delim2 = ']'
230.112 +
230.113 + if att == 'PASSWORD':
230.114 + valdef = parser.new_password()
230.115 + delim1 = ' ['
230.116 + delim2 = ']'
230.117 +
230.118 + while True:
230.119 + returned_input = raw_input("%-20s:" % (att + delim1 + valdef + delim2))
230.120 + ## logname may be a string to split
230.121 + if len(re.split(";", returned_input)) > 1:
230.122 + return returned_input
230.123 + else:
230.124 + if att == 'USER_ID':
230.125 + if not returned_input:
230.126 + return None
230.127 + elif isi_user.user_exists(returned_input):
230.128 + print "ERRORE: utente esistente"
230.129 + continue
230.130 + main_group = srv.maingroup_byprefix(returned_input)
230.131 + elif att == 'GRUPPO':
230.132 + if returned_input=='':
230.133 + returned_input = valdef
230.134 + elif returned_input not in system_main_groups:
230.135 + print "ERRORE: il gruppo principale dichiarato non esiste"
230.136 + continue
230.137 +
230.138 + elif att == 'GRUPPI' and data[3] in 'alunni esterni':
230.139 + if main_group == 'alunni':
230.140 + xx = ('alunni','una classe', 'dichiarata')
230.141 + else:
230.142 + xx = ('esterni','un corso', 'dichiarato')
230.143 + if returned_input=='':
230.144 + print MSG_ERR01 % xx
230.145 + continue
230.146 +
230.147 + elif att == 'PASSWORD' and returned_input=='':
230.148 + returned_input = valdef
230.149 +
230.150 + data += [returned_input]
230.151 + break
230.152 +
230.153 + return ';'.join(data)
230.154 +
230.155 +# def check_alulink(s):
230.156 +# if opts.noalulink: return
230.157 +# ss = s.split(';')
230.158 +# if ss[3] in ('alunni', 'esterni'):
230.159 +# classe = ss[4].split(',')[0]
230.160 +# if not classe in classi:
230.161 +# classi.append(classe)
230.162 +
230.163 +def handle_exceptions(e):
230.164 +
230.165 + import traceback
230.166 +
230.167 + if isinstance(e, exc.MissingMainGroup):
230.168 + if e.user:
230.169 + print "Missing Maingroup: '%s' while defining user '%s' (%s)" % (
230.170 + e.maingroup, e.user.logname, e.user.full_name)
230.171 + else:
230.172 + if not e.maingroup:
230.173 + print "Maingroup non definito: probabili problemi di formato file input"
230.174 + else:
230.175 + print "Missing Maingroup: '%s' " % (e.maingroup, )
230.176 + sys.exit(1)
230.177 + if isinstance(e, exc.AlreadyExistingUser):
230.178 + print "User '%s' si already defined" % e.logname
230.179 + sys.exit(1)
230.180 +
230.181 + traceback.print_exc()
230.182 + sys.exit(1)
230.183 +
230.184 +
230.185 +#### PROGRAM
230.186 +logger = isi.get_logger()
230.187 +logger.debug("Si comincia...")
230.188 +opts, args = optionparse.parse(__doc__)
230.189 +
230.190 +if opts.home:
230.191 + l.sambaHome = opts.home
230.192 +
230.193 +if opts.file_extended:
230.194 + opts.file = opts.file_extended
230.195 +
230.196 +if opts.update_passwd:
230.197 + ## update_passwd implies update_user
230.198 + opts.update_user = True
230.199 +
230.200 +conn = isi.IsiConn(dry_run=opts.dry_run)
230.201 +
230.202 +if opts.test_mode:
230.203 + conn.tests_running = True
230.204 +
230.205 +if opts.file:
230.206 + l = IsiUserAdd(conn, verbose=opts.verbose)
230.207 +else:
230.208 + l = isi.Manager(conn, verbose=opts.verbose)
230.209 +
230.210 +### implement isi-adduser user group
230.211 +if len(args) == 2:
230.212 + user_name, group_name = args
230.213 + print "Aggiungo utente al gruppo", group_name
230.214 + try:
230.215 + group = l.get_group(group_name)
230.216 + except MissingMatch:
230.217 + print "Il gruppo '%s' non esiste" % group_name
230.218 + sys,exit(1)
230.219 +
230.220 +
230.221 + group.add_member(user_name)
230.222 + execute('nscd -i group')
230.223 + sys.exit()
230.224 +
230.225 +if opts.show_conf:
230.226 + conn.show_conf()
230.227 + sys.exit(0)
230.228 +
230.229 +
230.230 +conn.backup()
230.231 +
230.232 +kw = {
230.233 + 'no_filesystem' : opts.no_filesystem,
230.234 + 'update_user' : opts.update_user,
230.235 + 'update_passwd' : opts.update_passwd,
230.236 + 'home_mode' : 'tar' if not opts.home_zap else 'rm' ,
230.237 + 'force_passwd_change' : opts.force_change_passwd,
230.238 + 'default_passwd' : opts.default_passwd,
230.239 + 'use_cf' : opts.use_cf,
230.240 + 'passwd_random' : opts.passwd_random,
230.241 + 'run_alulink' : not opts.noalulink,
230.242 + }
230.243 +## check args
230.244 +if not args:
230.245 + if opts.test:
230.246 + logger.debug(test2string(opts.test))
230.247 + opts.string = test2string(opts.test)
230.248 +
230.249 + if opts.string:
230.250 + try:
230.251 + l.parse_user_definition_string(opts.string, interactive=not opts.non_interactive, **kw)
230.252 + except Exception, e:
230.253 + handle_exceptions(e)
230.254 +
230.255 +if opts.interactive or opts.interactive_extended:
230.256 + l.parse_user_definition_string(go_interactive(l),interactive=True, **kw)
230.257 +
230.258 +# read file
230.259 +if opts.file:
230.260 + try:
230.261 + l.read_file(opts.file, interactive=not opts.non_interactive, **kw)
230.262 + except Exception, e:
230.263 + handle_exceptions(e)
230.264 +
230.265 +
230.266 +
230.267 +sys.exit(0)
230.268 +
231.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
231.2 +++ b/usr/sbin/isi-alulink Mon Apr 26 11:16:23 2010 +0200
231.3 @@ -0,0 +1,44 @@
231.4 +#!/usr/bin/python
231.5 +# -*- coding: utf-8 -*-
231.6 +
231.7 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
231.8 +#
231.9 +# This program is free software: you can redistribute it and/or modify
231.10 +# it under the terms of the GNU General Public License as published by
231.11 +# the Free Software Foundation, either version 3 of the License, or
231.12 +# (at your option) any later version.
231.13 +#
231.14 +# This program is distributed in the hope that it will be useful,
231.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
231.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
231.17 +# GNU General Public License for more details.
231.18 +#
231.19 +# You should have received a copy of the GNU General Public License
231.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
231.21 +
231.22 +
231.23 +
231.24 +u"""
231.25 +Crea per ogni classe i link agli studenti. I link hanno sia il logname che il
231.26 +nome/cognome completo per rendere facile capire chi siano.
231.27 +
231.28 + usage: %prog [options] class | course
231.29 +"""
231.30 +
231.31 +import sys
231.32 +from isi import srv
231.33 +from dry import optionparse
231.34 +from isi import filesystem, Manager
231.35 +
231.36 +
231.37 +#### PROGRAM
231.38 +opts, args = optionparse.parse(__doc__)
231.39 +
231.40 +
231.41 +if not args:
231.42 + args = srv.get_classes() + srv.get_courses()
231.43 +
231.44 +filesystem.create_alulink(args, manager=Manager() )
231.45 +
231.46 +sys.exit(0)
231.47 +
232.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
232.2 +++ b/usr/sbin/isi-area Mon Apr 26 11:16:23 2010 +0200
232.3 @@ -0,0 +1,133 @@
232.4 +#!/bin/bash
232.5 +# +-------------------------------------------------+
232.6 +# (C) 2002-2008 ReteIsi / www.reteisi.org
232.7 +# +-------------------------------------------------+
232.8 +# This program is free software; you can redistribute it and/or modify
232.9 +# it under the terms of the GNU General Public License as published by
232.10 +# the Free Software Foundation; either version 2, or (at your option)
232.11 +# any later version.
232.12 +# AUTORE: Massimo Mancini 2008 - [email protected]
232.13 +
232.14 +####### FUNCTIONS
232.15 +function help () {
232.16 +cat << FINE
232.17 +Comando: `basename $0`
232.18 +
232.19 +Sintassi: `basename $0` [ -h ] area gruppo
232.20 +
232.21 +Descrizione: Crea un'area condivisa:
232.22 +
232.23 + 1. la cartella /home/shares/area
232.24 + 2. di proprietà del gruppo <gruppo>
232.25 + 3. la share di area (se già non esiste in
232.26 + /etc/isi/samba/smb_aree.conf)
232.27 +
232.28 +Opzioni: -h help (Questa pagina di manuale)
232.29 + -p NON applica le acl
232.30 + -N non fa reload samba
232.31 + -v verboso
232.32 +FINE
232.33 +exit 0
232.34 +}
232.35 +function esegui () {
232.36 + debug $*
232.37 + eval $*
232.38 +}
232.39 +function debug () {
232.40 + if [ "$VERBOSE" = 1 ] ; then
232.41 + echo $*
232.42 + fi
232.43 +}
232.44 +#function set_perms () {
232.45 +# chmod 755 /home/shares/$area
232.46 +# chown root.$grp_area /home/shares/classi
232.47 +#}
232.48 +function crea_area () {
232.49 + if [ ! -d /home/shares/$area ] ; then
232.50 + esegui mkdir /home/shares/$area
232.51 + fi
232.52 + esegui chgrp $grp_area /home/shares/$area
232.53 +}
232.54 +function crea_acl () {
232.55 + # controlla esistenza acl in /etc/isi/acl.conf e in /etc/isi/acl-local.conf
232.56 + # se non trova nulla crea le acl in /etc/isi/acl-local.conf
232.57 + # applica le acl
232.58 + local CONF_FILE1=/etc/isi/acl.conf
232.59 + local CONF_FILE2=/etc/isi/acl-local.conf
232.60 + local CREA_ACL=0
232.61 + if ! grep -q "\[$area\]" $CONF_FILE1 ; then
232.62 + if [ -f $CONF_FILE2 ] ; then
232.63 + if ! grep -q "\[$area\]" $CONF_FILE2 ; then
232.64 + CREA_ACL=1
232.65 + fi
232.66 + else
232.67 + CREA_ACL=1
232.68 + fi
232.69 + fi
232.70 + if [ $CREA_ACL = 1 ] ; then
232.71 + cat <<EOF >> $CONF_FILE2
232.72 +
232.73 +[${area#/home/shares/}]
232.74 + path = /home/shares/$area
232.75 + grp = $grp_area
232.76 + g:$grp_area = rxw
232.77 + g:alunni = ---
232.78 + o = ---
232.79 +EOF
232.80 + debug "ACL creata in $CONF_FILE2"
232.81 + fi
232.82 + if [ -z $NO_ACL ] ; then
232.83 + debug "ATTENDI: applico acl..."
232.84 + isi-perms $area
232.85 + fi
232.86 +}
232.87 +function crea_share () {
232.88 +local CONF_FILE=/etc/isi/samba/smb_aree.conf
232.89 +
232.90 +if ! grep -q "\[$area\]" $CONF_FILE ; then
232.91 + debug Creo la share $area
232.92 + cat <<EOF >> $CONF_FILE
232.93 +
232.94 +[${area#/home/shares/}]
232.95 +comment = Area $area
232.96 +path = /home/shares/$area
232.97 +guest ok = no
232.98 +writable = yes
232.99 +browseable =yes
232.100 +
232.101 +EOF
232.102 +
232.103 +fi
232.104 +}
232.105 +
232.106 +
232.107 +####### PROGRAM
232.108 +
232.109 +while getopts hvNp var
232.110 +do
232.111 + case $var in
232.112 + h) clear; help; exit
232.113 + ;;
232.114 + v) VERBOSE=1
232.115 + ;;
232.116 + N) NO_SAMBA=1
232.117 + ;;
232.118 + p) NO_ACL=1
232.119 + ;;
232.120 + esac
232.121 +done
232.122 +shift ` expr $OPTIND - 1 `
232.123 +
232.124 +area="$1"
232.125 +grp_area="$2"
232.126 +
232.127 +[ -z "$area" ] && help
232.128 +[ -z "$grp_area" ] && help
232.129 +
232.130 +crea_area
232.131 +crea_share
232.132 +crea_acl
232.133 +
232.134 +[ -z "$NO_SAMBA" ] && /etc/init.d/samba reload > /dev/null
232.135 +
232.136 +exit 0
233.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
233.2 +++ b/usr/sbin/isi-changeattr Mon Apr 26 11:16:23 2010 +0200
233.3 @@ -0,0 +1,64 @@
233.4 +#!/usr/bin/python
233.5 +# -*- coding: utf-8 -*-
233.6 +
233.7 +# This program is free software; you can redistribute it and/or modify
233.8 +# it under the terms of the GNU General Public License as published by
233.9 +# the Free Software Foundation; either version 2, or (at your option)
233.10 +# any later version.
233.11 +
233.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
233.13 +
233.14 +"""
233.15 +Change an attribute of ldap. If no value is provided, the attribute is deleted
233.16 +
233.17 + usage: %prog [options] attribute value
233.18 + -N, --dry-run: don't touch the ldap db or filesystem
233.19 + -d, --debug: Mostra i comandi mentre li esegue
233.20 + -g, --group=GROUP: change to all user of GROUP
233.21 + -u, --uid=UID: change for UID
233.22 + -v, --verbose: be verbose
233.23 +"""
233.24 +
233.25 +import isi
233.26 +import sys
233.27 +import re
233.28 +from dry import optionparse
233.29 +
233.30 +
233.31 +#### PROGRAM
233.32 +opts, args = optionparse.parse(__doc__)
233.33 +
233.34 +c = isi.IsiConn(dry_run=opts.dry_run)
233.35 +l = isi.Manager(c)
233.36 +c.backup()
233.37 +
233.38 +if not opts.group and not opts.uid:
233.39 + msg = "You must provide logname or group via -u or -g option\n"
233.40 + sys.stdout.write(msg)
233.41 + sys.exit(1)
233.42 +
233.43 +if opts.group:
233.44 + users = l.get_members(opts.group)
233.45 +else:
233.46 + users = [opts.uid]
233.47 +
233.48 +
233.49 +attribute = args[0]
233.50 +try:
233.51 + value = args[1]
233.52 +except:
233.53 + value = None
233.54 +
233.55 +for uid in users:
233.56 + if opts.verbose:
233.57 + print uid
233.58 + try:
233.59 + c.modify(uid, attribute, value)
233.60 + except isi.MissingMatch:
233.61 + msg = "logname '%s' is missing\n" % uid
233.62 + sys.stdout.write(msg)
233.63 + sys.exit(1)
233.64 +
233.65 +sys.exit(0)
233.66 +
233.67 +
234.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
234.2 +++ b/usr/sbin/isi-classe Mon Apr 26 11:16:23 2010 +0200
234.3 @@ -0,0 +1,51 @@
234.4 +#!/usr/bin/python
234.5 +# -*- coding: utf-8 -*-
234.6 +
234.7 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
234.8 +#
234.9 +# This program is free software: you can redistribute it and/or modify
234.10 +# it under the terms of the GNU General Public License as published by
234.11 +# the Free Software Foundation, either version 3 of the License, or
234.12 +# (at your option) any later version.
234.13 +#
234.14 +# This program is distributed in the hope that it will be useful,
234.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
234.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
234.17 +# GNU General Public License for more details.
234.18 +#
234.19 +# You should have received a copy of the GNU General Public License
234.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
234.21 +
234.22 +
234.23 +
234.24 +u"""
234.25 +crea una classe con tutto ciò che comporta:
234.26 + * il gruppo
234.27 + * la share di samba
234.28 +
234.29 + usage: %prog [options] class | course
234.30 + -v, --verbose: be verbose
234.31 + -C, --course: create a course not a class
234.32 + -N, --no-samba-reload: don't reload samba (used when many classes are added)
234.33 +"""
234.34 +
234.35 +import sys
234.36 +from dry import optionparse
234.37 +from isi import filesystem, srv
234.38 +
234.39 +#### PROGRAM
234.40 +opts, args = optionparse.parse(__doc__)
234.41 +
234.42 +if args:
234.43 + classes = args
234.44 +else:
234.45 + if opts.course:
234.46 + classes = srv.get_courses()
234.47 + else:
234.48 + classes = srv.get_classes()
234.49 +
234.50 +for class_ in classes:
234.51 + filesystem.create_class(class_, course=opts.course, samba_reload= not opts.no_samba_reload)
234.52 +
234.53 +sys.exit(0)
234.54 +
235.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
235.2 +++ b/usr/sbin/isi-computer Mon Apr 26 11:16:23 2010 +0200
235.3 @@ -0,0 +1,65 @@
235.4 +#!/usr/bin/python
235.5 +# -*- coding: utf-8 -*-
235.6 +
235.7 +# This program is free software; you can redistribute it and/or modify
235.8 +# it under the terms of the GNU General Public License as published by
235.9 +# the Free Software Foundation; either version 2, or (at your option)
235.10 +# any later version.
235.11 +
235.12 +# AUTHORS: Massimo Mancini
235.13 +
235.14 +
235.15 +"""
235.16 +Senza opzioni restituisce la lista dei pc windows (join)
235.17 +
235.18 + usage: %prog [options] [host_name|file]
235.19 + -d, --delete=delete: elimina un computer (annulla il join)
235.20 + -f, --file=file: elimina tutti i computer elencati nel file
235.21 + -v, --verbose: aumenta i messaggi a video
235.22 +"""
235.23 +
235.24 +
235.25 +import isi
235.26 +import sys
235.27 +from dry import optionparse
235.28 +
235.29 +def del_computer(hostname, error):
235.30 + """error is different is we delete one computer from the command line
235.31 + or from a file, when deleteing from a file it is normal that some pc
235.32 + may be non-existing"""
235.33 +
235.34 + try:
235.35 + l.del_computer(hostname)
235.36 + except isi.MissingMatch, e:
235.37 + msg = " %s is not a joined machine on this Domain" % hostname
235.38 + sys.stderr.write("Error: %s\n" % msg)
235.39 + if error:
235.40 + sys.exit(error)
235.41 +
235.42 +opts, args = optionparse.parse(__doc__)
235.43 +
235.44 +hostname = None
235.45 +filename = None
235.46 +if opts.delete: hostname = opts.delete
235.47 +if opts.file : filename = opts.file
235.48 +l = isi.Manager(isi.IsiConn(), opts.verbose)
235.49 +
235.50 +if not (hostname or filename):
235.51 + computers = l.get_computers()
235.52 + if len(computers)==0:
235.53 + print "non trovo computer registrati sul dominio"
235.54 + else:
235.55 + for pc in computers:
235.56 + dn, data = pc
235.57 + print "%s" % data['uid'][0]
235.58 +
235.59 +else:
235.60 + if not hostname is None:
235.61 + del_computer(hostname, error=1)
235.62 + if not filename is None:
235.63 + for host in open(filename):
235.64 + host = host[:-1]
235.65 + del_computer(host, error=0)
235.66 +
235.67 +
235.68 +sys.exit(0)
236.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
236.2 +++ b/usr/sbin/isi-convert Mon Apr 26 11:16:23 2010 +0200
236.3 @@ -0,0 +1,97 @@
236.4 +#!/usr/bin/python
236.5 +# -*- coding: utf-8 -*-
236.6 +
236.7 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
236.8 +#
236.9 +# This program is free software: you can redistribute it and/or modify
236.10 +# it under the terms of the GNU General Public License as published by
236.11 +# the Free Software Foundation, either version 3 of the License, or
236.12 +# (at your option) any later version.
236.13 +#
236.14 +# This program is distributed in the hope that it will be useful,
236.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
236.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
236.17 +# GNU General Public License for more details.
236.18 +#
236.19 +# You should have received a copy of the GNU General Public License
236.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
236.21 +
236.22 +
236.23 +
236.24 +u"""
236.25 +Importa gli utenti da formati differenti. Il file può essere in formato .csv
236.26 +o .xls. Genera un file in formato .isi
236.27 +
236.28 +NOTA: non confondete il formato dei dati (la successione delle colonne) con il formato
236.29 + del file (.csv o .xls).
236.30 +
236.31 + usage: %prog [options] file
236.32 + -g, --group=GROUP: limit import for users (needed)
236.33 + -o, --output=FILE: produci l'output nel file FILE (default stdout)
236.34 + -r, --renamed: mostra quali utenti verrebbero rinominati
236.35 + -d, --deleted: mostra quali utenti verrebbero cancellati
236.36 + -e, --extended: usa il formato esteso
236.37 + -I, --id-name: usa d_nome.cognome per logname
236.38 + -N, --name: usa nome.cognome per logname
236.39 + -p, --random-password: generate random password
236.40 + -F, --file-format=FORMAT: file format is FORMAT ('isi' or 'sissi')
236.41 + -C, --use-cf: usa CF per nome + identificativo maingroup (default is in /etc/isi/defaults.py)
236.42 +"""
236.43 +
236.44 +import os
236.45 +import isi
236.46 +import sys
236.47 +from isi import bulk_users
236.48 +import re
236.49 +from dry import optionparse
236.50 +
236.51 +
236.52 +#### PROGRAM
236.53 +opts, args = optionparse.parse(__doc__)
236.54 +
236.55 +if len(args) <1:
236.56 + print "\nDevi indicare il file con gli utenti da importare!! \n"
236.57 + sys.exit(1)
236.58 +filename = args[0]
236.59 +
236.60 +if not os.path.exists(filename):
236.61 + print "File inesistente (%s)" % filename
236.62 + sys.exit(1)
236.63 +
236.64 +l = isi.Manager()
236.65 +
236.66 +if not opts.group:
236.67 + msg = "Devi indicare il gruppo con l'opzione -g\n"
236.68 + sys.stdout.write(msg)
236.69 + sys.exit(1)
236.70 +
236.71 +if not opts.file_format:
236.72 + opts.file_format = 'isi'
236.73 +
236.74 +if opts.name:
236.75 + user_format = 'name'
236.76 +elif opts.use_cf:
236.77 + user_format = 'cf'
236.78 +elif opts.id_name:
236.79 + user_format = 'id-name'
236.80 +else:
236.81 + user_format = None
236.82 +
236.83 +bulk = bulk_users.BulkUsers(opts.group, user_format=user_format,
236.84 + random_password=opts.random_password)
236.85 +bulk.read_file(filename, file_format=opts.file_format)
236.86 +
236.87 +if opts.renamed:
236.88 + output_text = bulk.renamed_as_text()
236.89 +elif opts.deleted:
236.90 + output_text = bulk.deleted_as_text()
236.91 +else:
236.92 + output_text = bulk.as_isi(extended=opts.extended)
236.93 +
236.94 +output_file = sys.stdout if not opts.output else open(opts.output, 'w')
236.95 +output_file.write(output_text + '\n')
236.96 +
236.97 +
236.98 +sys.exit(0)
236.99 +
236.100 +
237.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
237.2 +++ b/usr/sbin/isi-delprofilo Mon Apr 26 11:16:23 2010 +0200
237.3 @@ -0,0 +1,66 @@
237.4 +#!/bin/bash
237.5 +# +-------------------------------------------------+
237.6 +# (C) 2002-2008 ReteIsi / www.reteisi.org
237.7 +# +-------------------------------------------------+
237.8 +# This program is free software; you can redistribute it and/or modify
237.9 +# it under the terms of the GNU General Public License as published by
237.10 +# the Free Software Foundation; either version 2, or (at your option)
237.11 +# any later version.
237.12 +# AUTORE: massimo mancini 2008 - [email protected]
237.13 +
237.14 +
237.15 +function help () {
237.16 +cat << FINE
237.17 +Comando: `basename $0`
237.18 +
237.19 +Sintassi: `basename $0` [ -h ]
237.20 + `basename $0` gruppo utente profilo
237.21 +
237.22 +Descrizione: elimina il profilo windows di un utente
237.23 +
237.24 +Opzioni: -h help (Questa pagina di manuale)
237.25 + -v verbose
237.26 +
237.27 +FINE
237.28 +exit 0
237.29 +}
237.30 +
237.31 +
237.32 +####---------main-----------------
237.33 +
237.34 +VERBOSE=0
237.35 +while getopts hv var
237.36 + do
237.37 + case $var in
237.38 + h) help; exit
237.39 + ;;
237.40 + v) VERBOSE=1
237.41 + ;;
237.42 + esac
237.43 +done
237.44 +shift ` expr $OPTIND - 1 `
237.45 +
237.46 +GRP=$1
237.47 +USR=$2
237.48 +WIN=$3
237.49 +
237.50 +[ -z $GRP ] && echo "MANCA IL GRUPPO!" && help
237.51 +[ -z $USR ] && echo "MANCA L'UTENTE!" && help
237.52 +[ -z $WIN ] && echo "MANCA IL PROFILO (WinXP|Win95|Win2K)" && help
237.53 +
237.54 +DIR="/home/users/$GRP/$USR"
237.55 +PRF=$DIR/.profili/$WIN
237.56 +DSK=$DIR/old_desktop/$WIN
237.57 +
237.58 +[ ! -d $DSK ] && mkdir -p $DSK
237.59 +cp -a $PRF/Desktop/* $DSK
237.60 +
237.61 +if [ $GRP = "alunni" ] ; then
237.62 + chown -R $USR.docenti $DIR/old_desktop
237.63 +else
237.64 + chown -R $USR.$GRP $DIR/old_desktop
237.65 +fi
237.66 +[ $VERBOSE = 1 ] && echo "Desktop salvato in old_desktop"
237.67 +rm -fr $PRF
237.68 +[ $VERBOSE = 1 ] && echo "il profilo di $USR è stato eliminato"
237.69 +
238.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
238.2 +++ b/usr/sbin/isi-deluser Mon Apr 26 11:16:23 2010 +0200
238.3 @@ -0,0 +1,101 @@
238.4 +#!/usr/bin/python
238.5 +# -*- coding: utf-8 -*-
238.6 +
238.7 +# This program is free software; you can redistribute it and/or modify
238.8 +# it under the terms of the GNU General Public License as published by
238.9 +# the Free Software Foundation; either version 2, or (at your option)
238.10 +# any later version.
238.11 +
238.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
238.13 +
238.14 +"""
238.15 +Delete a user. You may leave the home directry untouched (default) or
238.16 +eliminate it or compress it
238.17 +
238.18 + usage: %prog [options] [name]
238.19 + -N, --dry-run: don't touch the ldap
238.20 + -g, --from-group=group: Eliminate all members from 'group'
238.21 + -z, --zap-home: Eliminate also the home dir (default is to create a tar.gz)
238.22 + -H, --home=rm|tar|none: rm, tar or ignore home dir
238.23 + -v, --verbose: be verbose
238.24 + -f, --from-file=filename: Loop on all users in file (one per line)
238.25 + -T, --test-mode: running tests - don't backup (go faster)
238.26 +"""
238.27 +
238.28 +import isi
238.29 +import sys
238.30 +from dry import optionparse
238.31 +opts, args = optionparse.parse(__doc__)
238.32 +if opts.zap_home:
238.33 + opts.home = 'rm'
238.34 +if not opts.home:
238.35 + opts.home = 'tar'
238.36 +
238.37 +#import ipdb; ipdb.set_trace()
238.38 +
238.39 +conn = isi.IsiConn(dry_run=opts.dry_run)
238.40 +l = isi.Manager(conn)
238.41 +l.home_mode = opts.home
238.42 +
238.43 +if opts.test_mode:
238.44 + conn.tests_running = True
238.45 +
238.46 +conn.backup()
238.47 +
238.48 +def del_user(user, error):
238.49 + """error is different if we delete one user from the command line
238.50 + or from a file, when deleting from a file it is normal that some user
238.51 + may be non-existng"""
238.52 +
238.53 + try:
238.54 + l.del_user(user)
238.55 + except isi.exc.MissingMatch, e:
238.56 + msg = "username %s is not a system user" % user
238.57 + sys.stderr.write("Error: %s\n" % msg)
238.58 + if error:
238.59 + sys.exit(error)
238.60 +
238.61 +def get_user_from_file():
238.62 + """file may have single logname or complete lines. We pick the first
238.63 + after splittin with ';' """
238.64 + users = []
238.65 + for line in open(opts.from_file):
238.66 + line = line.rstrip('\n').replace(' ', '')
238.67 + if line:
238.68 + users += [line.split(';')[0]]
238.69 + return users
238.70 +
238.71 +
238.72 +## check args
238.73 +if not len(args):
238.74 + if not opts.from_group and not opts.from_file:
238.75 + sys.stderr.write("Missing username\n")
238.76 + sys.exit(1)
238.77 +
238.78 +## if deleting a single user, raise an error if the user is missing
238.79 +## if looping from a group just issue a warning if the user is missing
238.80 +## but raise an error if the group is missing
238.81 +
238.82 +group = opts.from_group
238.83 +
238.84 +if group: # GROUP
238.85 +
238.86 + try:
238.87 + posix_group = l.get_group(group)
238.88 + posix_group.delete_members()
238.89 + sys.exit(0)
238.90 + except isi.exc.MissingMatch, e:
238.91 + msg = "group %s is not a system group" % group
238.92 + isi.srv.get_logger().warning(msg)
238.93 + sys.exit(1)
238.94 +
238.95 +
238.96 +elif opts.from_file:
238.97 + for user in get_user_from_file():
238.98 + if opts.verbose:
238.99 + print "elimino: %s" % user
238.100 + del_user(user, error=0)
238.101 +else: # USER
238.102 + del_user(args[0], error=1)
238.103 +
238.104 +sys.exit(0)
239.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239.2 +++ b/usr/sbin/isi-domain Mon Apr 26 11:16:23 2010 +0200
239.3 @@ -0,0 +1,628 @@
239.4 +#!/bin/bash
239.5 +# +-------------------------------------------------+
239.6 +# (C) ReteIsi / www.reteisi.org
239.7 +# +-------------------------------------------------+
239.8 +
239.9 +# This program is free software; you can redistribute it and/or modify
239.10 +# it under the terms of the GNU General Public License as published by
239.11 +# the Free Software Foundation; either version 2, or (at your option)
239.12 +# any later version.
239.13 +#
239.14 +#
239.15 +# AUTORI: Sandro Dentella <[email protected]>
239.16 +# Massimo Mancini <[email protected]>
239.17 +
239.18 +function help () {
239.19 +cat << FINE
239.20 +Comando: `basename $0`
239.21 +
239.22 +Sintassi: `basename $0`[ -h ]
239.23 +
239.24 +Descrizione: isi-domain dominio pdc-name pass
239.25 +
239.26 + pass è la pass di root che viene utilizzata anche
239.27 + come pass amministrativa di slapd, questa può essere
239.28 + in seguito cambiata con il comando: isi-passwd -A
239.29 +
239.30 + Se il dominio in /etc/samba/smb.conf è ISI-DOMAIN, Si suppone
239.31 + che non sia mai stato cambiato e viene rigenerato secrets.tdb
239.32 + Memorizza il nuovo SID nel file /etc/samba/domain.SID.
239.33 + Se trova domain.SID chiede se si vuole usare quel SID.
239.34 + (la cosa serve ad evitare di dovere rifare il
239.35 + join delle macchine.
239.36 +
239.37 +Opzioni: -h help (Questa pagina di manuale)
239.38 + -v verbose
239.39 + -q solo messaggi di errore
239.40 + -N secrets.tdb verrà cancellato
239.41 + -R cambia anche la password di root (come quella di admin ldap)
239.42 + -S crea/aggiorna SOLO la struttura di default
239.43 + -s NON crea/aggiorna la struttura di default
239.44 +
239.45 +NOTA: l'opzione -S crea/mantiene la struttura di default eventualmente descritta
239.46 +nel file /etc/isi-def-stru che serve a ridefinire le seguenti variabili:
239.47 +
239.48 + MAINGRPS="admins docenti segreteria ata alunni esterni ospiti"
239.49 + AREE="area_alunni area_docenti area_segreteria"
239.50 + CLASSI="classe_test"
239.51 + CORSI="corso_test"
239.52 +
239.53 +FINE
239.54 +}
239.55 +function _sintassi () {
239.56 + echo "Sintassi: isi-startup [-N -A -D -S] NOME_DOMINIO NOME_PDC PASSWD"
239.57 + exit
239.58 +}
239.59 +function check_syntax () {
239.60 + eco y "check_syntax"
239.61 + [ -z "$DOMAIN" ] && _sintassi
239.62 + [ -z "$PDC_NAME" ] && _sintassi
239.63 + [ -z "$PASSWD" ] && _sintassi
239.64 +}
239.65 +function change_password () {
239.66 + eco "y change_password"
239.67 + ## sistema
239.68 + if [ $PWD_ROOT -eq 1 ]; then
239.69 + eco g "cambio password di root"
239.70 + echo "root:$PASSWD" | chpasswd
239.71 + fi
239.72 + ## smbtools
239.73 + eco g "admin passwd in /etc/smbldap-tools/smbldap_bind.conf"
239.74 + perl -pi -se '
239.75 + { $_ =~ s/(slavePw|masterPw)=.*/$1="$pwd"/ }
239.76 + ' -- -pwd=$PASSWD /etc/smbldap-tools/smbldap_bind.conf
239.77 +
239.78 + ## admin ldap
239.79 + eco y "password admin ldap"
239.80 + local CRYPT_PASSWD=$(slappasswd -h "{CRYPT}" -s $PASSWD)
239.81 + eco g "ldapmodify $OPZ_MBIND"
239.82 + cat <<EOF |ldapmodify $OPZ_MBIND
239.83 +dn: $RBDN
239.84 +replace: userPassword
239.85 +userPassword: $CRYPT_PASSWD
239.86 +EOF
239.87 + ## samba: come raggiunere ldap
239.88 + eco g "reset password amministrativa di samba"
239.89 + smbpasswd -w $PASSWD
239.90 +
239.91 + ## samba (root/Administrator)
239.92 + eco g "cambio passord di $DOMAIN_ADMIN"
239.93 +# echo -e "$PASSWD\n$PASSWD"|smbpasswd -s root 2>&1 |grep -v 'Failed to'
239.94 + echo -e "$PASSWD\n$PASSWD"|smbpasswd -s $DOMAIN_ADMIN 2>&1 |grep -v 'Failed to'
239.95 +
239.96 + ## strumenti ldap*
239.97 + eco y "modifico /etc/*.secret"
239.98 + for f in ldap.secret libnss-ldap.secret pam_ldap.secret
239.99 + do
239.100 + if [ ! -L /etc/$f ] ; then
239.101 + eco g "modifico $f"
239.102 + echo $PASSWD > /etc/$f
239.103 + chmod 600 /etc/$f
239.104 + fi
239.105 + done
239.106 +
239.107 + ## reimposto le variabili connesse alla password
239.108 + LDAP_PWD=$PASSWD
239.109 + OPZ_SBIND="-xLLLD $RBDN -w $LDAP_PWD -h $HOST"
239.110 + OPZ_MBIND="-xD $RBDN -w $LDAP_PWD -h $HOST"
239.111 +
239.112 + [ $NEW = 1 ] && reset_secrets
239.113 +
239.114 +}
239.115 +function reset_secrets () {
239.116 + eco y "reset /var/lib/samba/secrets.tdb"
239.117 + rm /var/lib/samba/secrets.tdb
239.118 + ## ora lo ricreiamo pulito
239.119 + smbpasswd -w $LDAP_PWD
239.120 +}
239.121 +function read_conf () {
239.122 + eco y "leggo la configurazione"
239.123 + DOM_PREC=$(egrep "workgroup *= *" /etc/samba/smb.conf |
239.124 + sed 's/ *workgroup *= *//')
239.125 +
239.126 + ## se ISI-DOMAIN suppongo di resettare secrets.tdb
239.127 + [ "$DOM_PREC" = "ISI-DOMAIN" ] && NEW=1
239.128 +
239.129 + PDC_V=$(egrep "netbios name" /etc/samba/smb.conf |
239.130 + sed 's/ *netbios name *= *//')
239.131 + [ -z "$PDC_V" ] && PDC_V=$(cat /etc/hostname)
239.132 +
239.133 + ## solite variabili per ldap*
239.134 + if [ "$IS_UBUNTU" = 1 ] ; then
239.135 + RBDN=$(awk '/^ *rootbinddn/ {print $2$3$4$5}' /etc/ldap.conf )
239.136 + BASE=$(awk '/BASE/ {print $2 $3 $4 $5}' /etc/ldap/ldap.conf)
239.137 + HOST=$(awk '/HOST/ {print $2}' /etc/ldap/ldap.conf)
239.138 + else
239.139 + RBDN=$(awk '/^ *rootbinddn/ {print $2$3$4$5}' /etc/pam_ldap.conf )
239.140 + BASE=$(awk '/BASE/ {print $2 $3 $4 $5}' /etc/ldap/ldap.conf)
239.141 + HOST=$(awk '/HOST/ {print $2}' /etc/ldap/ldap.conf)
239.142 + fi
239.143 +
239.144 + LDAP_PWD=$(cat /etc/ldap.secret)
239.145 +
239.146 +# SID_OLD=$(net getlocalsid $DOM_PREC|sed 's/^SID for domain.* is: //')
239.147 +
239.148 + # SID_OLD=$(net getdomainsid |grep "SID for domain" |sed 's/^SID for domain.* is: //')
239.149 + # SID_LOC=$(net getdomainsid |grep "SID for local" |sed 's/^SID for local.* is: //')
239.150 +
239.151 + netbios_name=$(net getlocalsid|awk {'print $4'})
239.152 + SID_OLD=$(net getdomainsid|grep -v $netbios_name|awk {'print $NF'})
239.153 + SID_LOC=$(net getdomainsid|grep $netbios_name|awk {'print $NF'})
239.154 +
239.155 + if [ -z "$SID_LOC" ] ; then
239.156 + eco r "SID locale indefinito - provvedere"
239.157 + exit
239.158 + fi
239.159 +
239.160 + # amministrazione samba
239.161 + DOMAIN_ADMIN=$(getent group | grep :512: |awk -F":" '{print $4}'|awk -F"," '{print $1}')
239.162 + [ -z $DOMAIN_ADMIN ] && DOMAIN_ADMIN="Administrator"
239.163 +
239.164 + OPZ_SBIND="-xLLLD $RBDN -w $LDAP_PWD -h $HOST"
239.165 + OPZ_MBIND="-xD $RBDN -w $LDAP_PWD -h $HOST"
239.166 + if [ $VERBOSE = 1 ] ; then
239.167 + cat <<EOF
239.168 +CONFIGURAZIONE ATTUALE:
239.169 +DOMINIO........: $DOM_PREC
239.170 +SID DOMINIO....: $SID_OLD
239.171 +SID LOCALE.....: $SID_LOC
239.172 +PDC............: $PDC_V
239.173 +PWD LDAP.......: $LDAP_PWD
239.174 +DOMAIN ADMIN...: $DOMAIN_ADMIN
239.175 +EOF
239.176 + fi
239.177 +}
239.178 +function new_sid (){
239.179 + eco y "generazione nuovo sid"
239.180 + if [ -f /etc/samba/domain.SID ] ; then
239.181 + read -p "Esiste un SID memorizzato. Vuoi usare questo (s/n)? " RISP
239.182 + N=$(expr match "$RISP" '[yYsS]')
239.183 + if [ $N -gt 0 ] ; then
239.184 + SID=$(cat /etc/samba/domain.SID)
239.185 + fi
239.186 + fi
239.187 + if [ -z "$SID" ] ; then
239.188 + SID=$(isi-gensid)
239.189 + echo $SID > /etc/samba/domain.SID
239.190 + eco v "nuovo sid salvato in /etc/samba/domain.SID - $SID"
239.191 + fi
239.192 +}
239.193 +function check_ldap_pwd () {
239.194 + eco y "check funzionamento ldap"
239.195 + if ! ldapsearch $OPZ_SBIND "objectclass=dcObject" 1>/dev/null ; then
239.196 + echo Non riesco a contattare il server ldap: password non valida
239.197 + echo server non raggiungibile
239.198 + fi
239.199 +}
239.200 +function fix_PDC_name () {
239.201 + eco y "cambio nome PDC"
239.202 + ### non sostituisco solo nuovo con vecchio, nel caso
239.203 + # sia stata fatta qualche modifica incompleta a mano
239.204 + ### fix server PDC per smbldap, isi/logon.bat isi/logonupd.bat
239.205 + perl -pi -se '
239.206 + {$_ =~ s/\\\\([^\\]+)\\/\\\\$pdc\\/g }
239.207 + ' -- -pdc=$PDC_NAME /etc/smbldap-tools/smbldap.conf /etc/isi/logon{,upd}.bat
239.208 +
239.209 + ### fix ultimo argomento /etc/isi/logon.bat
239.210 + perl -pi -se '
239.211 + {$_ =~ s/logon(upd)?.pl.*/logon$1.pl $pdc/}
239.212 + ' -- -pdc=$PDC_NAME /etc/isi/logon{,upd}.bat
239.213 +
239.214 + perl -pi -se '
239.215 + {if ($_ =~ /netbios *name/) {$_ = " netbios name = $pdc\n" }}
239.216 + ' -- -pdc=$PDC_NAME /etc/samba/smb.conf
239.217 +
239.218 + echo $PDC_NAME > /etc/hostname
239.219 +
239.220 +}
239.221 +function fix_DOMAIN_name () {
239.222 + eco y "cambio nome dominio"
239.223 + # fix nome dominio
239.224 + perl -pi -se '
239.225 + {$_ =~ s/(sambaUnixIdPooldn="sambaDomainName=)([^,]*)(.*)/$1$dom$3/}
239.226 + ' -- -dom=$DOMAIN /etc/smbldap-tools/smbldap.conf
239.227 +
239.228 + # modifica /etc/samba/smb.conf
239.229 + perl -pi -se '
239.230 + {$_ =~ s/.*workgroup.*/ workgroup = $dom/ }
239.231 + ' -- -dom=$DOMAIN /etc/samba/smb.conf
239.232 +}
239.233 +function fix_SID_in_smbldap_tools () {
239.234 + eco y "cambio SID in /etc/smbldap_tools/smbldap.conf"
239.235 + ### fix smbldap-tools
239.236 + perl -pi -se '{if ($_ =~ /SID=/) {$_ = "SID=$SID\n"} }
239.237 + ' -- -SID=$SID /etc/smbldap-tools/smbldap.conf
239.238 +}
239.239 +
239.240 +function get_max_IDs () {
239.241 +# determina nextUID e nextGID e aggiunge i gruppi windows
239.242 + S_UID=$(getent passwd |
239.243 + awk -F":" '$3 > 999 && $3 < 30000 {print $3}'|
239.244 + sort -nr | head -n 1)
239.245 + S_GID=$(getent group |
239.246 + awk -F':' '$3 > 999 && $3 < 30000 {print $3}' |
239.247 + sort -nr | head -n 1)
239.248 +
239.249 + [ -z "$S_UID" ] && S_UID=999
239.250 + [ -z "$S_GID" ] && S_GID=999
239.251 +
239.252 + [ $S_UID -lt 1000 ] && S_UID=999;
239.253 + [ $S_GID -lt 1000 ] && S_GID=999;
239.254 +
239.255 + S_UID=`expr $S_UID + 1`
239.256 + S_GID=`expr $S_GID + 1`
239.257 +}
239.258 +
239.259 +function fix_LDAP_sambaDomainName () {
239.260 + local DN
239.261 + local LDAP_PASSWD=$(cat /etc/ldap.secret)
239.262 + ## Qui abbiamo un problema. Aggiungiamo la entry via ' net getlocalsid'
239.263 + ## dopo aver cambiato il nome in smb.conf.
239.264 + ## Questo crea una entry senza sambaUnixIdPool, quindi la modifichiamo
239.265 + OPTS=" -xD $RBDN -w $LDAP_PASSWD "
239.266 +
239.267 + ldapsearch -x -LLL $OPTS sambaDomainName=$DOMAIN > /tmp/dom.ldif
239.268 + ## controlla esistenza gidNumber
239.269 + if ! grep sambaUnixIdPool /tmp/dom.ldif >/dev/null; then
239.270 + get_max_IDs
239.271 + cat <<EOF | tee /tmp/modify.ldif| ldapmodify $OPTS
239.272 +dn: sambaDomainName=$DOMAIN,$BASE
239.273 +changetype: modify
239.274 +add: objectClass
239.275 +objectClass: sambaUnixIdPool
239.276 +-
239.277 +add: uidNumber
239.278 +uidNumber: $S_UID
239.279 +-
239.280 +add: gidNumber
239.281 +gidNumber: $S_GID
239.282 +EOF
239.283 +
239.284 + fi
239.285 +}
239.286 +
239.287 +
239.288 +function set_debconf_vars () {
239.289 + eco y "setting variabili debconf"
239.290 + # aggiusta le var debconf
239.291 + . /usr/share/debconf/confmodule
239.292 + db_set shared/sambaPdcName $PDC || true
239.293 + db_set shared/sambaDomainName $DOMAIN || true
239.294 + db_set samba-common/workgroup $DOMAIN || true
239.295 + db_stop
239.296 +}
239.297 +function add_samba_at_boot () {
239.298 + eco j "add_samba_at_boot"
239.299 + ### update-rc
239.300 + update-rc.d samba defaults # fallisce con file-rc
239.301 + [ -f /etc/runlevel.conf ] && \
239.302 + perl -pi -e '{if ($_ =~ /samba/) {$_ =~ s/\#//g }}' /etc/runlevel.conf
239.303 +
239.304 +}
239.305 +function eco() {
239.306 + ESC="\033["
239.307 + RED="${ESC}31;1m"
239.308 + GREEN="${ESC}32;1m"
239.309 + BLUE="${ESC}44;33;1m"
239.310 + YELLOW="${ESC}33;1m"
239.311 + NOR="${ESC}0m"
239.312 +
239.313 + local col=$1
239.314 + shift
239.315 + case $col in
239.316 + g) COL=$GREEN
239.317 + ;;
239.318 + b) COL=$BLUE
239.319 + ;;
239.320 + y) COL=$YELLOW
239.321 + ;;
239.322 + r) COL=$RED
239.323 + ;;
239.324 + n) COL=$NOR
239.325 + ;;
239.326 + esac
239.327 + case $col in
239.328 + [gby]) [ $QUIET = 0 ] && echo -e ${COL}$*$NOR
239.329 + ;;
239.330 + r) echo -e ${COL}$*$NOR 1>&2
239.331 + ;;
239.332 + n) [ $VERBOSE = 1 ] && echo $*
239.333 + ;;
239.334 + esac
239.335 +}
239.336 +
239.337 +###------------ creazione struttura reteISI---------------------
239.338 +# l'eventuale file di configurazione: /etc/isi/isi-def-stru.conf
239.339 +# definisce: gruppi principali, struttura delle cartelle
239.340 +
239.341 +function crea_dir_grp (){
239.342 + DOVE=$1
239.343 + COSA=$2
239.344 + OKGR=$3
239.345 + for x in $COSA; do
239.346 + eco g "creo $DOVE/$x"
239.347 + mkdir -p $DOVE/$x > /dev/null
239.348 + [ $OKGR = 1 ] && isi-addgroup $x
239.349 + done
239.350 +}
239.351 +
239.352 +function isi_default_stru(){
239.353 + # costanti
239.354 + GRP_SI=1
239.355 + GRP_NO=0
239.356 + UTENTI_IN="/home/users"
239.357 + SHARES_IN="/home/shares"
239.358 + FILE_DEF="/etc/isi/isi-def-stru.conf"
239.359 + # defaults (possono essere ridefiniti nel file di conf)
239.360 + MAINGRPS="admins docenti segreteria ata alunni esterni ospiti"
239.361 + AREE="area_alunni area_docenti area_segreteria"
239.362 + CLASSI="classe_test"
239.363 + CORSI="corso_test"
239.364 +
239.365 + [ -f $FILE_DEF ] && . $FILE_DEF
239.366 +
239.367 + # crea gruppi principali e cartelle relative
239.368 + crea_dir_grp $UTENTI_IN $MAINGRPS $GRP_SI
239.369 + # crea classi/corsi
239.370 + for x in $CLASSI; do
239.371 + isi-classe $x
239.372 + done
239.373 + for x in $CORSI; do
239.374 + isi-classe -C $x
239.375 + done
239.376 + # crea aree
239.377 + for x in $AREE; do
239.378 + isi-area $x
239.379 + done
239.380 + isi-perms
239.381 +}
239.382 +
239.383 +function slapd_stop () {
239.384 + eco y "fermo slapd"
239.385 + ## prima usiamo le buone maniere
239.386 + /etc/init.d/slapd stop
239.387 + if pgrep -x slapd ; then
239.388 + ## poi pero' ci arrabbiamo...
239.389 + eco b "provo ad uccidere slapd con -9"
239.390 + skill -9 slapd
239.391 + if pgrep -x slapd; then
239.392 + eco r "slapd non muore neanche con kill -9; esco"
239.393 + exit 1
239.394 + fi
239.395 + fi
239.396 +}
239.397 +function slapd_start () {
239.398 + local i=0
239.399 + eco y "avvio slapd"
239.400 + until [ "$(pidof slapd)" != "" ] ; do
239.401 + /etc/init.d/slapd start
239.402 + sleep 1
239.403 + i=$((i+1))
239.404 + if [ $i = 10 ] ; then
239.405 + eco r "slapd non parte!!!. Controllare."
239.406 + exit 1
239.407 + fi
239.408 + done
239.409 +}
239.410 +
239.411 +function samba_stop () {
239.412 + eco y "fermo Samba"
239.413 + invoke-rc.d samba stop
239.414 + if [ "$(pidof smbd)" != "" ] ; then
239.415 + eco r "Samba non si spegne. Riavviare a mano."
239.416 + exit 1
239.417 + fi
239.418 +}
239.419 +function samba_start () {
239.420 + local i=0
239.421 + eco y "avvio Samba"
239.422 + until [ "$(pidof smbd)" != "" ]
239.423 + do
239.424 + /etc/init.d/samba start
239.425 + sleep 1
239.426 + i=$((i+1))
239.427 + if [ $i = 10 ] ; then
239.428 + eco r "Samba non parte!!!. Controllare."
239.429 + exit 1
239.430 + fi
239.431 + done
239.432 +}
239.433 +function setting_sid () {
239.434 +# if [ "$SID" = "$SID_OLD" ] ; then
239.435 +# eco y "hai usato il vecchio SID: $SID"
239.436 +# else
239.437 +# eco y "nuovo SID di dominio: $SID"
239.438 +# net setdomainsid $SID
239.439 +# fi
239.440 + # risetta il SID del pdc
239.441 + eco y "setting domain SID: $SID"
239.442 + net setdomainsid $SID
239.443 + eco y "setting local SID: $SID_LOC"
239.444 + net setlocalsid $SID_LOC
239.445 + net getdomainsid
239.446 +
239.447 +}
239.448 +function domain_admin_permissions () {
239.449 + eco y "gestione permessi di Domain Admins e $DOMAIN_ADMIN ($1)"
239.450 +
239.451 + UP="$DOMAIN_ADMIN%$LDAP_PWD"
239.452 + P1=SeMachineAccountPrivilege
239.453 + P2=SeTakeOwnershipPrivilege
239.454 + P3=SeBackupPrivilege
239.455 + P4=SeRestorePrivilege
239.456 + P5=SeRemoteShutdownPrivilege
239.457 + P6=SePrintOperatorPrivilege
239.458 + P7=SeAddUsersPrivilege
239.459 + P8=SeDiskOperatorPrivilege
239.460 +
239.461 + net -U $UP rpc rights $1 "Domain Admins" $P1 $P2 $P3 $P4 $P5 $P6 $P7 $P8
239.462 +# net -U $UP rpc rights $1 $DOMAIN_ADMIN $P1 $P2 $P3 $P4 $P5 $P6 $P7 $P8
239.463 +}
239.464 +function slap_index_and_wins () {
239.465 + eco y "rigenero gli indici ldap"
239.466 + slapindex 2>/dev/null # la redirezione elimina un warning
239.467 + chown openldap.openldap /var/lib/ldap/*
239.468 + eco y "elimino /var/lib/samba/wins.dat"
239.469 + rm /var/lib/samba/wins.dat
239.470 +}
239.471 +function slapcat_and_modify () {
239.472 + eco y "slapcat > $LDIF_OLD poi lo modifico in $LDIF_NEW"
239.473 +
239.474 + slapcat > $LDIF_OLD
239.475 +
239.476 + sed "s%$SID_OLD%$SID%gi" $LDIF_OLD | sed "s%$DOM_PREC%$DOMAIN%gi" > $LDIF_NEW
239.477 +
239.478 + if [ "$SID_OLD" != "$SID" ] && grep -iqw $SID_OLD $LDIF_NEW ; then
239.479 + eco r "ERRORE: ridefinizione SID fallita"
239.480 + STOP_ON_ERROR=1
239.481 + fi
239.482 + if [ "$DOM_PREC" != "$DOMAIN" ] && grep -iqw $DOM_PREC $LDIF_NEW ; then
239.483 +# eco r $DOM_PREC
239.484 +# eco r $DOMAIN
239.485 +# exit
239.486 + eco r "ERRORE: ridefinizione DOMINIO fallita"
239.487 + STOP_ON_ERROR=1
239.488 + fi
239.489 +}
239.490 +function set_hostname (){
239.491 + OLD_HOSTNAME=$(hostname)
239.492 + ### squid
239.493 + FILE=/etc/squid.conf
239.494 + if [ -e "$FILE" ] ; then
239.495 + cp $FILE $FILE.2
239.496 + sed "s/^visible_hostname.*$/visible_hostname $PDC_NAME/" \
239.497 + < $FILE.2 > $FILE
239.498 + rm $FILE.2
239.499 + fi
239.500 + FILE=/etc/squid/squid.conf
239.501 + if [ -e "$FILE" ] ; then
239.502 + cp $FILE $FILE.2
239.503 + sed "s/^visible_hostname.*$/visible_hostname $PDC_NAME/" \
239.504 + < $FILE.2 > $FILE
239.505 + rm $FILE.2
239.506 + fi
239.507 + ### postfix
239.508 + [ -x /usr/sbin/postconf ] && postconf -e "myhostname = $PDC_NAME"
239.509 + ### /etc/hostname
239.510 + echo $PDC_NAME > /etc/hostname
239.511 + /etc/init.d/hostname.sh start > /dev/null
239.512 + ### /etc/mailname
239.513 + echo $PDC_NAME > /etc/mailname
239.514 + ### /etc/hosts
239.515 + FILE=/etc/hosts
239.516 + cp $FILE $FILE.2
239.517 + sed -i "s%argo-cd.argo.it%$PDC_NAME%" $FILE
239.518 + sed -i "s%$OLD_HOSTNAME%$PDC_NAME%" $FILE
239.519 + rm $FILE.2
239.520 + hostname $PDC_NAME
239.521 +}
239.522 +
239.523 +function invalid_nscd_cache(){
239.524 + # Invalido cache nscd
239.525 + [ ! -x /usr/sbin/nscd ] && return 1
239.526 + nscd -i passwd
239.527 + nscd -i group
239.528 +
239.529 + return 0
239.530 +}
239.531 +
239.532 +function clean_smb_cache(){
239.533 + rm -f /var/lib/samba/wins.dat
239.534 +}
239.535 +
239.536 +### OPTS
239.537 +STOP_ON_ERROR=0
239.538 +NEW=0
239.539 +PWD_ROOT=0
239.540 +SOLO_DEFSTRU=0
239.541 +NO_DEFSTRU=0
239.542 +VERBOSE=0
239.543 +QUIET=0
239.544 +IS_UBUNTU=0
239.545 +[ "$(lsb_release -is)" == "Ubuntu" ] && IS_UBUNTU=1
239.546 +
239.547 +while getopts hvqsSN var
239.548 +do
239.549 + case $var in
239.550 + h) clear; help; exit
239.551 + ;;
239.552 + v) VERBOSE=1
239.553 + ;;
239.554 + q) QUIET=1
239.555 + VERBOSE=0
239.556 + ;;
239.557 + N) NEW=1
239.558 + ;;
239.559 + s) NO_DEFSTRU=1
239.560 + ;;
239.561 + S) SOLO_DEFSTRU=1
239.562 + ;;
239.563 + R) PWD_ROOT=1
239.564 + esac
239.565 +done
239.566 +shift `expr $OPTIND - 1 `
239.567 +
239.568 +DOMAIN=$(echo $1|tr '[a-z]' '[A-Z]')
239.569 +PDC_NAME=$2
239.570 +PASSWD=$3
239.571 +
239.572 +LDIF_OLD=/root/dbold.ldif
239.573 +LDIF_NEW=/root/dbnew.ldif
239.574 +
239.575 +DOM_PREC=$(egrep "workgroup *= *" /etc/samba/smb.conf|sed 's/ *workgroup *= *//')
239.576 +
239.577 +
239.578 +### PROGRAMMA
239.579 +### controlla solo la struttura isi comprese le acl
239.580 +[ "$SOLO_DEFSTRU" = 1 ] && isi_default_stru && exit 0
239.581 +### ridefinizione dominio
239.582 +check_syntax
239.583 +read_conf
239.584 +check_ldap_pwd
239.585 +new_sid
239.586 +domain_admin_permissions 'revoke'
239.587 +samba_stop
239.588 +slapd_stop
239.589 +invalid_nscd_cache
239.590 +### qui si modificano SID e DOMINIO
239.591 +### se slapcat_and_modify fallisce STOP_ON_ERROR=1
239.592 +slapcat_and_modify
239.593 +if [ "$STOP_ON_ERROR" = 1 ]; then
239.594 + slapd_start
239.595 + samba_start
239.596 + exit 1
239.597 +else
239.598 + eco g "OK ridefinizione SID/DOMINIO"
239.599 +fi
239.600 +### modifica i file di conf
239.601 +set_hostname $PDC_NAME
239.602 +hostname $PDC_NAME
239.603 +fix_DOMAIN_name
239.604 +fix_PDC_name
239.605 +fix_SID_in_smbldap_tools
239.606 +### ricarica dbldap
239.607 +eco y "carico dbldap corretto"
239.608 +isi-slapd-reload -Rl $LDIF_NEW
239.609 +slapd_start
239.610 +samba_start
239.611 +
239.612 +### cambio la/le password
239.613 +change_password
239.614 +### risetto i sid che altrimenti risultano indefiniti
239.615 +setting_sid
239.616 +
239.617 +samba_stop
239.618 +slapd_stop
239.619 +invalid_nscd_cache
239.620 +slap_index_and_wins
239.621 +slapd_start
239.622 +fix_LDAP_sambaDomainName
239.623 +samba_start
239.624 +domain_admin_permissions 'grant'
239.625 +samba_stop
239.626 +clean_smb_cache
239.627 +samba_start
239.628 +set_debconf_vars
239.629 +#isi-tools -N $DOMAIN > /dev/null
239.630 +[ "$NO_DEFSTRU" = 1 ] || isi_default_stru
239.631 +### FINE
240.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
240.2 +++ b/usr/sbin/isi-gensid Mon Apr 26 11:16:23 2010 +0200
240.3 @@ -0,0 +1,11 @@
240.4 +#!/usr/bin/python
240.5 +# -*- coding: utf8 -*-
240.6 +
240.7 +""" calcola un domain SID """
240.8 +import random
240.9 +random.seed()
240.10 +x1=str(random.randint(0,0xFFFFFFFF))
240.11 +x2=str(random.randint(0,0xFFFFFFFF))
240.12 +x3=str(random.randint(0,0xFFFFFFFF))
240.13 +sid = 'S-1-5-21-%s-%s-%s' % (x1,x2,x3)
240.14 +print sid
241.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
241.2 +++ b/usr/sbin/isi-getattr Mon Apr 26 11:16:23 2010 +0200
241.3 @@ -0,0 +1,39 @@
241.4 +#!/usr/bin/python
241.5 +# -*- coding: utf-8 -*-
241.6 +
241.7 +# This program is free software; you can redistribute it and/or modify
241.8 +# it under the terms of the GNU General Public License as published by
241.9 +# the Free Software Foundation; either version 2, or (at your option)
241.10 +# any later version.
241.11 +
241.12 +# AUTORE: massimo mancini 2008 - [email protected]
241.13 +
241.14 +"""
241.15 +Restituisce un campo ldap dell'utente connettendosi al server ldap come
241.16 +amministratore ldap. Restituisce quindi anche i campi riservati.
241.17 +
241.18 + usage: %prog user attributo_ldap
241.19 +
241.20 +"""
241.21 +
241.22 +
241.23 +import isi,sys
241.24 +from dry import optionparse
241.25 +
241.26 +opts, args = optionparse.parse(__doc__)
241.27 +
241.28 +if len(args)<2:
241.29 + print "ERRORE: devi indicare utente e attributo"
241.30 + sys.exit()
241.31 +else:
241.32 + user = args[0]
241.33 + field = args[1]
241.34 +
241.35 +U = isi.Manager(isi.IsiConn())
241.36 +
241.37 +if U.user_exists(user):
241.38 + print U.get_ldap_field(user, field)
241.39 +else:
241.40 + print "utente inesistente: %s" % user
241.41 +
241.42 +
242.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
242.2 +++ b/usr/sbin/isi-groupcat Mon Apr 26 11:16:23 2010 +0200
242.3 @@ -0,0 +1,47 @@
242.4 +#!/usr/bin/python
242.5 +# -*- coding: utf-8 -*-
242.6 +
242.7 +# This program is free software; you can redistribute it and/or modify
242.8 +# it under the terms of the GNU General Public License as published by
242.9 +# the Free Software Foundation; either version 2, or (at your option)
242.10 +# any later version.
242.11 +
242.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
242.13 +
242.14 +
242.15 +"""
242.16 +Return a list of all member of a group
242.17 +
242.18 + usage: %prog [options] group_name
242.19 + -r, --record: return user's records standard part
242.20 + -R, --record-extended: return record extended
242.21 +"""
242.22 +
242.23 +
242.24 +import isi
242.25 +import sys
242.26 +from dry import optionparse
242.27 +
242.28 +opts, args = optionparse.parse(__doc__)
242.29 +group_name = args[0]
242.30 +
242.31 +l = isi.Manager()
242.32 +
242.33 +if not len(args):
242.34 + sys.stderr.write("Missing group name\n")
242.35 + sys.exit(1)
242.36 +
242.37 +group = l.get_group(group_name)
242.38 +
242.39 +if not group:
242.40 + sys.stderr.write("No matching group: %s\n" % args[0])
242.41 + sys.exit(1)
242.42 +
242.43 +
242.44 +if opts.record or opts.record_extended:
242.45 + print group.as_isi_format(opts.record_extended)
242.46 +
242.47 +else:
242.48 + print "\n".join(group.members)
242.49 +
242.50 +sys.exit(0)
243.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243.2 +++ b/usr/sbin/isi-perms Mon Apr 26 11:16:23 2010 +0200
243.3 @@ -0,0 +1,256 @@
243.4 +#!/usr/bin/python
243.5 +# -*- coding: utf-8 -*-
243.6 +
243.7 +# Copyright (C) 2006-2010, Sandro Dentella <[email protected]>
243.8 +#
243.9 +# This program is free software: you can redistribute it and/or modify
243.10 +# it under the terms of the GNU General Public License as published by
243.11 +# the Free Software Foundation, either version 3 of the License, or
243.12 +# (at your option) any later version.
243.13 +#
243.14 +# This program is distributed in the hope that it will be useful,
243.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
243.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
243.17 +# GNU General Public License for more details.
243.18 +#
243.19 +# You should have received a copy of the GNU General Public License
243.20 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
243.21 +
243.22 +
243.23 +"""
243.24 +usage: %prog files [options] [ cartella ] [ cartella] ...
243.25 + -d, --debug: print debugging
243.26 + -n, --dry-run: don't execute commands really, just show
243.27 + -p, --nopostexec: don't execute postexec command
243.28 + -P, --nopreexec: don't execute preeexec command
243.29 + -b, --remove-all: as in setfacl (zeros precedent acl)
243.30 + -w, --write: write the conf file resulting from merge of 2 conf files (implies -n)
243.31 + -f, --file=FILE: use file as configuration file
243.32 +"""
243.33 +
243.34 +import re
243.35 +import os, sys
243.36 +from dry import optionparse
243.37 +from isi.filesystem import has_acl_support
243.38 +import ConfigParser
243.39 +import glob
243.40 +
243.41 +#import subprocess #non disponibile in py2.3
243.42 +
243.43 +class ParsingPermError(Exception): pass
243.44 +
243.45 +class InputStream(object):
243.46 + """ Simple Wrapper for File-like objects. [c]StringIO doesn't provide
243.47 + a readline function for use with generate_tokens.
243.48 + Using a iterator-like interface doesn't succeed, because the readline
243.49 + function isn't used in such a context. (see <python-lib>/tokenize.py)
243.50 + """
243.51 + def __init__(self, file):
243.52 + f = open(file)
243.53 + data = f.read()
243.54 + data = re.sub(':(.*=)', r'|\1', data)
243.55 + f.close()
243.56 + self.__data = [ '%s\n' % x for x in data.splitlines() ]
243.57 + self.__lcount = 0
243.58 +
243.59 + def readline(self):
243.60 + try:
243.61 + line = self.__data[self.__lcount]
243.62 + self.__lcount += 1
243.63 + except IndexError:
243.64 + line = ''
243.65 + self.__lcount = 0
243.66 + line = re.sub(r'^ +', '', line)
243.67 + line = re.sub(r'#.*', '', line)
243.68 + return line
243.69 +
243.70 +class Perm(object):
243.71 + def __init__(self, name=None, model=None):
243.72 + self.perm = {}
243.73 + self.name = name
243.74 + self.path = name
243.75 + if model:
243.76 + self.perm = model
243.77 +
243.78 + def set(self, perm):
243.79 + """add a key/value pair in self.perm dict. Each key/value correspond
243.80 + to a permission added to the setfacl command line
243.81 + """
243.82 +
243.83 + perm = perm.replace('|', ':')
243.84 + m = re.match('([gu]:[-\w.]*|[mo]):([-rxw]+)', perm)
243.85 + if m:
243.86 + self.perm[m.group(1)] = m.group(2)
243.87 + else:
243.88 + raise ParsingPermError('permission could not be parsed: %s' % perm)
243.89 +
243.90 + def create_perm_spec(self):
243.91 + """setfacl accepts many perms in the same line as in::
243.92 +
243.93 + setfacl -R -d -m g:docenti:rxw,u::rxw,o:--- /home/sandro
243.94 +
243.95 + """
243.96 +
243.97 + P = ["%s:%s" % (k, self.perm[k]) for k in self.perm]
243.98 + return ",".join(P)
243.99 +
243.100 + def show(self):
243.101 + """not used..."""
243.102 + print self.perm
243.103 + print self.create_perm_spec()
243.104 +
243.105 + def read(self, items, mode=None):
243.106 + """implement 'copy' functions and set permissions"""
243.107 +
243.108 + for key, val in items:
243.109 + if key == 'copy':
243.110 + self.read(c.items(val), mode='copy')
243.111 +
243.112 + for key, val in items:
243.113 + if key in ('grp', 'public_html', 'copy'):
243.114 + continue
243.115 + elif key == 'path':
243.116 + if not mode == 'copy':
243.117 + self.path = val
243.118 + else:
243.119 + self.set("%s:%s" % (key, val))
243.120 +
243.121 + def grp(self):
243.122 + """if a 'grp' option exists, execute it
243.123 + """
243.124 + if c.has_option(self.name, 'grp'):
243.125 + grp = c.get(self.name, 'grp')
243.126 + cmd = 'chgrp -R %s %s' % (grp, self.path)
243.127 + exec_cmd(cmd)
243.128 +
243.129 + if c.has_option(self.name, 'public_html'):
243.130 + fix = c.get(self.name, 'public_html')
243.131 + if fix in ('yes', 'true', 1, 'si', '1'):
243.132 + self.public_html()
243.133 +
243.134 + def apply(self):
243.135 + for path in glob.glob(self.path):
243.136 + self.grp()
243.137 +
243.138 + if opts.remove_all:
243.139 + b = 'b'
243.140 + else:
243.141 + b = ''
243.142 + cmd = "setfacl -R -d -%sm %s '%s'" % (b, self.create_perm_spec(),
243.143 + path)
243.144 + exec_cmd(cmd)
243.145 + cmd2 = "setfacl -R -m %s '%s'" % (self.create_perm_spec(),
243.146 + path )
243.147 + exec_cmd(cmd2)
243.148 +
243.149 + def public_html(self):
243.150 + """fixes public_html permissions"""
243.151 +
243.152 + Dir = self.path
243.153 + cmd0 = "setfacl -m u:www-data:--x '%s' " % (Dir)
243.154 + cmd01 = "setfacl -m u:www-data:--x %s " % (Dir +'/*')
243.155 + cmd1 = "setfacl -R -m u:www-data:rx %s/*/public_html" % Dir
243.156 + cmd2 = "setfacl -R -d -m u:www-data:rx %s/*/public_html" % Dir
243.157 +
243.158 + if glob.glob("%s" % (Dir +'/*')):
243.159 + exec_cmd(cmd0)
243.160 + ## may be there are no public_html
243.161 + files = glob.glob("%s/*/public_html" % Dir)
243.162 + if files:
243.163 + exec_cmd(cmd1)
243.164 + exec_cmd(cmd2)
243.165 +
243.166 +def exec_cmd(cmd):
243.167 + ## debug
243.168 + if opts.debug:
243.169 + print >>sys.stderr, cmd
243.170 + ## exec
243.171 + if not opts.dry_run:
243.172 +# p = subprocess.Popen(cmd, shell=True)
243.173 +# p.wait()
243.174 + r, w, e = os.popen3(cmd)
243.175 + cmderr = e.readlines()
243.176 + w.close()
243.177 + e.close()
243.178 + if cmderr:
243.179 + print "COMANDO...:",cmd
243.180 + print "ERRORE....:",cmderr[0]
243.181 + #sys.exit(1)
243.182 +
243.183 +def exec_section(section):
243.184 + if not section in c.sections():
243.185 + return
243.186 + if c.has_option(section, 'file'):
243.187 + file = c.get(section, 'file')
243.188 + if os.path.exists(file):
243.189 + exec_cmd("sh %s" % (file))
243.190 +
243.191 + cmds = [cmd for cmd in c.options(section) if cmd.startswith('cmd')]
243.192 + cmds.sort
243.193 + for cmd in cmds:
243.194 + exec_cmd(c.get(section, cmd))
243.195 +
243.196 +### Program
243.197 +
243.198 +# controlla immediatamente se /home è sotto acl, in caso contrario esce
243.199 +# in condizioni normali trattasi di controllo superfluo, ma su una debian
243.200 +# nuda e cruda...
243.201 +
243.202 +if not has_acl_support('/home'):
243.203 + print "ATTENZIONE: /home non supporta le ACLs - permessi non stabiliti"
243.204 + sys.exit(0)
243.205 +
243.206 +opts, args = optionparse.parse(__doc__)
243.207 +if opts.write:
243.208 + opts.dry_run = True
243.209 +
243.210 +# ConfigParser parse g:group = rwx => g : 'group = rxw', so I parse acl.conf before
243.211 +# ConfigParser. I also allow spaces in the beginning of the line
243.212 +
243.213 +
243.214 +c = ConfigParser.ConfigParser()
243.215 +
243.216 +if opts.file:
243.217 + CONF_FILES = (opts.file)
243.218 +else:
243.219 + CONF_FILES = ('/etc/isi/acl.conf', '/etc/isi/acl-local.conf')
243.220 +
243.221 +if opts.debug:
243.222 + print "reading file:", CONF_FILES
243.223 +
243.224 +for file_name in CONF_FILES:
243.225 + if os.path.exists(file_name):
243.226 + f = InputStream(file_name)
243.227 + c.readfp(f,'cfg')
243.228 +
243.229 +
243.230 +if args:
243.231 + sections = args
243.232 +else:
243.233 + sections = c.sections()
243.234 +
243.235 +if opts.debug:
243.236 + print "sections: ", sections
243.237 +
243.238 +if not opts.nopreexec: exec_section('pre_exec')
243.239 +
243.240 +P = {}
243.241 +for sec in sections:
243.242 + if sec in ('post_exec', 'pre_exec'):
243.243 + continue
243.244 + P[sec] = Perm(name=sec)
243.245 + P[sec].read(c.items(sec))
243.246 + P[sec].apply()
243.247 +
243.248 +if not opts.nopostexec:
243.249 + exec_section('post_exec')
243.250 +
243.251 +
243.252 +if opts.write:
243.253 + f = open('/tmp/isi-perms.ini', 'w')
243.254 + c.write(f)
243.255 + f.close()
243.256 + f = open('/tmp/isi-perms.ini')
243.257 + txt = f.read()
243.258 + print txt
243.259 +
244.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
244.2 +++ b/usr/sbin/isi-quota Mon Apr 26 11:16:23 2010 +0200
244.3 @@ -0,0 +1,72 @@
244.4 +#!/usr/bin/python
244.5 +# -*- coding: utf-8 -*-
244.6 +
244.7 +# This program is free software; you can redistribute it and/or modify
244.8 +# it under the terms of the GNU General Public License as published by
244.9 +# the Free Software Foundation; either version 2, or (at your option)
244.10 +# any later version.
244.11 +
244.12 +# AUTHORS: Massimo Mancini
244.13 +
244.14 +"""
244.15 +ISI-QUOTA attribuisce la quota agli utenti di un gruppo definito sull'albero
244.16 +ldap e la somma di tutte le quote al gruppo stesso
244.17 +
244.18 + filesystem = partizione quotata
244.19 + gruppo = utenti da quotare
244.20 + S1 = soft lim dello spazio disco
244.21 + S2 = hard lim dello spazio disco (deve essere > S1)
244.22 + F1 = soft lim del numero dei files (inode)
244.23 + F2 = soft lim del numero dei files (deve essere > F1)
244.24 +
244.25 +limiti=0 equivale a nessuna quota
244.26 +
244.27 + usage: %prog <filesystem> < gruppo> [ S1 ] [ S2 ] [ F1 ] [ F2 ]
244.28 +
244.29 +"""
244.30 +
244.31 +import isi
244.32 +import sys, os
244.33 +import re
244.34 +import pexpect
244.35 +from dry import optionparse
244.36 +from dry.functions import execute, ExecuteError
244.37 +from isi.filesystem import show_file
244.38 +from isi.conf import defaults
244.39 +from isi.exc import QuotaError
244.40 +
244.41 +# defaults
244.42 +s1 = defaults.QUOTA_S1
244.43 +s2 = defaults.QUOTA_S2
244.44 +f1 = defaults.QUOTA_F1
244.45 +f2 = defaults.QUOTA_F2
244.46 +rep_file = defaults.QUOTA_REP
244.47 +
244.48 +opts, args = optionparse.parse(__doc__)
244.49 +
244.50 +if len(args)==0: print "ERRORE: devi indicare perlomeno filesystem e gruppo"
244.51 +if len(args)==1: print "ERRORE: devi indicare il gruppo"
244.52 +if len(args)>=2:
244.53 + fs = args[0]
244.54 + gruppo = args[1]
244.55 + if len(args)>2: s1 = int(args[2])
244.56 + if len(args)>3: s2 = int(args[3])
244.57 + if len(args)>4: f1 = int(args[4])
244.58 + if len(args)>5: f2 = int(args[5])
244.59 + if s1==0: print "disco: alert limit disabilitato"
244.60 + if s2==0: print "disco: space limit disabilitato"
244.61 + if f1==0: print "file : alert limit disabilitato"
244.62 + if f2==0: print "file : maxnr limit disabilitato"
244.63 +
244.64 +manager = isi.Manager()
244.65 +try:
244.66 + group = manager.get_group(gruppo)
244.67 + group.set_quota(fs, s1, s2, f1, f2)
244.68 + if os.path.isfile(rep_file):
244.69 + show_file(rep_file)
244.70 + else:
244.71 + print "ERRORE nella creazione del file %s" % rep_file
244.72 +except QuotaError, e:
244.73 + print "\nERRORE QUOTA:\n%s" % e
244.74 +
244.75 +
245.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
245.2 +++ b/usr/sbin/isi-setup Mon Apr 26 11:16:23 2010 +0200
245.3 @@ -0,0 +1,1356 @@
245.4 +#!/bin/bash
245.5 +# +-------------------------------------------------+
245.6 +# (C) ReteIsi / www.reteisi.org
245.7 +# +-------------------------------------------------+
245.8 +
245.9 +# This program is free software; you can redistribute it and/or modify
245.10 +# it under the terms of the GNU General Public License as published by
245.11 +# the Free Software Foundation; either version 2, or (at your option)
245.12 +# any later version.
245.13 +#
245.14 +#
245.15 +# AUTORI: Massimo Mancini <[email protected]>
245.16 +# Sandro Dentella <[email protected]>,
245.17 +
245.18 +# installa un sistema reteISI (slapd+samba+struttura delle cartelle)
245.19 +#
245.20 +
245.21 +### controlla le dipendenze e installa i pacchetti mancanti
245.22 +
245.23 +#set -e
245.24 +
245.25 +function check_hg_etc () {
245.26 + local PWD
245.27 + eco y "controllo che /etc sia sotto mercurial"
245.28 + if [ -d /etc/.hg ] ; then
245.29 + eco g "mercurial OK"
245.30 + else
245.31 + eco g "preparo il repository hg per /etc"
245.32 + PWD=$(pwd)
245.33 + cd /etc
245.34 + hg -q init
245.35 + hg -q add *
245.36 + hg -q commit -m "init repo"
245.37 + chmod 600 .hg
245.38 + cd $PWD
245.39 + fi
245.40 +}
245.41 +function new_sid (){
245.42 + eco y "generazione nuovi sid"
245.43 + SID=$(isi-gensid)
245.44 + SID_PDC=$(isi-gensid)
245.45 + if [ -f /etc/samba/domain.SID ] ; then
245.46 + read -p "Esiste un SID memorizzato per il DOMINIO . Vuoi usare questo (s/n)? " RISP
245.47 + N=$(expr match "$RISP" '[yYsS]')
245.48 + if [ "$N" -gt 0 ] ; then
245.49 + SID=$(cat /etc/samba/domain.SID)
245.50 + fi
245.51 + fi
245.52 + if [ -f /etc/samba/pdc.SID ] ; then
245.53 + read -p "Esiste un SID memorizzato per il PDC. Vuoi usare questo (s/n)? " RISP
245.54 + N=$(expr match "$RISP" '[yYsS]')
245.55 + if [ "$N" -gt 0 ] ; then
245.56 + SID=$(cat /etc/samba/domain.SID)
245.57 + fi
245.58 + fi
245.59 + echo $SID > /etc/samba/domain.SID
245.60 + echo $SID_PDC > /etc/samba/pdc.SID
245.61 + eco g "sid di $DOMAIN_NAME salvato in /etc/samba/domain.SID - $SID"
245.62 + eco g "sid di $PDC_NAME salvato in /etc/samba/pdc.SID - $SID_PDC"
245.63 +
245.64 +}
245.65 +function setting_sid () {
245.66 + eco y "setting SIDs"
245.67 + net setdomainsid $SID
245.68 + net setlocalsid $SID_PDC
245.69 +}
245.70 +function read_defaults(){
245.71 +# i dati seguenti possono essere ridefiniti
245.72 +# nel file seguente
245.73 + FILE_DEF="/etc/isi/isi-setup.conf"
245.74 + # distro target
245.75 + [ $IS_UBUNTU = 0 ] && DIST='lenny'
245.76 + [ $IS_UBUNTU = 1 ] && DIST='lenny'
245.77 + # pacchetti
245.78 + PKGS_COMMON='mercurial nscd at acl quota tofrodos procinfo reiserfsprogs xfsprogs slapd libnss-ldap libpam-ldap libnet-ldap-perl samba smbldap-tools migrationtools db4.2-util python-ldap python-dry python-urwid python-isi win-perl isi'
245.79 + PKGS_UBUNTU=" cracklib2 "
245.80 + PKGS_DEBIAN=" libcrack2 "
245.81 + # costanti
245.82 + UTENTI_IN="/home/users"
245.83 + SHARES_IN="/home/shares"
245.84 + CLASSI_IN="$SHARES_IN/classi"
245.85 + CORSI_IN="$SHARES_IN/corsi"
245.86 + PROFILE_DIR=".profili"
245.87 + # defaults (possono essere ridefiniti nel file di conf)
245.88 + MAINGRPS="admins,docenti,segreteria,ata,alunni,esterni,ospiti"
245.89 + AREE="area_alunni,area_docenti,area_segreteria,software"
245.90 + CLASSI="classe_test"
245.91 + CORSI="corso_test"
245.92 + DC1=$(echo $DNS_DOMAIN | awk -F"." '{print $1}')
245.93 + DC2=$(echo $DNS_DOMAIN | awk -F"." '{print $2}')
245.94 + BASE_DN="dc=$DC1,dc=$DC2"
245.95 + SERVER_LDAP=127.0.0.1
245.96 + ROOT_BIND_DN="cn=admin,$BASE_DN"
245.97 + URI_LDAP="ldap://$SERVER_LDAP"
245.98 + SIZELIMIT=5000
245.99 + # smbldap-populate uid e gid iniziali
245.100 +# SMBLDAP_LDIF='/etc/isi/smbldap_ini.ldif'
245.101 +# DOMAIN_ADMIN="Administrator"
245.102 + U_MIN=1000
245.103 + U_MAX=30000
245.104 + G_MIN=1000
245.105 + G_MAX=30000
245.106 + # variabili in /etc/samba/smb.conf e ambiente samba
245.107 + SAMBA_STRING="SERVER ISI"
245.108 + SAMBA_IFACE="eth0"
245.109 + SAMBA_ADD_MACHINE_SCRIPT="/usr/sbin/smbldap-useradd -w "
245.110 +# [ "$USO_PDBEDIT" = 0 ] && SAMBA_ADD_MACHINE_SCRIPT="/usr/sbin/smbldap-useradd -w "
245.111 +# [ "$USO_PDBEDIT" = 1 ] && SAMBA_ADD_MACHINE_SCRIPT="/usr/bin/pdbedit -a -m -u"
245.112 +
245.113 + [ "$USE_CONF" = 1 -a -f "$FILE_DEF" ] && . $FILE_DEF
245.114 +
245.115 + [ "$IS_UBUNTU" = 0 ] && PKGS="$PKGS_DEBIAN $PKGS_COMMON"
245.116 + [ "$IS_UBUNTU" = 1 ] && PKGS="$PKGS_UBUNTU $PKGS_COMMON"
245.117 +
245.118 + if [ ! "$SERVER_LDAP" = "localhost" -a ! "$SERVER_LDAP" = "127.0.0.1" ] ; then
245.119 + eco r "SLAPD NON LOCALE: $SERVER_LDAP, configurazione interrotta"
245.120 + exit 0
245.121 + fi
245.122 + if [ "$DUMP_CONF" = 1 ] ; then
245.123 + [ ! -d /etc/isi ] && mkdir /etc/isi
245.124 + cat <<DUMPEOF > /etc/isi/isi-setup.conf
245.125 +#### DEFAULTs FILE per ISI-SETUP
245.126 +# distribuzione
245.127 +DIST=$DIST
245.128 +PKGS="$PKGS_COMMON"
245.129 +PKGS_UBUNTU="$PKGS_UBUNTU"
245.130 +PKGS_DEBIAN="$PKGS_DEBIAN"
245.131 +# struttura ISI
245.132 +UTENTI_IN="$UTENTI_IN"
245.133 +SHARES_IN="$SHARES_IN"
245.134 +MAINGRPS="$MAINGRPS"
245.135 +AREE="$AREE"
245.136 +CLASSI="$CLASSI"
245.137 +CORSI="$CORSI"
245.138 +# dati dominio
245.139 +SID="$SID"
245.140 +SID_PDC="$SID_PDC"
245.141 +DOMAIN_NAME="$DOMAIN_NAME"
245.142 +PDC_NAME="$PDC_NAME"
245.143 +ORG_NAME="$ORG_NAME"
245.144 +DOMAIN_ADMIN="$DOMAIN_ADMIN"
245.145 +# dati ldap
245.146 +SERVER_LDAP="$SERVER_LDAP"
245.147 +DNS_DOMAIN="$DNS_DOMAIN"
245.148 +BASE_DN="$BASE_DN"
245.149 +ROOT_BIND_DN="$ROOT_BIND_DN"
245.150 +URI_LDAP="$URI_LDAP"
245.151 +LDAP_PWD="$LDAP_PWD"
245.152 +U_MIN=$U_MIN
245.153 +U_MAX=$U_MAX
245.154 +G_MIN=$G_MIN
245.155 +G_MAX=$G_MAX
245.156 +# parametri samba
245.157 +SAMBA_STRING="$SAMBA_STRING"
245.158 +SAMBA_IFACE="$SAMBA_IFACE"
245.159 +SAMBA_ADD_MACHINE_SCRIPT="$SAMBA_ADD_MACHINE_SCRIPT"
245.160 +DUMPEOF
245.161 + chmod 600 /etc/isi/isi-setup.conf
245.162 + eco g "defaults salvati in /etc/isi/isi-setup.conf"
245.163 + [ "$SOLO_DUMP_CONF" = 1 ] && exit
245.164 + fi
245.165 +}
245.166 +
245.167 +function eco() {
245.168 + ESC="\033["
245.169 + RED="${ESC}31;1m"
245.170 + GREEN="${ESC}32;1m"
245.171 + BLUE="${ESC}44;33;1m"
245.172 + YELLOW="${ESC}33;1m"
245.173 + NOR="${ESC}0m"
245.174 +
245.175 + local col=$1
245.176 + shift
245.177 + case $col in
245.178 + g) COL=$GREEN
245.179 + ;;
245.180 + b) COL=$BLUE
245.181 + ;;
245.182 + y) COL=$YELLOW
245.183 + ;;
245.184 + r) COL=$RED
245.185 + ;;
245.186 + n) COL=$NOR
245.187 + ;;
245.188 + esac
245.189 + case $col in
245.190 + [gby]) [ $QUIET = 0 ] && echo -e ${COL}$*$NOR
245.191 + ;;
245.192 + r) echo -e ${COL}$*$NOR 1>&2
245.193 + ;;
245.194 + n) [ $VERBOSE = 1 ] && echo $*
245.195 + ;;
245.196 + esac
245.197 +}
245.198 +
245.199 +function crea_dir (){
245.200 + DOVE=$1
245.201 + COSA=$(echo $2 | sed 's/,/ /g')
245.202 + for x in $COSA; do
245.203 + if [ ! -d "$DOVE/$x" ] ; then
245.204 + eco n "creo $DOVE/$x"
245.205 + mkdir -p $DOVE/$x
245.206 + fi
245.207 + done
245.208 +}
245.209 +
245.210 +function isi_default_stru(){
245.211 + eco y 'Preparazione filesystem ISI'
245.212 + # crea cartelle relative gruppi principali
245.213 + crea_dir $UTENTI_IN $MAINGRPS
245.214 + # crea cartelle classi/corsi
245.215 + crea_dir $CLASSI_IN $CLASSI
245.216 + crea_dir $CORSI_IN $CORSI
245.217 + # crea cartelle aree
245.218 + crea_dir $SHARES_IN $AREE
245.219 + ### copia grub4dos nella share software
245.220 + if [ -d /home/shares/software ] && [ ! -d /home/shares/software/grub4dos ]; then
245.221 + cp -a /usr/share/doc/isi/grub4dos /home/shares/software
245.222 + find /home/shares/software -name \*gz -exec gunzip {} \;
245.223 + fi
245.224 + ### /etc/skel
245.225 + for d in .profili public_html Documenti ; do
245.226 + [ -d /etc.skel/$d ] || mkdir -p /etc/skel/$d
245.227 + done
245.228 + ### i file in /etc/isi saranno installati dal pacchetto isi
245.229 + if [ "$STANDARD_SETUP" = 1 ] ; then
245.230 + [ ! -d /etc/isi ] && mkdir /etc/isi
245.231 + cp -a /usr/share/doc/isi/etc/isi/* /etc/isi/
245.232 + # link simbolico a /usr/lib/isi/acl.conf
245.233 + [ -L /etc/isi/acl.conf ] && rm /etc/isi/acl.conf
245.234 + ln -s /usr/lib/isi/acl.conf /etc/isi/acl.conf
245.235 + ### check isi-logon
245.236 + if [ -f /etc/isi/logon.conf.gz ] ; then
245.237 + [ -f /etc/isi/logon.conf ] && rm /etc/isi/logon.conf
245.238 + gunzip /etc/isi/logon.conf.gz
245.239 + fi
245.240 + for f in logon.conf logon.pl logonupd.pl ; do
245.241 + ff="/usr/share/WinActivePerl/$f"
245.242 + [ -f "$ff" ] && rm $ff
245.243 + ln -s /etc/isi/$f $ff
245.244 + done
245.245 + fi
245.246 + # aggiorna PDC_NAME in logon.bat logonupd.bat
245.247 + OLD_PDC=$(grep "\\\\" /etc/isi/logon.bat | awk -F"\\" '{print $3}')
245.248 + if [ "$OLD_PDC" != "$PDC_NAME" ] ; then
245.249 + sed -i "s%$OLD_PDC%$PDC_NAME%g" /etc/isi/logon.bat
245.250 + sed -i "s%$OLD_PDC%$PDC_NAME%g" /etc/isi/logonupd.bat
245.251 + fi
245.252 +}
245.253 +function _checkapt (){
245.254 + FILE="$1"
245.255 + REPO="$2"
245.256 + DIST="$3"
245.257 + RAMI="$4"
245.258 + local OPZ
245.259 + if ! egrep -q "[\s\t]*$REPO[\s\t]*$DIST[\s\t]*$RAMI" /etc/apt/sources.list ; then
245.260 + sed -i "s/^.*\($REPO.*\)/#\1/" /etc/apt/sources.list
245.261 + echo "deb http://$REPO $DIST $RAMI" >> /etc/apt/sources.list
245.262 + [ "$VERBOSE" = 1 ] && OPZ='' || OPZ='-q'
245.263 + wget $OPZ http://$REPO/dists/$DIST/public.key -O- | apt-key add - >/dev/null
245.264 + fi
245.265 + if grep -q $REPO /etc/apt/sources.list ; then
245.266 + eco g "FONTE APT OK: deb http://$REPO $DIST $RAMI"
245.267 + else
245.268 + eco r "ERRORE: manca la fonte $REPO"
245.269 + exit 1
245.270 + fi
245.271 +}
245.272 +
245.273 +function checkapt () {
245.274 + local op
245.275 + [ "$APT_UPD" = 0 ] && return
245.276 + eco y 'FASE 1: controllo e update delle fonti APT'
245.277 + _checkapt 'reteisi' 'apt.argolinux.org' $DIST 'main'
245.278 + _checkapt 'reteisi' 'apt.reteisi.org' $DIST 'isi'
245.279 + [ "$VERBOSE" = 0 ] && op="-qq" || op=""
245.280 + apt-get update $op
245.281 +}
245.282 +
245.283 +function _checkpkg (){
245.284 + local op
245.285 + if [ "$IS_UBUNTU" = 1 ] ; then
245.286 + if grep -wq $1 /tmp/PKGS_NO_UBUNTU &>/dev/null; then
245.287 + return 0
245.288 + fi
245.289 + fi
245.290 +
245.291 + [ "$APT_UPD" = 0 ] && return
245.292 + op="-y --force-yes"
245.293 + [ "$VERBOSE" = 0 ] && op="$op -qq"
245.294 + if dpkg -l $1 2>/dev/null | grep -q ii ; then
245.295 + eco g "PRESENTE: $1"
245.296 + else
245.297 + eco r "MANCANTE: $1 - installo...ATTENDI..."
245.298 + apt-get install $1 $op
245.299 + if dpkg -l $1 2>/dev/null | grep -q ii ; then
245.300 + eco g "INSTALLATO: $1"
245.301 + else
245.302 + eco r "IMPOSSIBILE installare $1"
245.303 + ERR_PKG="$ERR_PKG $1"
245.304 + fi
245.305 + fi
245.306 +}
245.307 +
245.308 +function check_packages () {
245.309 + ERR_PKG=""
245.310 + eco y 'FASE 2: controllo e/o installazione pacchetti'
245.311 + eco y "CONTROLLO: pacchetti"
245.312 + for p in $PKGS_COMMON ; do
245.313 + _checkpkg $p
245.314 + done
245.315 + if [ -z "$ERR_PKG" ] ; then
245.316 + eco v "pacchetti OK"
245.317 + else
245.318 + eco r "ERRORE FATALE - mancano pacchetti critici:\n\t$ERR_PKG"
245.319 + exit 1
245.320 + fi
245.321 +}
245.322 +
245.323 +function prep_debconf () {
245.324 + # ATTENZIONE qui si utilizza la tecnica del preseed.
245.325 + # È obbligatorio che tra il tipo della variabile debconf e il suo valore
245.326 + # ci sia ESATTAMENTE UNO SPAZIO.
245.327 +
245.328 + [ "$APT_UPD" = 0 ] && return
245.329 + eco y 'Preparazione variabili debconf (APT_UPD=$APT_UPD)'
245.330 + apt-get install debconf-utils -qq
245.331 +
245.332 + export DEBIAN_FRONTEND=noninteractive
245.333 + export DEBIAN_PRIORITY=critical
245.334 +
245.335 + cat <<PRESEED>> /tmp/isi.preseed
245.336 +# LDAP root account password:
245.337 +libpam-ldap libpam-ldap/rootbindpw password $LDAP_PWD
245.338 +# LDAP root account password:
245.339 +libnss-ldap libnss-ldap/rootbindpw password $LDAP_PWD
245.340 +# Encrypted admin password:
245.341 +slapd slapd/internal/adminpw password $LDAP_PWD
245.342 +# Administrator password:
245.343 +slapd slapd/password1 password $LDAP_PWD
245.344 +# Confirm password:
245.345 +slapd slapd/password2 password $LDAP_PWD
245.346 +# Password for database login account:
245.347 +libpam-ldap libpam-ldap/bindpw password
245.348 +# Password for database login account:
245.349 +libnss-ldap libnss-ldap/bindpw password
245.350 +# Does the LDAP database require login?
245.351 +libnss-ldap libnss-ldap/dblogin boolean false
245.352 +# Password mismatch
245.353 +slapd slapd/password_mismatch note
245.354 +# Retry configuration?
245.355 +slapd slapd/invalid_config boolean true
245.356 +# Organization name:
245.357 +slapd shared/organization string $ORG_NAME
245.358 +# Automatically update libnss-ldap's configuration file?
245.359 +libnss-ldap libnss-ldap/override boolean true
245.360 +# How do you want to run Samba?
245.361 +# Choices: daemons, inetd
245.362 +samba samba/run_mode select daemons
245.363 +# Distinguished name of the search base:
245.364 +libnss-ldap shared/ldapns/base-dn string $BASE_DN
245.365 +libpam-ldap shared/ldapns/base-dn string $BASE_DN
245.366 +# LDAP server Uniform Resource Identifier:
245.367 +libnss-ldap shared/ldapns/ldap-server string $URI_LDAP
245.368 +libpam-ldap shared/ldapns/ldap-server string $URI_LDAP
245.369 +# Use password encryption?
245.370 +samba-common samba-common/encrypt_passwords boolean true
245.371 +# Local crypt to use when changing passwords.
245.372 +# Choices: clear, crypt, nds, ad, exop, md5
245.373 +libpam-ldap libpam-ldap/pam_password select crypt
245.374 +# Modify smb.conf to use WINS settings from DHCP?
245.375 +samba-common samba-common/dhcp boolean false
245.376 +# Unprivileged database user:
245.377 +libpam-ldap libpam-ldap/binddn string cn=proxyuser,dc=example,dc=net
245.378 +# Make the configuration file readable/writeable by its owner only?
245.379 +libnss-ldap libnss-ldap/confperm boolean true
245.380 +# Workgroup/Domain Name:
245.381 +samba-common samba-common/workgroup string $DOMAIN_NAME
245.382 +# LDAP account for root:
245.383 +libpam-ldap libpam-ldap/rootbinddn string $ROOT_BIND_DN
245.384 +# LDAP account for root:
245.385 +libnss-ldap libnss-ldap/rootbinddn string $ROOT_BIND_DN
245.386 +# Make local root Database admin.
245.387 +libpam-ldap libpam-ldap/dbrootlogin boolean false
245.388 +# Database backend to use:
245.389 +# Choices: BDB, HDB
245.390 +slapd slapd/backend select HDB
245.391 +# Dump databases to file on upgrade:
245.392 +# Choices: always, when needed, never
245.393 +slapd slapd/dump_database select when needed
245.394 +# Allow LDAPv2 protocol?
245.395 +slapd slapd/allow_ldap_v2 boolean false
245.396 +# Make debconf change your config?
245.397 +libpam-ldap libpam-ldap/override boolean true
245.398 +# Omit OpenLDAP server configuration?
245.399 +slapd slapd/no_configuration boolean false
245.400 +# LDAP version to use:
245.401 +# Choices: 3, 2
245.402 +libnss-ldap shared/ldapns/ldap_version select 3
245.403 +libpam-ldap shared/ldapns/ldap_version select 3
245.404 +# Does the LDAP database require login?
245.405 +libpam-ldap libpam-ldap/dblogin boolean false
245.406 +# Abort installation after depmod error?
245.407 +# Move old database?
245.408 +slapd slapd/move_old_database boolean true
245.409 +# Unprivileged database user:
245.410 +libnss-ldap libnss-ldap/binddn string cn=proxyuser,dc=example,dc=net
245.411 +# Back up current database and create a new one?
245.412 +slapd slapd/suffix_change boolean false
245.413 +# Create samba password database, /var/lib/samba/passdb.tdb?
245.414 +samba samba/generate_smbpasswd boolean true
245.415 +## nsswitch.conf not managed automatically
245.416 +#libnss-ldap libnss-ldap/nsswitch note
245.417 +# Directory to use for dumped databases:
245.418 +slapd slapd/dump_database_destdir string /var/backups/slapd-VERSION
245.419 +# Do you want the database to be removed when slapd is purged?
245.420 +slapd slapd/purge_database boolean false
245.421 +# DNS domain name:
245.422 +slapd slapd/domain string $DNS_DOMAIN
245.423 +# Configure smb.conf automatically?
245.424 +samba-common samba-common/do_debconf boolean true
245.425 +PRESEED
245.426 +
245.427 + debconf-set-selections /tmp/isi.preseed
245.428 + rm /tmp/isi.preseed
245.429 +}
245.430 +
245.431 +function set_in_conf_file() {
245.432 + VAR=$1
245.433 + VALUE=$2
245.434 + SEP_REG="[ \t]"
245.435 + SEP=" "
245.436 + eco n "setting in $CONF_FILE - $VAR $VALUE"
245.437 + # 1^ case: var is not in file: just add it
245.438 + # 2^ case: VAR is in file
245.439 + if ! grep -q $VAR $CONF_FILE ; then
245.440 + echo ${VAR}${SEP}${VALUE} >> $CONF_FILE
245.441 + else
245.442 + sed -i "s%^[ #]*$VAR$SEP_REG.*%$VAR$SEP$VALUE%" $CONF_FILE
245.443 + fi
245.444 +return
245.445 +}
245.446 +function uncomment () {
245.447 + VAR=$1
245.448 + VAL=$2
245.449 + # comment all other poss=ible $1 not commented
245.450 + sed -i "s/^.*\($VAR.*\)/#\1/" $CONF_FILE
245.451 + # uncomment $1 $2
245.452 + sed -i "s/^.*\($VAR *$VAL\)/\1/" $CONF_FILE
245.453 +}
245.454 +function stop_services (){
245.455 +# [ $QUIET = 0 ] && /etc/init.d/slapd stop \
245.456 +# || /etc/init.d/slapd stop >/dev/null
245.457 +
245.458 + #invoke-rc.d slapd stop
245.459 + /etc/init.d/slapd stop
245.460 + until [ "$(pidof slapd)" = "" ] ; do
245.461 + sleep 1
245.462 + if [ "$(pidof slapd)" != "" ] ; then
245.463 + eco r "riprovo a fermare slapd"
245.464 + #invoke-rc.d slapd stop
245.465 + /etc/init.d/slapd stop
245.466 + else
245.467 + break
245.468 + fi
245.469 + i=$((i+1))
245.470 + if [ "$i" = 10 ] ; then
245.471 + eco r "slapd non si ferma !!! - ERRORE FATALE"
245.472 + exit 1
245.473 + fi
245.474 + done
245.475 +
245.476 + #invoke-rc.d samba stop
245.477 + /etc/init.d/samba stop
245.478 + until [ "$(pidof slapd)" = "" ] ; do
245.479 + sleep 1
245.480 + if [ "$(pidof slapd)" != "" ] ; then
245.481 + eco r "riprovo a fermare samba"
245.482 + #invoke-rc.d samba stop
245.483 + /etc/init.d/samba stop
245.484 + else
245.485 + break
245.486 + fi
245.487 + i=$((i+1))
245.488 + if [ "$i" = 10 ] ; then
245.489 + eco r "samba non si ferma !!! - ERRORE FATALE"
245.490 + exit 1
245.491 + fi
245.492 + done
245.493 +
245.494 +
245.495 +# if [ $PIDSLAP != "" ] ; then
245.496 +# eco r 'ERRORE: slapd non si ferma!!! - provo kill -9'
245.497 +# exit 1
245.498 +# fi
245.499 +# [ $QUIET = 0 ] && /etc/init.d/samba stop \
245.500 +# || /etc/init.d/samba stop >/dev/null
245.501 +# PIDS=$(pidof smbd)
245.502 +# PIDN=$(pidof nmbd)
245.503 +# until [ $PIDS != "" -o $PIDN != "" ] ; do
245.504 +# eco r 'ERRORE: samba non si ferma!!! provo kill -9'
245.505 +# kill -9 PIDS
245.506 +# kill -9 PIDN
245.507 +# PIDS=$(pidof smbd)
245.508 +# PIDN=$(pidof nmbd)
245.509 +# done
245.510 +}
245.511 +function start_services (){
245.512 + [ "$QUIET" = 0 ] && /etc/init.d/slapd start \
245.513 + || /etc/init.d/slapd start >/dev/null
245.514 +
245.515 + PID1=$(pgrep -c slapd)
245.516 + if [ "$PID1" = 0 ] ; then
245.517 + eco r 'ERRORE: slapd non parte!!!'
245.518 + exit 1
245.519 + else
245.520 + [ "$QUIET" = 0 ] && /etc/init.d/samba start \
245.521 + || /etc/init.d/samba start >/dev/null
245.522 + PID1=$(pgrep -c smbd)
245.523 + PID2=$(pgrep -c nmbd)
245.524 + if [ "$PID1" = 0 -o "$PID2" = 0 ] ; then
245.525 + eco r 'ERRORE: samba non parte!!!'
245.526 + exit 1
245.527 + fi
245.528 + fi
245.529 + eco g "slapd/samba correttamente avviati"
245.530 +}
245.531 +function check_secrets (){
245.532 + eco y "setting /etc/ldap.secret"
245.533 + rm -f /etc/libnss-ldap.secret
245.534 + rm -f /etc/pam_ldap.secret
245.535 + echo $LDAP_PWD > /etc/ldap.secret
245.536 + chmod 600 /etc/ldap.secret
245.537 + ln -s /etc/ldap.secret /etc/libnss-ldap.secret
245.538 + ln -s /etc/ldap.secret /etc/pam_ldap.secret
245.539 +}
245.540 +function setting_ldap (){
245.541 + eco y "setting conf ldap"
245.542 + if [ "$IS_UBUNTU" = 0 ] ; then #lenny/etch
245.543 + ### conf of /etc/ldap/ldap.conf
245.544 + CONF_FILE="/etc/ldap/ldap.conf"
245.545 + set_in_conf_file "BASE" "$BASE_DN"
245.546 + set_in_conf_file "URI" "$URI_LDAP"
245.547 + set_in_conf_file "HOST" "$SERVER_LDAP"
245.548 + set_in_conf_file "SIZELIMIT" "$SIZELIMIT"
245.549 +
245.550 + # defaults for libnss
245.551 + CONF_FILE="/etc/libnss-ldap.conf"
245.552 + if [ -e "$CONF_FILE" ] ; then
245.553 + set_in_conf_file "base" "$BASE_DN"
245.554 + set_in_conf_file "host" "$SERVER_LDAP"
245.555 + set_in_conf_file "ldap_version" "3"
245.556 + set_in_conf_file "rootbinddn" "$ROOT_BIND_DN"
245.557 + if [[ "$(expr match $URI_LDAP ldaps?://)" -gt 7 ]]; then
245.558 + set_in_conf_file "uri" "$URI_LDAP"
245.559 + fi
245.560 + uncomment "pam_password" "exop"
245.561 + XX=$(egrep "^[^#]*uri ldapi:///" $CONF_FILE)
245.562 + [ -z "$XX" ] || sed -i "s%^.*$XX%\#$XX%g" $CONF_FILE
245.563 + fi
245.564 +
245.565 + # defaults for libpam_ldap
245.566 + CONF_FILE="/etc/pam_ldap.conf"
245.567 + if [ -e "$CONF_FILE" ] ; then
245.568 + set_in_conf_file "base" "$BASE_DN"
245.569 + set_in_conf_file "host" "$SERVER_LDAP"
245.570 + set_in_conf_file "ldap_version" "3"
245.571 + set_in_conf_file "rootbinddn" "$ROOT_BIND_DN"
245.572 + uncomment "pam_password" "exop"
245.573 + XX=$(egrep "^[^#]*uri ldapi:///" $CONF_FILE)
245.574 + [ -z "$XX" ] || sed -i "s%^.*$XX%\#$XX%g" $CONF_FILE
245.575 + fi
245.576 + else #ubuntu
245.577 + ### conf of /etc/ldap/ldap.conf
245.578 + CONF_FILE="/etc/ldap/ldap.conf"
245.579 + set_in_conf_file "BASE" "$BASE_DN"
245.580 + set_in_conf_file "URI" "$URI_LDAP"
245.581 + set_in_conf_file "HOST" "$SERVER_LDAP"
245.582 + set_in_conf_file "SIZELIMIT" "$SIZELIMIT"
245.583 +
245.584 + CONF_FILE="/etc/ldap.conf"
245.585 + if [ -e "$CONF_FILE" ] ; then
245.586 + set_in_conf_file "base" "$BASE_DN"
245.587 + set_in_conf_file "host" "$SERVER_LDAP"
245.588 + set_in_conf_file "ldap_version" "3"
245.589 + set_in_conf_file "rootbinddn" "$ROOT_BIND_DN"
245.590 + uncomment "pam_password" "exop"
245.591 + fi
245.592 +
245.593 + # defaults for ldap.conf
245.594 + CONF_FILE="/etc/ldap.conf"
245.595 + if [ -e "$CONF_FILE" ] ; then
245.596 + set_in_conf_file "base" "$BASE_DN"
245.597 + set_in_conf_file "host" "$SERVER_LDAP"
245.598 + set_in_conf_file "ldap_version" "3"
245.599 + set_in_conf_file "rootbinddn" "$ROOT_BIND_DN"
245.600 + if [[ "$(expr match $URI_LDAP ldaps?://)" -gt 7 ]]; then
245.601 + set_in_conf_file "uri" "$URI_LDAP"
245.602 + fi
245.603 + uncomment "pam_password" "exop"
245.604 + XX=$(egrep "^[^#]*uri ldapi:///" $CONF_FILE)
245.605 + [ -z "$XX" ] || sed -i "s%^.*$XX%\#$XX%g" $CONF_FILE
245.606 + fi
245.607 + fi
245.608 +}
245.609 +
245.610 +function slap_add_indexes () {
245.611 + # adding slapd indexes only if they are not yet there
245.612 + if ! grep -q "eq,subinitial" /etc/ldap/slapd.conf ; then
245.613 + cp /etc/ldap/slapd.conf /tmp/slapd.conf
245.614 + eco y "Adding indexed to /etc/ldap/slapd.conf"
245.615 + awk ' {print}
245.616 + $1 == "index" && $2 == "objectClass" {
245.617 + print "index uid,uidNumber,gidNumber,memberUid eq"
245.618 + print "index cn,sn eq,subinitial"
245.619 + print "index sambaSID eq"
245.620 + print "index sambaPrimaryGroupSID eq"
245.621 + print "index sambaDomainName eq"
245.622 + print "index DisplayName eq"
245.623 + print "index sambaGroupType eq"
245.624 + print "index sambaSIDList eq"
245.625 + print "index uniqueMember eq"
245.626 + }' /tmp/slapd.conf > /etc/ldap/slapd.conf
245.627 + rm /tmp/slapd.conf
245.628 + fi
245.629 + if ! grep -q "sambaPwdMustChange" /etc/ldap/slapd.conf ; then
245.630 + cp /etc/ldap/slapd.conf /tmp/slapd.conf
245.631 + eco y "special access to pass* fields"
245.632 + awk ' $3 == "attrs=userPassword" {
245.633 + $0="access to attrs=userPassword, sambaNTPassword, sambaLMPassword, sambaPwdLastSet,sambaPwdMustChange, employeeNumber"
245.634 + }
245.635 + {print}' /tmp/slapd.conf > /etc/ldap/slapd.conf
245.636 + rm /tmp/slapd.conf
245.637 + fi
245.638 +}
245.639 +function slap_add_samba_schema () {
245.640 + #[ -f /etc/ldap/schema/samba.schema ] && return
245.641 + SCHEMA=/usr/share/doc/isi/etc/samba/samba.schema.gz
245.642 + if [ -f "$SCHEMA" ] ; then
245.643 + zcat $SCHEMA > /etc/ldap/schema/samba.schema
245.644 + eco n "Adding samba.schema to /etc/ldap/slapd.conf"
245.645 + if ! grep -q "/etc/ldap/schema/samba.schema" /etc/ldap/slapd.conf ; then
245.646 + cp /etc/ldap/slapd.conf /tmp/slapd.conf
245.647 + awk ' {print}
245.648 + /inetorgperson/ {print "include\t\t/etc/ldap/schema/samba.schema"}
245.649 + ' /tmp/slapd.conf > /etc/ldap/slapd.conf
245.650 + rm /tmp/slapd.conf
245.651 + fi
245.652 + else
245.653 + eco r "ERRORE FATALE: manca samba.schema"
245.654 + exit 1
245.655 + fi
245.656 +}
245.657 +function check_nsswitch() {
245.658 + eco y "setting /etc/nsswitch.conf"
245.659 + # password group shadow
245.660 + for string in passwd group shadow; do
245.661 + if ! egrep -q "$string.*ldap" /etc/nsswitch.conf ; then
245.662 + eco n "Adding 'ldap' to /etc/nsswitch.conf for $string"
245.663 + cp /etc/nsswitch.conf /tmp
245.664 + awk '{if($1 ~ string) {print string"\t files ldap"}
245.665 + else print
245.666 + }' string=$string: /tmp/nsswitch.conf > /etc/nsswitch.conf
245.667 + fi
245.668 + done
245.669 +}
245.670 +function check_pam() {
245.671 + # password group shadow
245.672 + eco y "setting pam"
245.673 + local PWD
245.674 + PWD=$(pwd)
245.675 + cd /etc/pam.d
245.676 +
245.677 + for file in account auth password session; do
245.678 + file=common-$file
245.679 + [ ! -e "$file" ] && continue
245.680 + if ! grep pam_ldap.so $file > /dev/null ; then
245.681 + eco n "Adding sufficient pam_ldap.so to /etc/pam.d/$file"
245.682 + cp $file /tmp
245.683 + awk '$3 == "pam_unix.so" {print $1"\t sufficient pam_ldap.so"
245.684 + if ($1 == "auth" && $0 !~ /first_pass/) {
245.685 + $0=$0" use_first_pass"
245.686 + }
245.687 + }
245.688 + {print}' /tmp/$file > $file
245.689 + rm -f /tmp/$file
245.690 + fi
245.691 + done
245.692 + # force smbd to reload pam setting
245.693 + /etc/init.d/ssh reload 1> /dev/null 2>&1
245.694 + #killall -HUP smbd 2> /dev/null ||true
245.695 + cd $PWD
245.696 +}
245.697 +function crea_smb_conf () {
245.698 + eco y "configuro Samba"
245.699 + # utmp logfile
245.700 + mkdir -p /var/log/samba/utmp
245.701 + mkdir -p /var/log/samba/wtmp
245.702 + touch /var/log/samba/utmp/utmpx
245.703 + touch /var/log/samba/wtmp/wtmpx
245.704 + # cancella eventuale wins.dat
245.705 + [ -f /var/lib/samba/wins.dat ] && rm /var/lib/samba/wins.dat
245.706 + # /etc/samba/smb.conf
245.707 + cat <<EOF > /etc/samba/smb.conf
245.708 +[global]
245.709 + workgroup = $DOMAIN_NAME
245.710 + netbios name = $PDC_NAME
245.711 + server string = %h $SERVER_STRING
245.712 + dns proxy = No
245.713 + bind interfaces only = Yes
245.714 + interfaces = lo, $SAMBA_IFACE
245.715 + smb ports = 139
245.716 +# invalid users = root
245.717 +# admin users = root,@admins
245.718 +# printer admin = @lpadmin
245.719 +
245.720 +### registra i logon via samba
245.721 + utmp = Yes
245.722 + utmp directory = /var/log/samba/utmp
245.723 + wtmp directory = /var/log/samba/wtmp
245.724 +
245.725 +### evita l'apertura di notepad con un file desktop.ini
245.726 + hide files = /desktop.ini/ntuser.ini/NTUSER.*/
245.727 +
245.728 +### conserva i permessi e i privilegi dei file dell'utente
245.729 + inherit acls = yes
245.730 + inherit owner = yes
245.731 +
245.732 + log file = /var/log/samba/log.%m
245.733 + max log size = 1000
245.734 + syslog = 0
245.735 + log level = 1
245.736 +
245.737 + security = user
245.738 + encrypt passwords = true
245.739 + passdb backend = ldapsam:ldap://$SERVER_LDAP/
245.740 + obey pam restrictions = no
245.741 + deadtime = 15
245.742 + browseable = no
245.743 +
245.744 + wins support = Yes
245.745 + name resolve order = lmhosts host wins bcast
245.746 +
245.747 + local master = yes
245.748 + domain master = Yes
245.749 + preferred master = Yes
245.750 + os level = 254
245.751 + domain logons = Yes
245.752 +
245.753 +# map system = yes
245.754 +# map archive = yes
245.755 +# map hidden = yes
245.756 +
245.757 + unix password sync = no
245.758 + enable privileges = yes
245.759 + passwd program = /usr/sbin/smbldap-passwd %u
245.760 + passwd chat = *New*password* %n\n *Retype*new*password* %n\n
245.761 + socket options = TCP_NODELAY, SO_KEEPALIVE
245.762 +
245.763 + load printers = yes
245.764 + printing = cups
245.765 + printcap name = cups
245.766 +
245.767 + ldap ssl = no
245.768 + ldap passwd sync = yes
245.769 + ldap machine suffix = ou=Computers
245.770 + ldap idmap suffix = ou=Idmaps
245.771 + ldap group suffix = ou=Groups
245.772 + ldap user suffix = ou=People
245.773 + ldap suffix = $BASE_DN
245.774 + ldap delete dn = Yes
245.775 + ldap admin dn = $ROOT_BIND_DN
245.776 +
245.777 + logon home = \\\\%N\\%U\\.\\\\.profili\\%a
245.778 + logon drive = H:
245.779 + logon path = \\\\%N\\%U\\.profili\\%a
245.780 + logon script = logon.bat
245.781 +
245.782 + add machine script = $SAMBA_ADD_MACHINE_SCRIPT "%m"
245.783 + set primary group script = /usr/sbin/smbldap-usermod -g "%g" "%u"
245.784 + delete user from group script = /usr/sbin/smbldap-groupmod -x "%u" "%g"
245.785 + add user to group script = /usr/sbin/smbldap-groupmod -m "%u" "%g"
245.786 + delete group script = /usr/sbin/smbldap-groupdel "%g"
245.787 + add group script = /usr/sbin/smbldap-groupadd -p "%g"
245.788 + delete user script = /usr/sbin/smbldap-userdel "%u"
245.789 + add user script = /usr/sbin/smbldap-useradd -m "%u"
245.790 +
245.791 + check password script = /usr/bin/crackcheck -s
245.792 +
245.793 + panic action = /usr/share/samba/panic-action %d
245.794 +
245.795 +[homes]
245.796 + comment = ISI-homes (NON MODIFICARE QUESTA RIGA)
245.797 + browseable = no
245.798 + writable = yes
245.799 + guest ok = no
245.800 + veto files = /public_html/
245.801 +
245.802 +[printers]
245.803 + comment = All Printers
245.804 + browseable = no
245.805 + path = /tmp
245.806 + printable = yes
245.807 + public = no
245.808 + writable = no
245.809 + create mode = 0700
245.810 +
245.811 +[print$]
245.812 + comment = Printer Drivers
245.813 + path = /var/lib/samba/printers
245.814 + browseable = yes
245.815 + read only = yes
245.816 + guest ok = no
245.817 + write list = @lpadmin, root
245.818 +
245.819 +include = /etc/isi/samba/smb_servizi.conf
245.820 +#include = /etc/isi/samba/smb_maingrps.conf
245.821 +include = /etc/isi/samba/smb_classi.conf
245.822 +include = /etc/isi/samba/smb_corsi.conf
245.823 +include = /etc/isi/samba/smb_aree.conf
245.824 +
245.825 +[perl]
245.826 + path = /usr/share/WinActivePerl
245.827 + comment = Per Windows Binaries
245.828 + public = yes
245.829 + writable = no
245.830 + guest ok = yes
245.831 + browseable = no
245.832 +
245.833 +
245.834 +[netlogon]
245.835 + comment = ISI-NetLogon (NON MODIFICARE QUESTA RIGA)
245.836 + path = /home/samba/netlogon
245.837 + guest ok = yes
245.838 + browseable = no
245.839 + create mask = 0644
245.840 + directory mask = 0755
245.841 + writable = yes
245.842 + root preexec=/usr/sbin/setlogonvar '%U' '%G' '%m'
245.843 + root postexec=/usr/sbin/rmlogonvar '%m'
245.844 +
245.845 +#[profiles]
245.846 +# comment = cartelle profili utente
245.847 +# path = $UTENTI_IN/%g/%u/$PROFILE_DIR%a
245.848 +# read only = No
245.849 +# create mask = 0660
245.850 +# directory mask = 2770
245.851 +# browseable = No
245.852 +# guest ok = Yes
245.853 +# profile acls = Yes
245.854 +# csc policy = disable
245.855 +# # next line is a great way to secure the profiles
245.856 +# force user = %U
245.857 +
245.858 +EOF
245.859 +
245.860 + # /home/samba/netlogon
245.861 + [ -d /home/samba/netlogon ] || mkdir -p /home/samba/netlogon
245.862 + # crea la dir per la registrazionre dei login via samba
245.863 + [ -d /var/www/sambalogon ] || mkdir -p /var/www/sambalogon
245.864 + # crea link simbolici a logon*.bat
245.865 + for f in logon.bat logonupd.bat ; do
245.866 + [ -e /home/samba/netlogon/$f ] && rm /home/samba/netlogon/$f
245.867 + ln -s /etc/isi/$f /home/samba/netlogon/$f
245.868 + done
245.869 +}
245.870 +function add_env_folder () {
245.871 + # aggiunge le cartelle d'ambiente env_WinXX_gruppo
245.872 + # con WinXX = Win98 e WinXP
245.873 + local PROGRAM_DIR=/usr/share/doc/isi/logon/WinMenuAvvio/Programmi
245.874 + eco y "creo le cartelle /home/samba/netlogon/ENV..."
245.875 + GRUPPI=$(echo $MAINGRPS|sed 's/,/ /g')
245.876 + for grp in $GRUPPI ; do
245.877 + for os in Win98 WinXP ; do
245.878 + DIRENV=/home/samba/netlogon/env_$os\_$grp
245.879 + if [ ! -d "$DIRENV" ] ; then
245.880 + mkdir -p $DIRENV/Desktop
245.881 + mkdir -p $DIRENV/Menu\ Avvio
245.882 + # regalino: link all'applet CambiaPassword del controlpanel
245.883 + if [ "$os" = "Win98" ] ; then
245.884 + cp /usr/share/doc/isi/logon/WinDesktop/Cambia* \
245.885 + $DIRENV/Desktop
245.886 + if [ -d $PROGRAM_DIR ] ; then
245.887 + cp -a /usr/share/doc/isi/logon/WinMenuAvvio/Programmi \
245.888 + $DIRENV/Menu\ Avvio
245.889 + fi
245.890 + fi
245.891 + chmod -R 775 $DIRENV
245.892 + fi
245.893 + done
245.894 + done
245.895 + chown -R root.admins /home/samba/netlogon/env* || echo admins non ancora presente...
245.896 +
245.897 +}
245.898 +
245.899 +function fix_ldap_sambaAlgorithmicRidBase () {
245.900 +
245.901 + ## Qui abbiamo un problema. smbldap-populate non crea (!!!)
245.902 + ## sambaAlgorithmicRidBase
245.903 +
245.904 + OPTS=" -D $ROOT_BIND_DN -w $LDAP_PWD "
245.905 + ldapsearch -xLLL $OPTS "(sambaDomainName=$DOMAIN_NAME)" > /tmp/dom.ldif
245.906 + ## controlla esistenza gidNumber
245.907 + if ! grep sambaAlgorithmicRidBase /tmp/dom.ldif >/dev/null; then
245.908 + eco y "fix sambaAlgorithmicRidBase: 1000"
245.909 + cat <<EOF > /tmp/dom.ldif
245.910 +dn: sambaDomainName=$DOMAIN_NAME,$BASE_DN
245.911 +changetype: modify
245.912 +add: sambaAlgorithmicRidBase
245.913 +sambaAlgorithmicRidBase: 1000
245.914 +EOF
245.915 + ldapmodify -x $OPTS -f /tmp/dom.ldif
245.916 + fi
245.917 +}
245.918 +
245.919 +function conf_populate {
245.920 + eco y "popolo ldap con i gruppi predefiniti Windows"
245.921 + S_UID=$(getent passwd | \
245.922 + awk -F":" -v umin=$U_MIN -v umax=$U_MAX \
245.923 + '$3 >= umin && $3 <= umax {print $3}'| \
245.924 + sort -nr | head -n 1)
245.925 + S_GID=$(getent group | \
245.926 + awk -F':' -v gmin=$G_MIN -v gmax=$G_MAX \
245.927 + '$3 >= gmin && $3 <= gmax {print $3}' | \
245.928 + sort -nr | head -n 1)
245.929 +
245.930 + [ -z "$S_UID" ] && S_UID=$U_MIN
245.931 + [ -z "$S_GID" ] && S_GID=$G_MIN
245.932 +
245.933 + [ "$S_UID" -lt "$U_MIN" ] && S_UID=$U_MIN
245.934 + [ "$S_GID" -lt "$G_MIN" ] && S_GID=$G_MIN
245.935 +
245.936 + [ "$S_UID" -gt "$U_MIN" ] && S_UID=`expr $S_UID + 1`
245.937 + [ "$S_GID" -gt "$G_MIN" ] && S_GID=`expr $S_GID + 1`
245.938 +
245.939 + if [ "$DOMAIN_ADMIN" = "root" ] ; then
245.940 + POPOPZ="-u $S_UID -g $S_GID"
245.941 + else
245.942 + A_UID=$S_UID
245.943 + S_UID=`expr $S_UID + 1`
245.944 + POPOPZ="-u $S_UID -g $S_GID -a $DOMAIN_ADMIN -k $A_UID -m 512"
245.945 + fi
245.946 + PWD2="$LDAP_PWD\n$LDAP_PWD\n"
245.947 +
245.948 + if [ "$QUIET" = 1 ] ; then
245.949 + echo -e $PWD2 | smbldap-populate $POPOPZ > /dev/null
245.950 + else
245.951 + echo -e $PWD2 | smbldap-populate $POPOPZ
245.952 + fi
245.953 + ### controllo allineamento uid/gid
245.954 +# isi-tools -N $DOMAIN_NAME > /dev/null
245.955 +}
245.956 +function grant_permission_to_domain_admin () {
245.957 + eco y "assegno i privilegi amministrativi a Domain Admins e $DOMAIN_ADMIN"
245.958 + ### ATTENZIONE: anche senza questo il join e' impossibile!
245.959 + ### smbldap-populate aggiunge Adminstrator con loginShell=/bin/false
245.960 + ### questo impedisce il join: xp risponde "Utente non trovato"
245.961 +
245.962 +# isi-changeattr -u $DOMAIN_ADMIN loginShell "/bin/bash"
245.963 +# ADMIN_HOME=$(isi-getattr Administrator homeDirectory)
245.964 +# [ -d $ADMIN_HOME ] || mkdir -p $ADMIN_HOME
245.965 +
245.966 + ### sembra necessaria anche la ripetizione su Administrator
245.967 +
245.968 + UP="$DOMAIN_ADMIN%$LDAP_PWD"
245.969 + P1=SeMachineAccountPrivilege
245.970 + P2=SeTakeOwnershipPrivilege
245.971 + P3=SeBackupPrivilege
245.972 + P4=SeRestorePrivilege
245.973 + P5=SeRemoteShutdownPrivilege
245.974 + P6=SePrintOperatorPrivilege
245.975 + P7=SeAddUsersPrivilege
245.976 + P8=SeDiskOperatorPrivilege
245.977 +
245.978 + net -U $UP rpc rights grant "Domain Admins" $P1 $P2 $P3 $P4 $P5 $P6 $P7 $P8
245.979 +# net -U $UP rpc rights grant $DOMAIN_ADMIN $P1 $P2 $P3 $P4 $P5 $P6 $P7 $P8
245.980 +
245.981 + if [ "$ADMIN_IS_NORMAL_USER" = 1 ] ; then
245.982 + eco g "rendo $DOMAIN_ADMIN un utente normale"
245.983 + isi-changeattr -u $DOMAIN_ADMIN loginShell "/bin/bash"
245.984 + ADMIN_HOME=$UTENTI_IN/admins/$DOMAIN_ADMIN
245.985 + [ -d "$ADMIN_HOME" ] || mkdir -p $ADMIN_HOME
245.986 + isi-changeattr -u $DOMAIN_ADMIN homeDirectory "$ADMIN_HOME"
245.987 + cp -a /etc/skel/* $ADMIN_HOME
245.988 + [ -d "$ADMIN_HOME/.profili" ] || mkdir $ADMIN_HOME/.profili
245.989 + isi-adduser $DOMAIN_ADMIN admins
245.990 + chown -R $DOMAIN_ADMIN $ADMIN_HOME
245.991 + fi
245.992 +}
245.993 +
245.994 +function crea_smbldap_conf_file(){
245.995 +cat <<CONF1 > /etc/smbldap-tools/smbldap.conf
245.996 +SID="$SID"
245.997 +slaveLDAP="$SERVER_LDAP"
245.998 +slavePort="389"
245.999 +masterLDAP="$SERVER_LDAP"
245.1000 +masterPort="389"
245.1001 +ldapTLS="0"
245.1002 +suffix="$BASE_DN"
245.1003 +usersdn="ou=People,$BASE_DN"
245.1004 +computersdn="ou=Computers,$BASE_DN"
245.1005 +groupsdn="ou=Groups,$BASE_DN"
245.1006 +idmapdn="ou=Idmap,$BASE_DN"
245.1007 +sambaUnixIdPooldn="sambaDomainName=$DOMAIN_NAME,$BASE_DN"
245.1008 +scope="sub"
245.1009 +hash_encrypt="SSHA"
245.1010 +crypt_salt_format="%s"
245.1011 +userLoginShell="/bin/bash"
245.1012 +userHome="/home/%U"
245.1013 +userGecos="System User"
245.1014 +defaultUserGid="513"
245.1015 +defaultComputerGid="515"
245.1016 +skeletonDir="/etc/skel"
245.1017 +defaultMaxPasswordAge="99"
245.1018 +userSmbHome=""
245.1019 +userProfile=""
245.1020 +userHomeDrive=""
245.1021 +mailDomain="$DNS_DOMAIN
245.1022 +with_smbpasswd="0"
245.1023 +smbpasswd="/usr/bin/smbpasswd"
245.1024 +defaultComputerGid0="515"
245.1025 +CONF1
245.1026 +
245.1027 +cat <<CONF2 > /etc/smbldap-tools/smbldap_bind.conf
245.1028 +slaveDN="$ROOT_BIND_DN"
245.1029 +slavePw="$LDAP_PWD"
245.1030 +masterDN="$ROOT_BIND_DN"
245.1031 +masterPw="$LDAP_PWD"
245.1032 +CONF2
245.1033 +}
245.1034 +
245.1035 +function reset_samba_secretdb (){
245.1036 + eco y "riscrivo /var/lib/samba/secret.tdb"
245.1037 + [ -f /var/lib/samba/secret.tdb ] && rm /var/lib/samba/secret.tdb
245.1038 + [ "$QUIET" = 0 ] && smbpasswd -w $LDAP_PWD
245.1039 + [ "$QUIET" = 1 ] && smbpasswd -w $LDAP_PWD > /dev/null
245.1040 +}
245.1041 +
245.1042 +function crea_gruppi_isi (){
245.1043 + GRUPPI=$(echo "$MAINGRPS,$CLASSI,$CORSI,nowww" | sed 's/,/ /g')
245.1044 + eco y "crea gruppi principali isi $GRUPPI"
245.1045 + isi-addgroup --quiet $GRUPPI
245.1046 + isi-addgroup --system --quiet plugdev audio
245.1047 +}
245.1048 +
245.1049 +
245.1050 +function check_acl_quota () {
245.1051 +
245.1052 + [ "$ACL_IN_FSTAB" = 0 -a "$QUOTA_IN_FSTAB" = 0 ] && return
245.1053 +
245.1054 + home=$(grep -w "/home" /etc/fstab)
245.1055 +
245.1056 + if [ -z "$home" ] ; then
245.1057 + home=$(grep -w "/" /etc/fstab)
245.1058 + fi
245.1059 +
245.1060 + dv=$(echo $home| awk '{print $1}')
245.1061 + mp=$(echo $home| awk '{print $2}')
245.1062 + fs=$(echo $home| awk '{print $3}')
245.1063 + op=$(echo $home| awk '{print $4}')
245.1064 + z1=$(echo $home| awk '{print $5}')
245.1065 + z2=$(echo $home| awk '{print $6}')
245.1066 +
245.1067 + if [ "$fs" != "xfs" ] ; then
245.1068 + if [ "$ACL_IN_FSTAB" = 1 ] ; then
245.1069 + if ! echo $op | grep -q acl ; then op="$op,acl" ; fi
245.1070 + fi
245.1071 + fi
245.1072 + if [ "$QUOTA_IN_FSTAB" = 1 ] ; then
245.1073 + if ! echo $op | grep -q usrquota ; then op="$op,usrquota" ; fi
245.1074 + if ! echo $op | grep -q grpquota ; then op="$op,grpquota" ; fi
245.1075 + fi
245.1076 +
245.1077 + home2="$dv $mp $fs $op $z1 $z2"
245.1078 + sed -i "s%^.*$home%$home2%" /etc/fstab
245.1079 +
245.1080 + if ! grep -q "$home2" /etc/fstab ; then
245.1081 + eco r "problemi acl/quota in /etc/fstab - correggere manualmente"
245.1082 + else
245.1083 + if [ "$REMOUNT_HOME" = 1 ] ; then
245.1084 + eco v "check acl/quota ok - remount $mp"
245.1085 + if ! mount $mp -o remount ; then
245.1086 + eco r "ERRORE: remount $mp fallito"
245.1087 + else
245.1088 + #TODO: attivazione quota
245.1089 + if grep -q usrquota /etc/fstab ; then
245.1090 + [ "$QUIET" = 0 ] && /etc/init.d/quota restart
245.1091 + [ "$QUIET" = 1 ] && /etc/init.d/quota restart > /dev/null
245.1092 + RETVAL=$?
245.1093 + if [ "$RETVAL" != "0" ] ; then
245.1094 + eco r "ATTENZIONE: problemi con la quota (retval = $RETVAL)"
245.1095 + fi
245.1096 + fi
245.1097 + fi
245.1098 + fi
245.1099 + fi
245.1100 +}
245.1101 +
245.1102 +function slap_index () {
245.1103 + eco y "rigenero gli indici ldap"
245.1104 + slapindex 2>/dev/null # la redirezione elimina un warning
245.1105 + chown openldap.openldap /var/lib/ldap/*
245.1106 +}
245.1107 +function fine(){
245.1108 + [ "$QUIET" = 1 ] && return
245.1109 + echo -e $YELLOW
245.1110 + cat <<FINE
245.1111 +$BORDO
245.1112 +L'installazione del software ReteISI è terminata. Dati installazione:
245.1113 +DOMINIO............= $DOMAIN_NAME
245.1114 +NOME PDC...........= $PDC_NAME
245.1115 +PWD ADMIN LDAP.....= $LDAP_PWD
245.1116 +ORGANIZZAZIONE.....= $ORG_NAME
245.1117 +DOMINIO DNS........= $DNS_DOMAIN
245.1118 +SID................= $SID
245.1119 +SID_PDC............: $SID_PDC
245.1120 +$BORDO
245.1121 +Puoi cambiare dominio ldap/samba con il comando:
245.1122 + isi-domain DOMINIO PDC PASSWORD
245.1123 +$BORDO
245.1124 +FINE
245.1125 + echo -e $NOR
245.1126 +}
245.1127 +function slapd_reconfigure (){
245.1128 + if grep -q $BASE_DN /etc/ldap/slapd.conf ; then
245.1129 + return
245.1130 + fi
245.1131 + eco y "riconfigurazione slapd"
245.1132 + APT_UPD=1
245.1133 + prep_debconf
245.1134 + [ "$QUIET" = 0 ] && dpkg-reconfigure slapd
245.1135 + [ "$QUIET" = 1 ] && dpkg-reconfigure slapd > /dev/null
245.1136 +}
245.1137 +function change_hostname (){
245.1138 + OLD_HOSTNAME=$(hostname)
245.1139 + ### squid
245.1140 + FILE=/etc/squid.conf
245.1141 + if [ -e "$FILE" ] ; then
245.1142 + cp $FILE $FILE.2
245.1143 + sed "s/^visible_hostname.*$/visible_hostname $PDC_NAME/" \
245.1144 + < $FILE.2 > $FILE
245.1145 + rm $FILE.2
245.1146 + fi
245.1147 + FILE=/etc/squid/squid.conf
245.1148 + if [ -e "$FILE" ] ; then
245.1149 + cp $FILE $FILE.2
245.1150 + sed "s/^visible_hostname.*$/visible_hostname $PDC_NAME/" \
245.1151 + < $FILE.2 > $FILE
245.1152 + rm $FILE.2
245.1153 + fi
245.1154 + ### postfix
245.1155 + [ -x /usr/sbin/postconf ] && postconf -e "myhostname = $PDC_NAME"
245.1156 + ### /etc/hostname
245.1157 + echo $PDC_NAME > /etc/hostname
245.1158 + /etc/init.d/hostname.sh start > /dev/null
245.1159 + ### /etc/mailname
245.1160 + echo $PDC_NAME > /etc/mailname
245.1161 + ### /etc/hosts
245.1162 + FILE=/etc/hosts
245.1163 + cp $FILE $FILE.2
245.1164 + sed -i "s%argo-cd.argo.it%$PDC_NAME%" $FILE
245.1165 + rm $FILE.2
245.1166 + hostname $PDC_NAME
245.1167 +}
245.1168 +
245.1169 +function set_nscd_conf_file(){
245.1170 + eco y "setting conf /etc/nscd.conf"
245.1171 + if [ -f /etc/nscd.conf ] ; then
245.1172 + ### conf of CONF_FILE="/etc/nscd.conf"
245.1173 + perl -i -p -e '{$_ =~ s/(persistent\s+(group|passwd|hosts|services).*)yes/$1no/;}' /etc/nscd.conf
245.1174 + fi
245.1175 +}
245.1176 +###------------main()
245.1177 +function main(){
245.1178 + /etc/init.d/nscd stop > /dev/null
245.1179 + read_defaults #legge i defaults (esce se SOLO_DUMP_CONF=1)
245.1180 + prep_debconf # prepara risposte debconf
245.1181 + checkapt # controlla le fonti apt
245.1182 + check_packages # controlla i pacchetti
245.1183 + stop_services
245.1184 + slapd_reconfigure # eventuale riconfigurazione di slapd
245.1185 + stop_services # stop slapd e samba
245.1186 + isi_default_stru # crea le cartelle ISI e i file di conf
245.1187 + check_secrets # check /etc/*.secret
245.1188 + check_nsswitch # configura nsswitch per ldap
245.1189 + check_pam # configura pam per ldap
245.1190 + setting_ldap # slapd e connessi (conf.preliminare)
245.1191 + crea_smbldap_conf_file # conf samba tools
245.1192 + crea_smb_conf
245.1193 + change_hostname
245.1194 + slap_add_samba_schema
245.1195 + start_services
245.1196 + conf_populate # popola l'albero ldap
245.1197 + reset_samba_secretdb # smbpasswd -w
245.1198 + fix_ldap_sambaAlgorithmicRidBase
245.1199 + setting_sid # net set domain/local sids
245.1200 + stop_services # stop slapd e samba
245.1201 + slap_add_indexes # aggiunge indici sul SID ecc.ecc.
245.1202 + slap_index # rigenera gli indici ldap
245.1203 + set_nscd_conf_file # Setta persistent a NO
245.1204 + check_acl_quota # controlla /etc/fstab per acl e quota su /home
245.1205 + start_services # start slapd/samba
245.1206 + crea_gruppi_isi # crea i gruppi main, classi e corsi
245.1207 + add_env_folder # creo le cartelle /home/samba/netlogon/env*
245.1208 + grant_permission_to_domain_admin
245.1209 + stop_services # stop slapd e samba
245.1210 + start_services # start slapd/samba
245.1211 + /etc/init.d/nscd start >/dev/null
245.1212 + fine
245.1213 +}
245.1214 +function help (){
245.1215 +cat <<EOF
245.1216 +$BORDO
245.1217 +ISI-SETUP installa ed esegue la configurazione di base di un PDC ldap/samba
245.1218 +configurato secondo il modello ISI (http://www.reteisi.org).
245.1219 +
245.1220 +USO: isi-setup [opzioni] [dominio_win] [pdc] [password] [org] [dns_base_ldap]
245.1221 +
245.1222 +OPZIONI: -h questo help
245.1223 + -v verbose - aumenta il numero di messaggi a video
245.1224 + -s script_mode - non chiede conferma prima di continuare
245.1225 + -d salva la configurazione in /etc/isi/isi-setup.conf
245.1226 + -D salva come sopra ed ESCE
245.1227 + -c utlizza /etc/isi/isi-setup.conf come file di conf.
245.1228 + -q solo messaggi di errore
245.1229 + -S NON esegue il setup standard, non tocca la conf che trova
245.1230 + -U NON esegue aggiornamento variabili debconf e pacchetti
245.1231 + -A NON controlla /etc/fstab per le acl
245.1232 + -T NON controlla /etc/fstab per la quota
245.1233 + -R NON esegue il remount di /home (inutile se espresse -AT)
245.1234 + -a NON rende l'amministratore di dominio un utente ordinario (nessuna shell, nessuna home)
245.1235 +
245.1236 +* DEFAULTS: org = ISI_ORG, dns_base_ldap = isi.lan
245.1237 +* Ad eventuali domande rispondere premendo ENTER
245.1238 +* ISI-SETUP ridirige errori e warning su STDERR
245.1239 +* Soppressione e logging dei messaggi si ottengono ridirigendo l'output.
245.1240 +$BORDO
245.1241 +EOF
245.1242 +}
245.1243 +### ----------------- inizio -----------------------
245.1244 +# dominio di default
245.1245 +DOMAIN_NAME='ISI-DOMAIN'
245.1246 +PDC_NAME='ISI-PDC'
245.1247 +LDAP_PWD='reteisi'
245.1248 +ORG_NAME='ISI-ORG'
245.1249 +DNS_DOMAIN='isi.lan'
245.1250 +#SID="S-1-5-21-2385007630-1092215365-3723864586"
245.1251 +#SID_PDC="S-1-5-21-2385007630-1092215365-3723864586"
245.1252 +DOMAIN_ADMIN="administrator"
245.1253 +ERR_PKG=""
245.1254 +QUIET=0
245.1255 +SETUP_LOG=""
245.1256 +VERBOSE=0
245.1257 +APT_UPD=1
245.1258 +DUMP_CONF=0
245.1259 +USE_CONF=0
245.1260 +STANDARD_SETUP=1
245.1261 +ACL_IN_FSTAB=1
245.1262 +QUOTA_IN_FSTAB=1
245.1263 +REMOUNT_HOME=1
245.1264 +SOLO_DUMP_CONF=0
245.1265 +#USO_PDBEDIT=0
245.1266 +ADMIN_IS_NORMAL_USER=1
245.1267 +IS_UBUNTU=0
245.1268 +[ "$(lsb_release -is)" == "Ubuntu" ] && IS_UBUNTU=1
245.1269 +
245.1270 +BORDO='=========================================================================='
245.1271 +while getopts hvqsdDcsqlUATRa: var
245.1272 +do
245.1273 +case $var in
245.1274 + h) help; exit
245.1275 + ;;
245.1276 + #FIXME: quiet
245.1277 + q) QUIET=1
245.1278 + VERBOSE=0
245.1279 + ;;
245.1280 + v) VERBOSE=1
245.1281 + ;;
245.1282 + s) SCRIPT_MODE=1
245.1283 + ;;
245.1284 + d) DUMP_CONF=1
245.1285 + ;;
245.1286 + D) SOLO_DUMP_CONF=1
245.1287 + DUMP_CONF=1
245.1288 + ;;
245.1289 + c) USE_CONF=1
245.1290 + ;;
245.1291 + S) STANDARD_SETUP=0
245.1292 + ;;
245.1293 + U) APT_UPD=0
245.1294 + ;;
245.1295 + A) ACL_IN_FSTAB=0
245.1296 + ;;
245.1297 + T) QUOTA_IN_FSTAB=0
245.1298 + ;;
245.1299 + R) REMOUNT_HOME=1
245.1300 + ;;
245.1301 +# j) USO_PDBEDIT=1
245.1302 +# ;;
245.1303 + a) DOMAIN_ADMIN=$OPTARG
245.1304 + ADMIN_IS_NORMAL_USER=0
245.1305 + ;;
245.1306 +esac
245.1307 +done
245.1308 +shift ` expr $OPTIND - 1 `
245.1309 +
245.1310 +#clear screen
245.1311 +
245.1312 +[ -z $1 ] || DOMAIN_NAME=$1
245.1313 +[ -z $2 ] || PDC_NAME=$2
245.1314 +[ -z $3 ] || LDAP_PWD=$3
245.1315 +[ -z $4 ] || ORG_NAME=$4
245.1316 +[ -z $5 ] || DNS_DOMAIN=$5
245.1317 +
245.1318 +check_hg_etc # controlla che /etc sia sotto mercurial
245.1319 +new_sid # genera nuovi SIDs
245.1320 +
245.1321 +if [ "$QUIET" = 1 -a "$SCRIPT_MODE" = 0 ] ; then
245.1322 + cat <<EOF
245.1323 +$BORDO
245.1324 +Definisco il dominio Samba/Ldap:
245.1325 +DOMINIO....................: $DOMAIN_NAME
245.1326 +NOME PDC...................: $PDC_NAME
245.1327 +DOMAIN_ADMINISTRATOR.......: $DOMAIN_ADMIN
245.1328 +PWD ADMIN LDAP.............: $LDAP_PWD
245.1329 +ORGANIZZAZIONE.............: $ORG_NAME
245.1330 +DOMINIO DNS................: $DNS_DOMAIN
245.1331 +SID........................: $SID
245.1332 +SID_PDC....................: $SID_PDC
245.1333 +$BORDO
245.1334 +eseguo con le seguenti opzioni:
245.1335 +QUIET..................(-q): $QUIET
245.1336 +VERBOSE................(-v): $VERBOSE
245.1337 +DUMP_CONF..............(-d): $DUMP_CONF
245.1338 +SOLO_DUMP_CONF.........(-D): $SOLO_DUMP_CONF
245.1339 +USE_CONF...............(-c): $USE_CONF
245.1340 +APT_UPD................(-U): $APT_UPD
245.1341 +STANDARD_SETUP.........(-S): $STANDARD_SETUP
245.1342 +ACL_IN_FSTAB...........(-A): $ACL_IN_FSTAB
245.1343 +QUOTA_IN_FSTAB.........(-Q): $QUOTA_IN_FSTAB
245.1344 +REMOUNT_HOME...........(-R): $REMOUNT_HOME
245.1345 +ADMIN_IS_NORMAL_USER...(-a): $ADMIN_IS_NORMAL_USER ($DOMAIN_ADMIN)
245.1346 +$BORDO
245.1347 +EOF
245.1348 + read -p "Continuo N/s ? " RISP
245.1349 + N=$(expr match "$RISP" '[yYsS]')
245.1350 + [ "$N" -gt 0 ] && main
245.1351 +else
245.1352 + main
245.1353 +fi
245.1354 +
245.1355 +
245.1356 +
245.1357 +
245.1358 +
245.1359 +
246.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
246.2 +++ b/usr/sbin/isi-slapd-reload Mon Apr 26 11:16:23 2010 +0200
246.3 @@ -0,0 +1,129 @@
246.4 +#!/bin/bash
246.5 +
246.6 +# Copyright (C) 2008, Sandro Dentella <[email protected]>
246.7 +#
246.8 +# This program is free software: you can redistribute it and/or modify
246.9 +# it under the terms of the GNU General Public License as published by
246.10 +# the Free Software Foundation, either version 3 of the License, or
246.11 +# (at your option) any later version.
246.12 +#
246.13 +# This program is distributed in the hope that it will be useful,
246.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
246.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
246.16 +# GNU General Public License for more details.
246.17 +#
246.18 +# You should have received a copy of the GNU General Public License
246.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
246.20 +
246.21 +
246.22 +function mk_temp_conf () {
246.23 + TMP_DIR=$(mktemp -dt ldap.XXXXXX )
246.24 + perl -s -pe '{$_ =~ s!^\s*(directory\s).*!\1"$TMP_DIR/ldap"! ;}' -- \
246.25 + -TMP_DIR=$TMP_DIR /etc/ldap/slapd.conf > $TMP_DIR/slapd.conf
246.26 + mkdir $TMP_DIR/ldap
246.27 + echo using $TMP_DIR/ldap
246.28 + cp /var/lib/ldap/DB_CONFIG $TMP_DIR/ldap
246.29 +}
246.30 +
246.31 +function slap_add () {
246.32 + if [ -z "$LDIF_FILE" ] ; then
246.33 + LDIF_FILE=$TMP_DIR/slapcat.ldif
246.34 + slapcat > $LDIF_FILE
246.35 + fi
246.36 + slapadd $VERBOSE -f $TMP_DIR/slapd.conf -l $LDIF_FILE
246.37 + if grep -q openldap /etc/passwd ; then
246.38 + chown -R openldap.openldap $TMP_DIR/ldap
246.39 + fi
246.40 +}
246.41 +function check_root () {
246.42 + if [ $(id -u) -gt 0 ] ; then
246.43 + echo you must be root
246.44 + exit 1
246.45 + fi
246.46 +}
246.47 +function backup_var_lib_ldap () {
246.48 + if [ -d /var/lib/ldap ] ; then
246.49 + BK_FILE=$TMP_DIR/ldapbak-$(date '+%y%m%d').tgz
246.50 + tar -czf $BK_FILE -C /var/lib/ ldap
246.51 + mv --backup=numbered $BK_FILE /root
246.52 + fi
246.53 +}
246.54 +
246.55 +function stop_for_sure_or_exit () {
246.56 + ## prima usiamo le buone maniere
246.57 +
246.58 + /etc/init.d/slapd stop
246.59 + if pgrep -x slapd ; then
246.60 + ## poi pero' ci arrabbiamo...
246.61 + my_echo "provo ad uccidere slapd con -9"
246.62 + skill -9 slapd
246.63 + if pgrep -x slapd; then
246.64 + echo "slapd non muore neanche con kill -9; esco"
246.65 + exit 1
246.66 + fi
246.67 + fi
246.68 +}
246.69 +function mv_start () {
246.70 + if [ -e /var/lib/ldap ] ; then
246.71 + mv /var/lib/ldap $TMP_DIR/ldap_bk
246.72 + fi
246.73 + mv $TMP_DIR/ldap /var/lib/ldap
246.74 + /etc/init.d/slapd start
246.75 + if ! pgrep slapd ; then
246.76 + echo "slapd non parte..."
246.77 + fi
246.78 +
246.79 +}
246.80 +function my_echo() {
246.81 + if [ ! "QUIET" = 1 ] ; then
246.82 + echo $*
246.83 + fi
246.84 +}
246.85 +function help () {
246.86 +cat << FINE
246.87 +Comando: `basename $0`
246.88 +
246.89 +Sintassi: `basename $0` [ -h ]
246.90 +
246.91 +Descrizione: Ricrea uno slapd a partire da slapcat della configurazione in
246.92 + atto o di una passata in argomento
246.93 +
246.94 +Opzioni: -h help (Questa pagina di manuale)
246.95 + -l ldif_file usa 'ldif_file' come contenuto del db ldap
246.96 + -R make it the Real slapd process
246.97 + spegni slapd, sposta la cartella e riparti
246.98 +
246.99 +FINE
246.100 +}
246.101 +
246.102 +
246.103 +while getopts vRqhl: var
246.104 +do
246.105 + case $var in
246.106 + h) clear; help; exit
246.107 + ;;
246.108 + l) LDIF_FILE=$OPTARG
246.109 + ;;
246.110 + R) REAL=1
246.111 + ;;
246.112 + q) QUIET=1
246.113 + ;;
246.114 + v) VERBOSE="-v"
246.115 + ;;
246.116 + esac
246.117 +done
246.118 +shift ` expr $OPTIND - 1 `
246.119 +
246.120 +
246.121 +check_root
246.122 +mk_temp_conf
246.123 +slap_add
246.124 +
246.125 +if [ "$REAL" = 1 ] ; then
246.126 + stop_for_sure_or_exit
246.127 + backup_var_lib_ldap
246.128 + mv_start
246.129 +else
246.130 + my_echo "il processo slapd non e' stato toccato perche' non hai usato opt -R"
246.131 + echo "Dati in $TMP_DIR/ldap"
246.132 +fi
247.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
247.2 +++ b/usr/sbin/isi-tools Mon Apr 26 11:16:23 2010 +0200
247.3 @@ -0,0 +1,435 @@
247.4 +#!/usr/bin/python
247.5 +# -*- coding: utf-8 -*-
247.6 +
247.7 +# This program is free software; you can redistribute it and/or modify
247.8 +# it under the terms of the GNU General Public License as published by
247.9 +# the Free Software Foundation; either version 2, or (at your option)
247.10 +# any later version.
247.11 +
247.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
247.13 +
247.14 +
247.15 +"""
247.16 +ISI-INFO effettua una serie di controlli e restituisce elenchi di utenti
247.17 + usage: %prog [options] [users_file_name|group_name|domain]
247.18 + -c, --classes: lista la composizione delle classi contenute nel file utenti passato
247.19 + -f, --field-ldap=field_ldap: lista la valorizzazione del campo ldap per gli utenti del gruppo indicato
247.20 + -p, --pwd-changed: restituisce gli utenti che hanno cambiato la password rispetto a quella definita nel file utenti
247.21 + -P, --pwd-nochanged: restituisce gli utenti che NON hanno cambiato la password rispetto a quella definita nel file utenti
247.22 + -B, --pwd-mustchange: costringe al rinnovo password tutti i membri di un gruppo
247.23 + -b, --pwd-mustchange-days=pwd_mustchange_days: fissa la data di scadenza password per i membri del gruppo a oggi + i giorni indicati
247.24 + -W, --pwd-when: mostra le date di last set e scadenza delle password
247.25 + -A, --pwd-canchange-days=pwd_canchange_days: fissa la data a partire dalla quale gli utenti del gruppo possono modificare la password, per impedire il cambio data indicare un numero positivo di giorni
247.26 + -n, --numbers-get: mostra i successivi uidNumber e gidNumber per il dominio samba indicato
247.27 + -N, --numbers-set: come -n ma corregge l'errore trovato
247.28 + -r, --rename-user=rename_user: formato vecchio_logname,nuovo_logname,[cf] (separatore virgola)
247.29 + -R, --rename-user-file=rename_user_file: cambia i logname contenuti nel file, formato come sopra
247.30 + -X, --force: non interrompe l'azione in caso di errore (in abbinamento con -R)
247.31 + -o, --output=out_file: scrive il risultato in un file
247.32 + -v, --verbose: aumenta i messaggi a video
247.33 + -j, --adjust: rimemorizza cn,sn,givenName,gecos,displayName per ogni utente nel file
247.34 +
247.35 +NOTA: le opzioni -c -p -n|N non sono cumulabili\n l'opzione -o funziona solo con -c -f -p
247.36 +"""
247.37 +
247.38 +import isi
247.39 +import sys, os
247.40 +import re
247.41 +import pexpect
247.42 +from dry import optionparse
247.43 +from dry.functions import execute, ExecuteError
247.44 +from isi.filesystem import show_file
247.45 +#from isi.srv import get_main_groups, interactive_add_classes, \
247.46 +# get_classes, get_courses, new_passwd, maingroup_byprefix, \
247.47 +# MultipleErrors, WrongLineFormat, WrongOperation
247.48 +from isi.conf.defaults import *
247.49 +from isi.srv import MissingMatch
247.50 +from time import mktime, localtime
247.51 +
247.52 +class IsiTool(object):
247.53 + def __init__(self, users_file=None, campo_ldap=None,
247.54 + gruppo=None, domain=None, out_file=None,
247.55 + pwd_canchange_days=-7, pwd_mustchange_days=0,
247.56 + verbose=False):
247.57 + self.users_file = users_file
247.58 + self.campo_ldap = campo_ldap
247.59 + self.gruppo = gruppo
247.60 + self.domain = domain
247.61 + self.pwd_canchange_days = pwd_canchange_days
247.62 + self.pwd_mustchange_days = pwd_mustchange_days
247.63 + self.verbose=verbose
247.64 + self.C = isi.IsiConn()
247.65 + self.U = isi.Manager(self.C)
247.66 + self.outf = None
247.67 + self.rename_user_line = None
247.68 + self.rename_user_file = None
247.69 + ret = False
247.70 + if out_file:
247.71 + ret = True
247.72 + if os.path.isfile(out_file):
247.73 + ret = raw_input("il file %s ESISTE! lo sovrascrivo (S/n)? " %
247.74 + out_file)
247.75 + if not ret: ret = 's'
247.76 + if ret in 'sS':
247.77 + ret = True
247.78 + else:
247.79 + ret = False
247.80 + print "stampo su stdout...\n"
247.81 + if ret:
247.82 + self.outf = open(out_file, 'w')
247.83 +
247.84 +
247.85 + def show(self, msg):
247.86 + if self.outf:
247.87 + self.outf.write(msg+'\n')
247.88 + else:
247.89 + print msg
247.90 +
247.91 + def show_file(self):
247.92 + if self.outf: show_file(out_file)
247.93 +
247.94 +
247.95 + def close_outf(self):
247.96 + if self.outf: self.outf.close()
247.97 +
247.98 + def print_classi_corsi(self, cosa, dict):
247.99 + nt = 0
247.100 + for k, v in dict.iteritems():
247.101 + self.show("-"*70)
247.102 + self.show("%s %s" % (cosa, k))
247.103 + self.show("-"*70)
247.104 + n = 0
247.105 + v.sort()
247.106 + for u in v:
247.107 + n += 1
247.108 + self.show("%s %s" % (n, u))
247.109 + nt += n
247.110 + self.show("-"*70)
247.111 + if cosa == 'CLASSE':
247.112 + self.show("trovate %s classi e %s alunni" % (len(dict), nt))
247.113 + else:
247.114 + self.show("trovati %s corsi e %s corsisti" % (len(dict), nt))
247.115 + self.show("-"*70)
247.116 +
247.117 + def info_classi(self):
247.118 + classi = {}
247.119 + corsi = {}
247.120 + try:
247.121 + uf = open(self.users_file)
247.122 + for line in uf:
247.123 + campi = line.split(';')
247.124 + # salta i record con meno di 5 campi (classe = campo6)
247.125 + if len(campi)<5 : continue
247.126 + mgrp = campi[3]
247.127 + if self.U.user_exists(campi[0]):
247.128 + u = (campi[1], campi[2], campi[0], '')
247.129 + else:
247.130 + u = (campi[1], campi[2], campi[0], 'INESISTENTE')
247.131 +
247.132 + s = "%-15s %-15s %s %s" % u
247.133 +
247.134 + if mgrp in ('alunni'):
247.135 + classe = campi[4].split(',')[0]
247.136 + if classi.has_key(classe):
247.137 + classi[classe].append(s)
247.138 + else:
247.139 + classi[classe] = [s]
247.140 + if mgrp in ('esterni'):
247.141 + corso = campi[4].split(',')[0]
247.142 + if corsi.has_key(corso):
247.143 + corsi[corso].append(s)
247.144 + else:
247.145 + corsi[corso] = [s]
247.146 + self.print_classi_corsi('CLASSE', classi)
247.147 + self.print_classi_corsi('CORSO', corsi)
247.148 +
247.149 + except IOError, e:
247.150 + print e
247.151 + print "ERRORE: il file %s non esiste" % self.users_file
247.152 +
247.153 + self.close_outf()
247.154 +
247.155 + def adjust_user(self):
247.156 + """ corregge cn,sn,gecos,givenNam,displayName """
247.157 + try:
247.158 + uf = open(self.users_file)
247.159 + rext = False
247.160 + for line in uf:
247.161 + campi = line.split(';')
247.162 + if len(campi)<7 : continue
247.163 + user = campi[0]
247.164 + cogn = campi[1]
247.165 + nome = campi[2]
247.166 + if len(campi)>7: # record esteso
247.167 + rext = True
247.168 +
247.169 + if self.verbose:
247.170 + print "elaboro %s - %s %s " % (user, cogn, nome)
247.171 + gecos = cn = "%s %s" % (nome.title(), cogn.title())
247.172 + sn = cogn.title()
247.173 + givenName = nome.title()
247.174 + displayName = "%s %s" % (cogn.upper(), nome.title())
247.175 + self.U.srv.modify(user,'cn',cn)
247.176 + self.U.srv.modify(user,'sn',sn)
247.177 + self.U.srv.modify(user,'gecos',gecos)
247.178 + self.U.srv.modify(user,'givenName',givenName)
247.179 + self.U.srv.modify(user,'displayName',displayName)
247.180 +
247.181 + except IOError, e:
247.182 + print e
247.183 + print "ERRORE: il file %s non esiste" % self.users_file
247.184 +
247.185 +
247.186 + def info_field(self):
247.187 + uu = self.U.get_members(self.gruppo)
247.188 + if uu:
247.189 + self.show("-"*70)
247.190 + self.show("Valore del campo ldap [%s] per i membri del gruppo [%s]" % \
247.191 + (self.campo_ldap, self.gruppo))
247.192 + self.show("-"*70)
247.193 + for u in uu:
247.194 +# d = self.U.get_attr(u, self.campo_ldap)[0]
247.195 + d = self.U.get_ldap_field(u, self.campo_ldap)
247.196 + if d:
247.197 + self.show("%-14s %s = %s" % (u, self.campo_ldap, d))
247.198 + else:
247.199 + self.show("%s %s = %s" % (u, self.campo_ldap, 'NON DEFINITO'))
247.200 + self.show("-"*70)
247.201 + else:
247.202 + print "GRUPPO INESISTENTE O VUOTO"
247.203 + self.close_outf()
247.204 +
247.205 + def info_pwds(self, pwd_changed):
247.206 + try:
247.207 + uf = open(self.users_file)
247.208 + for line in uf:
247.209 + campi = line.split(';')
247.210 + if len(campi)<7 : continue
247.211 + uid = campi[0]
247.212 + pwd = campi[6]
247.213 + if self.U.user_exists(uid):
247.214 + dn = self.U.get_user_dn_by_name(uid)
247.215 + cmd = "ldapsearch -xLLLD %s -w %s uid=%s %s" % \
247.216 + (dn, pwd, uid, uid)
247.217 + r, o, e = execute(cmd)
247.218 + if pwd_changed and e:
247.219 + self.show("%-15s PWD CAMBIATA" % uid )
247.220 + if not pwd_changed and not e:
247.221 + self.show("%-15s PWD NON CAMBIATA" % uid )
247.222 +
247.223 +
247.224 + except IOError, e:
247.225 + print e
247.226 + print "ERRORE: il file %s non esiste" % self.users_file
247.227 +
247.228 + self.close_outf()
247.229 +
247.230 + def info_nums(self, okset=False):
247.231 + """ restituisce o setta uidNumber gidNumber """
247.232 +
247.233 + def maxnum(cmd, nmax):
247.234 + r, o, e = execute(cmd)
247.235 + ll = o.split('\n')
247.236 + n = 0
247.237 + for l in ll:
247.238 + u = l.split(':')
247.239 +# if len(u)>3 and int(u[2]) >= UID_MIN and int(u[2]) <= UID_MAX:
247.240 + if len(u)>3 and int(u[2]) <= nmax:
247.241 + n = max(n, int(u[2]))
247.242 + return n
247.243 +
247.244 + nums = self.C.get_ugnums(self.domain)
247.245 + gidNumber = nums['gidNumber']
247.246 + uidNumber = nums['uidNumber']
247.247 + gid = maxnum("getent group" , GID_MAX)
247.248 + uid = maxnum("getent passwd", UID_MAX )
247.249 + print "-"*70
247.250 + print "ULTIMI NUMERI - gidNumber:%s\tuidNumber:%s\n" % (gid, uid)
247.251 + print "PROSSIMI NUMERI - gidNumber:%s\tuidNumber:%s\n" % \
247.252 + (gidNumber,uidNumber)
247.253 +
247.254 + if not okset and (gid > gidNumber-1 or uid > uidNumber-1):
247.255 + print "ATTENZIONE: è necessario allineare i numeri, usa l'opzione -N"
247.256 +
247.257 + print "-"*70
247.258 +
247.259 + if okset:
247.260 + gidNumber = max(gidNumber, GID_MIN)
247.261 + uidNumber = max(uidNumber, UID_MIN)
247.262 + if gid > gidNumber - 1: gidNumber = gid + 1
247.263 + if uid > uidNumber - 1: uidNumber = uid + 1
247.264 + if gidNumber <= GID_MAX and uidNumber <= UID_MAX:
247.265 + self.C.set_ugnums(self.domain, gidNumber=str(gidNumber))
247.266 + self.C.set_ugnums(self.domain, uidNumber=str(uidNumber))
247.267 + print "DOPO L'ALLINEAMENTO:"
247.268 + print "ULTIMI NUMERI - gidNumber:%s\tuidNumber:%s\n" % (gid, uid)
247.269 + print "PROSSIMI NUMERI - gidNumber:%s\tuidNumber:%s\n" % \
247.270 + (gidNumber,uidNumber)
247.271 + print "-"*70
247.272 + else:
247.273 + print "ALLINEAMENTO IMPOSSIBILE - NUMERI FUORI RANGE"
247.274 +
247.275 + def pwd_must_change(self):
247.276 + """ forza al rinnovo password i membri di un gruppo """
247.277 + try:
247.278 + self.U.verbose = self.verbose
247.279 + self.U.pwd_must_change(self.gruppo, self.pwd_mustchange_days)
247.280 + except:
247.281 + print "GRUPPO INESISTENTE O VUOTO"
247.282 +
247.283 + def pwd_can_change(self):
247.284 + """ abilita disabilita il cambio password """
247.285 + try:
247.286 + self.U.verbose = self.verbose
247.287 + self.U.pwd_can_change(self.gruppo, self.pwd_canchange_days)
247.288 + except:
247.289 + print "GRUPPO INESISTENTE O VUOTO"
247.290 +
247.291 + def pwd_expire(self):
247.292 + """ fissa la data di scadenza della password """
247.293 + try:
247.294 + self.U.verbose = self.verbose
247.295 + self.U.pwd_expire(self.gruppo, self.pwd_expire)
247.296 + except:
247.297 + print "GRUPPO INESISTENTE O VUOTO"
247.298 +
247.299 + def pwd_when(self):
247.300 + """ last set end expire dates of passwords"""
247.301 + try:
247.302 + self.U.pwd_when(self.gruppo, outf=self.outf)
247.303 + self.close_outf()
247.304 +
247.305 + except:
247.306 + raise
247.307 + print "GRUPPO INESISTENTE O VUOTO"
247.308 +
247.309 + def rename_user(self):
247.310 + """ modifica il logname e quel che ne segue """
247.311 + def logch(line):
247.312 + ll = line.split(',')
247.313 + # se manca il codice fiscale... così il formato è corretto
247.314 + if len(ll)==2: ll.append(None)
247.315 +
247.316 + old_l, new_l, cf = ll
247.317 + self.U.verbose = self.verbose
247.318 + self.U.rename_user(old_l, new_l, cf)
247.319 +
247.320 + if self.rename_user_file:
247.321 + # controlla che non ci siano new_id esistenti
247.322 + err = False
247.323 + collisioni=[]
247.324 + fcoll = open('/tmp/collisioni', 'w')
247.325 + for line in open(self.rename_user_file):
247.326 + line = line.rstrip('\n').replace(' ', '')
247.327 + if not ',' in line:
247.328 + if len(line)>0:
247.329 + print "ERRORE: %s" % line
247.330 + fcoll.write("ERRORE: %s\n" % line)
247.331 + continue
247.332 + u = line.split(',')
247.333 + if self.U.user_exists(u[1]):
247.334 + print "COLLISIONE CON UTENTE ESISTENTE: %s" % u[1]
247.335 + collisioni.append(u[:2])
247.336 + fcoll.write("%s\n" % line)
247.337 + err = True
247.338 + fcoll.close()
247.339 + if not err or opts.force:
247.340 + for line in open(self.rename_user_file):
247.341 + line = line.rstrip('\n').replace(' ', '')
247.342 + if not ',' in line: continue
247.343 + u = line.split(',')
247.344 + if not u[:2] in collisioni:
247.345 + try:
247.346 + logch(line)
247.347 + except MissingMatch, e:
247.348 + print "ERRORE (MissingMatch): %s - %s " % (line,e)
247.349 + else:
247.350 + print "IMPOSSIBILE PROCEDERE: errori e/o collisioni uid vecchi/nuovi"
247.351 + if len(collisioni)>0:
247.352 + print "errori e collisioni registrati in /tmp/collisioni"
247.353 + elif self.rename_user_line:
247.354 + logch(self.rename_user_line)
247.355 +
247.356 +#### PROGRAM
247.357 +
247.358 +# defaults
247.359 +users_file = domain = gruppo = out_file = None
247.360 +can_change = 1
247.361 +
247.362 +opts, args = optionparse.parse(__doc__)
247.363 +
247.364 +# -o file
247.365 +if opts.output: out_file = opts.output
247.366 +
247.367 +if opts.classes or opts.pwd_changed or opts.pwd_nochanged or opts.adjust:
247.368 + if len(args)==0:
247.369 + print "ERRORE: devi dirmi il nome del file utenti da utilizzare"
247.370 + else:
247.371 + users_file = args[0]
247.372 +
247.373 +
247.374 +if opts.numbers_get or opts.numbers_set:
247.375 + if len(args)==0:
247.376 + print "ERRORE: devi dirmi il nome del dominio samba"
247.377 + else:
247.378 + domain = args[0]
247.379 +
247.380 +if opts.field_ldap or opts.pwd_mustchange or \
247.381 + opts.pwd_canchange_days or opts.pwd_mustchange_days or opts.pwd_when:
247.382 + if len(args)==0:
247.383 + print "ERRORE: devi dirmi il nome di un gruppo"
247.384 + else:
247.385 + gruppo = args[0]
247.386 +
247.387 +
247.388 +tool = IsiTool(users_file=users_file,
247.389 + domain=domain,
247.390 + gruppo=gruppo,
247.391 + campo_ldap=opts.field_ldap,
247.392 + out_file=out_file,
247.393 + pwd_canchange_days=opts.pwd_canchange_days,
247.394 + pwd_mustchange_days=opts.pwd_mustchange_days,
247.395 + verbose=opts.verbose)
247.396 +
247.397 +if opts.classes:
247.398 + tool.info_classi() # -c
247.399 +
247.400 +if opts.field_ldap and gruppo:
247.401 + tool.info_field() # -f
247.402 +
247.403 +if opts.pwd_changed:
247.404 + tool.info_pwds(True) # -p
247.405 +
247.406 +if opts.pwd_nochanged:
247.407 + tool.info_pwds(False) # -P
247.408 +
247.409 +if opts.pwd_mustchange:
247.410 + tool.pwd_must_change() # -B
247.411 +
247.412 +if opts.pwd_mustchange_days:
247.413 + tool.pwd_mustchange_days = int(opts.pwd_mustchange_days)
247.414 + tool.pwd_must_change() # -E expiredata
247.415 +
247.416 +if opts.pwd_canchange_days:
247.417 + tool.pwd_canchange_days = int(opts.pwd_canchange_days)
247.418 + tool.pwd_can_change() # -A 0|1
247.419 +
247.420 +if opts.pwd_when:
247.421 + tool.pwd_when() # -W
247.422 +
247.423 +if opts.numbers_get:
247.424 + tool.info_nums(False) # -n
247.425 +
247.426 +if opts.numbers_set:
247.427 + tool.info_nums(True) # -N
247.428 +
247.429 +if opts.rename_user or opts.rename_user_file:
247.430 + tool.rename_user_line = opts.rename_user
247.431 + tool.rename_user_file = opts.rename_user_file
247.432 + tool.rename_user() # -r|-R
247.433 +
247.434 +if opts.adjust:
247.435 + tool.adjust_user() # -j
247.436 +
247.437 +tool.show_file()
247.438 +
248.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
248.2 +++ b/usr/sbin/isi-users Mon Apr 26 11:16:23 2010 +0200
248.3 @@ -0,0 +1,2047 @@
248.4 +#!/usr/bin/python
248.5 +# -*- coding: utf-8 -*-
248.6 +
248.7 +# This program is free software; you can redistribute it and/or modify
248.8 +# it under the terms of the GNU General Public License as published by
248.9 +# the Free Software Foundation; either version 2, or (at your option)
248.10 +# any later version.
248.11 +
248.12 +# AUTHORS: Sandro Dentella - Massimo Mancini
248.13 +
248.14 +
248.15 +import os, sys, re, random, string
248.16 +import urwid.curses_display, urwid
248.17 +import ldap,time
248.18 +import isi
248.19 +from isi.srv import new_passwd
248.20 +from dry.functions import execute, ExecuteError
248.21 +
248.22 +USERS_FILE = '/root/users_last_update'
248.23 +HOME_IN = '/home/users'
248.24 +PROFILO={
248.25 + '9x': 'Win95',
248.26 + 'xp': 'WinXP',
248.27 + '2k': 'Win2K',
248.28 + }
248.29 +
248.30 +CMD = "ls -l /bin/sh|awk '{print $10}'"
248.31 +r, w, e = os.popen3(CMD)
248.32 +ws = w.readlines()
248.33 +es = e.readlines()
248.34 +w.close()
248.35 +e.close()
248.36 +IS_DASH = (ws[0].find('dash')>= 0)
248.37 +
248.38 +blank = urwid.AttrWrap(urwid.Text(""),'body')
248.39 +sep = urwid.Divider('-')
248.40 +
248.41 +
248.42 +# FILECONF file di configurazione dello script
248.43 +FILECONF="/etc/isi/userpy.conf"
248.44 +
248.45 +
248.46 +class dictNoComplain(dict):
248.47 + """ il dizionario che non solleva eccezioni nel
248.48 + caso di chiave inesistente """
248.49 + valore = None
248.50 + def __getitem__(self,key):
248.51 + if not self.has_key(key) or self.get(key) == None:
248.52 + return ''
248.53 + else:
248.54 + return self.get(key)
248.55 +
248.56 +class isildap:
248.57 + configparm={}
248.58 + l = None
248.59 + members = None
248.60 + memdata = None
248.61 + campildap = (
248.62 + 'dn','cn','sn','uid','gecos','givenName',
248.63 + 'displayName','employeeNumber','employeeType',
248.64 + 'postOfficeBox','postalCode','homePhone',
248.65 + 'postalAddress','departmentNumber','homeDirectory','gidNumber'
248.66 + )
248.67 +
248.68 + datiuser = None
248.69 + err = None
248.70 +
248.71 + def __init__(self,gruppo=None,u='',p=''):
248.72 + """ crea una connessione ldap, passando u e p, vengono testate
248.73 + le credenziali """
248.74 +
248.75 + self.l = isi.Manager(isi.IsiConn())
248.76 +
248.77 + if gruppo:
248.78 +# self.l.delisildap_groupmembers
248.79 + self.isildap_groupmembers(gruppo)
248.80 + self.isildap_loadmemdata()
248.81 + else:
248.82 + print "ERRORE: manca il gruppo"
248.83 + sys.exit()
248.84 +
248.85 + def isildap_groupmembers(self,group):
248.86 + self.members = self.l.get_members(group)
248.87 +
248.88 + def isildap_userdata(self,uid):
248.89 + ret=dictNoComplain()
248.90 + result_data = self.l.get_ldap_data(uid, self.campildap)
248.91 + for k in result_data.keys():
248.92 + ret[k]=result_data[k][0]
248.93 + return ret
248.94 +
248.95 + def isildap_loadmemdata(self):
248.96 + self.memdata=dictNoComplain()
248.97 + print 'loading users...',
248.98 + for uid in self.members:
248.99 + self.memdata[uid]=self.isildap_userdata(uid)
248.100 + print
248.101 +
248.102 + def isildap_printmemdata(self):
248.103 + for u,d in self.memdata.iteritems():
248.104 + print '\t',string.ljust(u,20)
248.105 + for k,v in d.iteritems():
248.106 + print '\t\t',string.ljust(k,20),v
248.107 +
248.108 + def isildap_isuser(self,uid):
248.109 + return self.l.user_exists(uid)
248.110 +
248.111 +
248.112 +class orderedDict(dict):
248.113 + """
248.114 + dizionario ordinato: aggiunge la proprieta` self.ordKeys
248.115 + che contiene la lista delle chiavi secondo l'ordine di caricamento
248.116 + del dizionario
248.117 + il dizionario non solleva eccezioni nel caso di chiave inesistente
248.118 + """
248.119 + ordKeys = []
248.120 + to_order = None
248.121 + valore = None
248.122 + def __init__(self,to_order=None):
248.123 + self.ordKeys=[]
248.124 + return None
248.125 +
248.126 + def __getitem__(self,key):
248.127 + if not self.has_key(key) or self.get(key) == None:
248.128 + return ''
248.129 + else:
248.130 + return self.get(key)
248.131 +
248.132 + def __setitem__(self,k,v):
248.133 + if not self.has_key(k) or self.get(k) == None:
248.134 + self.ordKeys.append(k)
248.135 + self.setdefault(k,v)
248.136 + if self.to_order:
248.137 + self.ordKeys.sort()
248.138 + return None
248.139 +
248.140 +class VEdit(urwid.Edit):
248.141 + """ Edit widget con nome e validazione """
248.142 + def __init__(self,
248.143 + name='',
248.144 + condition='.*',
248.145 + maxlen=None,
248.146 + msgerr='',
248.147 + msghlp='',
248.148 + caption='',
248.149 + edit_text='',
248.150 + multiline=False,
248.151 + align='left',
248.152 + wrap='space',
248.153 + allow_tab=False,
248.154 + edit_pos=None,
248.155 + layout=None):
248.156 +
248.157 + urwid.Edit.__init__(self,caption,edit_text,multiline,align,wrap,
248.158 + allow_tab,edit_pos,layout)
248.159 +
248.160 + self.name = name
248.161 + self.rex = re.compile(condition)
248.162 + self.maxlen = maxlen
248.163 + self.msgerr = msgerr
248.164 + self.msghlp = msghlp
248.165 + #self.edit_text = edit_text
248.166 + #self.multiline = multiline
248.167 + #self.allow_tab = allow_tab
248.168 + self.set_caption( caption )
248.169 + #self.layout = layout
248.170 +
248.171 + if edit_pos is None:
248.172 + self.edit_pos = len(edit_text)
248.173 + else:
248.174 + self.set_edit_pos(edit_pos)
248.175 +
248.176 + self.highlight = None
248.177 + self.pref_col_maxcol = None, None
248.178 + self._shift_view_to_cursor = 0
248.179 +
248.180 + def RaiseMaxLen(self):
248.181 + if self.maxlen:
248.182 + return len(self.edit_text) >= self.maxlen
248.183 + else:
248.184 + return False
248.185 +
248.186 + def validate(self):
248.187 + return self.rex.match(self.edit_text)
248.188 +
248.189 + def vuota(self,end=0):
248.190 + self.set_edit_text(self.get_edit_text()[:end])
248.191 + self.set_edit_pos(end)
248.192 +
248.193 +
248.194 +class SelText(urwid.Text):
248.195 +
248.196 + def selectable(self): return True
248.197 +
248.198 + def keypress(self,(maxcol,),key):
248.199 + """Handle editing keystrokes, return others."""
248.200 + #self.set_text(('focus',self.get_text()[0]))
248.201 + return key
248.202 +
248.203 +class NamedWrap(urwid.AttrWrap):
248.204 + name = None
248.205 + def __init__(self, name, w, attr, focus_attr=None):
248.206 + self.name = name
248.207 + self.w = w
248.208 + self.attr = attr
248.209 + self.focus_attr = focus_attr
248.210 +
248.211 + def get_name(self):
248.212 + return self.name
248.213 +
248.214 +class SelTextWalker(urwid.SimpleListWalker):
248.215 +
248.216 + def rows(self, (maxcol,), focus=False ):
248.217 + """Return the number of rows required for this widget."""
248.218 + return len(self.contents)
248.219 +
248.220 + def render(self,(maxcol,), focus=False):
248.221 + for t in self.contents:
248.222 + return t[0].render()
248.223 +
248.224 +class HelpColumn(urwid.BoxWidget):
248.225 + help_text = [
248.226 + [ " Chiudi Help : ", ('key', "AltH") ],
248.227 + [ " Abbandona : ", ('key', "AltX") ],
248.228 + "-" ,
248.229 + [ " Nuovo utente : ",('key', "AltN | F8")],
248.230 + "",
248.231 + [ " Canc.da lista: ",('key', "Canc (Delete)")],
248.232 +# [ " Canc.da ldap : ",('key', "AltCanc")],
248.233 + [ " Canc.da ldap : ",('key', "F9")],
248.234 + "",
248.235 + [ " Salva attuale: ",('key', "AltS")],
248.236 + [ " Salva ed esce: ",('key', "AltF")],
248.237 + "-",
248.238 + [ " Mov.campi : ", ('key', "Su Giù Ds Sn PgSù PgGiù" )],
248.239 + [ " Mov.colonne : " ,('key', "Sn Ds AltSn AltDs")],
248.240 + [ " Ok campo : " ,('key', "Enter Tab")],
248.241 + [ " Canc.campo : ",('key', "CtrlK")],
248.242 + [ " Annulla edit : ",('key', "ESC")],
248.243 + "-",
248.244 + [ " Rilegge LDAP : ",('key', "AltR")],
248.245 + [ " Ricarica GRP : ",('key', "AltG")],
248.246 + "-",
248.247 + [ " Cambia passwd: ",('key', "AltP")],
248.248 + [ " Cambia quota : ",('key', "AltQ")],
248.249 + '-',
248.250 + [ " Canc.prof.XP : ",('key', "AltJ")],
248.251 + [ " Canc.prof.2K : ",('key', "AltL")],
248.252 + [ " Canc.prof.9x : ",('key', "AltI")],
248.253 + '-',
248.254 + [ ('buttnf'," CODICE COLORE ")],
248.255 + [ ('focuserr'," utente con dati errati")],
248.256 + [ ('focuscha'," utente con dati modificati")],
248.257 + [ ('focusnew'," nuovo utente")],
248.258 + [ ('focuspwd'," utente con passwd modificata")],
248.259 + [ ('focusdel'," utente eliminato da LDAP")],
248.260 + [ ('focus', " utente ldap senza errori")],
248.261 + [ ('focus', " ? utente senza quota")],
248.262 + [ ('focus', " + utente fuori quota")],
248.263 + '-',
248.264 + ["* L'aggiornamento LDAP viene eseguito solo terminando con AltF\n* La modifica delle password ordinata digitando AltP è invece immediata"],
248.265 + ]
248.266 +
248.267 + def __init__(self):
248.268 + self.head = urwid.AttrWrap(
248.269 + urwid.Text(["ISI-USER HELP"],'center'),'header')
248.270 + self.foot = urwid.AttrWrap(
248.271 + urwid.Text(["continua...Sù/Giù scorre"],'center'), 'footer' )
248.272 + self.items = [self.rigah(x) for x in self.help_text]
248.273 + self.listbox = urwid.ListBox( self.items )
248.274 + self.body = urwid.AttrWrap( self.listbox, 'help' )
248.275 + self.frame = urwid.Frame( self.body, header=self.head)
248.276 +
248.277 + def rigah(self,x):
248.278 + align = 'left'
248.279 + if x == '-':
248.280 + return sep
248.281 + else:
248.282 + return urwid.Text(x,align)
248.283 +
248.284 + def render( self, (maxcol, maxrow), **opts ):
248.285 + head_rows = self.head.rows( (maxcol,) )
248.286 + if "bottom" in self.listbox.ends_visible(
248.287 + (maxcol, maxrow-head_rows) ):
248.288 + self.frame.footer = None
248.289 + else:
248.290 + self.frame.footer = self.foot
248.291 + return self.frame.render( (maxcol, maxrow), ** opts )
248.292 +
248.293 + def keypress( self, size, key ):
248.294 + return self.frame.keypress( size, key )
248.295 +
248.296 +class AuthPassColumn(urwid.BoxWidget):
248.297 + help_text = [
248.298 + "-" ,
248.299 + [ " Admin password: "],
248.300 + "-",
248.301 + [ '#ATTENZIONE: la password digitata non viene visualizzata'],
248.302 + ]
248.303 +
248.304 + def __init__(self):
248.305 + self.head = urwid.AttrWrap(
248.306 + urwid.Text(["ISI-USER PASSWORD"],'center'),'header')
248.307 + self.foot = urwid.AttrWrap(
248.308 + urwid.Text(["continua...Su/Giu scorre"],'center'), 'footer' )
248.309 + self.items = [self.rigah(x) for x in self.help_text]
248.310 + self.listbox = urwid.ListBox( self.items )
248.311 + self.listbox.set_focus(1)
248.312 + self.body = urwid.AttrWrap( self.listbox, 'help' )
248.313 + self.frame = urwid.Frame( self.body, header=self.head)
248.314 +
248.315 + def rigah(self,x):
248.316 + align = 'left'
248.317 + x1 = string.replace(x[0],'#','')
248.318 + if x == '-':
248.319 + return sep
248.320 + elif x1 != x[0]:
248.321 + return urwid.AttrWrap(urwid.Text(x1,'left'),'help')
248.322 + else:
248.323 + return urwid.AttrWrap(urwid.Edit(('editcp',x)),'passwd')
248.324 +
248.325 + def render( self, (maxcol, maxrow), **opts ):
248.326 + head_rows = self.head.rows( (maxcol,) )
248.327 + if "bottom" in self.listbox.ends_visible(
248.328 + (maxcol, maxrow-head_rows) ):
248.329 + self.frame.footer = None
248.330 + else:
248.331 + self.frame.footer = self.foot
248.332 + return self.frame.render( (maxcol, maxrow), ** opts )
248.333 +
248.334 + def keypress( self, size, key ):
248.335 + return self.frame.keypress( size, key )
248.336 +
248.337 +class ConfirmColumn(urwid.BoxWidget):
248.338 + help_text = [
248.339 + ["-" ,
248.340 + [ " Confermi S/N ? "],
248.341 + "-",
248.342 + [ "#ATTENZIONE: ci sono modifiche non salvate - CONFERMARE l'uscita dal programma"],
248.343 + ],
248.344 + ["-" ,
248.345 + [ " Confermi S/N ? "],
248.346 + "-",
248.347 + [ "#ATTENZIONE: stai ordinando la cancellazione di un profilo remoto WINDOWS, il desktop sarà salvato nella cartella HOME/old_desktop"],
248.348 + ],
248.349 + ]
248.350 + titolo = [
248.351 + "ISI-USER: USCITA",
248.352 + "ISI-USER: ELIM.PROFILO",
248.353 + ]
248.354 +
248.355 + def __init__(self):
248.356 + self.head = None
248.357 + self.items = None
248.358 + self.listbox = None
248.359 + self.body = None
248.360 + self.frame = None
248.361 + self.load_msg(0)
248.362 + self.foot = urwid.AttrWrap(
248.363 + urwid.Text(["continua...Su/Giu scorre"],'center'), 'footer' )
248.364 +
248.365 +
248.366 + def load_msg(self, n=0, s=None):
248.367 + if not s is None:
248.368 + tit = "%s [%s]" % (self.titolo[n], s)
248.369 + else:
248.370 + tit = self.titolo[n]
248.371 + self.head = urwid.AttrWrap(
248.372 + urwid.Text([tit],'center'),'header')
248.373 + self.items = [self.rigah(x) for x in self.help_text[n]]
248.374 + self.listbox = urwid.ListBox( self.items )
248.375 + self.listbox.set_focus(1)
248.376 + self.body = urwid.AttrWrap( self.listbox, 'help' )
248.377 + self.frame = urwid.Frame( self.body, header=self.head)
248.378 +# self.frame._invalidate()
248.379 +
248.380 + def vuota(self):
248.381 + for w in self.items:
248.382 + if hasattr(w,'edit_text'):
248.383 + w.set_edit_text('')
248.384 + w.set_edit_pos(0)
248.385 +
248.386 + def rigah(self,x):
248.387 + align = 'left'
248.388 + x1 = string.replace(x[0],'#','')
248.389 + if x == '-':
248.390 + return sep
248.391 + elif x1 != x[0]:
248.392 + return urwid.AttrWrap(urwid.Text(x1,'left'),'help')
248.393 + else:
248.394 + return urwid.AttrWrap(urwid.Edit(('editcp',x)),'focus')
248.395 +
248.396 + def render( self, (maxcol, maxrow), **opts ):
248.397 + head_rows = self.head.rows( (maxcol,) )
248.398 + if "bottom" in self.listbox.ends_visible(
248.399 + (maxcol, maxrow-head_rows) ):
248.400 + self.frame.footer = None
248.401 + else:
248.402 + self.frame.footer = self.foot
248.403 + return self.frame.render( (maxcol, maxrow), ** opts )
248.404 +
248.405 + def keypress( self, size, key ):
248.406 + return self.frame.keypress( size, key )
248.407 +
248.408 +class authSudo:
248.409 + authChi = dictNoComplain()
248.410 + adminUsr = None
248.411 + adminGid = None
248.412 + adminGrp = None
248.413 + gruppo = None
248.414 + ru = None
248.415 + rg = None
248.416 +
248.417 + def __init__(self,gruppo):
248.418 + self.gruppo = gruppo
248.419 + #FILECONF="/etc/isi/userpy.conf"
248.420 + if os.environ.has_key('SUDO_USER'):
248.421 + self.adminUsr = os.environ['SUDO_USER']
248.422 + self.adminGid = os.environ['SUDO_GID']
248.423 + r,w,e = os.popen3("getent group | grep "+str(self.adminGid))
248.424 + self.adminGrp = '@'+string.split(w.readlines()[0],':',1)[0]
248.425 + x=w.readlines()
248.426 + w.close()
248.427 + e.close()
248.428 + else:
248.429 + self.adminUsr = os.environ['USER']
248.430 + self.adminGrp = 'root'
248.431 +
248.432 + upat = r'\b' + self.adminUsr + r'\b'
248.433 + gpat = self.adminGrp + r'\b'
248.434 + self.ru = re.compile(upat)
248.435 + self.rg = re.compile(gpat)
248.436 +
248.437 + if os.access(FILECONF,os.R_OK):
248.438 + f = open(FILECONF,"r")
248.439 + x = f.readlines()
248.440 + f.close()
248.441 + xr = re.compile(r'^\s*(.+)\s*=\s*(.+)\s*$')
248.442 + xm = re.compile(r'^(\w+)@(\w*)\s*$')
248.443 + cr = re.compile(r'^\s*#')
248.444 + for l in x:
248.445 + if cr.match(l): continue
248.446 + xl = xr.match(l)
248.447 + if xl:
248.448 + gg = xl.group(1)
248.449 + uu = xl.group(2)
248.450 + self.authChi[gg] = uu
248.451 + xx = xm.match(gg)
248.452 + if xx:
248.453 + gM = xx.group(1)
248.454 + gS = xx.group(2)
248.455 + #print '|'+gS+'|'
248.456 + if (gS):
248.457 + self.authChi[gS] = uu
248.458 + else:
248.459 + self.authChi[gM] = uu
248.460 +
248.461 +
248.462 + def main(self):
248.463 +
248.464 + if not os.access("/etc/smbldap-tools/smbldap_bind.conf",os.R_OK):
248.465 + print "\n============================================================="
248.466 + print "ERRORE: impossibile usare questa utility su questo sistema"
248.467 + print " smbldap-tools non correttamente installato o"
248.468 + print " permessi insufficienti - rivolgersi all'Amministratore"
248.469 + print "============================================================="
248.470 + sys.exit()
248.471 + elif self.adminUsr == 'root':
248.472 + return
248.473 + elif self.gruppo:
248.474 + #print '###',gruppo,self.authChi[gruppo]
248.475 + if not (self.ru.search(self.authChi[gruppo]) or \
248.476 + self.rg.search(self.authChi[gruppo])):
248.477 + print "\n=============================================="
248.478 + print "ACCESSO VIETATO - gruppo richiesto: "+gruppo
248.479 + print " "+self.adminUsr+self.adminGrp+" non ha i privilegi necessari"
248.480 + print " rivolgersi all'Amministratore"
248.481 + print "=============================================="
248.482 + sys.exit()
248.483 + else:
248.484 + print "\n=============================================="
248.485 + print "ACCESSO SENZA INDICAZIONE DEL GRUPPO VIETATO:"
248.486 + print " uso consentito al solo personale autorizzato"
248.487 + print " rivolgersi all'Amministratore"
248.488 + print "=============================================="
248.489 + sys.exit()
248.490 +
248.491 +
248.492 +
248.493 +class User:
248.494 + """ crea un oggetto utente
248.495 + le condizioni possibili sui campi sono espresse via regexp:
248.496 + campo obbligatorio '.+'
248.497 + campo facoltativo '.*'
248.498 + """
248.499 +
248.500 + CampiUtente = orderedDict()
248.501 + #defaults
248.502 + USERID_MINLEN = 5
248.503 + USERID_MAXLEN = 15
248.504 + USERPW_MINLEN = 8
248.505 + USERPW_MAXLEN = 14
248.506 + CLASSE_MAXLEN = 6
248.507 +
248.508 + PREFIX_ADMINS = "ad_"
248.509 + PREFIX_ALUNNI = "a_"
248.510 + PREFIX_ATA = "t_"
248.511 + PREFIX_DOCENTI= "d_"
248.512 + PREFIX_ESTERNI= "e_"
248.513 + PREFIX_OSPITI = "o_"
248.514 +
248.515 + # lettura parametri dal file di conf.
248.516 + if os.access(FILECONF,os.R_OK):
248.517 + f = open(FILECONF,"r")
248.518 + x = f.readlines()
248.519 + f.close()
248.520 + cr = re.compile(r'^\s*#')
248.521 + for l in x:
248.522 + if cr.match(l): continue
248.523 + ll=string.replace(l,'\n','')
248.524 + ll=string.replace(l,' ','')
248.525 + param = string.split(ll,'=')
248.526 + #print param
248.527 + if param[0] == 'USERID_MINLEN':
248.528 + USERID_MINLEN = int(param[1])
248.529 + if param[0] == 'USERID_MAXLEN':
248.530 + USERID_MAXLEN = int(param[1])
248.531 + if param[0] == 'USERPW_MINLEN':
248.532 + USERPW_MINLEN = int(param[1])
248.533 + if param[0] == 'USERPW_MAXLEN':
248.534 + USERPW_MAXLEN = int(param[1])
248.535 + if param[0] == 'CLASSE_MAXLEN':
248.536 + CLASSE_MAXLEN = int(param[1])
248.537 + if param[0] == 'PREFIX_ADMINS':
248.538 + PREFIX_ADMINS = param[1]
248.539 + if param[0] == 'PREFIX_ALUNNI':
248.540 + PREFIX_ALUNNI = param[1]
248.541 + if param[0] == 'PREFIX_ATA':
248.542 + PREFIX_ATA = param[1]
248.543 + if param[0] == 'PREFIX_DOCENTI':
248.544 + PREFIX_DOCENTI= param[1]
248.545 + if param[0] == 'PREFIX_ESTERNI':
248.546 + PREFIX_ESTERNI = param[1]
248.547 + if param[0] == 'PREFIX_OSPITI':
248.548 + PREFIX_OSPITI = param[1]
248.549 +
248.550 + CampiUtente['userMGrp'] = {
248.551 + 'caption':"Gruppo princ.",
248.552 + 'required':True,
248.553 + 'condition':'^.+$',
248.554 + 'default':'=alunni',
248.555 + 'visible':True,
248.556 + 'maxlen':None,
248.557 + 'msgerr':'CAMPO OBBLIGATORIO',
248.558 + 'msghlp':'inserire il gruppo principale'
248.559 + }
248.560 +
248.561 + CampiUtente['userID'] = {
248.562 + 'caption':"UserID",
248.563 + 'required':True,
248.564 + 'condition':'^[a-z_0-9\.]{'+str(USERID_MINLEN)+','+str(USERID_MAXLEN)+'}$',
248.565 + 'default':'',
248.566 + 'visible':True,
248.567 + 'maxlen':USERID_MAXLEN,
248.568 + 'msgerr':'CAMPO OBBLIGATORIO ('+str(USERID_MINLEN)+'-'+\
248.569 + str(USERID_MAXLEN)+' car.)',
248.570 + 'msghlp':'inserisci il nome utente'
248.571 + }
248.572 +
248.573 + CampiUtente['userPass'] = {
248.574 + 'caption':"Password",
248.575 + 'required':True,
248.576 + 'condition':'^.{'+str(USERPW_MINLEN)+','+str(USERPW_MAXLEN)+'}$',
248.577 + 'default':'',
248.578 + 'visible':True,
248.579 + 'maxlen':USERPW_MAXLEN,
248.580 + 'msgerr':'OBBL.se nuovo utente ('+str(USERPW_MINLEN)+'-'+\
248.581 + str(USERPW_MAXLEN)+')',
248.582 + 'msghlp':'cambia la pass al volo con AltP'
248.583 + }
248.584 +
248.585 +
248.586 + CampiUtente['userCognome'] = {
248.587 + 'caption':"Cognome",
248.588 + 'required':True,
248.589 + 'condition':'^[a-z\' A-Z]{2,25}$',
248.590 + 'default':'',
248.591 + 'visible':True,
248.592 + 'maxlen':None,
248.593 + 'msgerr':'CAMPO OBBLIGATORIO',
248.594 + 'msghlp':'inserisci il Cognome'
248.595 + }
248.596 +
248.597 + CampiUtente['userNome'] = {
248.598 + 'caption':"Nome",
248.599 + 'required':None,
248.600 + 'condition':'^[a-z A-Z]*$',
248.601 + 'default':'',
248.602 + 'visible':True,
248.603 + 'maxlen':None,
248.604 + 'msgerr':'',
248.605 + 'msghlp':'inserisci il Nome'
248.606 + }
248.607 +
248.608 + CampiUtente['userCF'] = {
248.609 + 'caption':"Cod.fiscale",
248.610 + 'required':None,
248.611 + 'condition':'^[a-zA-Z]{6,6}[0-9]{2,2}[a-zA-Z]{1,1}[0-9]{2,2}[a-zA-Z]{1}[0-9]{3,3}[a-zA-Z]{1,1}|^$',
248.612 + 'default':'',
248.613 + 'visible':True,
248.614 + 'maxlen':None,
248.615 + 'msgerr':'formato errato',
248.616 + 'msghlp':'inserisci il codice fiscale'
248.617 + }
248.618 +
248.619 + CampiUtente['userClasse'] = {
248.620 + 'caption':"Classe",
248.621 + 'required':None,
248.622 + 'condition':'^.*$',
248.623 + 'default':'=',
248.624 + 'visible':True,
248.625 + 'maxlen':CLASSE_MAXLEN,
248.626 + 'msgerr':'',
248.627 + 'msghlp':'obbligatorio se alunno'
248.628 + }
248.629 +
248.630 + CampiUtente['userAGrp'] = {
248.631 + 'caption':"Altri gruppi",
248.632 + 'required':None,
248.633 + 'condition':'^.*$',
248.634 + 'default':'',
248.635 + 'visible':True,
248.636 + 'maxlen':None,
248.637 + 'msgerr':'',
248.638 + 'msghlp':'separa i gruppi con la virgola'
248.639 + }
248.640 +
248.641 + CampiUtente['userSex'] = {
248.642 + 'caption':"Sesso",
248.643 + 'required':None,
248.644 + 'condition':'^[mMfF]?$',
248.645 + 'default':'',
248.646 + 'visible':True,
248.647 + 'maxlen':1,
248.648 + 'msgerr':'valori ammessi: vuoto mMfF',
248.649 + 'msghlp':'inserisci M o F'
248.650 + }
248.651 +
248.652 +
248.653 + CampiUtente['userNatoil'] = {
248.654 + 'caption':"Nato il",
248.655 + 'required':None,
248.656 + 'condition':'^.*$',
248.657 + 'default':'',
248.658 + 'visible':False,
248.659 + 'maxlen':None,
248.660 + 'msgerr':'',
248.661 + 'msghlp':'inserisci la data di nascita'
248.662 + }
248.663 +
248.664 + CampiUtente['userNatoa'] = {
248.665 + 'caption':"Nato a",
248.666 + 'required':None,
248.667 + 'condition':'^.*$',
248.668 + 'default':'',
248.669 + 'visible':False,
248.670 + 'maxlen':None,
248.671 + 'msgerr':'',
248.672 + 'msghlp':'inserisci il luogo di nascita'
248.673 + }
248.674 +
248.675 + CampiUtente['userNatoPr'] = {
248.676 + 'caption':"Prov.nascita",
248.677 + 'required':None,
248.678 + 'condition':'.*',
248.679 + 'default':'',
248.680 + 'visible':False,
248.681 + 'maxlen':2,
248.682 + 'msgerr':'',
248.683 + 'msghlp':'inserisci la provincia di nascita'
248.684 + }
248.685 +
248.686 + CampiUtente['userNatoSt'] = {
248.687 + 'caption':"Stato",
248.688 + 'required':None,
248.689 + 'condition':'^.*$',
248.690 + 'default':'',
248.691 + 'visible':False,
248.692 + 'maxlen':None,
248.693 + 'msgerr':'',
248.694 + 'msghlp':'inserisci lo stato di nascita'
248.695 + }
248.696 +
248.697 + CampiUtente['userInd'] = {
248.698 + 'caption':"Indirizzo",
248.699 + 'required':None,
248.700 + 'condition':'^.*$',
248.701 + 'default':'',
248.702 + 'visible':True,
248.703 + 'maxlen':None,
248.704 + 'msgerr':'',
248.705 + 'msghlp':"inserisci l'indirizzo"
248.706 + }
248.707 +
248.708 + CampiUtente['userCap'] = {
248.709 + 'caption':"Cap",
248.710 + 'required':None,
248.711 + 'condition':'^[0-9]{5,5}$|^$',
248.712 + 'default':'',
248.713 + 'visible':True,
248.714 + 'maxlen':5,
248.715 + 'msgerr':'formato errato',
248.716 + 'msghlp':'inserisci il C.A.P.'
248.717 + }
248.718 +
248.719 + CampiUtente['userCitta'] = {
248.720 + 'caption':"Citta",
248.721 + 'required':None,
248.722 + 'condition':'^.*$',
248.723 + 'default':'',
248.724 + 'visible':True,
248.725 + 'maxlen':None,
248.726 + 'msgerr':'',
248.727 + 'msghlp':'luogo di residenza'
248.728 + }
248.729 +
248.730 + CampiUtente['userProv'] = {
248.731 + 'caption':"Provincia",
248.732 + 'required':None,
248.733 + 'condition':'^.*$',
248.734 + 'default':'',
248.735 + 'visible':True,
248.736 + 'maxlen':None,
248.737 + 'msgerr':'',
248.738 + 'msghlp':'provinca di residenza'
248.739 + }
248.740 +
248.741 + CampiUtente['userTel1'] = {
248.742 + 'caption':"Telefono1",
248.743 + 'required':None,
248.744 + 'condition':'^.*$',
248.745 + 'default':'',
248.746 + 'visible':True,
248.747 + 'maxlen':None,
248.748 + 'msgerr':'',
248.749 + 'msghlp':'telefono di casa'
248.750 + }
248.751 +
248.752 + CampiUtente['userTel2'] = {
248.753 + 'caption':"Telefono2",
248.754 + 'required':None,
248.755 + 'condition':'^.*$',
248.756 + 'default':'',
248.757 + 'visible':False,
248.758 + 'maxlen':None,
248.759 + 'msgerr':'',
248.760 + 'msghlp':'altro telefono'
248.761 + }
248.762 +
248.763 + CampiUtente['userEmail'] = {
248.764 + 'caption':"E-mail",
248.765 + 'required':None,
248.766 + 'condition':'^.+@.+^|^$',
248.767 + 'default':'',
248.768 + 'visible':False,
248.769 + 'maxlen':None,
248.770 + 'msgerr':'indirizzo e-mail non valido',
248.771 + 'msghlp':'inserisci un indirizzo email valido'
248.772 + }
248.773 +
248.774 + CampiUtente['userPadreC'] = {
248.775 + 'caption':"Cognome padre",
248.776 + 'required':None,
248.777 + 'condition':'^.*$',
248.778 + 'default':'',
248.779 + 'visible':False,
248.780 + 'maxlen':None,
248.781 + 'msgerr':'',
248.782 + 'msghlp':'inserisci il cognome del padre'
248.783 + }
248.784 +
248.785 + CampiUtente['userPadreN'] = {
248.786 + 'caption':"Nome padre",
248.787 + 'required':None,
248.788 + 'condition':'^.*$',
248.789 + 'default':'',
248.790 + 'visible':False,
248.791 + 'maxlen':None,
248.792 + 'msgerr':'',
248.793 + 'msghlp':'inserisci il nome del padre'
248.794 + }
248.795 +
248.796 + CampiUtente['userMadreC'] = {
248.797 + 'caption':"Cognome madre",
248.798 + 'required':None,
248.799 + 'condition':'.*',
248.800 + 'default':'',
248.801 + 'visible':False,
248.802 + 'maxlen':None,
248.803 + 'msgerr':'',
248.804 + 'msghlp':'inserisci il cognome della madre'
248.805 + }
248.806 +
248.807 + CampiUtente['userMadreN'] = {
248.808 + 'caption':"Nome madre",
248.809 + 'required':None,
248.810 + 'condition':'^.*$',
248.811 + 'default':'',
248.812 + 'visible':False,
248.813 + 'maxlen':None,
248.814 + 'msgerr':'',
248.815 + 'msghlp':'inserisci il nome della madre'
248.816 + }
248.817 +
248.818 + CampiQuota = orderedDict()
248.819 +
248.820 + CampiQuota['quota_sl'] = {
248.821 + 'caption':"Allarme a (in kb)",
248.822 + 'required':None,
248.823 + 'condition':'^[0-9]*$',
248.824 + 'default':'0',
248.825 + 'visible':True,
248.826 + 'maxlen':None,
248.827 + 'msgerr':'',
248.828 + 'msghlp':'soglia di allarme spazio insufficiente'
248.829 + }
248.830 +
248.831 + CampiQuota['quota_hl'] = {
248.832 + 'caption':"Limite max.(in kb)",
248.833 + 'required':None,
248.834 + 'condition':'^[0-9]*$',
248.835 + 'default':'0',
248.836 + 'visible':True,
248.837 + 'maxlen':None,
248.838 + 'msgerr':'',
248.839 + 'msghlp':'soglia invalicabile - spazio totale'
248.840 + }
248.841 +
248.842 + PrefixID = dictNoComplain()
248.843 +
248.844 + PrefixID['alunni' ] = PREFIX_ALUNNI
248.845 + PrefixID['admins' ] = PREFIX_ADMINS
248.846 + PrefixID['ata' ] = PREFIX_ATA
248.847 + PrefixID['docenti'] = PREFIX_DOCENTI
248.848 + PrefixID['esterni'] = PREFIX_ESTERNI
248.849 + PrefixID['ospiti' ] = PREFIX_OSPITI
248.850 +
248.851 + # sequenza campi compatibile solo con gli scripts isi*
248.852 + TracRec = ('userID','userCognome','userNome','userMGrp',
248.853 + 'userAGrp','userCF','userPass','userSex',
248.854 + 'userInd','userCitta','userCap','userProv','userTel1')
248.855 +
248.856 +# tracciato record potenziale (SISSI)
248.857 +# TracRec = ('userID','userCognome','userNome','userMGrp',
248.858 +# 'userAGrp','userCF','userPass','userSex',
248.859 +# 'userInd','userCitta','userCap','userProv','userTel1',
248.860 +# 'userTel2','userNatoil','userNatoa','userNatoPr','userNatoSt',
248.861 +# 'userPadreC','userPadreN','userMadreC','userMadreN')
248.862 +
248.863 + newUser = None # si tratta di un nuovo utente ?
248.864 + newPass = None # password cambiata ?
248.865 + changed = None # dati modificati?
248.866 + novalid = None # i dati contengono errori?
248.867 + delUser = None # l'utente deve essere eliminato da ldap?
248.868 +
248.869 + Campi = orderedDict()
248.870 + for campo in CampiUtente.ordKeys:
248.871 + if CampiUtente[campo]['visible']:
248.872 + if CampiUtente[campo]['required']:
248.873 + ob = ' *: '
248.874 + else:
248.875 + ob = ' : '
248.876 + caption = string.rjust(CampiUtente[campo]['caption'],20)+ob
248.877 + Campi[campo] = VEdit(campo,
248.878 + CampiUtente[campo]['condition'],
248.879 + CampiUtente[campo]['maxlen'],
248.880 + CampiUtente[campo]['msgerr'],
248.881 + CampiUtente[campo]['msghlp'],
248.882 + ('editcp',caption),
248.883 + string.lstrip(CampiUtente[campo]['default'],'='))
248.884 +
248.885 + Quota = orderedDict()
248.886 + for campo in CampiQuota.ordKeys:
248.887 + if CampiQuota[campo]['visible']:
248.888 + if CampiQuota[campo]['required']:
248.889 + ob = ' *: '
248.890 + else:
248.891 + ob = ' : '
248.892 + caption = string.rjust(CampiQuota[campo]['caption'],20)+ob
248.893 + Quota[campo] = VEdit(campo,
248.894 + CampiQuota[campo]['condition'],
248.895 + CampiQuota[campo]['maxlen'],
248.896 + CampiQuota[campo]['msgerr'],
248.897 + CampiQuota[campo]['msghlp'],
248.898 + ('editcp',caption),
248.899 + string.lstrip(CampiQuota[campo]['default'],'='))
248.900 +
248.901 + Quota['h1'] = sep
248.902 + Quota['h2'] = urwid.Text('Quota in kilobytes (50000 = 50Mb)\nAltQ - assegna la quota\nESC - rinuncia')
248.903 +
248.904 + def __init__(self):
248.905 + self.items=[] # campi editabili frame di sinistra
248.906 + self.itemq=[] # campi quota
248.907 + for c in self.Campi.ordKeys:
248.908 + self.items.append(urwid.AttrWrap(self.Campi[c],'editbx','editfc'))
248.909 +
248.910 + for c in self.Quota.ordKeys:
248.911 + if c in ('h1','h2'):
248.912 + self.itemq.append(urwid.AttrWrap(self.Quota[c],'help'))
248.913 + else:
248.914 + self.itemq.append(urwid.AttrWrap(self.Quota[c],'editbx','editfc'))
248.915 +
248.916 + def get_campo(self,nome):
248.917 + v = ''
248.918 + if nome in ('quota_sl','quota_hl'):
248.919 + if self.CampiQuota[nome]['visible']:
248.920 + v = self.Quota[nome].get_edit_text()
248.921 + else:
248.922 + if self.CampiUtente[nome]['visible']:
248.923 + v = self.Campi[nome].get_edit_text()
248.924 + return v
248.925 +
248.926 + def get_default(self,nome):
248.927 + if nome in ('quota_sl','quota_hl'):
248.928 + return self.CampiQuot[nome]['default']
248.929 + else:
248.930 + return self.CampiUtente[nome]['default']
248.931 +
248.932 + def set_campo(self,nome,valore):
248.933 + if nome in ('quota_sl','quota_hl'):
248.934 + if self.CampiQuota[nome]['visible']:
248.935 + self.Quota[nome].set_edit_text(valore)
248.936 + else:
248.937 + if self.CampiUtente[nome]['visible']:
248.938 + self.Campi[nome].set_edit_text(valore)
248.939 +
248.940 + def is_visible(self,nome):
248.941 + if nome in ('quota_sl','quota_hl'):
248.942 + return self.CampiQuot[nome]['visible']
248.943 + else:
248.944 + return self.CampiUtente[nome]['visible']
248.945 +
248.946 +
248.947 +class AddUser:
248.948 + palette = [
248.949 + ('body' , 'black' , 'light gray', 'standout'),
248.950 + ('reverse' , 'light gray', 'dark blue'),
248.951 + ('header' , 'yellow' , 'dark blue', 'bold'),
248.952 + ('footer' , 'yellow' , 'dark blue', 'bold'),
248.953 + ('focus' , 'black' , 'light gray', 'standout'),
248.954 + ('focusnew', 'dark blue' , 'light gray', 'standout'),
248.955 + ('focuserr', 'dark red' , 'light gray', 'standout'),
248.956 + ('focusdel', 'yellow' , 'dark red', 'standout'),
248.957 + ('focuspwd', 'yellow' , 'light gray', 'standout'),
248.958 + ('focuscha', 'white', 'light gray', 'standout'),
248.959 + ('selfocus', 'yellow' , 'dark magenta',\
248.960 + ('bold','standout','underline')),
248.961 + ('title' , 'dark red' , 'light gray',('standout','underline')),
248.962 + ('help' , 'dark blue' , 'light gray', 'standout'),
248.963 + ('helpnote', 'dark red' , 'light gray'),
248.964 + ('passwd' , 'dark red' , 'dark red'),
248.965 + ('key' , 'yellow' , 'light gray', ('standout','underline')),
248.966 + ('editfc' , 'white' , 'black', 'bold'),
248.967 + ('editbx' , 'light gray', 'black'),
248.968 + ('editcp' , 'black' , 'light gray', 'standout'),
248.969 + ('errorcp' , 'dark red' , 'light gray', 'standout'),
248.970 + ('alert' , 'yellow' , 'dark red', 'standout'),
248.971 + ('newuser' , 'dark red' , 'light gray', 'standout'),
248.972 + ('bright' , 'dark gray' , 'light gray', ('bold','standout')),
248.973 + ('error' , 'white' , 'black', ('bold','standout')),
248.974 + ('buttn' , 'black' , 'dark cyan'),
248.975 + ('buttnf' , 'white' , 'dark blue','bold'),
248.976 + ]
248.977 +
248.978 + htxt1 = urwid.Text("ISI-USERS [AltH-help]")
248.979 + ftxt1 = urwid.Text("")
248.980 + head1 = urwid.AttrWrap( htxt1, 'header' )
248.981 + foot0 = urwid.AttrWrap( ftxt1, 'alert' )
248.982 + foot1 = urwid.AttrWrap( ftxt1, 'footer' )
248.983 +
248.984 + htxt2 = urwid.Text("Lista utenti gruppo:")
248.985 + ftxt2 = urwid.Text("")
248.986 + head2 = urwid.AttrWrap( htxt2, 'header' )
248.987 + foot2 = urwid.AttrWrap( ftxt2, 'footer' )
248.988 +
248.989 + htxt4 = urwid.Text("QUOTA DISCO")
248.990 + ftxt4 = urwid.Text("")
248.991 + head4 = urwid.AttrWrap( htxt4, 'header' )
248.992 + foot4 = urwid.AttrWrap( ftxt4, 'footer' )
248.993 +
248.994 + AttUser = User()
248.995 + AttUid = None
248.996 +
248.997 + #inserisco separatori tra campi, preparo frame di sinistra
248.998 + AttUser.items.insert(0,blank)
248.999 + AttUser.items.insert(2,sep)
248.1000 + AttUser.items.insert(5,sep)
248.1001 + AttUser.items.insert(11,sep)
248.1002 + AttUser.items.insert(17,sep)
248.1003 + AttUser.items.append(sep)
248.1004 + AttUser.items.append(blank)
248.1005 +
248.1006 + num_items=len(AttUser.items)
248.1007 + num_user = 0
248.1008 +
248.1009 + AttUser.itemq.insert(0,blank)
248.1010 +
248.1011 + usersRecords = {}
248.1012 + usersImmessi = {}
248.1013 + usersQuota = {}
248.1014 + usersInOrd = []
248.1015 +
248.1016 + LBoxF = urwid.ListBox(AttUser.items)
248.1017 + LBoxQ = urwid.ListBox(AttUser.itemq)
248.1018 +
248.1019 + ListaID = [sep]
248.1020 + LBoxL = urwid.ListBox(ListaID)
248.1021 + LBoxH = HelpColumn()
248.1022 + LBoxP = AuthPassColumn()
248.1023 + LBoxC = ConfirmColumn()
248.1024 +
248.1025 + oShow = 0
248.1026 + FC = urwid.Frame(LBoxF,head1, foot1)
248.1027 + FL = [ urwid.Frame(LBoxL,head2,foot2), LBoxH, LBoxP, LBoxC,
248.1028 + urwid.Frame(LBoxQ,head4,foot4) ]
248.1029 +
248.1030 + oC2 = (
248.1031 + urwid.Overlay(FL[0],FL[1],'left',('relative',100),'top',('relative',100)),
248.1032 + urwid.Overlay(FL[1],FL[0],'left',('relative',100),'top',('relative',100)),
248.1033 + urwid.Overlay(FL[2],FL[0],'left',('relative',100),'top',('relative',100)),
248.1034 + urwid.Overlay(FL[3],FL[0],'left',('relative',100),'top',('relative',100)),
248.1035 + urwid.Overlay(FL[4],FL[0],'left',('relative',100),'top',('relative',100))
248.1036 + )
248.1037 +
248.1038 + # FIXME: per il momento interfaccio la libreria attraverso gli oggetti
248.1039 + # già esistenti nella vecchia versione di isi-users
248.1040 + # LDAPCON conterrà la connessione ad ldap, LDAPCON.l è l'oggetto isi.Manager
248.1041 + # che mette a disposizione tutte le funzioni di libreria
248.1042 +
248.1043 + LDAPCON = None
248.1044 + changed = None
248.1045 + user_exist = None
248.1046 + auth = None
248.1047 + op_pwd = None
248.1048 + op_fine = None
248.1049 + alulink = []
248.1050 + size= None
248.1051 + gruppo = None
248.1052 + ldapLoadErr = None
248.1053 + cancProfilo = None
248.1054 +
248.1055 + def __init__(self,gruppo=None):
248.1056 + """autorizza l'utente e carica utenti del gruppo"""
248.1057 +
248.1058 + self.auth = authSudo(gruppo)
248.1059 + self.auth.main()
248.1060 + self.gruppo=gruppo
248.1061 +
248.1062 + if gruppo:
248.1063 + self.htxt2.set_text('Gruppo: '+self.gruppo+' | admin: '+ \
248.1064 + self.auth.adminUsr+self.auth.adminGrp)
248.1065 + self.LDAPCON = isildap(gruppo)
248.1066 + # carica tutti gli utenti del gruppo
248.1067 + self.load_fromldap()
248.1068 +
248.1069 +
248.1070 + self.user_exist = False
248.1071 + self.okalert = False
248.1072 +
248.1073 + if self.usersInOrd:
248.1074 + self.ncol=1
248.1075 + else:
248.1076 + self.ncol=0
248.1077 +
248.1078 + self.col_list = [ ('weight',45,self.FC),
248.1079 + ('weight',30,self.oC2[self.oShow])
248.1080 + ]
248.1081 +
248.1082 + self.columns = urwid.Columns( self.col_list, 1 )
248.1083 + self.columns.set_focus_column( self.ncol )
248.1084 + self.top = urwid.AttrWrap( self.columns, 'body' )
248.1085 +
248.1086 +
248.1087 + def main(self):
248.1088 + self.ui = urwid.curses_display.Screen()
248.1089 + self.ui.register_palette(self.palette)
248.1090 + self.ui.run_wrapper( self.run )
248.1091 + return self.num_user
248.1092 +
248.1093 + def run(self):
248.1094 + self.ui.set_mouse_tracking()
248.1095 + while True:
248.1096 + self.size = self.ui.get_cols_rows()
248.1097 + if not self.ldapLoadErr is None:
248.1098 + self.alert('DATI/UTENTI INESISTENTI:\n'+self.ldapLoadErr)
248.1099 + self.ldapLoadErr = None
248.1100 +
248.1101 + if not self.AttUser.get_campo('userPass'):
248.1102 + self.AttUser.set_campo('userPass',new_passwd(8))
248.1103 +
248.1104 + Altro = None
248.1105 + NoValid = None
248.1106 + k = None
248.1107 +
248.1108 + changeshow = None
248.1109 + self.num_user = len(self.usersImmessi)
248.1110 +
248.1111 + while True:
248.1112 + if Altro: break
248.1113 +
248.1114 + if changeshow:
248.1115 + changeshow = None
248.1116 + self.col_list = [ ('weight',45,self.FC),
248.1117 + ('weight',30,self.FL[self.oShow])
248.1118 + ]
248.1119 + self.columns = urwid.Columns( self.col_list, 1 )
248.1120 + self.columns.set_focus_column( self.ncol )
248.1121 + self.top = urwid.AttrWrap( self.columns, 'body' )
248.1122 +
248.1123 + self.ncol = self.columns.get_focus_column()
248.1124 + c,p = self.LBoxF.get_focus()
248.1125 + if not hasattr(c,'validate'):
248.1126 + self.LBoxF.set_focus(1)
248.1127 + c,p = self.LBoxF.get_focus()
248.1128 +
248.1129 + if self.ncol == 0:
248.1130 + if NoValid:
248.1131 + self.stato(c,'err')
248.1132 + else:
248.1133 + self.stato(c,'hlp')
248.1134 + else:
248.1135 + self.cambiaDatiUser()
248.1136 + self.aggiorna_form()
248.1137 +
248.1138 + self.draw_screen( self.size)
248.1139 +
248.1140 + NoValid = None
248.1141 + keys = None
248.1142 +
248.1143 + while not keys:
248.1144 + keys = self.ui.get_input()
248.1145 + for k in keys:
248.1146 + if urwid.is_mouse_event(k):
248.1147 + event, button, col, row = k
248.1148 + self.top.mouse_event( self.size,event, button, col, row,focus=True )
248.1149 + continue
248.1150 +
248.1151 + if k == "window resize":
248.1152 + self.size = self.ui.get_cols_rows()
248.1153 + continue
248.1154 +
248.1155 + if self.cancProfilo:
248.1156 + if self.oShow == 3 and k in ('s','S'):
248.1157 + k = self.cancProfilo
248.1158 + changeshow = True
248.1159 + self.oShow=0
248.1160 + elif self.oShow == 3 and k in ('n','N'):
248.1161 + self.cancProfilo = None
248.1162 +# self.LBoxC.vuota() #probabilmente inutile
248.1163 + changeshow = True
248.1164 + self.oShow=0
248.1165 + k=''
248.1166 + else:
248.1167 + if self.oShow == 3 and k in ('s','S'):
248.1168 + self.num_user = 0
248.1169 + return
248.1170 + elif self.oShow == 3 and k in ('n','N'):
248.1171 +# self.LBoxC.vuota() #probabilmente inutile
248.1172 + changeshow = True
248.1173 + self.oShow=0
248.1174 + k=''
248.1175 + elif self.oShow == 3:
248.1176 + k=''
248.1177 + else:
248.1178 + pass
248.1179 +
248.1180 + if k in ('meta x','meta X'):
248.1181 + if self.ncol == 0:
248.1182 + self.cambiaDatiUser()
248.1183 + if len(self.usersRecords) > 0:
248.1184 + self.LBoxC.load_msg(0)
248.1185 + changeshow = True
248.1186 + self.oShow = 3
248.1187 + self.ncol=1
248.1188 + k = ''
248.1189 + else:
248.1190 + self.num_user = 0
248.1191 + return
248.1192 +
248.1193 + if k in ('left','meta left') and self.oShow == 2:
248.1194 + k = ''
248.1195 +
248.1196 + if k == 'esc':
248.1197 + if self.ncol == 0 and len(self.usersImmessi)>0:
248.1198 + self.alert('')
248.1199 + self.AttUser.changed = False
248.1200 + k='meta right'
248.1201 + if self.oShow == 2:
248.1202 + self.alert('')
248.1203 + changeshow = True
248.1204 + self.oShow = 0
248.1205 + self.op_pwd = None
248.1206 + self.op_fine = None
248.1207 + elif self.oShow == 4:
248.1208 + self.alert('')
248.1209 + changeshow = True
248.1210 + self.oShow = 0
248.1211 +
248.1212 + if k in ('meta s','meta S'):
248.1213 + if self.ncol == 0 and self.checkPrivileges():
248.1214 + self.AttUser.changed = True
248.1215 + self.AddRecord()
248.1216 + k='meta right'
248.1217 +
248.1218 + if k in ('meta r','meta R'): #ricarica da ldap
248.1219 + self.reloadFromLdap()
248.1220 + break
248.1221 + if k in ('meta g','meta G'): #ricarica da ldap
248.1222 + self.load_fromldap()
248.1223 + #---------------------------------------------------
248.1224 + if k in ('meta h','meta H'):
248.1225 + changeshow = True
248.1226 + if self.oShow == 1:
248.1227 + self.oShow=0
248.1228 + else:
248.1229 + self.oShow=1
248.1230 +
248.1231 + elif k in ('meta q','meta Q'):
248.1232 + changeshow = True
248.1233 + if self.oShow == 4:
248.1234 + q = [ self.AttUser.get_campo('quota_sl'),
248.1235 + self.AttUser.get_campo('quota_hl') ]
248.1236 + self.set_quota(self.AttUid,q)
248.1237 + self.oShow=0
248.1238 + else:
248.1239 + q = self.get_quota(self.AttUid)
248.1240 + self.AttUser.set_campo('quota_sl',q[1])
248.1241 + self.AttUser.set_campo('quota_hl',q[2])
248.1242 + self.LBoxQ.set_focus(1)
248.1243 + self.oShow=4
248.1244 +
248.1245 + elif k in ('meta i','meta I'): # cancella profilo Win9x
248.1246 + if self.cancProfilo is None:
248.1247 + self.cancProfilo = k
248.1248 + self.LBoxC.load_msg(1, '9x')
248.1249 + changeshow = True
248.1250 + self.oShow = 3
248.1251 +# self.ncol=1
248.1252 + else:
248.1253 + self.elimina_profilo(PROFILO['9x'])
248.1254 + k = ''
248.1255 +
248.1256 + elif k in ('meta j','meta J'): # cancella profilo WinXP
248.1257 + if self.cancProfilo is None:
248.1258 + self.cancProfilo = k
248.1259 + self.LBoxC.load_msg(1, 'xp')
248.1260 + changeshow = True
248.1261 + self.oShow = 3
248.1262 +# self.ncol=1
248.1263 + else:
248.1264 + self.elimina_profilo(PROFILO['xp'])
248.1265 + k = ''
248.1266 +
248.1267 + elif k in ('meta l','meta L'): # cancella profilo WinXP
248.1268 + if self.cancProfilo is None:
248.1269 + self.cancProfilo = k
248.1270 + self.LBoxC.load_msg(1, '2k')
248.1271 + changeshow = True
248.1272 + self.oShow = 3
248.1273 +# self.ncol=1
248.1274 + else:
248.1275 + self.elimina_profilo(PROFILO['2k'])
248.1276 + k = ''
248.1277 +
248.1278 + elif k in ('ctrl k','ctrl K'):
248.1279 + if self.ncol == 0:
248.1280 + c.vuota(c.edit_pos)
248.1281 + self.AttUser.changed = True
248.1282 +
248.1283 + elif k in ('meta p','meta P'): # CAMBIA PASSWORD
248.1284 + k=''
248.1285 + if self.ncol == 0:
248.1286 + if not self.AttUser.get_campo('userPass'):
248.1287 + self.LBoxF.set_focus(4)
248.1288 + elif self.auth.adminUsr == 'root':
248.1289 + if self.cambiaPass():
248.1290 + self.AttUser.set_campo('userPass','')
248.1291 + self.op_pwd = None
248.1292 + else:
248.1293 + changeshow = True
248.1294 + self.op_pwd = True
248.1295 + if self.oShow == 2:
248.1296 + self.oShow=0
248.1297 + else:
248.1298 + self.oShow=2
248.1299 + self.ncol=1
248.1300 +
248.1301 + elif k in ('enter','tab'): # attivo solo sulla colonna 0
248.1302 + if self.ncol == 0 and \
248.1303 + self.checkPrivileges() and self.oShow<2:
248.1304 + self.is_new_user(self.AttUser.get_campo('userID'))
248.1305 + if c.name == 'userPass' and \
248.1306 + self.user_exist and not c.get_edit_text():
248.1307 + k = 'down'
248.1308 + elif c.validate():
248.1309 + k = 'down'
248.1310 + self.IDPrefix(c)
248.1311 + else:
248.1312 + NoValid = True
248.1313 + self.columns.set_focus_column(self.ncol-1)
248.1314 + elif self.oShow == 2:
248.1315 + if self.op_pwd:
248.1316 + if self.cambiaPass():
248.1317 + self.AttUser.set_campo('userPass','')
248.1318 + changeshow = True
248.1319 + self.oShow = 0
248.1320 + self.op_pwd = None
248.1321 + elif self.op_fine:
248.1322 + self.UsersFile()
248.1323 + self.updateLdap()
248.1324 + return
248.1325 + elif self.oShow == 4:
248.1326 + k = 'down'
248.1327 + elif self.ncol==1 and self.oShow==0:
248.1328 + pass
248.1329 +
248.1330 + elif k in ('up','down','page up','page down'):
248.1331 + if self.ncol == 0:
248.1332 + if not c.validate():
248.1333 + if c.name == 'userPass' and \
248.1334 + self.user_exist and not c.edit_text:
248.1335 + pass
248.1336 + else:
248.1337 + c.set_caption(('errorcp',c.caption))
248.1338 + else:
248.1339 + c.set_caption(('editcp',c.caption))
248.1340 +
248.1341 + self.is_new_user(self.AttUser.get_campo('userID'))
248.1342 + self.IDPrefix(c)
248.1343 + else:
248.1344 + self.alert('')
248.1345 +
248.1346 + elif k in ('right','left'):
248.1347 + pass
248.1348 +
248.1349 + elif k == 'meta left':
248.1350 + if self.ncol > 0:
248.1351 + self.columns.set_focus_column(self.ncol-1)
248.1352 + k = ''
248.1353 +
248.1354 + elif k == 'meta right':
248.1355 + if self.ncol == 0 and self.checkPrivileges():
248.1356 + self.cambiaDatiUser()
248.1357 + self.columns.set_focus_column(1)
248.1358 + k = ''
248.1359 +
248.1360 + elif k == 'f9': #ex 'meta delete':
248.1361 + if self.ncol == 1:
248.1362 + if self.AttUser.delUser:
248.1363 + self.AttUser.delUser = False
248.1364 + self.AttUser.changed = True
248.1365 + else:
248.1366 + self.AttUser.delUser = True
248.1367 + self.AddRecord()
248.1368 +
248.1369 + elif k == 'delete':
248.1370 + if self.ncol == 1:
248.1371 + if self.oShow == 0:
248.1372 + k = self.DeleteUser()
248.1373 + if k == 'left':
248.1374 + self.vuota()
248.1375 + self.LBoxF.set_focus(1)
248.1376 + self.num_user = 0
248.1377 + Altro = True
248.1378 + self.AttUser.changed = False
248.1379 + elif self.oShow == 4:
248.1380 + pass
248.1381 + else:
248.1382 + self.AttUser.changed = True
248.1383 +
248.1384 + elif k == 'backspace':
248.1385 + if self.oShow ==0 and self.ncol == 0:
248.1386 + self.AttUser.changed = True
248.1387 +
248.1388 + elif k in ('meta f','meta F'): # registra
248.1389 + if self.ncol == 0:
248.1390 + self.cambiaDatiUser()
248.1391 + if len(self.usersRecords) == 0:
248.1392 + self.alert('nessun aggiornamento necessario')
248.1393 + else:
248.1394 + if self.ncol==0 and not self.checkPrivileges():
248.1395 + k = ''
248.1396 + else:
248.1397 + if self.auth.adminUsr == 'root':
248.1398 + self.UsersFile()
248.1399 + self.updateLdap()
248.1400 + return
248.1401 + else:
248.1402 + changeshow = True
248.1403 + self.op_fine = True
248.1404 + if self.oShow == 2:
248.1405 + self.oShow=0
248.1406 + else:
248.1407 + self.oShow=2
248.1408 + self.ncol=1
248.1409 +
248.1410 + elif k in ('f8','meta n','meta N') : # altro record
248.1411 + if self.ncol == 0:
248.1412 + if self.ValidateAll() and \
248.1413 + self.checkPrivileges():
248.1414 + self.AddRecord()
248.1415 + self.vuota()
248.1416 + self.AttUser.changed = False
248.1417 + self.LBoxF.set_focus(1)
248.1418 + Altro = True
248.1419 + else:
248.1420 + NoValid=True
248.1421 + k = ''
248.1422 + else:
248.1423 + self.vuota()
248.1424 + self.LBoxF.set_focus(1)
248.1425 + Altro = True
248.1426 + self.ncol = self.columns.set_focus_column(0)
248.1427 +
248.1428 + elif not k in ('delete','left','right','backspace'):
248.1429 + if self.ncol == 0:
248.1430 + if c.RaiseMaxLen():
248.1431 + k=''
248.1432 + else:
248.1433 + self.AttUser.changed = True
248.1434 +# self.alert(keys)
248.1435 + if k: self.top.keypress( self.size, k )
248.1436 +
248.1437 +#-------------------------------------------------------------------------
248.1438 + def elimina_profilo(self, pwin):
248.1439 + """ elimina profilo windows"""
248.1440 + self.alert('%s - elimino profilo %s, attendi...' % (self.AttUid, pwin))
248.1441 + self.cancProfilo = None
248.1442 + if not self.checkPrivileges(): return
248.1443 + maingrp = self.AttUser.get_campo('userMGrp')
248.1444 + home = "%s/%s/%s" % (HOME_IN, maingrp, self.AttUid)
248.1445 + profilo = "%s/%s/%s/.profili/%s" % \
248.1446 + (HOME_IN, maingrp, self.AttUid, pwin)
248.1447 + if os.path.isdir(profilo):
248.1448 + try:
248.1449 + cmd = "isi-delprofilo %s %s %s" % (maingrp, self.AttUid, pwin)
248.1450 + r, o, e = execute(cmd)
248.1451 + self.alert('%s - profilo %s eliminato' % (self.AttUid, pwin))
248.1452 + except ExecuteError, e:
248.1453 + self.alert("ERRORE: %s" % e)
248.1454 + else:
248.1455 + self.alert('%s - profilo %s inesistente' % (self.AttUid, pwin))
248.1456 +
248.1457 + def aggiorna_form(self):
248.1458 + """ il try serve per la compatibità con la versione etch """
248.1459 + i=0
248.1460 + try:
248.1461 + for i in range(len(self.AttUser.items)):
248.1462 + self.AttUser.items[i]._invalidate()
248.1463 + except:
248.1464 + pass
248.1465 +
248.1466 + def draw_screen(self, size):
248.1467 + """ disegna la schermata """
248.1468 + canvas = self.top.render( size, focus=True )
248.1469 + self.ui.draw_screen( size, canvas )
248.1470 +
248.1471 + def IDPrefix(self,c):
248.1472 + """ prefissa userID dipendentemente dal gruppo principale """
248.1473 + if c.name == 'userMGrp' and self.AttUser.get_campo('userID') =='':
248.1474 + self.AttUser.set_campo('userID',self.AttUser.PrefixID[c.edit_text])
248.1475 +
248.1476 + def cambiaDatiUser(self):
248.1477 + """ sincronizza lista utente e form dati """
248.1478 + if self.checkPrivileges() and self.AttUser.changed:
248.1479 + if self.user_exist or self.ValidateAll(): self.AddRecord()
248.1480 + self.ReloadDatiUser()
248.1481 + alertmsg=''
248.1482 + if self.AttUser.newUser:
248.1483 + alertmsg += 'NEW'
248.1484 + if self.AttUser.newPass:
248.1485 + alertmsg += '|PWD'
248.1486 + if self.AttUser.changed:
248.1487 + alertmsg += '|MOD'
248.1488 + if self.AttUser.delUser:
248.1489 + alertmsg = ' ELIMINATO '
248.1490 + self.AttUid = self.AttUser.get_campo('userID')
248.1491 +
248.1492 + self.is_new_user(self.AttUid)
248.1493 + x = 'UT:'+string.ljust(str(self.num_user),4) +'|'+ \
248.1494 + string.ljust(self.AttUid,13) +'|'
248.1495 + self.ftxt2.set_text([x,('key',alertmsg)] )
248.1496 +
248.1497 + def alert(self,msg):
248.1498 + """ visualizza un messaggio sotto i campi"""
248.1499 + n = len(self.AttUser.items)-1
248.1500 + if msg:
248.1501 + self.AttUser.items[n]=\
248.1502 + urwid.AttrWrap(urwid.Text(msg,'center'),'alert')
248.1503 + else:
248.1504 + self.AttUser.items[n]=\
248.1505 + urwid.AttrWrap(urwid.Text(msg,'center'),'body')
248.1506 + try:
248.1507 + self.AttUser.items[n]._invalidate()
248.1508 + except:
248.1509 + pass
248.1510 + self.draw_screen( self.size )
248.1511 +
248.1512 + def topalert(self,msg,align='center'):
248.1513 + """ visualizza un messaggio sopra i campi """
248.1514 + if msg:
248.1515 + self.AttUser.items[0] = \
248.1516 + urwid.AttrWrap(urwid.Text(msg,align),'focuspwd')
248.1517 + else:
248.1518 + self.AttUser.items[0] = blank
248.1519 + self.AttUser.items[0]._invalidate()
248.1520 + self.draw_screen( self.size )
248.1521 +
248.1522 + def stato(self,c,tmsg):
248.1523 + """ aggiorna la riga di stato """
248.1524 +
248.1525 + if self.AttUser.changed:
248.1526 + ch = '*'
248.1527 + else:
248.1528 + ch = ' '
248.1529 +
248.1530 + if tmsg == 'err':
248.1531 + color = 'error'
248.1532 + msg = ch+'|'+c.msgerr
248.1533 + allinea = 'center'
248.1534 + elif tmsg == 'hlp':
248.1535 + color = 'footer'
248.1536 + msg = ch+'|'+c.msghlp
248.1537 + allinea = 'left'
248.1538 + else:
248.1539 + pass
248.1540 +
248.1541 + self.ftxt1.set_align_mode(allinea)
248.1542 + self.ftxt1.set_text((color,msg))
248.1543 +
248.1544 +
248.1545 + def ValidateAll(self):
248.1546 + """ valida tutti i campi della maschera """
248.1547 + ret = True
248.1548 + self.AttUser.novalid = False
248.1549 + i = 0
248.1550 + for c in self.AttUser.items:
248.1551 + if hasattr(c,'validate'):
248.1552 + if c.validate():
248.1553 + c.set_caption(('editcp',c.caption))
248.1554 + else:
248.1555 + if c.name == 'userPass' and not \
248.1556 + self.AttUser.newUser and not c.edit_text:
248.1557 + ret = True
248.1558 + elif c.name == 'userClasse' and not \
248.1559 + c.edit_text and \
248.1560 + string.lower(self.AttUser.get_campo('userMGrp'))=='alunni':
248.1561 + ret = False
248.1562 + else:
248.1563 + self.LBoxF.set_focus(i)
248.1564 + c.set_caption(('errorcp',c.caption))
248.1565 + ret = False
248.1566 +
248.1567 + i += 1
248.1568 +
248.1569 + if not ret:
248.1570 + self.AttUser.novalid = True
248.1571 +
248.1572 + return ret
248.1573 +
248.1574 + def checkPrivileges(self):
248.1575 + """ controlla che l'admin abbia i privilegi sui gruppi dichiarati"""
248.1576 + ret = True
248.1577 + err = ''
248.1578 + if self.auth.adminUsr == 'root':
248.1579 + pass
248.1580 + else:
248.1581 + gM = self.auth.authChi[self.AttUser.get_campo('userMGrp')]
248.1582 +
248.1583 + gC = self.auth.authChi[self.AttUser.get_campo('userClasse')]
248.1584 +
248.1585 + if not (self.auth.ru.search(gM+'@'+gC) or \
248.1586 + self.auth.rg.search(gM+'@'+gC)):
248.1587 + err += ' '+self.AttUser.get_campo('userClasse')
248.1588 + ret = False
248.1589 +
248.1590 + gg = string.split(self.AttUser.get_campo('userAGrp'),',')
248.1591 + for g in gg:
248.1592 + if g:
248.1593 + gx = self.auth.authChi[g]
248.1594 + if not (self.auth.ru.search(gM+'@'+gx) or \
248.1595 + self.auth.rg.search(gM+'@'+gx)):
248.1596 + err += ' '+g
248.1597 + ret = False
248.1598 + if not ret:
248.1599 + self.alert('OPERAZIONE VIETATA:\nimpossibile assegnare utenti a gruppi ['+ \
248.1600 + err+'] su cui non si hanno privilegi')
248.1601 + return ret
248.1602 +
248.1603 + def vuota(self):
248.1604 + """
248.1605 + vuota tutti campi
248.1606 + rispetta i default e se il default inizia con =
248.1607 + ripropone (non cancella) il valore attuale
248.1608 + """
248.1609 + rex=re.compile('^=')
248.1610 + for c in self.AttUser.Campi.keys():
248.1611 + vd=self.AttUser.get_default(c)
248.1612 + if not rex.match(vd):
248.1613 + self.AttUser.set_campo(c,string.lstrip(vd,'='))
248.1614 + self.AttUser.changed = False
248.1615 + self.AttUser.newPass = False
248.1616 + self.AttUser.newUser = False
248.1617 + self.AttUser.novalid = False
248.1618 +
248.1619 +
248.1620 + def DeleteUser(self):
248.1621 + """ cancella l'utente dalla lista della seconda colonna """
248.1622 + uid = self.AttUser.get_campo('userID')
248.1623 + cog = self.AttUser.get_campo('userCognome')
248.1624 + nom = self.AttUser.get_campo('userNome')
248.1625 +
248.1626 + cn = string.ljust(cog,10) +' '+ nom
248.1627 + cni = self.usersInOrd.index(cn+uid)
248.1628 +
248.1629 + del self.usersInOrd[cni]
248.1630 + del self.ListaID[cni]
248.1631 + del self.usersImmessi[uid]
248.1632 +
248.1633 + if self.usersRecords.has_key(uid):
248.1634 + del self.usersRecords[uid]
248.1635 +
248.1636 + self.num_user -= 1
248.1637 +
248.1638 + ll=len(self.usersInOrd)
248.1639 + if cni == ll:
248.1640 + cni -= 1
248.1641 +
248.1642 + if ll>0:
248.1643 +# self.ListaUt.set_focus(cni)
248.1644 + self.LBoxL.set_focus(cni)
248.1645 + self.ReloadDatiUser()
248.1646 + return ''
248.1647 + else:
248.1648 + self.vuota()
248.1649 + return 'left'
248.1650 +
248.1651 + def reloadFromLdap(self):
248.1652 + """ rilegge il record ldap """
248.1653 + uid = self.AttUser.get_campo('userID')
248.1654 + cog = self.AttUser.get_campo('userCognome')
248.1655 + nom = self.AttUser.get_campo('userNome')
248.1656 +
248.1657 + cn = string.ljust(cog,10) +' '+ nom
248.1658 + try:
248.1659 + cni = self.usersInOrd.index(cn+uid)
248.1660 +
248.1661 + del self.usersInOrd[cni]
248.1662 + del self.ListaID[cni]
248.1663 + del self.usersImmessi[uid]
248.1664 +
248.1665 + if self.usersRecords.has_key(uid):
248.1666 + del self.usersRecords[uid]
248.1667 + self.AttUser.changed = False
248.1668 + self.load_fromldap(uid)
248.1669 + except:
248.1670 + self.alert('nessun utente in lista')
248.1671 +
248.1672 + def ReloadDatiUser(self):
248.1673 + """ rilegge i dati caricati """
248.1674 + if len(self.usersInOrd)>0:
248.1675 +# w,p = self.ListaUt.get_focus()
248.1676 + w,p = self.LBoxL.get_focus()
248.1677 + if hasattr(w,'name') and self.usersImmessi.has_key(w.name):
248.1678 +# self.alert(w.name)
248.1679 + uc = self.usersImmessi[w.name]
248.1680 + for c,txt in uc.iteritems():
248.1681 + if c == 'changed':
248.1682 + self.AttUser.changed = uc['changed']
248.1683 + elif c == 'newPass':
248.1684 + self.AttUser.newPass = uc['newPass']
248.1685 + elif c == 'newUser':
248.1686 + self.AttUser.newUser = uc['newUser']
248.1687 + elif c == 'novalid':
248.1688 + self.AttUser.novalid = uc['novalid']
248.1689 + elif c == 'delUser':
248.1690 + self.AttUser.delUser = uc['delUser']
248.1691 + else:
248.1692 + self.AttUser.set_campo(c,txt)
248.1693 +
248.1694 + if not self.ValidateAll():
248.1695 + self.ftxt1.set_align_mode('center')
248.1696 + self.ftxt1.set_text(('error','errore nei dati'))
248.1697 + else:
248.1698 + uid = self.AttUser.get_campo('userID')
248.1699 + if self.usersQuota[uid][1]:
248.1700 + x ='QUOTA| L1:'+string.ljust(self.usersQuota[uid][1],8)+ \
248.1701 + '| L2:'+ string.ljust(self.usersQuota[uid][2],8)+ \
248.1702 + '| DSK:'+string.ljust(self.usersQuota[uid][0],8)
248.1703 + else:
248.1704 + x = 'QUOTA non assegnata'
248.1705 + self.ftxt1.set_align_mode('left')
248.1706 + self.ftxt1.set_text(('footer',x))
248.1707 +
248.1708 +
248.1709 + def AddRecord(self,Force=None):
248.1710 + """ aggiorna/aggiunge il record dell'utente in memoria """
248.1711 + uid = self.AttUser.get_campo('userID')
248.1712 + cog = self.AttUser.get_campo('userCognome')
248.1713 + nom = self.AttUser.get_campo('userNome')
248.1714 + self.usersQuota[uid] = self.get_quota(uid)
248.1715 +
248.1716 + # ?=quota sconosciuta +=quota superata spazio=quota ok
248.1717 + quo = '?'
248.1718 + if self.usersQuota[uid][1] or self.usersQuota[uid][2]:
248.1719 + quo = ' '
248.1720 + try:
248.1721 + i=string.index(self.usersQuota[uid][0],'*')
248.1722 + quo = '+'
248.1723 + except:
248.1724 + pass
248.1725 +
248.1726 + cn = string.ljust(cog,10) + ' ' + nom
248.1727 + r = string.ljust(uid,15) + quo + cn
248.1728 +
248.1729 + self.ValidateAll()
248.1730 + if not self.usersImmessi.has_key(uid):
248.1731 + self.usersInOrd.append(cn+uid)
248.1732 + self.usersInOrd.sort()
248.1733 + k = self.usersInOrd.index(cn+uid)
248.1734 + if Force: # in questo caso si tratta di utente esistente
248.1735 + if not self.AttUser.novalid:
248.1736 + if self.AttUser.newPass:
248.1737 + x = NamedWrap(uid,SelText(r,'left','clip'),\
248.1738 + 'focuspwd','selfocus')
248.1739 + else:
248.1740 + x = NamedWrap(uid,SelText(r,'left','clip'),\
248.1741 + 'focus','selfocus')
248.1742 + else:
248.1743 + x = NamedWrap(uid,SelText(r,'left','clip'),'focuserr',\
248.1744 + 'selfocus')
248.1745 + else:
248.1746 + x = NamedWrap(uid,SelText(r,'left','clip'),'focusnew',\
248.1747 + 'selfocus')
248.1748 +
248.1749 +
248.1750 + if k > len(self.ListaID):
248.1751 + self.ListaID.append(x)
248.1752 + else:
248.1753 + self.ListaID.insert(k,x)
248.1754 +
248.1755 + else:
248.1756 + for nw in self.ListaID:
248.1757 + if hasattr(nw,'name') and nw.get_name() == uid:
248.1758 + nw.w.set_text(r)
248.1759 + if self.AttUser.delUser:
248.1760 + nw.attr='focusdel'
248.1761 + elif self.AttUser.newUser:
248.1762 + nw.attr='focusnew'
248.1763 + elif self.AttUser.newPass:
248.1764 + nw.attr='focuspwd'
248.1765 + elif self.AttUser.novalid:
248.1766 + nw.attr='focuserr'
248.1767 + elif self.AttUser.changed:
248.1768 + nw.attr='focuscha'
248.1769 + else:
248.1770 + nw.attr='focus'
248.1771 +
248.1772 + self.usersImmessi[uid] = {}
248.1773 + for c in self.AttUser.Campi.ordKeys:
248.1774 + self.usersImmessi[uid][c] = self.AttUser.get_campo(c)
248.1775 + self.usersImmessi[uid]['newUser'] = self.AttUser.newUser
248.1776 + self.usersImmessi[uid]['newPass'] = self.AttUser.newPass
248.1777 + self.usersImmessi[uid]['changed'] = self.AttUser.changed
248.1778 + self.usersImmessi[uid]['delUser'] = self.AttUser.delUser
248.1779 + if self.AttUser.newUser:
248.1780 + self.alulinkClasse(self.usersImmessi[uid]['userClasse'])
248.1781 + elif self.usersImmessi[uid]['userClasse'] != \
248.1782 + self.LDAPCON.memdata[uid]['departmentNumber']:
248.1783 + self.alulinkClasse(self.usersImmessi[uid]['userClasse'])
248.1784 + self.alulinkClasse(self.LDAPCON.memdata[uid]['departmentNumber'])
248.1785 + self.UserRecord(uid)
248.1786 +
248.1787 + def alulinkClasse(self,classe):
248.1788 + """ determina quali classi debbono essere alulinkate """
248.1789 + try:
248.1790 + self.alulink.index(classe)
248.1791 + except:
248.1792 + self.alulink.append(classe)
248.1793 + cc=""
248.1794 + for c in self.alulink:
248.1795 + cc+=c+' '
248.1796 + self.alert('alulink: '+cc)
248.1797 +
248.1798 + def UserRecord(self,uid):
248.1799 + """ costruisce il record utente """
248.1800 + rec = None
248.1801 + xxx = self.AttUser.get_campo('userAGrp')
248.1802 + yyy = self.AttUser.get_campo('userClasse')
248.1803 + if yyy:
248.1804 + if xxx:
248.1805 + xxx1 = yyy + ',' + xxx
248.1806 + else:
248.1807 + xxx1 = yyy
248.1808 + self.AttUser.set_campo('userAGrp',xxx1)
248.1809 +
248.1810 + if not self.AttUser.get_campo('userPass'):
248.1811 + self.AttUser.set_campo('userPass','_UNCHANGED_')
248.1812 +
248.1813 + if self.AttUser.changed or self.AttUser.delUser:
248.1814 + rec = ";".join(["%s" % self.AttUser.get_campo(c) \
248.1815 + for c in self.AttUser.TracRec])
248.1816 + if self.AttUser.delUser:
248.1817 + rec = '-'+rec
248.1818 + else:
248.1819 + pass
248.1820 + if rec:
248.1821 + self.usersRecords[uid] = rec
248.1822 + self.AttUser.set_campo('userAGrp',xxx)
248.1823 +# self.alert(rec)
248.1824 +
248.1825 + def UsersFile(self):
248.1826 + """ salva su file i record immessi """
248.1827 + f = open(USERS_FILE,'w')
248.1828 + self.num_user=0
248.1829 + for u,rec in self.usersRecords.iteritems():
248.1830 + self.num_user += 1
248.1831 + f.write(rec + '\n')
248.1832 + f.close
248.1833 +
248.1834 + def cambiaPass(self):
248.1835 + """ attiva la procedura di cambio password """
248.1836 + ret = False
248.1837 + if not self.auth.adminUsr == 'root':
248.1838 + p = self.LBoxP.items[1].get_edit_text()
248.1839 + if not p:
248.1840 + self.alert('ERRORE: password vuota\nriprova o premi ESC')
248.1841 + self.LBoxP.items[1].set_edit_text('')
248.1842 + self.LBoxP.items[1].set_edit_pos(0)
248.1843 + self.columns.set_focus_column(1)
248.1844 + return ret
248.1845 + dn = self.LDAPCON.l.srv.get_dn(self.auth.adminUsr)
248.1846 + try:
248.1847 + self.LDAPCON.l.srv.bind(dn=dn,passwd=p)
248.1848 + except:
248.1849 + self.alert('ERRORE: credenziali errate\nriprova o premi ESC')
248.1850 + self.LBoxP.items[1].set_edit_text('')
248.1851 + self.LBoxP.items[1].set_edit_pos(0)
248.1852 + self.columns.set_focus_column(1)
248.1853 + del pl
248.1854 + return ret
248.1855 +
248.1856 + wu = self.AttUser.Campi['userID']
248.1857 + wp = self.AttUser.Campi['userPass']
248.1858 + if wu.validate() and wp.validate() and not self.AttUser.newUser:
248.1859 + p = wp.get_edit_text()
248.1860 + u = wu.get_edit_text()
248.1861 + if IS_DASH:
248.1862 + CMD = 'echo "' + p + '\\n' + p + '\\n' + \
248.1863 + '" | smbldap-passwd '+ u
248.1864 +
248.1865 + else:
248.1866 + CMD = 'echo -e "' + p + '\\n' + p + '\\n' + \
248.1867 + '" | smbldap-passwd '+ u
248.1868 +
248.1869 + r, w, e = os.popen3(CMD)
248.1870 + cmderr = w.readlines()
248.1871 + w.close()
248.1872 + e.close()
248.1873 +
248.1874 + if len(cmderr)>3:
248.1875 + self.alert('ERRORE NEL CAMBIAMENTO DELLA PASSWORD\n'+cmderr[3])
248.1876 + else:
248.1877 + self.alert('PASSWORD CAMBIATA')
248.1878 + self.AttUser.newPass = True
248.1879 + self.AddRecord()
248.1880 + ret = True
248.1881 +
248.1882 + else:
248.1883 + self.alert('IMPOSSIBILE CAMBIARE LA PASSWORD\nutente e/o password non validi')
248.1884 + return ret
248.1885 +
248.1886 +
248.1887 + def load_fromldap(self,uid=None):
248.1888 + """
248.1889 + trasferisce i dati ldap come se fossero acquisiti manualmente
248.1890 + e li aggiunge alle liste interne
248.1891 + campildap = (
248.1892 + 'dn','cn','sn','uid','gecos','givenName',
248.1893 + 'displayName','employeeNumber','employeeType',
248.1894 + 'postOfficeBox','postalCode','homePhone',
248.1895 + 'postalAddress','departmentNumber','homeDirectory,gidNumber'
248.1896 + )
248.1897 + """
248.1898 + for u,d in self.LDAPCON.memdata.iteritems():
248.1899 + if uid == None:
248.1900 + pass
248.1901 + elif u != uid:
248.1902 + continue
248.1903 + try:
248.1904 + user_id = string.strip(d['uid'])
248.1905 +
248.1906 + # recupera il maingroup MGrp
248.1907 + all_groups = self.LDAPCON.l.get_user_groups(user_id)
248.1908 + MGrp = all_groups[0] # gruppo principale
248.1909 + CGrp = string.strip(d['departmentNumber']) # classe
248.1910 + if CGrp:
248.1911 + all_groups.remove(CGrp) # altri gruppi
248.1912 + AGrp = ",".join(all_groups[1:])
248.1913 + self.AttUser.set_campo('userMGrp',MGrp)
248.1914 + self.AttUser.set_campo('userID',user_id)
248.1915 + self.AttUser.set_campo('userPass','')
248.1916 + self.AttUser.set_campo('userCognome',string.strip(d['sn']))
248.1917 + self.AttUser.set_campo('userNome',string.strip(d['givenName']))
248.1918 + self.AttUser.set_campo('userClasse',CGrp)
248.1919 + self.AttUser.set_campo('userAGrp',AGrp)
248.1920 + self.AttUser.set_campo('userSex',\
248.1921 + string.strip(d['employeeType']))
248.1922 + self.AttUser.set_campo('userCF',\
248.1923 + string.strip(d['employeeNumber']))
248.1924 + self.AttUser.set_campo('userNatoil','')
248.1925 + self.AttUser.set_campo('userNatoa','')
248.1926 + self.AttUser.set_campo('userNatoPr','')
248.1927 + self.AttUser.set_campo('userNatoSt','')
248.1928 + self.AttUser.set_campo('userInd',\
248.1929 + string.strip(d['postalAddress']))
248.1930 + self.AttUser.set_campo('userCap',string.strip(d['postalCode']))
248.1931 +
248.1932 + rp = re.compile('^(.*)\((.*)\)')
248.1933 + cp = rp.match(d['postOfficeBox'])
248.1934 + if cp:
248.1935 + self.AttUser.set_campo('userCitta',\
248.1936 + string.strip(cp.group(1)))
248.1937 + self.AttUser.set_campo('userProv',string.strip(cp.group(2)))
248.1938 + else:
248.1939 + self.AttUser.set_campo('userCitta',string.strip(d['postOfficeBox']))
248.1940 + self.AttUser.set_campo('userProv','')
248.1941 +
248.1942 + self.AttUser.set_campo('userTel1',string.strip(d['homePhone']))
248.1943 + self.AttUser.set_campo('userTel2','')
248.1944 + self.AttUser.set_campo('userEmail','')
248.1945 + self.AttUser.set_campo('userPadreC','')
248.1946 + self.AttUser.set_campo('userPadreN','')
248.1947 + self.AttUser.set_campo('userMadreC','')
248.1948 + self.AttUser.set_campo('userMadreN','')
248.1949 + self.AttUser.changed = False
248.1950 + self.AttUser.novalid = False
248.1951 + self.AttUser.newPass = False
248.1952 + self.AttUser.newUser = False
248.1953 + self.AddRecord(True)
248.1954 + except:
248.1955 + if self.ldapLoadErr is None:
248.1956 + self.ldapLoadErr = u
248.1957 + else:
248.1958 + self.ldapLoadErr += ", "+u
248.1959 +
248.1960 + if uid == None:
248.1961 + pass
248.1962 + elif u == uid:
248.1963 + break
248.1964 +
248.1965 +
248.1966 + def is_new_user(self,uid):
248.1967 + """ verifica se l'utente esiste su ldap """
248.1968 + if not(self.LDAPCON):
248.1969 + sys.exit()
248.1970 + else:
248.1971 + if self.LDAPCON.isildap_isuser(uid):
248.1972 + self.user_exist = True
248.1973 + self.AttUser.newUser = False
248.1974 + self.AttUser.items[0] = blank
248.1975 + else:
248.1976 + self.user_exist = False
248.1977 + self.AttUser.newUser = True
248.1978 + self.AttUser.items[0] = \
248.1979 + urwid.AttrWrap(urwid.Text("Nuovo utente",'right'),'newuser')
248.1980 + if not self.gruppo is None:
248.1981 + mg = string.lower(self.AttUser.get_campo('userMGrp'))
248.1982 + if (mg =='alunni' or mg == 'esterni') and not \
248.1983 + mg == self.gruppo:
248.1984 + self.AttUser.set_campo('userClasse',self.gruppo)
248.1985 +
248.1986 + def updateLdap(self):
248.1987 + """ aggiorna ldap """
248.1988 + self.alert('ATTENDI: aggiornamento ldap in corso...')
248.1989 + self.LDAPCON.l.read_file(USERS_FILE) # non si passano opzioni
248.1990 +
248.1991 + def load_quota(self):
248.1992 + for u,d in self.usersImmessi.iteritems():
248.1993 + self.usersQuota[u] = self.get_quota(u)
248.1994 +
248.1995 + def get_quota(self,uid):
248.1996 + ret = ['','','']
248.1997 + # if necessario per evitare che la ricerca della quota
248.1998 + # di un utente non ancora aggiunto a ldap e quindi inesistente
248.1999 + # invalidi la cache nscd
248.2000 + if self.LDAPCON.isildap_isuser(uid):
248.2001 + CMD = 'quota ' + uid+' | grep -v File'
248.2002 + r, w, e = os.popen3(CMD)
248.2003 + x = w.readlines()
248.2004 + w.close()
248.2005 + e.close()
248.2006 + lx=len(x)
248.2007 + if lx>1:
248.2008 + if lx==2:
248.2009 + qr = string.split(x[lx-1])[1:4]
248.2010 + else:
248.2011 + qr = string.split(x[lx-1])[0:3]
248.2012 + ret = qr
248.2013 + return ret
248.2014 +
248.2015 +
248.2016 + def set_quota(self,uid,lim):
248.2017 + if int(lim[0])>0 and int(lim[1]) and not (
248.2018 + lim[0] == self.usersQuota[uid][1] and
248.2019 + lim[1] == self.usersQuota[uid][2]):
248.2020 + CMD = 'setquota ' + uid + ' ' + str(lim[0]) + ' ' +\
248.2021 + str(lim[1]) + ' 0 0 -a'
248.2022 + r, w, e = os.popen3(CMD)
248.2023 + x = w.readlines()
248.2024 + w.close()
248.2025 + e.close()
248.2026 + self.alert('setting...\n'+CMD)
248.2027 + time.sleep(2)
248.2028 + self.alert('')
248.2029 + q = self.get_quota(uid)
248.2030 + if not (q[1] == lim[0] and q[2] == lim[1]):
248.2031 + self.alert('IMPOSSIBILE ASSEGNARE LA QUOTA\n'+q[1]+'='+\
248.2032 + lim[0]+'|'+q[2]+'='+lim[1])
248.2033 + else:
248.2034 + self.usersQuota[uid] = q
248.2035 +
248.2036 +#########################################################
248.2037 +
248.2038 +
248.2039 +gruppo = None
248.2040 +if not len(sys.argv) == 2:
248.2041 + print "USO: isi-users <gruppo>"
248.2042 + sys.exit(1)
248.2043 +else:
248.2044 + gruppo = sys.argv[1]
248.2045 +
248.2046 +n=AddUser(gruppo).main()
248.2047 +print "---------------------------------------------------"
248.2048 +print "salvati "+str(n)+" records in %s Good bye!" % USERS_FILE
248.2049 +print "---------------------------------------------------"
248.2050 +sys.exit(0)
249.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249.2 +++ b/usr/sbin/isi-wlg Mon Apr 26 11:16:23 2010 +0200
249.3 @@ -0,0 +1,329 @@
249.4 +#!/usr/bin/python
249.5 +# -*- coding: utf-8 -*-
249.6 +
249.7 +# This program is free software; you can redistribute it and/or modify
249.8 +# it under the terms of the GNU General Public License as published by
249.9 +# the Free Software Foundation; either version 2, or (at your option)
249.10 +# any later version.
249.11 +
249.12 +# AUTHOR: Massimo Mancini
249.13 +
249.14 +"""
249.15 +ISI-WINDOWS_LOCAL_GROUP (WLG)
249.16 +isi-wlg -aggiunge o cancella un utente/gruppo di dominio a/da un gruppo locale
249.17 + WinXP (Administrators, Power Users o altro)
249.18 + -cambia la password dell'Administrator del client XP
249.19 +
249.20 + usage: %prog <options>
249.21 + -a, --add-user=add_user: utente/gruppo da aggiungere al gruppo locale XP nel formato DOMINIO\\NOME (due controbarre)
249.22 + -x, --canc-user=canc_user: utente/gruppo da eliminare dal gruppo locale XP
249.23 + -g, --local-group=local_group: agisce sul gruppo locale XP indicato
249.24 + -l, --labinfo=labinfo: nome dell'aula descritta in /etc/isi/labinfo.secret
249.25 + -P, --newlocalpwd: cambia la password all'Administrator locale XP
249.26 + -S, --host=host: workstation windows su cui agire (incompatibile con -l)
249.27 + -U, --hostadmin=hostadmin: account amministrativo sull'host nel formatp user%pwd
249.28 + -A, --admindom: richiede le credenziali di un amministratore di dominio
249.29 + -M, --maplab=maplab: <nome,range_ip> nel formato nmap; ricerca i client e compila il file di conf dell'aula [nome]
249.30 +
249.31 +NOTA1: esprimendo l'opzione -A le operazioni verranno svolte dall'amministratore
249.32 +di dominio, prescindendo quindi dalle credenziali dichiarate nel file di conf.
249.33 +"""
249.34 +
249.35 +import isi
249.36 +import sys, os, getpass
249.37 +import re
249.38 +from dry import optionparse
249.39 +from dry.functions import execute, ExecuteError
249.40 +
249.41 +####-----------------------------------------COSTANTI
249.42 +
249.43 +# file di conf dei laboratori
249.44 +INFOLABS="/etc/isi/labinfo.secret"
249.45 +BORDO="-"*70
249.46 +# parametri
249.47 +adc = None # amministratore di dominio%password
249.48 +acw = None # amministratore client%password
249.49 +pwd = None # nuova password amministrativa locale (XP)
249.50 +wlg = None # gruppo locale windows
249.51 +usr = None # utente o gruppo da aggiungere
249.52 +wks = None # workstation windows
249.53 +adc = None # credenziali amministratore di dominio
249.54 +aula = None # eventuale aula
249.55 +
249.56 +# net command
249.57 +# NETADD/DEL = net rpc group addmem|delmem wlg usr -S wks -U account_admin
249.58 +NETADD = "net rpc group addmem %s %s -S %s -U %s"
249.59 +NETDEL = "net rpc group delmem %s %s -S %s -U %s"
249.60 +
249.61 +# NETPWD = net rpc password Administrator NUOVA_PASSWORD -S wks -U account_admin
249.62 +NETPWD = "net rpc password %s %s -S %s -U %s"
249.63 +
249.64 +# NETMAP = nmap -O -sS range_ip
249.65 +NETMAP = "nmap -O -sS %s"
249.66 +
249.67 +
249.68 +####----------------------------------------- FUNCTIONS
249.69 +def crea_aula(nome, o):
249.70 + aula = "[%s]\n" % nome
249.71 + ll = [aula]
249.72 + print BORDO
249.73 + print aula
249.74 + for line in o.split('\n'):
249.75 + if line.startswith('Interesting'):
249.76 + print "###",line
249.77 + hh = line.split(' ')
249.78 + if len(hh)>4:
249.79 + host_name = hh[3]
249.80 + host_ip = hh[4].replace('(', '').replace(')', '')
249.81 + else:
249.82 + host_name = 'SENZA_NOME_CHECK_DNS'
249.83 + host_ip = hh[3].replace('(', '').replace(')', '')
249.84 +
249.85 + if line.startswith('Running'):
249.86 + host_os = line.split(':')[1].strip()
249.87 + if 'Windows XP' in host_os:
249.88 + ll.append(host_name+'\n')
249.89 + print "aggiunto: %s %s %s" % (host_ip, host_name, host_os)
249.90 + else:
249.91 + print "scartato: %s %s %s" % (host_ip, host_name, host_os)
249.92 + if len(ll)>1:
249.93 + print BORDO
249.94 + fl = open(INFOLABS, 'a')
249.95 + fl.writelines(ll)
249.96 + fl.close()
249.97 + else:
249.98 + alert('ATTENZIONE: aula %s non aggiunta a %s' % (nome, INFOLABS))
249.99 +
249.100 +def ask_for_new_local_password():
249.101 + print "NUOVE CREDENZIALI AMMINISTRATIVE SUL CLIENT:"
249.102 + while True:
249.103 + ret = getpass.getpass('Nuova password: ')
249.104 + re2 = getpass.getpass('Ripeti password: ')
249.105 + if ret == re2:
249.106 + break
249.107 + else:
249.108 + print "le password non coincidono!!!"
249.109 + return ret
249.110 +
249.111 +def ask_for_domain_admin():
249.112 + if opts.admindom:
249.113 + print "CREDENZIALI DI UN AMMINISTRATORE DI DOMINIO"
249.114 + ad_nome = raw_input("Login (administrator): ")
249.115 + ad_pass = getpass.getpass('Password: ')
249.116 + if not ad_nome:
249.117 + ret = 'administrator%'+ad_pass
249.118 + else:
249.119 + ret = ad_nome+'%'+ad_pass
249.120 + return ret
249.121 +
249.122 +def alert(msg):
249.123 + print "%s\n%s\n%s\n" % (BORDO, msg, BORDO)
249.124 +
249.125 +def setting_pwd(net_cmd, usr, pwd, wks, adc, aula ):
249.126 + """ setting delle password amministrative dei client"""
249.127 + #questa op.deve ridefinire la descrizione dell'aula
249.128 + #intestazione della sezione nel file di configurazione
249.129 + #se l'operazione ordinata e' su tutta l'aula
249.130 + wks_new = []
249.131 + if aula:
249.132 + if adc:
249.133 + wks_new.append([aula+usr+"%"+pwd])
249.134 + for w in wks:
249.135 + # se viene passato administrator%password di dominio
249.136 + if adc:
249.137 + adm = adc
249.138 + else:
249.139 + adm = "%s/%s" % (w[0], w[1])
249.140 +
249.141 + cmd = net_cmd % (usr, pwd, w[0], adm)
249.142 + print "elaboro %s su %s..." % (usr, w[0]),
249.143 + r, o, e = execute(cmd)
249.144 + if e:
249.145 + err = e.split(':')
249.146 + if len(err)>1:
249.147 + esito = err[1].strip(' ')
249.148 + else:
249.149 + esito = e
249.150 + else:
249.151 + esito = 'OK'
249.152 + if adc:
249.153 + wks_new.append([w[0], '', esito])
249.154 + else:
249.155 + wks_new.append([w[0], usr+'%'+pwd, esito])
249.156 + print esito
249.157 +
249.158 + # adesso deve rimettere a posto il file di configurazione
249.159 + # ci sono due casi: aula o singola macchina
249.160 + #FIXME
249.161 + fl = open(INFOLABS, 'r')
249.162 + ll = []
249.163 + aula_trovata = False
249.164 + #TODO: tenere conto che su qualche macchina il comando potrebbe non funzionare
249.165 + for line in fl:
249.166 + line = line.strip(' ')
249.167 + if aula and line.startswith(aula):
249.168 + aula_trovata = True
249.169 + for w in wks_new: ll.append(w[0]+'\n')
249.170 + else:
249.171 + if aula_trovata and line.startswith('['): # next aula
249.172 + aula_trovata = False
249.173 + if aula_trovata:
249.174 + # salta tutte le righe relative all'aula
249.175 + pass
249.176 + else:
249.177 + if not aula and line.startswith(wks[0][0]):
249.178 + line = "%s;%s\n" % (wks[0][0],usr+'%'+pwd)
249.179 + ll.append(line)
249.180 + fl.close()
249.181 + fl = open(INFOLABS, 'w')
249.182 + # il file di conf e' riscritto (ogni riga e' gia' terminata da \n)
249.183 + fl.writelines(ll)
249.184 + fl.close()
249.185 +
249.186 +
249.187 +def setting_wlg(net_cmd, wlg, usr, wks, adc ):
249.188 + """ modifica la composizione di un gruppo locale"""
249.189 + for w in wks:
249.190 + # se viene passato l'amministratore di dominio....
249.191 + if adc: adm = adc
249.192 + else: adm = "%s/%s" % (w[0], w[1])
249.193 + cmd = net_cmd % (wlg, usr, w[0], adm)
249.194 + print "elaboro %s su %s..." % (usr, w[0]),
249.195 + r, o, e = execute(cmd)
249.196 + if e:
249.197 + err = e.split(':')
249.198 + if len(err)>1: print err[1].strip(' ')
249.199 + else: print e
249.200 + else: print "OK!"
249.201 +
249.202 +def mapping_lab(maplab):
249.203 + if not os.path.isfile('usr/bin/nmap'):
249.204 + alert('ERRORE: nmap mancante (apt-get install nmap)')
249.205 + else:
249.206 + try:
249.207 + nome, range_ip = maplab.split(',')
249.208 + cmd = 'grep %s %s' % (nome, INFOLABS)
249.209 + r, o, e = execute(cmd)
249.210 + if not o: # se grep non trova nulla
249.211 + cmd = NETMAP % range_ip
249.212 + r, o, e = execute(cmd)
249.213 + if e:
249.214 + print "ERRORE %s" % e
249.215 + else:
249.216 + crea_aula(nome, o)
249.217 + else:
249.218 + alert('ERRORE: aula già definita, cambiare nome')
249.219 + except e:
249.220 + alert("ERRORE: errore di formato in %s %s" % (maplab, e))
249.221 +def read_aula_description(aula):
249.222 + wks = []
249.223 + admin_account = None
249.224 + is_aula = False
249.225 + fl = open(INFOLABS, 'r')
249.226 + for line in fl:
249.227 + line = line.strip('\n')
249.228 + line = line.strip(' ')
249.229 + if len(line)>0 and not line.startswith('#'):
249.230 + if is_aula and not line.startswith('['):
249.231 + ww = line.split(';')
249.232 + if len(ww)==1:
249.233 + if admin_account:
249.234 + ww.append(admin_account)
249.235 + else:
249.236 + ww.append('ACCOUNT_AMMINISTRATIVO_MANCANTE')
249.237 + wks.append(ww)
249.238 + if aula in line:
249.239 + is_aula = True
249.240 + aa = line.split(']')
249.241 + if len(aa)>1: admin_account = aa[1]
249.242 + elif "[" in line: is_aula = False
249.243 + fl.close()
249.244 + return wks
249.245 +
249.246 +####----------------------------------------- PROGRAM
249.247 +opts, args = optionparse.parse(__doc__)
249.248 +
249.249 +if opts.local_group: wlg = opts.local_group
249.250 +
249.251 +if opts.maplab:
249.252 + mapping_lab(opts.maplab)
249.253 + sys.exit()
249.254 +
249.255 +if opts.newlocalpwd:
249.256 + # questa richiesta e' prioritaria e alternativa alle altre
249.257 + net_cmd = NETPWD
249.258 + net_msg = 'Cambio la password amministrativa locale'
249.259 + usr = "Administrator"
249.260 +elif opts.add_user:
249.261 + net_cmd = NETADD
249.262 + net_msg = 'AGGIUNGO [%s] al gruppo locale [%s]'
249.263 + usr = opts.add_user
249.264 +elif opts.canc_user:
249.265 + net_cmd = NETDEL
249.266 + net_msg = 'ELIMINO [%s] dal gruppo locale [%s]'
249.267 + usr = opts.canc_user
249.268 +else:
249.269 + if not opts.newlocalpwd:
249.270 + alert("ERRORE: devi specificare -a UTENTE oppure -x UTENTE")
249.271 + else:
249.272 + alert("ERRORE: non hai richiesto nessuna operazione [-a|-x|-P]!!!")
249.273 + print __doc__
249.274 + sys.exit()
249.275 +
249.276 +if opts.host and opts.labinfo:
249.277 + alert("ERRORE: le opzioni -l e -S sono incompatibili")
249.278 + print __doc__
249.279 + sys.exit()
249.280 +
249.281 +if opts.host:
249.282 + if opts.hostadmin:
249.283 + wks = [[opts.host, opts.hostadmin]]
249.284 + elif opts.admindom:
249.285 + wks = [[opts.host, 'DOMAIN_ADMIN']]
249.286 +
249.287 +if opts.labinfo:
249.288 + if os.path.isfile(INFOLABS):
249.289 + aula = "[%s]" % opts.labinfo
249.290 + wks = read_aula_description(aula)
249.291 + if len(wks) == 0:
249.292 + alert("ERRORE: descrizione aula %s mancante in %s" % (aula, INFOLABS))
249.293 + sys.exit()
249.294 + else:
249.295 + alert("ERRORE: file di conf. dei laboratori mancante (%s)" % INFOLABS)
249.296 + sys.exit()
249.297 +
249.298 +err = []
249.299 +
249.300 +if not opts.newlocalpwd and wlg is None:
249.301 + err.append(" gruppo locale non dichiarato")
249.302 +if usr is None:
249.303 + err.append(" utente o gruppo da aggiungere mancante")
249.304 +if wks is None:
249.305 + err.append(" macchina bersaglio non dichiarata o credenziali mancanti")
249.306 +
249.307 +if len(err) == 0:
249.308 + print BORDO
249.309 + if opts.newlocalpwd: print "CAMBIO PASSWORD AMMINISTRATIVA"
249.310 + else: print (net_msg % (usr, wlg))
249.311 + if opts.labinfo: print "delle macchine dell'aula %s:" % opts.labinfo
249.312 + else: print 'delle macchine:'
249.313 + for w in wks:
249.314 + if "MANCANTE" in w[1]: print " %s %s" % (w[0], w[1])
249.315 + else: print " %s" % w[0]
249.316 + print BORDO
249.317 + ret=raw_input('Confermi (s/n)?')
249.318 + if ret and ret in 'sS':
249.319 + if opts.admindom: adc = ask_for_domain_admin()
249.320 + if opts.newlocalpwd:
249.321 + pwd = ask_for_new_local_password()
249.322 + setting_pwd(net_cmd, usr, pwd, wks, adc, aula)
249.323 + else:
249.324 + setting_wlg(net_cmd, wlg, usr, wks, adc)
249.325 + else:
249.326 + alert("operazione NON effettuata")
249.327 +else:
249.328 + print "Elaborazione impossibile.\nERRORI:"
249.329 + for e in err: print e
249.330 +
249.331 +print BORDO
249.332 +
250.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250.2 +++ b/usr/sbin/rmlogonvar Mon Apr 26 11:16:23 2010 +0200
250.3 @@ -0,0 +1,10 @@
250.4 +#!/bin/bash
250.5 +
250.6 +# +-------------------------------------------------+
250.7 +# � 2002-2005 ReteIsi / www.reteisi.org
250.8 +# +-------------------------------------------------+
250.9 +# $Id: rmlogonvar 43 2021-10-30 07:35:24Z max $
250.10 +
250.11 +
250.12 +VARDIR="/home/samba/netlogon"
250.13 +rm $VARDIR/logonvar_$1
251.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
251.2 +++ b/usr/sbin/setlogonvar Mon Apr 26 11:16:23 2010 +0200
251.3 @@ -0,0 +1,48 @@
251.4 +#!/bin/bash
251.5 +
251.6 +# +-------------------------------------------------+
251.7 +# © 2002-2008 ReteIsi / www.reteisi.org
251.8 +# +-------------------------------------------------+
251.9 +# This program is free software; you can redistribute it and/or modify
251.10 +# it under the terms of the GNU General Public License as published by
251.11 +# the Free Software Foundation; either version 2, or (at your option)
251.12 +# any later version.
251.13 +
251.14 +# AUTHOR: Massimo Mancini
251.15 +
251.16 +# E' possibile aggiungere l'utente che si logga
251.17 +# o la sua classe ad un gruppo locale windows (WLG)
251.18 +# il WLG di destinazione e' gestito dal file di conf
251.19 +# /etc/isi/wlg.secret
251.20 +
251.21 +USR=$1
251.22 +GRP=$2
251.23 +CLI=$3
251.24 +
251.25 +VARDIR="/home/samba/netlogon"
251.26 +WWWDIR="/var/www/sambalogon"
251.27 +VARFILE=$VARDIR/logonvar_$CLI
251.28 +
251.29 +if [ -f $VARFILE ] ; then
251.30 + if ! egrep -q "^$1," $VARFILE ; then
251.31 + rm $VARFILE
251.32 + fi
251.33 +fi
251.34 +
251.35 +if [ ! -f $VARFILE ] ; then
251.36 + classe=$(isi-getattr $USR departmentNumber)
251.37 +
251.38 + # WindowsLocalGroups
251.39 + WLG=$(setlogonwlg $USR $CLI $classe)
251.40 +
251.41 + quotasup=$(quota $USR | grep \*)
251.42 + DT=$(date +%y%m%d)
251.43 + D1=$(date +%y-%m-%d)
251.44 + TM=$(date +%H:%M)
251.45 + [ -z $quotasup ] && quotasup="INQUOTA" || quotasup="FUORIQUOTA"
251.46 +
251.47 + CHI="$USR,$GRP,$classe,$quotasup"
251.48 + CHI_QUANDO="$D1;$TM;$1;$GRP;$classe;$quotasup;$CLI;$WLG"
251.49 + echo $CHI > $VARFILE
251.50 + echo $CHI_QUANDO >> $WWWDIR/logon-$DT
251.51 +fi
252.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
252.2 +++ b/usr/sbin/setlogonwlg Mon Apr 26 11:16:23 2010 +0200
252.3 @@ -0,0 +1,73 @@
252.4 +#!/bin/bash
252.5 +
252.6 +# This program is free software; you can redistribute it and/or modify
252.7 +# it under the terms of the GNU General Public License as published by
252.8 +# the Free Software Foundation; either version 2, or (at your option)
252.9 +# any later version.
252.10 +
252.11 +# AUTHORS: Massimo Mancini
252.12 +#
252.13 +# SCOPO:aggiungere|eliminare un utente o un gruppo a|da un gruppo locale
252.14 +# sul client windows da cui si sta effettuando il logon
252.15 +
252.16 +
252.17 +function get_var (){
252.18 + STATO=$(echo $1 | awk -F":" '{print $1}')
252.19 + WLG=$(echo $1 | awk -F":" '{print $3}')
252.20 + WKS=$(echo $1 | awk -F":" '{print $4}')
252.21 + PWD=$(echo $1 | awk -F":" '{print $5}')
252.22 +}
252.23 +
252.24 +function wlg_op_on () {
252.25 + local USR
252.26 + [ -z $1 ] && return
252.27 + USR=$1
252.28 + OPR=""
252.29 + STATO=''
252.30 + WLG=''
252.31 + WKS=''
252.32 + PWD=''
252.33 + DENY=$(egrep -i "^DENY.*:$USR:" $SECRET)
252.34 + if [ -z $DENY ] ; then
252.35 + ALLOW=$(egrep -i "^ALLOW.*:$USR:" $SECRET)
252.36 + if [ ! -z $ALLOW ]; then
252.37 + OPR='addmem'
252.38 + get_var $ALLOW
252.39 + fi
252.40 + else
252.41 + OPR='delmem'
252.42 + get_var $DENY
252.43 + fi
252.44 +
252.45 + if [ -z $USR ] || [ -z $CLI ] || [ -z $OPR ] || [ -z $WLG ] || [ -z $WKS ] || [ -z $PWD ] ; then
252.46 + ret=""
252.47 + else
252.48 + # check sulla macchina dell'utente
252.49 + if ! echo $CLI | egrep -q $WKS; then
252.50 + ret="no_on_this_host"
252.51 + else
252.52 + ERR=$(net rpc group $OPR $WLG $USR -U "$CLI/$PWD" -S $CLI 2>&1)
252.53 + [ "$?" = "0" ] && ret="$OPR:$WLG:$USR" || ret="$ERR"
252.54 + fi
252.55 + fi
252.56 + echo $ret
252.57 +}
252.58 +
252.59 +###### ------------program--------------------
252.60 +
252.61 +USR=$1 # utente
252.62 +CLI=$2 # client windows (nomehost)
252.63 +GRP=$3 # gruppo di dominio (tipicamente una classe) - può non esserci
252.64 +
252.65 +# file di configurazione
252.66 +SECRET="/etc/isi/wlg.secret"
252.67 +if [ -f $SECRET ] ; then
252.68 + ret=""
252.69 + ret_u=$(wlg_op_on $USR)
252.70 + ret_g=$(wlg_op_on $GRP)
252.71 + ret="$ret_u $ret_g"
252.72 +else
252.73 + ret="no_/etc/wlg.secret"
252.74 +fi
252.75 +echo $ret
252.76 +
253.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
253.2 +++ b/usr/share/WinActivePerl/lib/ISI/Logon.pm Mon Apr 26 11:16:23 2010 +0200
253.3 @@ -0,0 +1,1461 @@
253.4 +# +-------------------------------------------------+
253.5 +# � 2002-2005 ReteIsi / www.reteisi.org
253.6 +# +-------------------------------------------------+
253.7 +# $Id: Logon.pm 250 2021-09-24 16:00:13Z max $
253.8 +
253.9 +### DEFINIZIONE PACKAGE
253.10 +# Copyright: Sandro Dentella - Massimo Mancini, Marco Vaninetti Aug 2004-2005
253.11 +# This program is free software; you can redistribute it and/or modify
253.12 +# it under the terms of the GNU General Public License as published by
253.13 +# the Free Software Foundation; either version 2, or (at your option)
253.14 +# any later version.
253.15 +
253.16 +package ISI::Logon;
253.17 +
253.18 +BEGIN {
253.19 + use Exporter ();
253.20 + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
253.21 +
253.22 + # set the version for version checking
253.23 + # if using RCS/CVS, this may be preferred
253.24 + $VERSION = sprintf "%d.%03d", q$Revision: 250 $ =~ /(\d+)/g;
253.25 +
253.26 + @ISA = qw(Exporter Autoload Win32::TieRegistry);
253.27 + @EXPORT = qw(&version &ReadConf &OsName &WinPol9x &opgruppo
253.28 + &IsWin9x &GetInfoLogon &WinMsgBox &WinSet &DbgClose);
253.29 +}
253.30 +
253.31 +### INIZIO CODICE
253.32 +
253.33 +use WIN32;
253.34 +use Win32::TieRegistry; $Registry->Delimiter("/");
253.35 +
253.36 +#use strict;
253.37 +$DBG = 0 ; # attiva modo DEBUG
253.38 +
253.39 +$OUTPUT="";
253.40 +@CMD=();
253.41 +
253.42 +@DscType=qw(REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY REG_DWORD);
253.43 +%ValType=(REG_NONE => 0,
253.44 + REG_SZ => 1,
253.45 + REG_EXPAND_SZ => 2,
253.46 + REG_BINARY => 3,
253.47 + REG_DWORD => 4);
253.48 +
253.49 +
253.50 +### CHIAVI DI REGISTRO
253.51 +# Formato descrizione array chiavi di registro:
253.52 +
253.53 +# @nome = ( keyroot;,
253.54 +# ValueName=ValueType:default);
253.55 +
253.56 +# l'idea e` che per produrre un certo settaggio di registro
253.57 +# ci si limita alla conf della chiave senza ulteriori interventi sul codice
253.58 +# Tenere presente che per attivare certe funzioni occorre definire
253.59 +# delle chiavi con certi valori ma per disabilitarle occorre cancellare
253.60 +# la chiave che contiene quelle variabili (DELKEY) o cancellare solo
253.61 +# le variabili (values) contenuti nella chiave (DELVAL);
253.62 +# in altri casi l'on/off della funzionalita` di ottiene settando a 0 o a 1 la
253.63 +# variabile corrispondente
253.64 +
253.65 +
253.66 +
253.67 +### nome netbios del client
253.68 +#$K_CLIENTNAME = "LMachine/System/CurrentControlSet/Services/VxD/VNETSUP/";
253.69 +
253.70 +
253.71 +### WinSet IE - start page
253.72 +@K_IEMAIN = ("CUser/Software/Microsoft/Internet Explorer/Main/",
253.73 + "Start__Page=REG_SZ:");
253.74 +
253.75 +### WinSet - proxy
253.76 +@K_INTNETSET = ("CUser/Software/Microsoft/Windows/CurrentVersion/Internet Settings/",
253.77 + "ProxyEnable=REG_DWORD:0x00000001",
253.78 + "EnableAutodial=REG_DWORD:0x00000000",
253.79 + "EnableHttp1_1=REG_DWORD:0x00000001",
253.80 + "ProxyHttp1.1=REG_DWORD:0x00000001",
253.81 + "ProxyOverride=REG_SZ:<local>",
253.82 + "ProxyServer=REG_SZ:");
253.83 +
253.84 +### WinSet - profile
253.85 +@K_NOPROFILE = ("CUser/Software/Microsoft/Windows NT/CurrentVersion/Winlogon/",
253.86 + "ExcludeProfileDirs=REG_SZ:''");
253.87 +
253.88 +### WinSet - no_local_profile (Disable Local Caching of Domain User Profiles)
253.89 +@K_NOLOCALPROFILE1 = ("LMachine/Software/Microsoft/Windows NT/CurrentVersion/Winlogon/",
253.90 + "DeleteRoamingCache=REG_DWORD:0x00000001");
253.91 +
253.92 +@K_NOLOCALPROFILE2 = ("LMachine/Software/Policies/Microsoft/Windows/",
253.93 + "DeleteRoamingCache=REG_DWORD:0x00000001");
253.94 +
253.95 +### WinSet - document_folder (_CDOC viene decodificato in C:\Documenti)
253.96 +@K_DOCFOLDER1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.97 + "Personal=REG_SZ:_CDOC",
253.98 + "My__Picture=REG_SZ:_CDOC\Immagini",
253.99 + "My__Music=REG_SZ:_CDOC\Musica",
253.100 + "My__Video=REG_SZ:_CDOC\Video");
253.101 +
253.102 +@K_DOCFOLDER2 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders/",
253.103 + "Personal=REG_SZ:_CDOC",
253.104 + "My__Picture=REG_SZ:_CDOC\Immagini",
253.105 + "My__Music=REG_SZ:_CDOC\Musica",
253.106 + "My__Video=REG_SZ:_CDOC\Video");
253.107 +
253.108 +
253.109 +# WinSet - last-user (winXP)
253.110 +@K_LASTUSR_ON = ("LMachine/Software/Microsoft/Windows/CurrentVersion/policies/system/",
253.111 + "dontdisplaylastusername=REG_DWORD:0x00000000");
253.112 +
253.113 +@K_LASTUSR_OFF= ("LMachine/Software/Microsoft/Windows/CurrentVersion/policies/system/",
253.114 + "dontdisplaylastusername=REG_DWORD:0x00000001");
253.115 +
253.116 +### WinPol - last-user (win9X, al momento funziona solo se � installato Tweakui)
253.117 +@K_LASTUSER_OFF = ("LMachine/Software/Microsoft/Windows/CurrentVersion/Winlogon/",
253.118 + "DontDisplayLastUserName=REG_SZ:1");
253.119 +@K_LASTUSER_ON = ("LMachine/Software/Microsoft/Windows/CurrentVersion/Winlogon/",
253.120 + "DontDisplayLastUserName=REG_SZ:0");
253.121 +
253.122 +### WinSet - sync
253.123 +@K_SYNC_ON = ("CUser/Software/Microsoft/Windows/CurrentVersion/NetCache/",
253.124 + "SyncAtLogoff=REG_DWORD:0x00000001",
253.125 + "SyncAtLogon=REG_DWORD:0x00000001");
253.126 +@K_SYNC_OFF = ("CUser/Software/Microsoft/Windows/CurrentVersion/NetCache/",
253.127 + "SyncAtLogoff=REG_DWORD:0x00000000",
253.128 + "SyncAtLogon=REG_DWORD:0x00000000");
253.129 +
253.130 +### winset sezione 'iepasswordcache'
253.131 +
253.132 +@K_IEPASSWORDCACHING_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Internet Settings/",
253.133 + "DisablePasswordCaching=REG_DWORD:0x00000001");
253.134 +
253.135 +@K_IEPASSWORDCACHING_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Internet Settings/",
253.136 + "DisablePasswordCaching=REG_DWORD:0x00000001");
253.137 +
253.138 +
253.139 +### winset sezione 'autorun'
253.140 +
253.141 +@K_AUTORUN_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.142 + "NoDriveTypeAutoRun=REG_DWORD:0x91");
253.143 +
253.144 +# policies win98 sezione 'clearpol' - elimina gruppodll e altre restrizioni (non settabile)
253.145 +@K_CLEAR_D1 = ("LMachine/Network/Logon/",
253.146 + "PolicyHandler=REG_SZ:''");
253.147 +
253.148 +@K_CLEAR_D2 = ("LMachine/System/CurrentControlSet/Services/MSNP32/NetworkProvider/",
253.149 + "GroupFcn=REG_SZ:''");
253.150 +
253.151 +@K_CLEAR_D3 = ("LMachine/System/CurrentControlSet/Services/NWNP32/");
253.152 +
253.153 +@K_CLEAR_A1 = ("LMachine/Software/Microsoft/Windows/CurrentVersion/Setup/OptionalComponents/GroupPol/",
253.154 + "INF=REG_SZ:grouppol.inf",
253.155 + "Installed=REG_SZ:0",
253.156 + "Section=REG_SZ:Group_Pol");
253.157 +
253.158 +# policies win98 sezione 'pwdcaching' - elimina la cache delle password (non settabile)
253.159 +@K_PWDCACHING = ("LMachine/Software/Microsoft/Windows/CurrentVersion/Policies/Network/",
253.160 + "DisablePwdCaching=REG_DWORD:1");
253.161 +
253.162 +
253.163 +# policies win98 sezione 'shell_run'
253.164 +@K_NOCPAN1_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/RestrictRun/");
253.165 +@K_NOCPAN1_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/RestrictRun/");
253.166 +
253.167 +# policies win98 sezione 'nosetfolder'
253.168 +@K_NOCPAN2_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.169 + "NoSetFolders=REG_DWORD:0x00000001");
253.170 +@K_NOCPAN2_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.171 + "NoSetFolders=REG_DWORD:0x00000001");
253.172 +
253.173 +### policies win98 sezione 'nodrive'
253.174 +@K_NODRIVE_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.175 + "NoDrives=REG_DWORD:67108863");
253.176 +@K_NODRIVE_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.177 + "NoDrives=REG_DWORD:67108863");
253.178 +
253.179 +### policies win98 sezione 'nodrivec'
253.180 +@K_NODRIVEC_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.181 + "NoDrives=REG_BINARY:04,00,0,00");
253.182 +@K_NODRIVEC_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.183 + "NoDrives=REG_BINARY:04,00,0,00");
253.184 +
253.185 +### policies win98 sezione 'nofind'
253.186 +@K_NOFIND_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.187 + "NoFind=REG_DWORD:0x00000001");
253.188 +@K_NOFIND_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.189 + "NoFind=REG_DWORD:0x00000001");
253.190 +
253.191 +### policies win98 sezione 'nohistory'
253.192 +@K_NOHISTORY1_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.193 + "ClearRecentDocsOnExit=REG_BINARY:01,00,00,00");
253.194 +@K_NOHISTORY1_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.195 + "ClearRecentDocsOnExit=REG_BINARY:01,00,00,00");
253.196 +@K_NOHISTORY2_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.197 + "NoRecentDocsHistory=REG_BINARY:01,00,00,00");
253.198 +@K_NOHISTORY2_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.199 + "NoRecentDocsHistory=REG_BINARY:01,00,00,00");
253.200 +
253.201 +### policies win98 sezione 'noactivedesktop'
253.202 +@K_NOACTIVED_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.203 + "NoActiveDesktop=REG_BINARY:01,00,00,00",
253.204 + "NoActiveDesktopChanges=REG_BINARY:01,00,00,00",
253.205 + "NoSetActiveDesktop=REG_BINARY:01,00,00,00");
253.206 +@K_NOACTIVED_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.207 + "NoActiveDesktop=REG_BINARY:01,00,00,00",
253.208 + "NoActiveDesktopChanges=REG_BINARY:01,00,00,00",
253.209 + "NoSetActiveDesktop=REG_BINARY:01,00,00,00");
253.210 +
253.211 +# policies win98 sezione 'access'
253.212 +@K_NETLOGON1 = ("LMachine/Network/Logon/",
253.213 + "UserProfiles=REG_DWORD:1",
253.214 + "UseHomeDirectory=REG_DWORD:1",
253.215 + "MustBeValidated=REG_DWORD:1");
253.216 +
253.217 +@K_NETLOGON2 = ("LMachine/Software/Microsoft/Windows/CurrentVersion/Winlogon/",
253.218 + "LegalNoticeCaption=REG_SZ:Avvertenza",
253.219 + "LegalNoticeText=REG_SZ:Accesso riservato agli utenti autorizzati.");
253.220 +
253.221 +
253.222 +### policies win98 sezione 'net' - ON setting, OFF DELKEY
253.223 +@K_NONET_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Network/",
253.224 + "NoNetSetup=REG_DWORD:0x00000001",
253.225 + "NoNetSetupIDPage=REG_DWORD:0x00000001",
253.226 + "NoNetSetupSecurityPage=REG_DWORD:0x00000001");
253.227 +
253.228 +@K_NONET_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Network/",
253.229 + "NoNetSetup=REG_DWORD:0x00000001",
253.230 + "NoNetSetupIDPage=REG_DWORD:0x00000001",
253.231 + "NoNetSetupSecurityPage=REG_DWORD:0x00000001");
253.232 +
253.233 +### policies win98 sezione 'screen' - ON setting, OFF DELVAL
253.234 +@K_SCREEN_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.235 + "NoDispAppearancePage=REG_DWORD:0x00000000",
253.236 + "NoDispBackgroundPage=REG_DWORD:0x00000000",
253.237 + "NoDispCPL=REG_DWORD:0x00000000",
253.238 + "NoDispScrSavPage=REG_DWORD:0x00000000",
253.239 + "NoDispSettingsPage=REG_DWORD:0x00000001");
253.240 +
253.241 +@K_SCREEN_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.242 + "NoDispAppearancePage=REG_DWORD:0x00000000",
253.243 + "NoDispBackgroundPage=REG_DWORD:0x00000000",
253.244 + "NoDispCPL=REG_DWORD:0x00000000",
253.245 + "NoDispScrSavPage=REG_DWORD:0x00000000",
253.246 + "NoDispSettingsPage=REG_DWORD:0x00000001");
253.247 +
253.248 +### policies win98 sezione 'printer' - ON setting, OFF DELVAL
253.249 +@K_NOSTP_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.250 + "NoAddPrinter=REG_DWORD:0x00000001",
253.251 + "NoDeletePrinter=REG_DWORD:0x00000001",
253.252 + "NoPrinterTabs=REG_DWORD:0x00000001");
253.253 +
253.254 +@K_NOSTP_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.255 + "NoAddPrinter=REG_DWORD:0x00000001",
253.256 + "NoDeletePrinter=REG_DWORD:0x:00000001",
253.257 + "NoPrinterTabs=REG_DWORD:0x00000001");
253.258 +
253.259 +### policies win98 sezione 'passwd' - ON setting, OFF DELVAL
253.260 +@K_CHPWD_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.261 + "NoAdminPage=REG_DWORD:0x00000001",
253.262 + "NoProfilePage=REG_DWORD:0x00000001");
253.263 +
253.264 +@K_CHPWD_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.265 + "NoAdminPage=REG_DVWORD:0x00000001",
253.266 + "NoProfilePage=REG_DWORD:0x00000001");
253.267 +
253.268 +### policies win98 sezione 'system' - ON setting, OFF DELVAL
253.269 +@K_SYS_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.270 + "NoConfigPage=REG_DWORD:0x00000001",
253.271 + "NoDevMgrPage=REG_DWORD:0x00000001",
253.272 + "NoFileSysPage=REG_DWORD:0x00000001",
253.273 + "NoVirtMemPage=REG_DWORD:0x00000001");
253.274 +
253.275 +@K_SYS_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.276 + "NoConfigPage=REG_DWORD:0x00000001",
253.277 + "NoDevMgrPage=REG_DWORD:0x00000001",
253.278 + "NoFileSysPage=REG_DWORD:0x00000001",
253.279 + "NoVirtMemPage=REG_DWORD:0x00000001");
253.280 +
253.281 +### policies win98 sezione 'shell-esegui' - ON setting, OFF DELVAL
253.282 +@K_SHRUN_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.283 + "NoRun=REG_DWORD:0x00000001");
253.284 +
253.285 +@K_SHRUN_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.286 + "NoRun=REG_DWORD:0x00000001");
253.287 +
253.288 +### policies win98 sezione 'shell-noregtools' - ON setting, OFF DELVAL
253.289 +
253.290 +@K_SHRTOOLS_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.291 + "DisableRegistryTools=REG_DWORD:0x00000001");
253.292 +
253.293 +@K_SHRTOOLS_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/System/",
253.294 + "DisableRegistryTools=REG_DWORD:0x00000001");
253.295 +
253.296 +### policies win98 sezione 'shell-winoldapp' - ON setting, OFF DELVAL
253.297 +
253.298 +@K_SHOLDAPP_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/WinOldApp/",
253.299 + "Disabled=REG_DWORD:0x00000001",
253.300 + "NoRealMode=REG_DWORD:0x00000001");
253.301 +
253.302 +@K_SHOLDAPP_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/WinOldApp/",
253.303 + "Disabled=REG_DWORD:0x00000001",
253.304 + "NoRealMode=REG_DWORD:0x00000001");
253.305 +
253.306 +### policies win98 sezione 'nosavesettings' - ON setting, OFF DELVAL
253.307 +
253.308 +@K_NOSAVESETTINGS_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.309 + "NoSaveSettings=REG_BINARY:01,00,00,00");
253.310 +
253.311 +@K_NOSAVESETTINGS_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/",
253.312 + "NoSaveSettings=REG_BINARY:01,00,00,00");
253.313 +
253.314 +### policies win98 sezione 'iecachedays'
253.315 +
253.316 +@K_IECACHEDAYS_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/Internet Settings/Url History",
253.317 + "DaysToKeep=REG_DWORD:0x00000000");
253.318 +
253.319 +@K_IECACHEDAYS_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/Internet Settings/Url History/",
253.320 + "DaysToKeep=REG_DWORD:0x00000000");
253.321 +
253.322 +
253.323 +
253.324 +### policies win98 sezione 'profiledirs' - vengono settati tutti i percorsi di default
253.325 +@K_ALLPROFILEDIRS = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.326 + "AppData=REG_SZ:_DUPROF\\Application Data",
253.327 + "Cache=REG_SZ:_DUPROF\\Temporary Internet Files",
253.328 + "Cookies=REG_SZ:_DUPROF\\Cookies",
253.329 + "Desktop=REG_SZ:_DUPROF\\Desktop",
253.330 + "Favorites=REG_SZ:_DUPROF\\Preferiti",
253.331 + "History=REG_SZ:_DUPROF\\Cronologia",
253.332 + "NetHood=REG_SZ:_DUPROF\\Risorse di rete",
253.333 + "Programs=REG_SZ:_DUPROF\\Menu Avvio\\Programmi",
253.334 + "Recent=REG_SZ:_DUPROF\\Recent",
253.335 + "Start Menu=REG_SZ:_DUPROF\\Menu Avvio",
253.336 + "Startup=REG_SZ:_DUPROF\\Menu Avvio\\Programmi\\Esecuzione automatica");
253.337 +
253.338 +### policies win98 sezione 'updateprofiledirs' - vengono impostate le cartelle in roaming
253.339 +
253.340 +@F_APPDATA_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/AppData/",
253.341 + "CentralFile=REG_SZ:Application Data",
253.342 + "LocalFile=REG_SZ:Application Data","Name=REG_SZ:\*.\*",
253.343 + "DefaultDir=REG_SZ:\*windir\\Application Data",
253.344 + "MustBeRelative=REG_DWORD:1",
253.345 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.346 + "RegValue=REG_SZ:AppData");
253.347 +
253.348 +@F_APPDATA_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/AppData/",
253.349 + "CentralFile=REG_SZ:Application Data",
253.350 + "LocalFile=REG_SZ:Application Data",
253.351 + "Name=REG_SZ:\*.\*",
253.352 + "DefaultDir=REG_SZ:\*windir\\Application Data",
253.353 + "MustBeRelative=REG_DWORD:1",
253.354 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.355 + "RegValue=REG_SZ:AppData");
253.356 +
253.357 +@F_APPDATA1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.358 + "AppData=REG_SZ:_CUPROF\\Application Data");
253.359 +
253.360 +@F_CACHE_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Cache/",
253.361 + "CentralFile=REG_SZ:Temporary Internet Files",
253.362 + "LocalFile=REG_SZ:Temporary Internet Files",
253.363 + "Name=REG_SZ:",
253.364 + "MustBeRelative=REG_DWORD:1",
253.365 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.366 + "RegValue=REG_SZ:Cache");
253.367 +
253.368 +@F_CACHE_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Cache/",
253.369 + "CentralFile=REG_SZ:Temporary Internet Files",
253.370 + "LocalFile=REG_SZ:Temporary Internet Files",
253.371 + "Name=REG_SZ:",
253.372 + "MustBeRelative=REG_DWORD:1",
253.373 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.374 + "RegValue=REG_SZ:Cache");
253.375 +
253.376 +@F_CACHE1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.377 + "Cache=REG_SZ:_CUPROF\\Temporary Internet Files");
253.378 +
253.379 +@F_COOKIES_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Cookies/",
253.380 + "CentralFile=REG_SZ:Cookies",
253.381 + "DefaultDir=REG_SZ:\*windir\\Cookies",
253.382 + "LocalFile=REG_SZ:Cookies",
253.383 + "Name=REG_SZ:\*.\*",
253.384 + "MustBeRelative=REG_DWORD:1",
253.385 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.386 + "RegValue=REG_SZ:Cookies");
253.387 +
253.388 +@F_COOKIES_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Cookies/",
253.389 + "CentralFile=REG_SZ:Cookies",
253.390 + "DefaultDir=REG_SZ:\*windir\\Cookies",
253.391 + "LocalFile=REG_SZ:Cookies",
253.392 + "Name=REG_SZ:\*.\*",
253.393 + "MustBeRelative=REG_DWORD:1",
253.394 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.395 + "RegValue=REG_SZ:Cookies");
253.396 +
253.397 +@F_COOKIES1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.398 + "Cookies=REG_SZ:_CUPROF\\Cookies");
253.399 +
253.400 +@F_DESKTOP_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Desktop/",
253.401 + "CentralFile=REG_SZ:Desktop",
253.402 + "LocalFile=REG_SZ:Desktop",
253.403 + "Name=REG_SZ:\*.\*",
253.404 + "MustBeRelative=REG_DWORD:1",
253.405 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.406 + "RegValue=REG_SZ:Desktop");
253.407 +
253.408 +@F_DESKTOP_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Desktop/",
253.409 + "CentralFile=REG_SZ:Desktop",
253.410 + "LocalFile=REG_SZ:Desktop",
253.411 + "Name=REG_SZ:\*.\*",
253.412 + "MustBeRelative=REG_DWORD:1",
253.413 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.414 + "RegValue=REG_SZ:Desktop");
253.415 +
253.416 +@F_DESKTOP1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.417 + "Desktop=REG_SZ:_CUPROF\\Desktop");
253.418 +
253.419 +@F_FAVORITES_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Favorites/",
253.420 + "CentralFile=REG_SZ:Preferiti",
253.421 + "LocalFile=REG_SZ:Preferiti",
253.422 + "Name=REG_SZ:\*.\*",
253.423 + "MustBeRelative=REG_DWORD:1",
253.424 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.425 + "RegValue=REG_SZ:Favorites");
253.426 +
253.427 +@F_FAVORITES_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Favorites/",
253.428 + "CentralFile=REG_SZ:Preferiti",
253.429 + "LocalFile=REG_SZ:Preferiti",
253.430 + "Name=REG_SZ:\*.\*",
253.431 + "MustBeRelative=REG_DWORD:1",
253.432 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.433 + "RegValue=REG_SZ:Favorites");
253.434 +
253.435 +@F_FAVORITES1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.436 + "Favorites=REG_SZ:_CUPROF\\Favorites");
253.437 +
253.438 +@F_HISTORY_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/History/",
253.439 + "CentralFile=REG_SZ:Cronologia",
253.440 + "LocalFile=REG_SZ:Cronologia",
253.441 + "Name=REG_SZ:\*.\*",
253.442 + "DefaultDir=REG_SZ:\*windir\\Cronologia",
253.443 + "MustBeRelative=REG_DWORD:1",
253.444 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.445 + "RegValue=REG_SZ:History");
253.446 +
253.447 +@F_HISTORY_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/History/",
253.448 + "CentralFile=REG_SZ:Cronologia",
253.449 + "LocalFile=REG_SZ:Cronologia",
253.450 + "Name=REG_SZ:\*.\*",
253.451 + "DefaultDir=REG_SZ:\*windir\\Cronologia",
253.452 + "MustBeRelative=REG_DWORD:1",
253.453 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.454 + "RegValue=REG_SZ:History");
253.455 +
253.456 +@F_HISTORY1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.457 + "History=REG_SZ:_CUPROF\\Cronologia");
253.458 +
253.459 +@F_NETHOOD_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/NetHood/",
253.460 + "CentralFile=REG_SZ:Risorse di Rete",
253.461 + "LocalFile=REG_SZ:Risorse di Rete",
253.462 + "Name=REG_SZ:\*.\*",
253.463 + "MustBeRelative=REG_DWORD:1",
253.464 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.465 + "RegValue=REG_SZ:NetHood");
253.466 +
253.467 +@F_NETHOOD_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/NetHood/",
253.468 + "CentralFile=REG_SZ:Risorse di Rete",
253.469 + "LocalFile=REG_SZ:Risorse di Rete",
253.470 + "Name=REG_SZ:\*.\*",
253.471 + "MustBeRelative=REG_DWORD:1",
253.472 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.473 + "RegValue=REG_SZ:NetHood");
253.474 +
253.475 +@F_NETHOOD1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.476 + "NetHood=REG_SZ:_CUPROF\\NetHood");
253.477 +
253.478 +@F_RECENT_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Recent/",
253.479 + "CentralFile=REG_SZ:Recent",
253.480 + "LocalFile=REG_SZ:Recent",
253.481 + "Name=REG_SZ:\*.\*",
253.482 + "MustBeRelative=REG_DWORD:1",
253.483 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.484 + "RegValue=REG_SZ:Recent");
253.485 +
253.486 +@F_RECENT_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Recent/",
253.487 + "CentralFile=REG_SZ:Recent",
253.488 + "LocalFile=REG_SZ:Recent",
253.489 + "Name=REG_SZ:\*.\*",
253.490 + "MustBeRelative=REG_DWORD:1",
253.491 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.492 + "RegValue=REG_SZ:Recent");
253.493 +
253.494 +@F_RECENT1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.495 + "Recent=REG_SZ:_CUPROF\\Recent");
253.496 +
253.497 +@F_START_MENU_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Start Menu/",
253.498 + "CentralFile=REG_SZ:Menu Avvio",
253.499 + "LocalFile=REG_SZ:Menu Avvio",
253.500 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.501 + "MustBeRelative=REG_DWORD:1",
253.502 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.503 + "RegValue=REG_SZ:Start Menu");
253.504 +
253.505 +@F_START_MENU_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Start Menu/",
253.506 + "CentralFile=REG_SZ:Menu Avvio",
253.507 + "LocalFile=REG_SZ:Menu Avvio",
253.508 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.509 + "MustBeRelative=REG_DWORD:1",
253.510 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.511 + "RegValue=REG_SZ:Start Menu");
253.512 +
253.513 +@F_START_MENU1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.514 + "Start Menu=REG_SZ:_CUPROF\\Menu Avvio");
253.515 +
253.516 +@F_PROGRAMS_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/SecondaryProfileReconciliation/Programs/",
253.517 + "CentralFile=REG_SZ:Programmi",
253.518 + "LocalFile=REG_SZ:Menu Avvio\\Programmi",
253.519 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.520 + "MustBeRelative=REG_DWORD:1",
253.521 + "ParentKey=REG_SZ:Start Menu",
253.522 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.523 + "RegValue=REG_SZ:Programs");
253.524 +
253.525 +@F_PROGRAMS_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Programs/",
253.526 + "CentralFile=REG_SZ:Programmi",
253.527 + "LocalFile=REG_SZ:Menu Avvio\\Programmi",
253.528 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.529 + "MustBeRelative=REG_DWORD:1",
253.530 + "ParentKey=REG_SZ:Start Menu",
253.531 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.532 + "RegValue=REG_SZ:Programs");
253.533 +
253.534 +@F_PROGRAMS1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.535 + "Startup=REG_SZ:_CUPROF\\Programmi");
253.536 +
253.537 +@F_STARTUP_CU = ("CUser/Software/Microsoft/Windows/CurrentVersion/SecondaryProfileReconciliation/Startup/",
253.538 + "CentralFile=REG_SZ:Esecuzione Automatica",
253.539 + "LocalFile=REG_SZ:Menu Avvio\\Programmi\\Esecuzione Automatica",
253.540 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.541 + "MustBeRelative=REG_DWORD:1",
253.542 + "ParentKey=REG_SZ:Start Menu",
253.543 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.544 + "RegValue=REG_SZ:Startup");
253.545 +
253.546 +@F_STARTUP_DU = ("Users/.DEFAULT/Software/Microsoft/Windows/CurrentVersion/ProfileReconciliation/Startup/",
253.547 + "CentralFile=REG_SZ:Esecuzione Automatica",
253.548 + "LocalFile=REG_SZ:Menu Avvio\\Programmi\\Esecuzione Automatica",
253.549 + "Name=REG_SZ:\*.lnk,\*.pif,\*.url",
253.550 + "MustBeRelative=REG_DWORD:1",
253.551 + "ParentKey=REG_SZ:Start Menu",
253.552 + "RegKey=REG_SZ:Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
253.553 + "RegValue=REG_SZ:Startup");
253.554 +
253.555 +@F_STARTUP1 = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/User Shell Folders/",
253.556 + "Startup=REG_SZ:_CUPROF\\Menu Avvio\\Programmi\\Esecuzione automatica");
253.557 +
253.558 +### policies win98 sezione 'updatecontrol' - viene preparato RunOnce per eseguire aggiorna.bat
253.559 +@K_UPDATE = ("LMachine/Software/Microsoft/Windows/CurrentVersion/RunOnce/",
253.560 + "LogonUpd=REG_SZ:_DIRLOGON\\logonupd.bat");
253.561 +
253.562 +@K_LABELHOME = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/MountPoints2/_NETUSEHOME/",
253.563 + "_LabelFromDesktopINI=REG_SZ:HOME");
253.564 +@K_LABELCLASSE = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/MountPoints2/_NETUSECLASSE/",
253.565 + "_LabelFromDesktopINI=REG_SZ:MIA_CLASSE");
253.566 +@K_LABELSCAMBIO = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/MountPoints2/_NETUSESCAMBIO/",
253.567 + "_LabelFromDesktopINI=REG_SZ:SCAMBIO");
253.568 +@K_LABELMIOWEB = ("CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/MountPoints2/_NETUSEMIOWEB/",
253.569 + "_LabelFromDesktopINI=REG_SZ:MIO_WEB");
253.570 +
253.571 +
253.572 +sub version {
253.573 + &debug ("Version: 0.9x\n");
253.574 +}
253.575 +
253.576 +sub opgruppo {
253.577 + my $opdef = shift;
253.578 + my $group = shift;
253.579 + my $opvar = shift;
253.580 + my $OkRestrict = $opdef ;
253.581 +
253.582 + $OkRestrict=$$opvar{''} if ((defined($$opvar{''})));
253.583 + $OkRestrict=$$opvar{$group} if ((defined($$opvar{$group})));
253.584 +
253.585 +# &WinMsgBox ("$opvar [ $group ] = $OkRestrict\n",0,"OPGRUPPO") if ($DBG);
253.586 + my $msg = "$opvar"."[".$group."] = $OkRestrict\n";
253.587 + &debug ($msg,0,"OPGRUPPO");
253.588 +
253.589 + return $OkRestrict;
253.590 +}
253.591 +sub ReadConf {
253.592 + my $fname=shift; #nome del file di conf
253.593 + my $okupd=shift; #se 1 ReadConf e` chiamata da logonupd.pl
253.594 + my $file = "$ENV{LOGONSERVER}\\perl\\$fname";
253.595 + my $dbgf="";
253.596 + my $posdbgf="";
253.597 + my $dbgshare;
253.598 + my $dbgclien;
253.599 + my $dbgusers;
253.600 +
253.601 + open CONF, $file || die "ERRORE $f NON ESISTE";
253.602 +
253.603 + my $msg="";
253.604 + my $x, $i=0;
253.605 + while (<CONF>) {
253.606 +
253.607 + # elimina fine riga e commenti
253.608 + chop($_); s/\#.*// ; next if ($_ eq "");
253.609 +
253.610 + # qui non sono riuscito a trovare una regexp
253.611 + # che facesse il lavoro dell'if in colpo solo
253.612 + # la creazione implicita delle variabili
253.613 + # ci risparmia un sacco di codice
253.614 +
253.615 + if (m/.*\[.*/) {
253.616 + m/(.*)\[(.*)\]\s*=\s*(.*)/i ;
253.617 + $msg .= "1=$1, 2=$2 , 3=$3 , 4=$4 , 5=$5\n" ; #if ($i>20);
253.618 + $x=$1;
253.619 + $$x{$2}=$3;
253.620 + }else{
253.621 + m/(\S*)\s*=\s*(.*)/i ;
253.622 + $msg .= "1=$1, 2=$2 , 3=$3 , 4=$4 , 5=$5\n" ; #if ($i>20);
253.623 + $x=$1;
253.624 + $$x{''}=$2;
253.625 + }
253.626 + $i++;
253.627 + }
253.628 + close CONF;
253.629 +
253.630 + # DBG diverso da zero solo se _DebugLevel > 1
253.631 + $DBG = &opgruppo(0,$ENV{MAINGROUP},'_DebugLevel');
253.632 + $dbgshare = &opgruppo(0,$ENV{MAINGROUP},'_DebugShare');
253.633 + $dbgusers = &opgruppo(0,$ENV{MAINGROUP},'_DebugUsers');
253.634 + $dbgclien = &opgruppo(0,$ENV{MAINGROUP},'_DebugClients');
253.635 +
253.636 + if ($DBG == 3 && $dbgusers){
253.637 + $DBG=0 if ($dbgusers !~ m/$ENV{USERNAME}/i);
253.638 + WinMsgBox("DEBUG_LEVEL=$DBG per gli utenti: $dbgusers") if ($DBG);
253.639 + }
253.640 + if ($DBG == 3 && $dbgclien){
253.641 + $DBG=0 if ($dbgclien !~ m/$ENV{NETBIOSNAME}/i);
253.642 + WinMsgBox("DEBUG_LEVEL=$DBG per i clients: $dbgclien") if ($DBG);
253.643 + }
253.644 +
253.645 + if ($DBG == 0) { #nessun debug
253.646 + $OUTPUT="";
253.647 +
253.648 + }elsif ($DBG == 1){ #debug su conole
253.649 + $OUTPUT="";
253.650 +
253.651 + }elsif ($DBG == 2){ #debug via WinMsgBox
253.652 + $OUTPUT="";
253.653 +
253.654 + }elsif ($DBG == 3){ #debug su file in homes
253.655 + $OUTPUT = "FILE";
253.656 + if ($dbgshare){
253.657 + $dbgf=$ENV{LOGONSERVER}."\\".$dbgshare."\\DBG_".$ENV{NETBIOSNAME}.".TXT";
253.658 + }else{
253.659 + $dbgf=$ENV{LOGONSERVER}."\\".$ENV{USERNAME}."\\DBG_".$ENV{NETBIOSNAME}.".TXT";
253.660 + }
253.661 +
253.662 +# }elsif ($DBG == 4){ #debug su file in [netlogon]
253.663 +# $OUTPUT = "FILE";
253.664 +# $dbgf=$ENV{LOGONSERVER}."\\dbglogon\\DBG_".$ENV{NETBIOSNAME}.".TXT";
253.665 +
253.666 + }else{
253.667 + WinMsgBox("_DebugLevel = $DBG, i valori ammessi sono 0,1,2,3\ndebug disabilitato",0,"ERRORE IN LOGON.CONF");
253.668 + $DBG=0;$OUTPUT=""
253.669 + }
253.670 +
253.671 + if ($OUTPUT =~ m/FILE/ ){
253.672 + my $opf;
253.673 + if ($okupd){
253.674 + $opf='>>';
253.675 + }else{
253.676 + $opf='>';
253.677 + }
253.678 + if (!open(OUT,"$opf $dbgf")){
253.679 + WinMsgBox("non riesco ad aprire $dbgf",0,"ERRORE DEBUG");
253.680 + }else{
253.681 + WinMsgBox("ho aperto $dbgf [$opf]",0,"FILE DEBUG");
253.682 + print OUT "###------INIZIO DEBUG [$opf]------\n";
253.683 + }
253.684 + }
253.685 +
253.686 + print "DEBUG_LEVEL=$DBG DEBUG_FILE=$dbgf \n";
253.687 +
253.688 + &ListENV if ($DBG);
253.689 + &debug("Leggo $file per gruppo $ENV{MAINGROUP}");
253.690 + &debug($msg,0,"CONFIGURAZIONE") if ($msg ne "");
253.691 +
253.692 +}
253.693 +sub DbgClose {close OUT;}
253.694 +
253.695 +sub OsName {
253.696 + my $os=Win32::GetOSName();
253.697 + $os=~ s/\/\.Net//;
253.698 + return $os;
253.699 +}
253.700 +sub GetInfoLogon {
253.701 + # recupera username e maingroup eliminando le
253.702 + # differenze fra le versioni di windows
253.703 + # necessita di uno script aggiuntivo lanciato
253.704 + # da samba con direttiva root preexec (setlogonvar)
253.705 + # setlogonvar contiene uid,maingrp,classe
253.706 + # POSSIBILE SVILUPPO: recuperare maingrp, classe
253.707 + # direttamente da ldap....
253.708 + # ma lo uid va comunque passato via file
253.709 +
253.710 + my $srv = shift;
253.711 + my $r, $f;
253.712 +
253.713 + $ENV{NETBIOSNAME}=Win32::NodeName;
253.714 + $ENV{OSCLIENT}=&OsName();
253.715 +
253.716 + if (&IsWin9x) {
253.717 + chomp($srv);
253.718 + $ENV{LOGONSERVER} = "\\\\$srv";
253.719 + $ENV{USERNAME} = Win32::LoginName();
253.720 + $ENV{ALLUSERSPROFILE} = "C:\\Windows\\All Users";
253.721 + }
253.722 +
253.723 + # non e` affatto detto che Win32::LogonName() funzioni !!!
253.724 +
253.725 +# chdir "$ENV{LOGONSERVER}\\perl";
253.726 +
253.727 +# $f="$ENV{LOGONSERVER}\\perl\\logonvar_$ENV{NETBIOSNAME}";
253.728 +
253.729 + $f="$ENV{LOGONSERVER}\\netlogon\\logonvar_$ENV{NETBIOSNAME}";
253.730 + open UI,$f;while (<UI>){$r=$_;} close UI ; #unlink($f);
253.731 + chop($r); @info=split(/,/,$r);
253.732 +
253.733 + $ENV{USERNAME}= $info[0] if (!$ENV{USERNAME});
253.734 + $ENV{MAINGROUP}= $info[1];
253.735 + $ENV{CLASSE}=$info[2];
253.736 + $ENV{QUOTA}=$info[3];
253.737 +
253.738 + WinMsgBox("ATTENZIONE: spazio disco insufficente!!!\nse non liberi spazio non potrai salvare nuovi file.",0,"QUOTA DISCO SUPERATA") if ($ENV{QUOTA} =~ m/FUORIQUOTA/);
253.739 +}
253.740 +sub WinMsgBox {
253.741 + my $msg=shift;
253.742 + my $flags=shift;
253.743 + my $title=shift;
253.744 + Win32::MsgBox($msg,$flags,$title);
253.745 +}
253.746 +sub debug {
253.747 + ### _DebugLevel = 0 nessun messaggio
253.748 + ### = 1 solo messaggi di console
253.749 + ### = 2 con WinMsgBox
253.750 + ### = 3 messaggi in un file locale in HOMES
253.751 + ### = 4 messaggi in file remoto in /home/samba/netlogon
253.752 + my $msg = shift ;
253.753 + my $lvl = shift ;
253.754 + # A title is accepted as 3^ argument
253.755 + my $title = shift ;
253.756 +
253.757 + return if ($DBG == 0);
253.758 +
253.759 +
253.760 + if ($DBG =~ m/[134]/ ) {
253.761 + if ($OUTPUT == 'FILE') {
253.762 + print OUT "$title\n";
253.763 + print OUT "$msg\n";
253.764 + } else {
253.765 + print "$title\n";
253.766 + print "$msg\n";
253.767 + }
253.768 + }
253.769 + if ($DBG == 2 ) {
253.770 + Win32::MsgBox($msg, 0, $title) ;
253.771 + }
253.772 +}
253.773 +sub ListENV {
253.774 + my $key, $msg="";
253.775 + &debug(Win32::LoginName(),0,'Win32::LoginName') ;
253.776 + foreach $key (sort keys %ENV) {
253.777 + $msg .= "$key = $ENV{$key}\n";
253.778 + }
253.779 + &debug($msg,0,'VARIABILI ENV');
253.780 +}
253.781 +sub IsWin9x {
253.782 + return ($ENV{OSCLIENT} =~ m/Win95|Win98|WinME/i)
253.783 +}
253.784 +sub WinSet {
253.785 + my $op=shift;
253.786 + my $nomute=shift;
253.787 + if ($OUTPUT){
253.788 + print OUT "#### SETTING $op\n" if ($nomute);
253.789 + }else{
253.790 + print "#### SETTING $op\n" if ($nomute);
253.791 + }
253.792 + my $group = $ENV{MAINGROUP};
253.793 +
253.794 + if ($op eq 'start_page') {
253.795 + &SetKeyVal(\@K_IEMAIN,$group,"EXPLORER");
253.796 +
253.797 + }elsif ($op eq 'proxy'){
253.798 + &SetKeyVal(\@K_INTNETSET,$group,"PROXY");
253.799 +
253.800 + }elsif ($op eq 'no_profile') {
253.801 + return if (&IsWin9x) ; # win9x non supportato
253.802 + &SetKeyVal(\@K_NOPROFILE,$group,"NO_PROFILE");
253.803 +
253.804 + }elsif ($op eq 'no_local_profile') {
253.805 + return if (&IsWin9x) ; # win9x non supportato
253.806 + &SetKeyVal(\@K_NOLOCALPROFILE1,$group,"NOLOCALPROFILE1");
253.807 + &SetKeyVal(\@K_NOLOCALPROFILE2,$group,"NOLOCALPROFILE2");
253.808 +
253.809 + }elsif ($op eq 'last_user') {
253.810 + return if (&IsWin9x) ; # win9x supportato in modo diverso
253.811 + my $OkRestrict = &opgruppo(undef,$group,'_NoDispLastUser');
253.812 + if (defined($OkRestrict)){
253.813 + &SetKeyVal(\@K_LASTUSR_OFF,$group,"NODISP_LASTUSER") if ($OkRestrict);
253.814 + &SetKeyVal(\@K_LASTUSR_ON, $group,"NODISP_LASTUSER") if (!$OkRestrict);
253.815 + }
253.816 +
253.817 + }elsif ($op eq 'sync') {
253.818 + return if (&IsWin9x) ; # win9x non supportato
253.819 + my $OkRestrict = &opgruppo(undef,$group,'_NoSync');
253.820 + if (defined($OkRestrict)){
253.821 + &SetKeyVal(\@K_SYNC_OFF,$group,"NOSYNC") if ($OkRestrict);
253.822 + &SetKeyVal(\@K_SYNC_ON, $group,"NOSYNC") if (!$OkRestrict);
253.823 + }
253.824 +
253.825 + }elsif ($op eq 'iepasswordcache') {
253.826 + &ApplicaPol('_RestrictIEPasswordCaching',\@K_IEPASSWORDCACHING_DU,\@K_IEPASSWORDCACHING_CU,$op,'DELVAL',$setDU);
253.827 +
253.828 + }elsif ($op eq 'autorun') {
253.829 + &SetKeyVal(\@K_AUTORUN_CU,$group,"AUTORUN");
253.830 +
253.831 + }elsif ($op eq 'document_folder') {
253.832 + &SetKeyVal(\@K_DOCFOLDER1,$group,"DOC_FOLDER1");
253.833 + &SetKeyVal(\@K_DOCFOLDER2,$group,"DOC_FOLDER2");
253.834 +
253.835 + }elsif ($op eq 'net_use') {
253.836 + &net_use();
253.837 +
253.838 + }elsif ($op eq 'set_printers') {
253.839 + &set_printers();
253.840 +
253.841 + }elsif ($op eq 'net_time') {
253.842 + &net_time();
253.843 +
253.844 + }elsif ($op eq 'std_env') {
253.845 + &standard_env();
253.846 +
253.847 + }else{
253.848 +
253.849 + &debug('ERRORE IN /etc/isi/logon.conf (WinSet): '.$op,0,"OPZIONE SCONOSCIUTA");
253.850 + }
253.851 +}
253.852 +sub WinPol9x {
253.853 + # Win9xPol dovrebbe emulare CONFIG.POL
253.854 +
253.855 + my $pol=shift;
253.856 + my $nomute=shift;
253.857 + my $setDU=shift; #per logon2.bat
253.858 +
253.859 + if ($OUTPUT){
253.860 + print OUT "#### SETTING $pol\n" if ($nomute);
253.861 + }else{
253.862 + print "#### SETTING $pol\n" if ($nomute);
253.863 + }
253.864 +
253.865 + my $key,$val;
253.866 +
253.867 + return if (!&IsWin9x);
253.868 + #print $OUTPUT "sto simulando CONFIG.POL sezione $pol\n" if ($DBG);
253.869 +
253.870 + # modo di cancellazione vuoto significa che per eliminare la restrizione
253.871 + # si agisce su /etc/isi/logon.conf cambiando il valore delle variabili
253.872 +
253.873 +
253.874 + if ($pol eq 'clearpol'){
253.875 + &DelKeyVal(\@K_CLEAR_D1,'DELVAL',"ELIMINO GRUPPOL 1");
253.876 + &DelKeyVal(\@K_CLEAR_D2,'DELVAL',"ELIMINO GRUPPOL 2");
253.877 + &DelKeyVal(\@K_CLEAR_D3,'DELKEY',"ELIMINO GRUPPOL 3");
253.878 + &SetKeyVal(\@K_CLEAR_A1,"","ELIMINO GRUPPOL 4");
253.879 +
253.880 + }elsif ($pol eq 'access'){
253.881 + &ApplicaPol('_RestrictLogon','',\@K_NETLOGON1,$pol,'DELVAL','');
253.882 + &ApplicaPol('_RestrictLogon','',\@K_NETLOGON2,$pol,'DELVAL','');
253.883 +
253.884 + }elsif ($pol eq 'pwdcaching'){
253.885 + &SetKeyVal(\@K_PWDCACHING,"","NO PASSWORD CACHING");
253.886 +
253.887 + }elsif ($pol eq 'last_user') {
253.888 + &SetKeyVal(\@K_LASTUSER_OFF,"","NO_DISP_LASTUSER") if($_NoDispLastUser9X{''} eq 1);
253.889 + &SetKeyVal(\@K_LASTUSER_ON,"","NO_DISP_LASTUSER") if($_NoDispLastUser9X{''} eq 0);
253.890 +
253.891 + }elsif ($pol eq 'nocpan'){
253.892 + &ApplicaPol('_RestrictCpan',\@K_NOCPAN1_DU,\@K_NOCPAN1_CU,$pol,'DELKEY',$setDU);
253.893 + &ApplicaPol('_RestrictCpan',\@K_NOCPAN2_DU,\@K_NOCPAN2_CU,$pol,'DELVAL',$setDU);
253.894 +
253.895 + }elsif ($pol eq 'appwiz'){
253.896 + &AppWiz('_NoAppWiz',$pol);
253.897 +
253.898 + }elsif ($pol eq 'nodrive'){
253.899 + &ApplicaPol('_RestrictDrive',\@K_NOHYSTORY_DU,\@K_NOHYSTORY_CU,$pol,'DELVAL',$setDU);
253.900 +
253.901 + }elsif ($pol eq 'nodrivec'){
253.902 + &ApplicaPol('_RestrictDriveC',\@K_NODRIVEC_DU,\@K_NODRIVEC_CU,$pol,'DELVAL',$setDU);
253.903 +
253.904 + }elsif ($pol eq 'nohistory'){
253.905 + &ApplicaPol('_RestrictHistory',\@K_NOHISTORY1_DU,\@K_NOHISTORY1_CU,$pol,'DELVAL',$setDU);
253.906 + &ApplicaPol('_RestrictHistory',\@K_NOHISTORY2_DU,\@K_NOHISTORY2_CU,$pol,'DELVAL',$setDU);
253.907 +
253.908 + }elsif ($pol eq 'iecachedays'){
253.909 + if($_SetIECache{''} eq 1){
253.910 + &SetKeyVal(\@K_IECACHEDAYS_CU,"","IE CACHE DAYS");
253.911 + &SetKeyVal(\@K_IECACHEDAYS_DU,"","IE CACHE DAYS");
253.912 + }
253.913 +
253.914 + }elsif ($pol eq 'noactivedesktop'){
253.915 + &ApplicaPol('_RestrictActiveDesktop',\@K_NOACTIVED_DU,\@K_NOACTIVED_CU,$pol,'DELVAL',$setDU);
253.916 +
253.917 + }elsif ($pol eq 'nofind'){
253.918 + &ApplicaPol('_RestrictFind',\@K_NOFIND_DU,\@K_NOFIND_CU,$pol,'DELVAL',$setDU);
253.919 +
253.920 + }elsif ($pol eq 'paranoia'){
253.921 + my $OkRestrict = &opgruppo(0,$ENV{MAINGROUP},'_OkParanoia');
253.922 + if($OkRestrict){
253.923 + @CMD=();
253.924 + push(@CMD,"deltree /y C:\\Windows\\Desktop\\\*.\*");
253.925 + &esegui;
253.926 + @CMD=();
253.927 + push(@CMD,"deltree /y C:\\Recycled\\\*.\* ");
253.928 + &esegui;
253.929 + }
253.930 +
253.931 + }elsif ($pol eq 'screen'){
253.932 + &ApplicaPol('_RestrictScreen',\@K_SCREEN_DU,\@K_SCREEN_CU,$pol,'DELVAL',$setDU);
253.933 +
253.934 + }elsif ($pol eq 'net'){
253.935 + &ApplicaPol('_RestrictNet',\@K_NONET_DU,\@K_NONET_CU,$pol,'DELKEY',$setDU);
253.936 +
253.937 + }elsif ($pol eq 'passwd'){
253.938 + &ApplicaPol('_RestrictPasswd',\@K_CHPWD_DU,\@K_CHPWD_CU,$pol,'DELVAL',$setDU);
253.939 +
253.940 + }elsif ($pol eq 'printer'){
253.941 + &ApplicaPol('_RestrictPrinter',\@K_NOSTP_DU,\@K_NOSTP_CU,$pol,'DELVAL',$setDU);
253.942 +
253.943 + }elsif ($pol eq 'system'){
253.944 + &ApplicaPol('_RestrictSystem',\@K_SYS_DU,\@K_SYS_CU,$pol,'DELVAL',$setDU);
253.945 +
253.946 + }elsif ($pol eq 'shell_run'){
253.947 + &ApplicaPol('_RestrictRun',\@K_SHRUN_DU,\@K_SHRUN_CU,$pol,'DELVAL',$setDU);
253.948 +
253.949 + }elsif ($pol eq 'shell_noregtools'){
253.950 + &ApplicaPol('_RestrictRegTools',\@K_SHRTOOLS_DU,\@K_SHRTOOLS_CU,$pol,'DELVAL',$setDU);
253.951 +
253.952 + }elsif ($pol eq 'shell_winoldapp'){
253.953 + &ApplicaPol('_RestrictOldApp',\@K_SHOLDAPP_DU,\@K_SHOLDAPP_CU,$pol,'DELVAL',$setDU);
253.954 +
253.955 + }elsif ($pol eq 'nosavesettings'){
253.956 + &ApplicaPol('_RestrictSaveSettings',\@K_NOSAVESETTINGS_DU,\@K_NOSAVESETTINGS_CU,$pol,'DELVAL',$setDU);
253.957 +
253.958 + }elsif ($pol eq 'profiledirs'){
253.959 + &SetKeyVal(\@K_ALLPROFILEDIRS,'DELVAL',"TUTTE LE CARTELLE A DEFAULT");
253.960 +
253.961 + }elsif ($pol eq 'updateprofiledirs'){
253.962 +
253.963 + #metto tutti i percorsi a valori di default
253.964 +
253.965 + &SetKeyVal(\@K_ALLPROFILEDIRS,'DELVAL',"TUTTE LE CARTELLE A DEFAULT");
253.966 +
253.967 + #Tolgo tutte le cartelle dal roaming sia per l'utente che per il DEFAULT user
253.968 +
253.969 + &DelKeyVal(\@F_APPDATA_CU,"DELKEY","CARTELLA APPDATA");
253.970 + &DelKeyVal(\@F_CACHE_CU,"DELKEY","CARTELLA CACHE");
253.971 + &DelKeyVal(\@F_COOKIES_CU,"DELKEY","CARTELLA COOKIES");
253.972 + &DelKeyVal(\@F_DESKTOP_CU,"DELKEY","CARTELLA DESKTOP");
253.973 + &DelKeyVal(\@F_HISTORY_CU,"DELKEY","CARTELLA CRONOLOGIA");
253.974 + &DelKeyVal(\@F_NETHOOD_CU,"DELKEY","CARTELLA RISORSE DI RETE");
253.975 + &DelKeyVal(\@F_PROGRAMS_CU,"DELKEY","CARTELLA MENU PROGRAMMI");
253.976 + &DelKeyVal(\@F_RECENT_CU,"DELKEY","CARTELLA RECENTI");
253.977 + &DelKeyVal(\@F_START_MENU_CU,"DELKEY","CARTELLA MENU AVVIO");
253.978 + &DelKeyVal(\@F_STARTUP_CU,"DELKEY","CARTELLA ESECUZIONE AUTOMATICA");
253.979 + &DelKeyVal(\@F_APPDATA_DU,"DELKEY","CARTELLA APPDATA");
253.980 + &DelKeyVal(\@F_CACHE_DU,"DELKEY","CARTELLA CACHE");
253.981 + &DelKeyVal(\@F_COOKIES_DU,"DELKEY","CARTELLA COOKIES"); ##m1#a_test#.profili#WinXP
253.982 + &DelKeyVal(\@F_DESKTOP_DU,"DELKEY","CARTELLA DESKTOP");
253.983 + &DelKeyVal(\@F_HISTORY_DU,"DELKEY","CARTELLA CRONOLOGIA");
253.984 + &DelKeyVal(\@F_NETHOOD_DU,"DELKEY","CARTELLA RISORSE DI RETE");
253.985 + &DelKeyVal(\@F_PROGRAMS_DU,"DELKEY","CARTELLA MENU PROGRAMMI");
253.986 + &DelKeyVal(\@F_RECENT_DU,"DELKEY","CARTELLA RECENTI");
253.987 + &DelKeyVal(\@F_START_MENU_DU,"DELKEY","CARTELLA MENU AVVIO");
253.988 + &DelKeyVal(\@F_STARTUP_DU,"DELKEY","CARTELLA ESECUZIONE AUTOMATICA");
253.989 +
253.990 + #Metto in roaming solo le cartelle selezionate in logon.conf e setto i percorsi di queste.
253.991 + #Se i percorsi non sono specificati in logon.conf, vengono usati i valori di default per i roaming profiles
253.992 + #Vengono anche precisate quali devono essere le cartelle in roaming per i nuovi utenti (DEFAULT USER)
253.993 +
253.994 + my $ProfileDirs = &opgruppo(1,$group,'_ProfileDirs');
253.995 + @dirs=split(/;/,$ProfileDirs);
253.996 + for (my $k=0 ;$k<@dirs ;$k++){
253.997 + if ($dirs[$k] eq 'AppData'){
253.998 + &SetKeyVal(\@F_APPDATA_CU,"","CARTELLA APPDATA");
253.999 + &SetKeyVal(\@F_APPDATA_DU,"","CARTELLA APPDATA");
253.1000 + &SetKeyVal(\@F_APPDATA1,"","CARTELLA APPDATA");
253.1001 + } elsif ($dirs[$k] eq 'Cache') {
253.1002 + &SetKeyVal(\@F_CACHE_CU,"","CARTELLA CACHE");
253.1003 + &SetKeyVal(\@F_CACHE_DU,"","CARTELLA CACHE");
253.1004 + &SetKeyVal(\@F_CACHE1,"","CARTELLA CACHE");
253.1005 + } elsif ($dirs[$k] eq 'Cookies') {
253.1006 + &SetKeyVal(\@F_COOKIES_CU,"","CARTELLA COOKIES");
253.1007 + &SetKeyVal(\@F_COOKIES_DU,"","CARTELLA COOKIES");
253.1008 + &SetKeyVal(\@F_COOKIES1,"","CARTELLA COOKIES");
253.1009 + } elsif ($dirs[$k] eq 'Desktop') {
253.1010 + &SetKeyVal(\@F_DESKTOP_CU,"","CARTELLA DESKTOP");
253.1011 + &SetKeyVal(\@F_DESKTOP_DU,"","CARTELLA DESKTOP");
253.1012 + &SetKeyVal(\@F_DESKTOP1,"","CARTELLA DESKTOP");
253.1013 + } elsif ($dirs[$k] eq 'Favorites') {
253.1014 + &SetKeyVal(\@F_FAVORITES_CU,"","CARTELLA PREFERITI");
253.1015 + &SetKeyVal(\@F_FAVORITES_DU,"","CARTELLA PREFERITI");
253.1016 + &SetKeyVal(\@F_FAVORITES1,"","CARTELLA PREFERITI");
253.1017 + } elsif ($dirs[$k] eq 'History') {
253.1018 + &SetKeyVal(\@F_HISTORY_CU,"","CARTELLA CRONOLOGIA");
253.1019 + &SetKeyVal(\@F_HISTORY_DU,"","CARTELLA CRONOLOGIA");
253.1020 + &SetKeyVal(\@F_HISTORY1,"","CARTELLA CRONOLOGIA");
253.1021 + } elsif ($dirs[$k] eq 'NetHood') {
253.1022 + &SetKeyVal(\@F_NETHOOD_CU,"","CARTELLA RISORSE DI RETE");
253.1023 + &SetKeyVal(\@F_NETHOOD_DU,"","CARTELLA RISORSE DI RETE");
253.1024 + &SetKeyVal(\@F_NETHOOD1,"","CARTELLA RISORSE DI RETE");
253.1025 + } elsif ($dirs[$k] eq 'Programs') {
253.1026 + &SetKeyVal(\@F_PROGRAMS_CU,"","CARTELLA MENU PROGRAMMI");
253.1027 + &SetKeyVal(\@F_PROGRAMS_DU,"","CARTELLA MENU PROGRAMMI");
253.1028 + &SetKeyVal(\@F_PROGRAMS1,"","CARTELLA MENU PROGRAMMI");
253.1029 + } elsif ($dirs[$k] eq 'Recent') {
253.1030 + &SetKeyVal(\@F_RECENT_CU,"","CARTELLA RECENTI");
253.1031 + &SetKeyVal(\@F_RECENT_DU,"","CARTELLA RECENTI");
253.1032 + &SetKeyVal(\@F_RECENT1,"","CARTELLA RECENTI");
253.1033 + } elsif ($dirs[$k] eq 'Start Menu') {
253.1034 + &SetKeyVal(\@F_START_MENU_CU,"","CARTELLA MENU AVVIO");
253.1035 + &SetKeyVal(\@F_START_MENU_DU,"","CARTELLA MENU AVVIO");
253.1036 + &SetKeyVal(\@F_START_MENU1,"","CARTELLA MENU AVVIO");
253.1037 + } elsif ($dirs[$k] eq 'Startup') {
253.1038 + &SetKeyVal(\@F_STARTUP_CU,"","CARTELLA ESECUZIONE AUTOMATICA");
253.1039 + &SetKeyVal(\@F_STARTUP_DU,"","CARTELLA ESECUZIONE AUTOMATICA");
253.1040 + &SetKeyVal(\@F_STARTUP1,"","CARTELLA ESECUZIONE AUTOMATICA");
253.1041 + }
253.1042 + }
253.1043 + $newvers= $_Versione{''};
253.1044 + chop $newvers;
253.1045 + my $file = "H:\\.profili\\Win95\\Versione";
253.1046 + open (OUTV, ">$file");
253.1047 + print OUTV "$newvers\n";
253.1048 + close OUTV;
253.1049 + exec ("RUNDLL32 SHELL32.DLL,SHExitWindowsEx 0");
253.1050 +
253.1051 + }elsif ($pol eq 'updatecontrol'){
253.1052 +
253.1053 + #controlliamo se il profilo � da aggiornare
253.1054 + #se la risposta � affermativa prepariamo RunOnce
253.1055 +
253.1056 + $newvers= $_Versione{''};
253.1057 + my $file = "H:\\.profili\\Win95\\Versione";
253.1058 + if(!-e $file){
253.1059 + &SetKeyVal(\@K_UPDATE,"","MANCA IL FILE: PREPARO AGGIORNAMENTO");
253.1060 + WinMsgBox("ATTENZIONE: alla fine di queste operazioni\nsar� necessario ripetere il login",0,"PRIMA CONFIGURAZIONE");
253.1061 + }else{
253.1062 + open (FILE, $file);
253.1063 + $oldvers= $_;
253.1064 + while (<FILE>) {
253.1065 + $oldvers = $_;
253.1066 + }
253.1067 + close FILE;
253.1068 + chop($oldvers);
253.1069 + chop($newvers);
253.1070 + if ($newvers ne $oldvers) {
253.1071 + &SetKeyVal(\@K_UPDATE,"","VERSIONE SBAGLIATA: PREPARO AGGIORNAMENTO");
253.1072 + WinMsgBox("ATTENZIONE: alla fine di queste operazioni\nsar� necessario ripetere il login",0,"AGGIORNAMENTO DELLA CONFIGURAZIONE");
253.1073 + }
253.1074 + }
253.1075 +
253.1076 + }elsif ($pol eq 'startupdate'){
253.1077 + $datfile = "C:\\WINDOWS\\profiles\\$ENV{USERNAME}\\user.dat";
253.1078 + if(!-e $datfile){
253.1079 + # inutile aggiornare, l'utente non ha scaricato il suo profilo! usciamo da aggiorna.pl
253.1080 + exit;
253.1081 + }
253.1082 + }else{
253.1083 + &debug('ERRORE IN /etc/isi/logon.conf (WinPol9x): $pol',0,"OPZIONE SCONOSCIUTA");
253.1084 + }
253.1085 +}
253.1086 +sub AppWiz {
253.1087 + my $opvar = shift; # var di /etc/isi/logon.conf
253.1088 + my $tit = shift; # titolo
253.1089 + my $group = $ENV{MAINGROUP};
253.1090 + my $OkRestrict = &opgruppo(1,$group,$opvar);
253.1091 + my $src="$ENV{LOGONSERVER}\\perl\\win98\\Appwiz.cpl";
253.1092 + my $dst="C:\\WINDOWS\\SYSTEM\\Appwiz.cpl";
253.1093 + if ($OkRestrict){
253.1094 + &debug("del $dst",0,"STO PER ESEGUIRE...") ;
253.1095 + @CMD=();
253.1096 + push(@CMD,"del $dst");
253.1097 + &esegui;
253.1098 + }else{
253.1099 + if ($x){
253.1100 + WinMsgBox("ERRORE: impossibile ripristinare Appwiz",0,"AGGIORNAMENTO DELLA CONFIGURAZIONE");
253.1101 + }else{
253.1102 + &debug("copy $src $dst",0,"STO PER ESEGUIRE...") ;
253.1103 + @CMD=();
253.1104 + push(@CMD,"copy $src $dst");
253.1105 + &esegui;
253.1106 + }
253.1107 + }
253.1108 +}
253.1109 +
253.1110 +sub ApplicaPol {
253.1111 + my $opvar = shift; # var di /etc/isi/logon.conf
253.1112 + my $aDU = shift; # chiavi default user
253.1113 + my $aCU = shift; # chiavi current user
253.1114 + my $tit = shift; # titolo
253.1115 + my $opDel = shift; # modo di cancellazione
253.1116 + my $setDU = shift; # per logon2.bat in Esecuzione Automatica
253.1117 +
253.1118 + my $group=$ENV{MAINGROUP};
253.1119 + my $OkRestrict = &opgruppo(1,$group,$opvar);
253.1120 +
253.1121 + &Restrict($OkRestrict,$aDU,$group,"$tit\_DU",$opDel) if ($setDU);
253.1122 + &Restrict($OkRestrict,$aCU,$group,"$tit\_CU",$opDel);
253.1123 +}
253.1124 +sub Restrict {
253.1125 + $ok=shift;
253.1126 + $refreg=shift;
253.1127 + $group=shift;
253.1128 + $titolo=shift;
253.1129 + $opcanc=shift;
253.1130 + if ($ok) {
253.1131 + &SetKeyVal($refreg,$group,$titolo);
253.1132 + }elsif ($opcanc){
253.1133 + &DelKeyVal($refreg,$opcanc,$titolo);
253.1134 + }
253.1135 +}
253.1136 +sub DelKeyVal {
253.1137 + $r=shift;
253.1138 + $op=shift;
253.1139 + $titolo=shift;
253.1140 + my $v,$rvar,$key,$kroot,$kvar;
253.1141 + my @kv = @$r,$oldv,$oldop;
253.1142 + my $msg="";
253.1143 +
253.1144 + $kroot = $kv[0];
253.1145 +
253.1146 + if (!defined($Registry->{$kroot})){return;}
253.1147 +
253.1148 + # opzioni possibili DELKEY | DELVAL
253.1149 + if ($op eq 'DELKEY') {
253.1150 + delete $Registry->{$kroot};
253.1151 + $msg .= "DELKEY $kroot \n" ;
253.1152 + }elsif ($op eq 'DELVAL') {
253.1153 +
253.1154 + $msg .= "ELIMINO I VALORI SOTTO (FastDelete=$oldopt):\n$kroot\n" ;
253.1155 +
253.1156 + $key = $Registry->{$kroot};
253.1157 + $oldopt=$key->FastDelete( 1 );
253.1158 +
253.1159 + # elimina key var
253.1160 + for (my $j=1;$j<@kv;$j++){
253.1161 + @rvar=split(/=|:/,$kv[$j]);
253.1162 + $kvar=$rvar[0];
253.1163 + $kvar=~s/\_{2}/ /g;
253.1164 + if (defined($key->{$kvar})) {
253.1165 + $oldv=delete $key->{$kvar};
253.1166 + $msg .= "DELVAR $kvar = $oldv\n" ;
253.1167 + }
253.1168 + }
253.1169 + }
253.1170 + &debug($msg,0,"ELIMINO VOCE DI REGISTRO: $titolo") ;
253.1171 +}
253.1172 +#--------------
253.1173 +sub SetKeyVal {
253.1174 +
253.1175 + # setting del valore delle variabili in una chiave di registro
253.1176 + # se la chiave non esiste viene creata
253.1177 +
253.1178 + $r=shift;
253.1179 + $group=shift;
253.1180 + $pol=shift;
253.1181 +
253.1182 + my $v,$rvar,$key,$kroot,$kvar,$cvar,$kdef;
253.1183 + my $vval,$vtype,$NOERR;
253.1184 +
253.1185 + my @kv = @$r;
253.1186 + my $msg="";
253.1187 +
253.1188 + if ($DBG){
253.1189 + $msg .= "#------ voci di registro -------\n";
253.1190 + #stranamente lo statement while ($k) non funziona....
253.1191 + for (my $k=0 ;$k<@kv ;$k++){
253.1192 + $msg .= "$k) $kv[$k] \n";
253.1193 + }
253.1194 + $msg .= "#-------------valori -----------\n";
253.1195 + }
253.1196 +
253.1197 + $kroot = $kv[0];
253.1198 +
253.1199 + # setting delle label delle connessioni H: L: S: W:
253.1200 + if ($pol eq "LABELHOME"){
253.1201 +
253.1202 + my $pdc=$ENV{LOGONSERVER}; $pdc =~ s/\\//g;
253.1203 + # per tener conto della tecnica della // o di /./
253.1204 +# my $unit1="##".$pdc."#".$ENV{USERNAME}."#.profili#".$ENV{OSCLIENT};
253.1205 + my $unit2="##".$pdc."#".$ENV{USERNAME};
253.1206 +# $kroot =~ s/_NETUSEHOME/$unit1/g ;
253.1207 + $kroot =~ s/_NETUSEHOME/$unit2/i ;
253.1208 + #&WinMsgBox($kroot,0,$pol);
253.1209 +
253.1210 + }
253.1211 +
253.1212 + if ($pol eq "LABELCLASSE" && $ENV{MAINGROUP}=~m/alunni|esterni/i){
253.1213 +
253.1214 + my $pdc=$ENV{LOGONSERVER}; $pdc =~ s/\\//g;
253.1215 + my $unita="##".$pdc."#".$ENV{CLASSE};
253.1216 + $kroot =~ s/_NETUSECLASSE/$unita/i ;
253.1217 + #&WinMsgBox($kroot,0,$pol);
253.1218 +
253.1219 + }
253.1220 +
253.1221 + if ($pol eq "LABELSCAMBIO"){
253.1222 +
253.1223 + my $pdc=$ENV{LOGONSERVER}; $pdc =~ s/\\//g;
253.1224 + my $unita="##".$pdc."#scambio";
253.1225 + $kroot =~ s/_NETUSESCAMBIO/$unita/i ;
253.1226 + #&WinMsgBox($kroot,0,$pol);
253.1227 +
253.1228 + }
253.1229 + if ($pol eq "LABELMIOWEB"){
253.1230 +
253.1231 + my $pdc=$ENV{LOGONSERVER}; $pdc =~ s/\\//g;
253.1232 + my $unita="##".$pdc."#mioweb";
253.1233 + $kroot =~ s/_NETUSEMIOWEB/$unita/i ;
253.1234 + #&WinMsgBox($kroot,0,$pol);
253.1235 +
253.1236 + }
253.1237 +
253.1238 +
253.1239 + $key = $Registry->{$kroot};
253.1240 +
253.1241 + if (!defined($key)){
253.1242 + if (!IsWin9x && $kroot){ # !~ m/^CUser/i){
253.1243 + debug "OP.INTERROTTA - NON TROVO: $kroot\n";
253.1244 + return;
253.1245 + }
253.1246 + $key=$Registry->{$kroot}={};
253.1247 + $msg .= "CREO : $kroot\n" ;
253.1248 + }
253.1249 +
253.1250 + #&dispOptions($key,$kroot);
253.1251 +
253.1252 + #$key->SetOptions(DWordsToHex=>1);
253.1253 +
253.1254 + $msg .= "ROOT = $kroot\n";
253.1255 +
253.1256 + # key var
253.1257 + for (my $j=1;$j<@kv;$j++){
253.1258 +
253.1259 + @rvar=split(/=|:/,$kv[$j]);
253.1260 + $kvar=$cvar=$rvar[0];
253.1261 + $kvar =~ s/\_{2}/ /g;
253.1262 + $ktyp=$rvar[1];
253.1263 + $kdef=$rvar[2];
253.1264 +
253.1265 + if (defined($$cvar{$group})){
253.1266 + $v=$$cvar{$group}; # esiste il valore per il gruppo
253.1267 + }elsif (defined($$cvar{''})){
253.1268 + $v=$$cvar{''}; # default definito
253.1269 + }else{
253.1270 + $v = $kdef; # default di sistema
253.1271 + $v =~ s/_CDOC/C\:Documenti/g if ($kdef =~ '_CDOC');
253.1272 + $v =~ s/_HDOC/H\:Documenti/g if ($kdef =~ '_HDOC');
253.1273 + $v ="H:\Documenti" if ($kdef eq '_HDOC');
253.1274 + my $user = $ENV{USERNAME};
253.1275 + $v =~ s/_CUPROF/C:\\WINDOWS\\Profiles\\$user/g if ($kdef =~ '_CUPROF');
253.1276 + $v =~ s/_DUPROF/C:\\WINDOWS/g if ($kdef =~ '_DUPROF');
253.1277 + my $perldir="$ENV{LOGONSERVER}\\perl";
253.1278 + $v =~ s/_DIRPERL/$perldir/g if ($kdef =~ '_DIRPERL');
253.1279 + my $dirlogon="$ENV{LOGONSERVER}\\netlogon";
253.1280 + $v =~ s/_DIRLOGON/$dirlogon/g if ($kdef =~ '_DIRLOGON');
253.1281 + }
253.1282 +
253.1283 + ($vval,$vtype)=$key->GetValue($kvar);
253.1284 +
253.1285 + if (!defined($key->{$kvar})){
253.1286 + $vtype=$ValType{$ktyp};
253.1287 + $msg .= "ADDVAR: $kvar = $ktyp:$v\n" ;
253.1288 + }
253.1289 +
253.1290 + if ($vtype == $ValType{REG_SZ}){
253.1291 + $msg .= "$j) $kvar \t $vval -> $v \t(".$DscType[$vtype].")\n" ;
253.1292 + }
253.1293 +
253.1294 + if ($vtype == $ValType{REG_DWORD}){
253.1295 + $msg .= "$j) $kvar \t $vval -> $v \t(".$DscType[$vtype].")\n" ;
253.1296 + }
253.1297 +
253.1298 + if ($vtype == $ValType{REG_BINARY}){
253.1299 + $msg .= "$j) $kvar \t".unpack("L",$vval)." -> $v \t(" . $DscType[$vtype] . ")\n" ;
253.1300 + }
253.1301 +
253.1302 + $msg .= " SETVALUE: $kvar , $v , $DscType[$vtype]\n" ;
253.1303 +
253.1304 + # forzo la costruzione del valore esadecimale perche' non sembra avvenire
253.1305 + # automaticamente come documentato, con l'occasione evito la necessita` di indicare
253.1306 + # il valore come 0x.....
253.1307 +
253.1308 + if ($vtype == $ValType{REG_DWORD}){
253.1309 + if ($v =~ m/^0x/) {
253.1310 + $v=pack('L',substr($v,3));
253.1311 + }else{
253.1312 + $v=pack('L',$v);
253.1313 + }
253.1314 + }
253.1315 +
253.1316 + if ($vtype == $ValType{REG_BINARY}){
253.1317 + $v=pack('C4',$v);
253.1318 + }
253.1319 + $NOERR=$key->SetValue($kvar , $v , $DscType[$vtype]);
253.1320 + &debug("$kroot\n$kvar = $v\t\t$DscType[$vtype]\n",0,"ERRORE DI REGISTRO") if (!$NOERR);
253.1321 + }
253.1322 + $msg .= "#-------------------------------\n" ;
253.1323 + &debug($msg,0,"RegSettings: $pol gruppo: $group") ;
253.1324 +}
253.1325 +sub dispOptions{
253.1326 + my $key=shift;
253.1327 + my $kroot=shift;
253.1328 + my %opt,$k,$v,$msg="";
253.1329 +
253.1330 + debug("$pol: $kroot");
253.1331 + $key->GetOptions(\%opt);
253.1332 + while (($k,$v)=each(%opt)){
253.1333 + $msg .= "$k = $v\n";
253.1334 + }
253.1335 + &debug($msg,0,"REG OPTIONS");
253.1336 +}
253.1337 +sub net_use {
253.1338 +
253.1339 + @CMD=();
253.1340 + $group=$ENV{MAINGROUP};
253.1341 + my $option="";
253.1342 + my $share;
253.1343 + my $g;
253.1344 + my $udsk;
253.1345 +
253.1346 + if (&IsWin9x){
253.1347 + push(@CMD,"ECHO NET USE H: /HOME") ;
253.1348 + push(@CMD,"NET USE H: /HOME");
253.1349 + }
253.1350 +
253.1351 + $option="/PERSISTENT:NO" if (!&IsWin9x);
253.1352 + if ($ENV{CLASSE}){
253.1353 + push(@CMD,"ECHO NET USE L: $ENV{LOGONSERVER}\\$ENV{CLASSE} $option") ;
253.1354 + push(@CMD,"NET USE L: $ENV{LOGONSERVER}\\$ENV{CLASSE} $option");
253.1355 + }
253.1356 +
253.1357 + while (($u,$s)=each(%_NetFolder)){
253.1358 +
253.1359 + # vecchia sintassi _NetFolder[S]=share,gruppo
253.1360 + ($share,$g)=split(/,/,$s);
253.1361 +
253.1362 + # nuova sintassi _NetFolder[S:gruppo]=share
253.1363 + # se ERRONEAMENTE (o per vedere che succede) si scrivesse
253.1364 + # _NetFolder[S:gruppo1]=share,gruppo2 allora vincerebbe
253.1365 + # gruppo1, ma non ci sarebbe il mascheramento generato dalla
253.1366 + # vecchia sintassi
253.1367 + ($udsk,$g)=split(/:/,$u);
253.1368 +
253.1369 + if ($group eq $g || $g eq ""){
253.1370 + push(@CMD,"ECHO NET USE $udsk: $ENV{LOGONSERVER}\\$share $option") ;
253.1371 + push(@CMD,"NET USE $udsk: $ENV{LOGONSERVER}\\$share $option");
253.1372 + }
253.1373 + }
253.1374 +
253.1375 + &esegui;
253.1376 +
253.1377 + if (! &IsWin9x){
253.1378 + &SetKeyVal(\@K_LABELHOME,"", "LABELHOME");
253.1379 + &SetKeyVal(\@K_LABELCLASSE,"", "LABELCLASSE");
253.1380 + &SetKeyVal(\@K_LABELSCAMBIO,"","LABELSCAMBIO");
253.1381 + &SetKeyVal(\@K_LABELMIOWEB,"", "LABELMIOWEB");
253.1382 + }
253.1383 +}
253.1384 +sub set_printers {
253.1385 +
253.1386 + @CMD=();
253.1387 + $group=$ENV{MAINGROUP};
253.1388 + my $option="";
253.1389 + my $share;
253.1390 + my $g;
253.1391 + my $udsk;
253.1392 + my $my_printers;
253.1393 + while (($g,$share)=each(%UserPrinter)) {
253.1394 + $my_printers .= "$share ($g)";
253.1395 + }
253.1396 + push(@CMD,"ECHO Ci sono1 $group". $my_printers) ;
253.1397 +
253.1398 + if (! &IsWin9x){
253.1399 + push(@CMD,"ECHO Ci sono2") ;
253.1400 + while (($g,$share)=each(%UserPrinter)) {
253.1401 +
253.1402 + if ($group eq $g || $g eq ""){
253.1403 + push(@CMD,"ECHO RunDLL32 PrintUI.DLL,PrintUIEntry /dn /n $share /q") ;
253.1404 + push(@CMD,"ECHO RunDLL32 PrintUI.DLL,PrintUIEntry /in /n $share /q") ;
253.1405 + push(@CMD,"RunDLL32 PrintUI.DLL,PrintUIEntry /dn /n $ENV{LOGONSERVER}\\$share /q");
253.1406 + push(@CMD,"RunDLL32 PrintUI.DLL,PrintUIEntry /in /n $ENV{LOGONSERVER}\\$share /q");
253.1407 + }
253.1408 + }
253.1409 + if ($group eq 'admins' || $group eq 'Domain Admins') {
253.1410 + while (($g,$share)=each(%PcPrinter)) {
253.1411 + push(@CMD,"ECHO RunDLL32 PrintUI.DLL,PrintUIEntry /gd /n $share /q") ;
253.1412 + push(@CMD,"ECHO RunDLL32 PrintUI.DLL,PrintUIEntry /ga /n $share /q") ;
253.1413 + push(@CMD,"RunDLL32 PrintUI.DLL,PrintUIEntry /gd /n $ENV{LOGONSERVER}\\$share /q");
253.1414 + push(@CMD,"RunDLL32 PrintUI.DLL,PrintUIEntry /ga /n $ENV{LOGONSERVER}\\$share /q");
253.1415 + }
253.1416 + }
253.1417 + }
253.1418 +
253.1419 + &esegui;
253.1420 +
253.1421 +}
253.1422 +sub net_time {
253.1423 + my $Ok=&opgruppo(1,$ENV{MAINGROUP},'_NetTime');
253.1424 + if ($Ok){
253.1425 + @CMD=();
253.1426 + push(@CMD,"NET TIME $ENV{LOGONSERVER} /SET /YES");
253.1427 + &esegui;
253.1428 + }
253.1429 +}
253.1430 +sub standard_env {
253.1431 +
253.1432 + my $group = $ENV{MAINGROUP};
253.1433 + my $os = $ENV{OSCLIENT};
253.1434 + my $Ok=&opgruppo(0,$group,"_Env".$os);
253.1435 +
253.1436 + &debug("$group $os $Ok ",0,"PRIMA DI ESEGUIRE......") ;
253.1437 +
253.1438 + if ($Ok){
253.1439 + my $src = "$ENV{LOGONSERVER}\\netlogon\\env_".$os."_".$group;
253.1440 + my $dst;
253.1441 + if (&IsWin9x) {
253.1442 + $dst = "$ENV{ALLUSERSPROFILE}";
253.1443 + }else{
253.1444 + $dst = "$ENV{ALLUSERSPROFILE}";
253.1445 + }
253.1446 + &debug("xcopy $src $dst /S /Y /C /I /Q /R",0,
253.1447 + "STO PER ESEGUIRE......") ;
253.1448 + @CMD=();
253.1449 + push(@CMD,"xcopy $src \"$dst\" /S /Y /C /I /Q /R");
253.1450 + &esegui;
253.1451 + }
253.1452 +}
253.1453 +sub esegui {
253.1454 + my $success, $msg="",$msgerr="";
253.1455 +
253.1456 + foreach (@CMD) {
253.1457 + $success = system($_) ;
253.1458 + $msg .= "$_ ( $success )\n" ;
253.1459 + }
253.1460 + &debug($msg,0,'COMANDI ESEGUITI');
253.1461 + return $success;
253.1462 +}
253.1463 +
253.1464 +1;
254.1 Binary file usr/share/WinActivePerl/win98/Appwiz.cpl has changed
255.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
255.2 +++ b/usr/share/doc/isi/acl.conf Mon Apr 26 11:16:23 2010 +0200
255.3 @@ -0,0 +1,17 @@
255.4 +[/home/alunni]
255.5 + g:docenti = rxw
255.6 + g:ata = rxw
255.7 + o = ---
255.8 +
255.9 +[/home/docenti]
255.10 + o = ---
255.11 +
255.12 +[/home/area_scambio]
255.13 + copy = /home/classi
255.14 + g:alunni = rx-
255.15 +
255.16 +[/home/classi]
255.17 + g:docenti = rxw
255.18 + g:ata = rxw
255.19 + o = r--
255.20 +
256.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
256.2 +++ b/usr/share/doc/isi/etc/isi/acl-local.conf Mon Apr 26 11:16:23 2010 +0200
256.3 @@ -0,0 +1,1 @@
256.4 +### acl-local.conf - personalizza/sovrascrive acl.conf
257.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
257.2 +++ b/usr/share/doc/isi/etc/isi/defaults.py Mon Apr 26 11:16:23 2010 +0200
257.3 @@ -0,0 +1,80 @@
257.4 +#!/usr/bin/python
257.5 +# -*- coding: utf-8 -*-
257.6 +
257.7 +# This program is free software; you can redistribute it and/or modify
257.8 +# it under the terms of the GNU General Public License as published by
257.9 +# the Free Software Foundation; either version 2, or (at your option)
257.10 +# any later version.
257.11 +
257.12 +
257.13 +# AUTHORS: Sandro Dentella - Massimo Mancini
257.14 +
257.15 +"""
257.16 +These defaults will be overwritten by values in /etc/isi/defaults.py
257.17 +"""
257.18 +import os
257.19 +# struttura della /home
257.20 +GROUPS_PATH = '/home/users'
257.21 +CLASSES_PATH = '/home/shares/classi'
257.22 +COURSES_PATH = '/home/shares/corsi'
257.23 +
257.24 +# gruppi a cui vanno assegnati gli utenti se si vuole che possano
257.25 +# usare chiavette e audio dei client linux
257.26 +#EXTRA_GROUPS = []
257.27 +EXTRA_GROUPS = ['plugdev','audio', 'fuse']
257.28 +
257.29 +
257.30 +# usato da isi2-adduser per l'imput interattivo
257.31 +DATI_USER = "USER_ID COGNOME NOME GRUPPO GRUPPI COD.FISC. PASSWORD SESSO INDIRIZZO COMUNE CAP PROVINCIA TELEFONO"
257.32 +
257.33 +# configurazione del logger
257.34 +LOG_FILE = '/var/log/users_error.log'
257.35 +LOG_MODE = 'w'
257.36 +LOG_FORMAT = '%(asctime)s %(name)-8s %(levelname)-8s %(message)s'
257.37 +LOG_DATE_FORMAT='%y-%m-%d %H:%M'
257.38 +
257.39 +# configurazione del backup ldap
257.40 +BAK_LDAP_FILE = '/etc/isi/slapcat.ldif'
257.41 +
257.42 +# QUOTA
257.43 +QUOTA_S1 = 0
257.44 +QUOTA_S2 = 0
257.45 +QUOTA_F1 = 0
257.46 +QUOTA_F2 = 0
257.47 +QUOTA_REP = '/tmp/repquota.txt'
257.48 +
257.49 +# PERMESSI DI DEFAULT SU HOME E FILE (indipendenti da acl)
257.50 +# alunni ed esterni
257.51 +PERMS_HOME_ALU = '2770'
257.52 +PERMS_FILE_ALU = '660'
257.53 +# tutti gli altri
257.54 +PERMS_HOME_ALL = '2700'
257.55 +PERMS_FILE_ALL = '600'
257.56 +
257.57 +# NUMERI INIZIALI LDAP
257.58 +UID_MIN = 1000
257.59 +GID_MIN = 1000
257.60 +UID_MAX = 30000
257.61 +GID_MAX = 30000
257.62 +
257.63 +## User's logname format
257.64 +
257.65 +GROUP_IDS = {
257.66 + 'alunni' : 'a',
257.67 + 'docenti' : 'd',
257.68 + 'admins' : 'ad',
257.69 + 'esterni' : 'e',
257.70 + 'segreteria' : 's',
257.71 + 'ata' : 'at',
257.72 + }
257.73 +
257.74 +USER_FORMAT = {
257.75 + 'default' : u'%(group_id)s_%(cf).8s',
257.76 + 'docenti' : u'%(first_name)s.%(last_name)s',
257.77 + }
257.78 +
257.79 +CLASSE_FORMAT = u"%(corso)s%(anno_corso)s%(sezione)s"
257.80 +
257.81 +if os.path.exists('/etc/isi/defaults.py'):
257.82 + execfile('/etc/isi/defaults.py')
257.83 +
258.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
258.2 +++ b/usr/share/doc/isi/etc/isi/labinfo.secret Mon Apr 26 11:16:23 2010 +0200
258.3 @@ -0,0 +1,24 @@
258.4 +### /etc/isi/labinfo.secret
258.5 +### file di configurazione delle aule di informatica
258.6 +### viene usato da isi-wlg per la manipolazione dei gruppi locali
258.7 +### dei client windows (xp) dell'aula stessa
258.8 +### e modificato isi-wlg nel caso di cambio della password amministrativa
258.9 +### del client
258.10 +### FORMATO LINEA: nomehostXP;Administrator_locale%password
258.11 +### Esempi (replicare decommentando):
258.12 +
258.13 +### con credenziali amministrative individuali
258.14 +#[aula1]
258.15 +#pc01;administrator%password1
258.16 +#pc02;administrator%password2
258.17 +
258.18 +
258.19 +### con credenziali amministrative uniche
258.20 +#[aula2]administrator%password
258.21 +#pc01
258.22 +#pc02
258.23 +
258.24 +### con credenziali amministrative miste
258.25 +#[aula1]administrator%password
258.26 +#pc01
258.27 +#pc02;administrator%password2
259.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
259.2 +++ b/usr/share/doc/isi/etc/isi/logon.bat Mon Apr 26 11:16:23 2010 +0200
259.3 @@ -0,0 +1,3 @@
259.4 +:: ##### LOGON.BAT creato da ISI-LOGON #####
259.5 +@ECHO OFF
259.6 +\\ISI-PDC\perl\bin\perl \\ISI-PDC\perl\logon.pl ISI-PDC
260.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
260.2 +++ b/usr/share/doc/isi/etc/isi/logon.conf Mon Apr 26 11:16:23 2010 +0200
260.3 @@ -0,0 +1,265 @@
260.4 +# +-------------------------------------------------+
260.5 +# � 2002-2005 ReteIsi / www.reteisi.org
260.6 +# +-------------------------------------------------+
260.7 +# $Id: logon.conf 160 2021-09-02 17:23:43Z max $
260.8 +
260.9 +###-----------------------------------------------------------------------
260.10 +### Le variabili dichiarate in questo file sono di due tipi
260.11 +### quelle che iniziano con un _ sono variabili interne e servono
260.12 +### ad abilitare (1) o disabilitare (0) la funzionalita`corrispondente
260.13 +### oppure a passare variabili di configurazione specifiche di
260.14 +### ISI-logon; le altre DEVONO corrispondere a voci di registro a cui
260.15 +### si vuole assegnare il valore scritto di seguito (es. 0x00000001).
260.16 +### Per ottenere una differente impostazione per uno specifico gruppo
260.17 +### basta specificare il gruppo come nell'esempio:
260.18 +### Start__Page[alunni] = www.google.com
260.19 +### Quando i nomi usati per le variabili sono quelli del registro di
260.20 +### windows, se il nome della variabile di registro contiene uno
260.21 +### spazio, sostituirlo con due _ (.Es "Start Page" = Start__Page)
260.22 +
260.23 +### sulle variabili prefissate con underscore in generale
260.24 +### 1 applica la restrizione
260.25 +### 0 rimuove la restrizione
260.26 +### il valore delle variabili di registro va espresso
260.27 +### coerentemente con il TIPO (se REG_DWORD, 0x......)
260.28 +
260.29 +### NOTA: Le variabili sono *case sensitive*
260.30 +###-----------------------------------------------------------------------
260.31 +
260.32 +### versione di logon.conf - DA INCREMENTARE AD OGNI MODIFICA di logon.conf
260.33 +### per attivare l'aggiornamento degli user.dat (agisce sui client win98)
260.34 +
260.35 +_Versione = 0;
260.36 +
260.37 +### DEBUG (0,1,2,3)
260.38 +### 0 = nessun debug
260.39 +### 1 = solo console su video o su file (se valorizzato _DebugFile)
260.40 +### 2 = su schermo (in box grafici: lungo, completo e noioso ;-)
260.41 +### 3 = sul file locale DBG_macchina.TXT nella HOME
260.42 +
260.43 +
260.44 +_DebugLevel = 1
260.45 +
260.46 +### opzioni aggiuntive se _DebugLevel=3
260.47 +### _DebugShare share samba in cui centralizzare
260.48 +### _DebugUsers lista degli utenti da sottoporre a debug
260.49 +### _DebugClients lista dei clients da sottoporre a debug
260.50 +
260.51 +# _DebugShare =
260.52 +# _DebugUsers =
260.53 +# _DebugClients=
260.54 +
260.55 +
260.56 +### WinSet sezione 'start_page'
260.57 +Start__Page = www.google.it
260.58 +Start__Page[admins] = www.google.it
260.59 +
260.60 +### WinSet sezione 'proxy'
260.61 +ProxyServer = XXX.XXX.XXX:8128 # DansGuardian
260.62 +ProxyServer[admins] = XXX.XXX.XXX:3128 # Squid (FW permettendo)
260.63 +ProxyOverride = www.XXX.XXX,<local>
260.64 +
260.65 +### WinSet sezione 'no_profile' (solo XP)
260.66 +ExcludeProfileDirs = Impostazioni locali;Temporary Internet Files;Cronologia;Temp;Documenti;Cookies;SendTo
260.67 +
260.68 +### WinSet sezione 'no_local_profile' (solo XP)
260.69 +DeleteRoamingCache = 1
260.70 +
260.71 +### WinSet sezione 'document_folder'
260.72 +Personal = H:\Documenti
260.73 +My__Picture =
260.74 +My__Music =
260.75 +My__Video =
260.76 +
260.77 +### WinSet sezione 'paranoia_folders' solo per win9x
260.78 +### se _OkParanoia = 1 vengono ripuliti ad ogni logon il Desktop e il cestino di default.
260.79 +_OkParanoia = 0
260.80 +
260.81 +
260.82 +### WinSet sezione 'iepasswordcache' - non salva le password digitate quando si accede a siti web
260.83 +
260.84 +_RestrictIEPasswordCaching = 0
260.85 +
260.86 +### WinSet sezione 'sync' (solo WinXP)
260.87 +### per disabilitare la sincronizzazione delle cartelle non in linea
260.88 +### è necessario porre a 1 la seguente variabile
260.89 +_NoSync = 1
260.90 +
260.91 +
260.92 +### WinSet sezione 'autorun' (PER IL MOMENTO NON FUNZIONA!!!!_
260.93 +### valori possibili:
260.94 +### 0x91 = abilita autorun
260.95 +### 0x95 = disabilita autorun da USB lo mantiene per i CD
260.96 +### 0xB5 = disabilita completamente l'autorun
260.97 +NoDriveTypeAutorun = 0xB5
260.98 +
260.99 +### WinSet sezione 'last-user' (WinXP)
260.100 +### gli utenti normali non hanno permessi sufficenti
260.101 +### gli amministratori (admins) invece possono
260.102 +### questa situazione viene gestita eliminando
260.103 +### il default
260.104 +
260.105 +_NoDispLastUser[admins] = 0
260.106 +
260.107 +### WinPol9x sezione 'last-user' (Win9X solo con Tweakui installato)
260.108 +_NoDispLastUser9X = 1
260.109 +
260.110 +### parametri validi per Win9x - default molto restrittivo
260.111 +
260.112 +### di seguito sono specifate tutte e solo le cartelle che possono essere messe in roaming
260.113 +### separare le cartelle con un ; per default tutte le cartelle sono in roaming
260.114 +
260.115 +#_ProleDirs = AppData;Cache;Cookies;Desktop;Favorites;History;NetHood;Programs;Recent;Start Menu;Startup
260.116 +_ProfileDirs = AppData;Temporary Internet Files;Cookies;Desktop;Favorites;History;NetHood;Programs;Recent;Start Menu;Startup
260.117 +
260.118 +### se le cartelle vengono messe in roaming possono anche essere rimappate sul server in modo
260.119 +### da salvare i documenti durante la sessione ed evitare "traffico" all'uscita,
260.120 +### se non si specifica alcun percorso vengono messe in roaming nel modo "classico"
260.121 +### con il salvataggio sul server all'uscita
260.122 +
260.123 +#esempi di percorsi:
260.124 +#Desktop = H:\.profili\Win95\Desktop
260.125 +#Cookies=H:\.profili\Win95\Cookies
260.126 +#Favorites=H:\.profili\Win95\Favorites
260.127 +
260.128 +
260.129 +### WinPol9x sezione 'access'
260.130 +_RestrictLogon = 1
260.131 +_RestrictLogon[admins] = 1
260.132 +# valori di registro
260.133 +UserProfiles = 1 #0x00000001 # si vogliono i roaming profiles
260.134 +UseHomeDirectory = 1 #0x00000001
260.135 +MustBeValidated = 1 #0x00000001 # si vuole l'autenticazione ldap
260.136 +MustBeValidated[admins] = 1 #0x00000000
260.137 +LegalNoticeCaption = XXX.XXX
260.138 +LegalNoticeText = accesso riservato agli utenti autorizzati.
260.139 +
260.140 +### WinPol9x sezione 'nocpan' - fa sparire dal pannello di controllo
260.141 +_RestrictCpan = 0
260.142 +
260.143 +### WinPol9x sezione 'appwiz' - fa sparire dal pannello di controllo
260.144 +### l'applet Installa/Rimuovi applicazioni
260.145 +_NoAppWiz = 0
260.146 +
260.147 +### WinPol9x sezione 'nodrive' - fa sparire le periferiche dalle risorse del computer
260.148 +_RestrictDrive = 0
260.149 +_RestrictDrive[admins] = 0
260.150 +
260.151 +###WinPol9x sezione 'nodrivec' - fa sparire il disco C dalle risorse del computer
260.152 +_RestrictDriveC = 1
260.153 +_RestrictDriveC[admins] = 0
260.154 +
260.155 +### WinPol9x sezione 'nofind' - fa sparire la voce trova dal menu avvio
260.156 +_RestrictFind = 1
260.157 +_RestrictFind[admins] = 0
260.158 +
260.159 +### WinPol9x sezione 'nohistory' - cancella la cronologia
260.160 +_RestrictHistory = 0
260.161 +
260.162 +### WinPol9x sezione 'iecachedays' - se _SetIECache è settato a 1
260.163 +### con la variabile successiva DaysToKeep è possibile impostare per
260.164 +### quanti giorni restano nella cache le pagine web visitate
260.165 +### Con DaysToKeep = 0x00000000 le pagine non vengono salvate
260.166 +_SetIECache = 0
260.167 +DaysToKeep = 0x00000000
260.168 +
260.169 +
260.170 +
260.171 +### WinPol9x sezione 'nosavesettings' - non salva i cambiamenti al Desktop all'uscita
260.172 +_RestrictSaveSettings = 0
260.173 +
260.174 +### WinPol9x sezione 'noactivedesktop' - disattiva l'Active Desktop
260.175 +_RestrictActiveDesktop = 0
260.176 +
260.177 +### WinPol9x sezione 'screen' - abilita le restrizioni dello schermo
260.178 +_RestrictScreen = 1
260.179 +_RestrictScreen[admins] = 0
260.180 +
260.181 +# opzioni restrizioni screen
260.182 +NoDispAppearancePage = 0 #0x00000000
260.183 +NoDispBackgroundPage = 0 #0x00000000
260.184 +NoDispCPL = 0 #0x00000000
260.185 +NoDispScrSavPage = 0 #0x00000000
260.186 +NoDispSettingsPage = 1 #0x00000001
260.187 +
260.188 +# opzioni altre applet del pannello di controllo
260.189 +NoAdminPage = 1
260.190 +NoConfigPage = 1
260.191 +NoDevMgrPage = 1
260.192 +NoFileSysPage = 1
260.193 +NoProfilePage = 1
260.194 +NoVirtMemPage = 1
260.195 +
260.196 +### WinPol9x sezione 'net' - Risorse di rete Proprietà
260.197 +_RestrictNet = 0
260.198 +_RestrictNet[admins] = 0
260.199 +
260.200 +### WinPol9x sezione 'passwd' = Pannello di controllo Password
260.201 +_RestrictPasswd = 1
260.202 +_RestrictPasswd[admins] = 0
260.203 +
260.204 +### WinPol9x sezione 'printer' - Impostazioni stampanti
260.205 +_RestrictPrinter = 1
260.206 +_RestrictPrinter[admins] = 0
260.207 +
260.208 +### WinPol9x sezione 'system' - Restrizioni varie sul sistema
260.209 +_RestrictSystem = 1
260.210 +_RestrictSystem[admins] = 0
260.211 +
260.212 +### WinPol9x sezione 'shell-run' - Start Esegui
260.213 +_RestrictRun = 0
260.214 +_RestrictRun[admins] = 0
260.215 +
260.216 +### WinPol9x sezione 'shell-noregtools' - tools per la modifica del registro
260.217 +_RestrictRegTools = 0
260.218 +_RestrictRegTools[admins] = 0
260.219 +
260.220 +### WinPol9x sezione 'shell-winoldapp' - vecchie applicazioni
260.221 +_RestrictOldApp = 0
260.222 +_RestrictOldApp[admins] = 0
260.223 +
260.224 +
260.225 +### connessioni di rete oltre a quelle attivate
260.226 +### automaticamente, che sono:
260.227 +### H: -> homedir
260.228 +### L: -> classe (solo per gli alunni)
260.229 +### la sintassi e'la seguente:
260.230 +### NetFolder[unita'[:gruppo]] = nome della condivisione
260.231 +### esempio _NetFolder[U:admins]=util
260.232 +
260.233 +_NetFolder[W:alunni] = mioweb
260.234 +_NetFolder[S:admins] = software
260.235 +_NetFolder[Y:Domain Admins] = software
260.236 +_NetFolder[Y:docenti] = software
260.237 +_NetFolder[U] = area_alunni
260.238 +_NetFolder[T:docenti] = area_docenti
260.239 +_NetFolder[T:docenti] = area_segreteria
260.240 +_NetFolder[K:docenti] = classi
260.241 +_NetFolder[K:admins] = classi
260.242 +_NetFolder[X:admins] = dati
260.243 +
260.244 +### sincronizzazione orologio
260.245 +
260.246 +_NetTime = 1
260.247 +
260.248 +### forzatura ambiente di default (desktop, menu avvio ecc.ecc.)
260.249 +### la si ottiene copiando la seguente cartella
260.250 +
260.251 +### [netlogon]\env_$os_$gruppo\* -> C:\Windows\All Users (Win9x)
260.252 +### [netlogon]\env_$os_gruppo\* -> C:\Documents and Settings\All Users (WinXP)
260.253 +
260.254 +### dove os = $ENV{OSCLIENT} e'la versione di windows che gira sul client
260.255 +### cioe'una delle seguenti: Win95,Win98,WinME,WinNT,Win2K,WinXP
260.256 +
260.257 +_EnvWin98 = 1
260.258 +_EnvWin98[admins] = 0
260.259 +
260.260 +### ATTENZIONE: per WinXP,Win2K occorre che la cartella di destinazione sia
260.261 +### scrivibile dagli utenti di dominio il che normalmente non e'; si
260.262 +### consiglia di non attivare questa funzionalità che, se il client è
260.263 +### correttamente configurato si rivela sostanzialmente inutile
260.264 +
260.265 +_EnvWinXP = 0
260.266 +
260.267 +
260.268 +
261.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
261.2 +++ b/usr/share/doc/isi/etc/isi/logon.pl Mon Apr 26 11:16:23 2010 +0200
261.3 @@ -0,0 +1,115 @@
261.4 +#!/usr/bin/perl
261.5 +
261.6 +# +-------------------------------------------------+
261.7 +# � 2002-2005 ReteIsi / www.reteisi.org
261.8 +# +-------------------------------------------------+
261.9 +# $Id: logon.pl,v 1.2 2021/09/02 17:23:43 max Exp $
261.10 +
261.11 +use ISI::Logon ;
261.12 +
261.13 +# logon.bat richiama logon.pl passandogli
261.14 +# il nome netbios del server che deve essere
261.15 +# definito a mano, questo se vogliamo
261.16 +# che tutte le versioni di windows
261.17 +# si comportino allo stesso modo
261.18 +# tutte le variabili necessarie sono contenute
261.19 +# nell'hash %ENV
261.20 +
261.21 +my $srv = shift;
261.22 +
261.23 +my $DBG = 1; # attivazione modalita` DEBUG (messaggistica in finestra DOS, comoda!)
261.24 +my $SDU = 1; # setting Users/.DEFAULT
261.25 +
261.26 +#$group = shift;
261.27 +
261.28 +&GetInfoLogon($srv);
261.29 +
261.30 +&ReadConf("logon.conf",0);
261.31 +
261.32 +$DBG=&opgruppo(1,$ENV{MAINGROUP},'_DebugLevel');
261.33 +
261.34 +print "NOME SERVER = $ENV{LOGONSERVER}\n" if ($DBG);
261.35 +print "VER.OS CLIENT= $ENV{OSCLIENT} \n" if ($DBG);
261.36 +print "NOME CLIENT = $ENV{NETBIOSNAME}\n" if ($DBG);
261.37 +print "UTENTE = $ENV{USERNAME}\n" if ($DBG);
261.38 +print "GRUPPO MAIN = $ENV{MAINGROUP}\n" if ($DBG);
261.39 +
261.40 +
261.41 +### policies x win9x - sostituisce CONFIG.POL
261.42 +### primo passaggio
261.43 +
261.44 +
261.45 +
261.46 +&WinPol9x('clearpol',$DBG);
261.47 +&WinPol9x('access',$DBG);
261.48 +&WinPol9x('pwdcaching',$DBG);
261.49 +&WinPol9x('nocpan',$DBG);
261.50 +&WinPol9x('appwiz',$DBG);
261.51 +&WinPol9x('nodrive',$DBG);
261.52 +&WinPol9x('nodrivec',$DBG);
261.53 +&WinPol9x('noactivedesktop',$DBG);
261.54 +&WinPol9x('nohistory',$DBG);
261.55 +&WinPol9x('nosavesettings',$DBG);
261.56 +&WinPol9x('paranoia',$DBG);
261.57 +&WinPol9x('nofind',$DBG);
261.58 +&WinPol9x('last_user',$DBG);
261.59 +&WinPol9x('screen',$DBG);
261.60 +&WinPol9x('net',$DBG);
261.61 +&WinPol9x('passwd',$DBG);
261.62 +&WinPol9x('printer',$DBG);
261.63 +&WinPol9x('system',$DBG);
261.64 +&WinPol9x('shell_run',$DBG);
261.65 +&WinPol9x('shell_noregtools',$DBG);
261.66 +&WinPol9x('shell_winoldapp',$DBG);
261.67 +&WinPol9x('iecachedays',$DBG);
261.68 +
261.69 +### visualizzazione nome ultimo utente
261.70 +
261.71 +&WinSet('last_user',$DBG);
261.72 +
261.73 +### setting browser (IE)
261.74 +
261.75 +&WinSet('start_page',$DBG);
261.76 +&WinSet('proxy',$DBG);
261.77 +&WinSet('no_profile',$DBG);
261.78 +&WinSet('no_local_profile',$DBG);
261.79 +&WinSet('sync',$DBG);
261.80 +&WinSet('autorun',$DBG);
261.81 +&WinSet('document_folder',$DBG);
261.82 +&WinSet('iepasswordcache',$DBG);
261.83 +
261.84 +### connessione cartelle di rete
261.85 +
261.86 +&WinSet('net_use',$DBG);
261.87 +
261.88 +### controllo se l'utente ha il profilo aggiornato
261.89 +### eventualmente attivo l'aggiornamento con lo script logonupd.pl
261.90 +&WinPol9x('updatecontrol',$DBG);
261.91 +
261.92 +### sincronizzazione dell'orologio
261.93 +
261.94 +&WinSet('net_time',$DBG);
261.95 +&WinSet('set_printer',$DBG);
261.96 +
261.97 +### predisposizione ambiente client standard
261.98 +
261.99 +&WinSet('std_env',$DBG);
261.100 +
261.101 +&DbgClose();
261.102 +
261.103 +###-------fine-----------------
261.104 +
261.105 +
261.106 +
261.107 +
261.108 +
261.109 +
261.110 +
261.111 +
261.112 +
261.113 +
261.114 +
261.115 +
261.116 +
261.117 +
261.118 +
262.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
262.2 +++ b/usr/share/doc/isi/etc/isi/logonupd.bat Mon Apr 26 11:16:23 2010 +0200
262.3 @@ -0,0 +1,3 @@
262.4 +:: ##### LOGON.BAT creato da ISI-LOGON #####
262.5 +@ECHO OFF
262.6 +\\ISI-PDC\perl\bin\perl \\ISI-PDC\perl\logonupd.pl ISI-PDC
263.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
263.2 +++ b/usr/share/doc/isi/etc/isi/logonupd.pl Mon Apr 26 11:16:23 2010 +0200
263.3 @@ -0,0 +1,86 @@
263.4 +#!/usr/bin/perl
263.5 +
263.6 +# +-------------------------------------------------+
263.7 +# � 2002-2005 ReteIsi / www.reteisi.org
263.8 +# +-------------------------------------------------+
263.9 +# $Id: logonupd.pl,v 1.1.1.2 2021/10/30 07:35:24 max Exp $
263.10 +
263.11 +use ISI::Logon ;
263.12 +
263.13 +# logon.bat richiama logon.pl passandogli
263.14 +# il nome netbios del server che deve essere
263.15 +# definito a mano, questo se vogliamo
263.16 +# che tutte le versioni di windows
263.17 +# si comportino allo stesso modo
263.18 +# tutte le variabili necessarie sono contenute
263.19 +# nell'hash %ENV
263.20 +
263.21 +my $srv = shift;
263.22 +
263.23 +my $DBG = 1; # attivazione modalita` DEBUG (messaggistica in finestra DOS, comoda!)
263.24 +my $SDU = 0; # setting Users/.DEFAULT
263.25 +
263.26 +#$group = shift;
263.27 +
263.28 +&GetInfoLogon($srv);
263.29 +
263.30 +&ReadConf("logon.conf",1);
263.31 +
263.32 +$DBG=&opgruppo(1,$ENV{MAINGROUP},'_DebugLevel');
263.33 +
263.34 +print "NOME SERVER = $ENV{LOGONSERVER}\n" if ($DBG);
263.35 +print "VER.OS CLIENT= $ENV{OSCLIENT} \n" if ($DBG);
263.36 +print "NOME CLIENT = $ENV{NETBIOSNAME}\n" if ($DBG);
263.37 +print "UTENTE = $ENV{USERNAME}\n" if ($DBG);
263.38 +print "GRUPPO MAIN = $ENV{MAINGROUP}\n" if ($DBG);
263.39 +
263.40 +
263.41 +### policies x win9x - sostituisce CONFIG.POL
263.42 +### secondo passaggio (commentate le istruzioni da non ripetere)
263.43 +
263.44 +&WinPol9x('startupdate',$DBG);
263.45 +
263.46 +&WinPol9x('clearpol',$DBG);
263.47 +&WinPol9x('access',$DBG);
263.48 +#&WinPol9x('pwdcaching',$DBG);
263.49 +&WinPol9x('nocpan',$DBG);
263.50 +&WinPol9x('nodrive',$DBG);
263.51 +&WinPol9x('nodrivec',$DBG);
263.52 +&WinPol9x('noactivedesktop',$DBG);
263.53 +&WinPol9x('nohistory',$DBG);
263.54 +&WinPol9x('nosavesettings',$DBG);
263.55 +#&WinPol9x('paranoia',$DBG);
263.56 +&WinPol9x('nofind',$DBG);
263.57 +&WinPol9x('last_user',$DBG);
263.58 +&WinPol9x('screen',$DBG);
263.59 +&WinPol9x('net',$DBG);
263.60 +&WinPol9x('passwd',$DBG);
263.61 +&WinPol9x('printer',$DBG);
263.62 +&WinPol9x('system',$DBG);
263.63 +&WinPol9x('shell_run',$DBG);
263.64 +&WinPol9x('shell_noregtools',$DBG);
263.65 +&WinPol9x('shell_winoldapp',$DBG);
263.66 +&WinPol9x('iecachedays',$DBG);
263.67 +#&WinSet('start_page',$DBG);
263.68 +#&WinSet('proxy',$DBG);
263.69 +#&WinSet('no_profile',$DBG);
263.70 +#&WinSet('sync',$DBG);
263.71 +&WinSet('document_folder',$DBG);
263.72 +&WinSet('iepasswordcache',$DBG);
263.73 +&WinPol9x('profiledirs',$DBG);
263.74 +&WinPol9x('updateprofiledirs',$DBG);
263.75 +
263.76 +&DbgClose();
263.77 +
263.78 +
263.79 +
263.80 +
263.81 +
263.82 +
263.83 +
263.84 +
263.85 +
263.86 +
263.87 +
263.88 +
263.89 +
264.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
264.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_aree.conf Mon Apr 26 11:16:23 2010 +0200
264.3 @@ -0,0 +1,26 @@
264.4 +[area_alunni]
264.5 + comment = cartella pubblica di scambio
264.6 + path = /home/shares/area_alunni
264.7 + read only = No
264.8 + directory mask = 0777
264.9 +
264.10 +[area_segreteria]
264.11 + path = /home/shares/area_segreteria
264.12 + comment = cartella per comunicazioni segreteria
264.13 + read only = No
264.14 + directory mask = 0770
264.15 +
264.16 +[area_docenti]
264.17 + path = /home/shares/area_docenti
264.18 + comment = cartella per scambio fra docenti
264.19 + read only = No
264.20 + directory mask = 0770
264.21 +
264.22 +
264.23 +[area_riservata]
264.24 + comment = Area area_riservata
264.25 + path = /home/shares/area_riservata
264.26 + guest ok = no
264.27 + writable = yes
264.28 + browseable =yes
264.29 +
265.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
265.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_classi.conf Mon Apr 26 11:16:23 2010 +0200
265.3 @@ -0,0 +1,17 @@
265.4 +# classi SAMBA - generate con Webmin-ISI-Classi il 08.05.2021
265.5 +
265.6 +[classi]
265.7 +comment = cartella classi
265.8 +path = /home/shares/classi
265.9 +guest ok = no
265.10 +writable = yes
265.11 +browseable = yes
265.12 +
265.13 +
265.14 +[classe_test]
265.15 +comment = Classe Test
265.16 +path = /home/shares/classi/classe_test
265.17 +guest ok = no
265.18 +writable = yes
265.19 +browseable = no
265.20 +
266.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
266.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_corsi.conf Mon Apr 26 11:16:23 2010 +0200
266.3 @@ -0,0 +1,16 @@
266.4 +# corsi SAMBA - reteisi
266.5 +
266.6 +[corsi]
266.7 +comment = cartella corsi
266.8 +path = /home/shares/corsi
266.9 +guest ok = no
266.10 +writable = yes
266.11 +browseable =yes
266.12 +
266.13 +[corso_test]
266.14 +comment = cartella di classe del corso
266.15 +path = /home/shares/corsi/corso_test
266.16 +guest ok = no
266.17 +writable = yes
266.18 +browseable =no
266.19 +
267.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
267.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_homes.conf Mon Apr 26 11:16:23 2010 +0200
267.3 @@ -0,0 +1,11 @@
267.4 +# aree SAMBA - modello HOME distribuito da reteisi
267.5 +
267.6 +[homes]
267.7 + comment = ISI-homes (NON MODIFICARE QUESTA RIGA)
267.8 + browseable = no
267.9 + writable = yes
267.10 + guest ok = no
267.11 + veto files = /public_html/
267.12 +
267.13 +
267.14 +
268.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
268.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_maingrps.conf Mon Apr 26 11:16:23 2010 +0200
268.3 @@ -0,0 +1,66 @@
268.4 +### share SAMBA - reteisi
268.5 +
268.6 +[admins]
268.7 +comment = cartella di gruppo
268.8 +path = /home/users/admins
268.9 +guest ok = no
268.10 +writable = yes
268.11 +browseable = no
268.12 +valid users = root,@admins
268.13 +
268.14 +[alunni]
268.15 +comment = cartella di gruppo
268.16 +path = /home/users/alunni
268.17 +guest ok = no
268.18 +writable = yes
268.19 +browseable = yes
268.20 +valid users = root,@admins,@alunni,@docenti
268.21 +
268.22 +[ata]
268.23 +comment = cartella di gruppo
268.24 +path = /home/users/ata
268.25 +guest ok = no
268.26 +writable = yes
268.27 +browseable = yes
268.28 +valid users = root,@admins,@ata
268.29 +
268.30 +[docenti]
268.31 +comment = cartella di gruppo
268.32 +path = /home/users/docenti
268.33 +guest ok = no
268.34 +writable = yes
268.35 +browseable = yes
268.36 +valid users = root,@admins,@docenti
268.37 +
268.38 +[esterni]
268.39 +comment = cartella di gruppo
268.40 +path = /home/users/esterni
268.41 +guest ok = no
268.42 +writable = yes
268.43 +browseable = yes
268.44 +valid users = root,@admins,@esterni,@docenti
268.45 +
268.46 +[segreteria]
268.47 +comment = cartella di gruppo
268.48 +path = /home/users/segreteria
268.49 +guest ok = no
268.50 +writable = yes
268.51 +browseable = yes
268.52 +valid users = root,@admins,@segreteria
268.53 +
268.54 +[ospiti]
268.55 +comment = cartella di gruppo
268.56 +path = /home/users/ospiti
268.57 +guest ok = no
268.58 +writable = yes
268.59 +browseable = yes
268.60 +valid users = root,@admins,@ospiti
268.61 +
268.62 +[gruppo-test]
268.63 +comment = cartella di gruppo
268.64 +path = /home/users/grtest
268.65 +guest ok = no
268.66 +writable = yes
268.67 +browseable = yes
268.68 +valid users = root,@admins,@grtest,@docenti
268.69 +
269.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
269.2 +++ b/usr/share/doc/isi/etc/isi/samba/smb_servizi.conf Mon Apr 26 11:16:23 2010 +0200
269.3 @@ -0,0 +1,31 @@
269.4 +[preside]
269.5 + comment = Home del preside
269.6 + path = /home/users/admins/preside
269.7 + browseable = no
269.8 + writable = yes
269.9 + guest ok = no
269.10 + create mask = 0600
269.11 + directory mask = 0700
269.12 + valid users = preside
269.13 +
269.14 +[mioweb]
269.15 + comment = web directories
269.16 + path = /home/users/%G/%u/public_html
269.17 + browseable = no
269.18 + writable = yes
269.19 + guest ok = no
269.20 + force create mode = 0644
269.21 + force directory mode = 0711
269.22 +
269.23 +[software]
269.24 + comment = cartella applicazioni
269.25 + path = /home/shares/software
269.26 + read only = No
269.27 + directory mask = 0777
269.28 +
269.29 +[dati]
269.30 + comment = /home del server
269.31 + path = /home
269.32 + read only = No
269.33 + browseable = no
269.34 +
270.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270.2 +++ b/usr/share/doc/isi/etc/isi/save-config/isi.list Mon Apr 26 11:16:23 2010 +0200
270.3 @@ -0,0 +1,9 @@
270.4 +# file di configurazione per save-config
270.5 +# salvataggio configurazione isi
270.6 +# deve essere copiato in /etc/save-config/files/isi.list
270.7 +
270.8 +/etc/smbldap-tools/
270.9 +/etc/isi
270.10 +/home/samba
270.11 +/var/ldap
270.12 +/var/lib/samba
271.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
271.2 +++ b/usr/share/doc/isi/etc/isi/sissi-tabcorsi Mon Apr 26 11:16:23 2010 +0200
271.3 @@ -0,0 +1,7 @@
271.4 +# tabella di traduzione nome corsi SISSI -> classi isi
271.5 +# formato: corso_sissi = classe_isi
271.6 +# Esempio (per un ITCG):
271.7 +# progetto cinque = geo
271.8 +# geometri = geo
271.9 +# indirizzo giuridico economico aziendale = ige
271.10 +# progetto mercurio = pro
272.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
272.2 +++ b/usr/share/doc/isi/etc/isi/userid-come Mon Apr 26 11:16:23 2010 +0200
272.3 @@ -0,0 +1,29 @@
272.4 +# REGOLA PER LA COSTRUZIONE DELLO USERID
272.5 +# si tratta in pratica di un frammento i codice
272.6 +# perl che viene interpretato al volo e che puo'
272.7 +# essere modificato dall'utente senza toccare lo script
272.8 +# principale isi-prepusers
272.9 +# le righe precedute dal segno # sono commenti e possono
272.10 +# essere inserite dovunque
272.11 +# le variabili in MAISCOLO sono da considerare note e
272.12 +# gia' valorizzate con i dati utente.
272.13 +# Esse sono $COGNOME, $NOME, $CODFISC, $NATOIL
272.14 +# la data di nascita e' restituita nel formato yymmgg
272.15 +
272.16 +# la regola di default e'
272.17 +#
272.18 +# $UID="a_".substr($CODFISC,0,11)
272.19 +#
272.20 +# ed e' quella assunta quando questo file non contiene
272.21 +# istruzioni eseguibili ( o non esiste, o e vuoto, o tutte
272.22 +# le righe sono commentate.
272.23 +
272.24 +# esempio 1 = primi 4 caratteri del cognome
272.25 +# $UID=substr($COGNOME,0,4);
272.26 +
272.27 +# esempio 2 = primi 3 caratteri del cognome + primi 3 del nome
272.28 +# $UID=substr($COGNOME,0,3).substr($NOME,0,3);
272.29 +
272.30 +# esempio 3 = primi 3 car.cognome + primi 3 del nome + data di nascita
272.31 +# $UID = substr($COGNOME,0,3).substr($NOME,0,3).$NATOIL;
272.32 +
273.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
273.2 +++ b/usr/share/doc/isi/etc/isi/userpy.conf Mon Apr 26 11:16:23 2010 +0200
273.3 @@ -0,0 +1,42 @@
273.4 +######################################################################
273.5 +# ISI_USERS
273.6 +# file di configurazione dei permessi di accesso dei dati utenti
273.7 +#
273.8 +# SINTASSI 1:
273.9 +# gruppo_princ@gruppo_sec = admin1, admin2, @gruppo1, @gruppo2 ...
273.10 +#
273.11 +# SINTASSI 2:
273.12 +# gruppo_princ@ = admin1, admin2, @gruppo1, @gruppo2 ...
273.13 +#
273.14 +# le righe che iniziano con un # sono commenti e non saranno
273.15 +# interpretate
273.16 +# la sintassi 2 assegna privilegi di root a tutti gli utenti del
273.17 +# gruppo principale
273.18 +#
273.19 +# NOTA BENE:
273.20 +# affinche' gli utenti dichiarati amministratori di quella
273.21 +# particolare risorsa possano effettivamente operare, occorre
273.22 +# che isi-users sia chiamato via sudo, esempio:
273.23 +#
273.24 +# $ sudo isi-users classe
273.25 +#
273.26 +# il che comporta la corretta configurazione del file /ets/sudoers
273.27 +# vedi esempio in /usr/share/doc/isi-ldap3/sudo/sudoers
273.28 +######################################################################
273.29 +# lunghezze min, max di userID, password e nome classe
273.30 +USERID_MINLEN = 5
273.31 +USERID_MAXLEN = 15
273.32 +USERPW_MINLEN = 8
273.33 +USERPW_MAXLEN = 14
273.34 +CLASSE_MAXLEN = 6
273.35 +
273.36 +PREFIX_ADMINS = "ad_"
273.37 +PREFIX_ALUNNI = "a_"
273.38 +PREFIX_ATA = "t_"
273.39 +PREFIX_DOCENTI= "d_"
273.40 +PREFIX_ESTERNI= "e_"
273.41 +PREFIX_OSPITI = "o_"
273.42 +
273.43 +# -----------------------------------------------------
273.44 +# da qui in poi l'assegnazione dei privilegi sui gruppi
273.45 +# -----------------------------------------------------
274.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
274.2 +++ b/usr/share/doc/isi/etc/isi/wlg.secret Mon Apr 26 11:16:23 2010 +0200
274.3 @@ -0,0 +1,23 @@
274.4 +### WLG.SECRET: file di configurazione di setlogonwlg per la gestione
274.5 +### dei gruppi locali su client XP durante la fase di logon
274.6 +
274.7 +### NOTA IMPORTANTE: proteggere questo file con chmod 600
274.8 +### per evitare di esporre le password amministrative dei client
274.9 +
274.10 +### FORMATO (separatore :)
274.11 +### campo1) stato: ALLOW|DENY la precedenza è DENY
274.12 +### campo2) user|gruppo da aggiungere o da cancellare dal gruppo locale
274.13 +### campo3) gruppo locale windows
274.14 +### campo4) espressione regolare per il nome host del client windows
274.15 +### campo5) credenziali amministrative del client
274.16 +
274.17 +### per disabilitare una direttiva basta commentarla
274.18 +### per abilitare una direttiva presente basta decommentarla
274.19 +### la direttiva DEVE cominciare a inizio riga, non solo ammessi spazi
274.20 +
274.21 +#DENY:aatest:Administrators:^xp:Administrator%password
274.22 +#DENY:classe_test:Administrators:^xp:Administrator%password
274.23 +
274.24 +#ALLOW:aatest:Administrators:^xp:Administrator%password
274.25 +#ALLOW:classe_test:Administrators:^xp:Administrator%password
274.26 +
275.1 Binary file usr/share/doc/isi/etc/samba/samba.schema.gz has changed
276.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
276.2 +++ b/usr/share/doc/isi/etc/samba/smb.conf Mon Apr 26 11:16:23 2010 +0200
276.3 @@ -0,0 +1,158 @@
276.4 +##################################################
276.5 +# FILE DI CONFIGURAZIONE PER PDC SAMBA3.2
276.6 +##################################################
276.7 +[global]
276.8 + workgroup = ISI-DOMAIN
276.9 + netbios name = ISI-PDC
276.10 + server string = %h
276.11 + dns proxy = No
276.12 + bind interfaces only = Yes
276.13 + interfaces = lo, eth0
276.14 + smb ports = 139
276.15 +
276.16 +# invalid users = root
276.17 +# admin users = root,@admins
276.18 +# printer admin = @lpadmin
276.19 +
276.20 +### registra i logon via samba: ATTENZIONE le cartelle vanno create
276.21 +# utmp = Yes
276.22 +# utmp directory = /var/log/samba/utmp
276.23 +# wtmp directory = /var/log/samba/wtmp
276.24 +
276.25 +### evita l'apertura di notepad con un file desktop.ini
276.26 + hide files = /desktop.ini/ntuser.ini/NTUSER.*/
276.27 +
276.28 +### conserva i permessi e i privilegi dei file dell'utente
276.29 + inherit acls = yes
276.30 + inherit owner = yes
276.31 +
276.32 + log file = /var/log/samba/log.%m
276.33 + max log size = 1000
276.34 + syslog = 0
276.35 + log level = 0
276.36 +
276.37 + security = user
276.38 + encrypt passwords = true
276.39 + passdb backend = ldapsam:ldap://127.0.0.1/
276.40 + obey pam restrictions = no
276.41 + deadtime = 15
276.42 + browseable = no
276.43 +
276.44 + wins support = Yes
276.45 + name resolve order = lmhosts host wins bcast
276.46 +
276.47 + local master = yes
276.48 + domain master = Yes
276.49 + preferred master = Yes
276.50 + os level = 254
276.51 + domain logons = Yes
276.52 +
276.53 +# map system = yes
276.54 +# map archive = yes
276.55 +# map hidden = yes
276.56 +
276.57 + unix password sync = no
276.58 + enable privileges = yes
276.59 + passwd program = /usr/sbin/smbldap-passwd %u
276.60 + passwd chat = *New*password* %n\n *Retype*new*password* %n\n
276.61 + socket options = TCP_NODELAY, SO_KEEPALIVE
276.62 +
276.63 + load printers = yes
276.64 + printing = cups
276.65 + printcap name = cups
276.66 +
276.67 + ldap ssl = no
276.68 + ldap passwd sync = yes
276.69 + ldap machine suffix = ou=Computers
276.70 + ldap idmap suffix = ou=Idmaps
276.71 + ldap group suffix = ou=Groups
276.72 + ldap user suffix = ou=People
276.73 + ldap suffix = dc=isi,dc=lan
276.74 + ldap delete dn = Yes
276.75 + ldap admin dn = cn=admin,dc=isi,dc=lan
276.76 +
276.77 + logon home = \\%N\%U\.\\.profili\%a
276.78 + logon drive = H:
276.79 + logon path = \\%N\%U\.profili\%a
276.80 + logon script = logon.bat
276.81 +
276.82 + add machine script = /usr/sbin/smbldap-useradd -w "%m"
276.83 + set primary group script = /usr/sbin/smbldap-usermod -g "%g" "%u"
276.84 + delete user from group script = /usr/sbin/smbldap-groupmod -x "%u" "%g"
276.85 + add user to group script = /usr/sbin/smbldap-groupmod -m "%u" "%g"
276.86 + delete group script = /usr/sbin/smbldap-groupdel "%g"
276.87 + add group script = /usr/sbin/smbldap-groupadd -p "%g"
276.88 + delete user script = /usr/sbin/smbldap-userdel "%u"
276.89 + add user script = /usr/sbin/smbldap-useradd -m "%u"
276.90 + check password script = /usr/bin/crackcheck -s
276.91 +
276.92 + panic action = /usr/share/samba/panic-action %d
276.93 + check password script = /usr/bin/crackcheck -s
276.94 +
276.95 +[homes]
276.96 + comment = ISI-homes (NON MODIFICARE QUESTA RIGA)
276.97 + browseable = no
276.98 + writable = yes
276.99 + guest ok = no
276.100 + veto files = /public_html/
276.101 +
276.102 +[printers]
276.103 + comment = All Printers
276.104 + browseable = no
276.105 + path = /tmp
276.106 + printable = yes
276.107 + public = no
276.108 + writable = no
276.109 + create mode = 0700
276.110 +
276.111 +[print$]
276.112 + comment = Printer Drivers
276.113 + path = /var/lib/samba/printers
276.114 + browseable = yes
276.115 + read only = yes
276.116 + guest ok = no
276.117 + write list = @lpadmin, root
276.118 +
276.119 +#### ATTENZIONE: configurare i file da includere secondo necessità
276.120 +#include = /etc/isi/samba/smb_servizi.conf
276.121 +#include = /etc/isi/samba/smb_maingrps.conf
276.122 +#include = /etc/isi/samba/smb_classi.conf
276.123 +#include = /etc/isi/samba/smb_corsi.conf
276.124 +#include = /etc/isi/samba/smb_aree.conf
276.125 +
276.126 +[perl]
276.127 + path = /usr/share/WinActivePerl
276.128 + comment = Per Windows Binaries
276.129 + public = yes
276.130 + writable = no
276.131 + guest ok = yes
276.132 + browseable = no
276.133 +
276.134 +[netlogon]
276.135 + comment = ISI-NetLogon (NON MODIFICARE QUESTA RIGA)
276.136 + path = /home/samba/netlogon
276.137 + guest ok = yes
276.138 + browseable = no
276.139 + create mask = 0644
276.140 + directory mask = 0755
276.141 + writable = yes
276.142 + root preexec=/usr/sbin/setlogonvar '%U' '%G' '%m'
276.143 + root postexec=/usr/sbin/rmlogonvar '%m'
276.144 +
276.145 +### la share seguente è opzionale, decommentare se si vuole una condivisione
276.146 +### per indirizzare velocemente il profilo
276.147 +
276.148 +#[profiles]
276.149 +# comment = cartelle profili utente
276.150 +# path = /home/users/%g/%u/.profili/%a
276.151 +# path = /home/users/profili
276.152 +# read only = No
276.153 +# create mask = 0660
276.154 +# directory mask = 2770
276.155 +# browseable = No
276.156 +# guest ok = Yes
276.157 +# profile acls = Yes
276.158 +# csc policy = disable
276.159 +# # next line is a great way to secure the profiles
276.160 +# force user = %U
276.161 +
277.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
277.2 +++ b/usr/share/doc/isi/etc/skel/.Xdefaults Mon Apr 26 11:16:23 2010 +0200
277.3 @@ -0,0 +1,48 @@
277.4 +! *background: linen
277.5 +*background: gray85
277.6 +!*Background: gray85
277.7 +*foreground: gray22
277.8 +Emacs.font: 6x13
277.9 +Emacs.pane.menubar.font: 6x13
277.10 +Emacs*menu*font: 6x13
277.11 +Emacs.geometry: 80x55
277.12 +! Emacs.font: -b&h-lucidatypewriter-medium-r-*-*-12-120-75-75-m-*-*-*
277.13 +Emacs.background: gray78
277.14 +Emacs.font-lock-reference-face.attributeForeground: forestgreen
277.15 +Emacs.font-lock-string-face.attributeForeground: slateblue4
277.16 +!Emacs.font-lock-function-name-face.attributeFont: 7x13bold
277.17 +!Emacs.font-lock-function-name-face.attributeFont: lucidasans-bold-14
277.18 +!Emacs.font-lock-function-name-face.attributeForeground: salmon
277.19 +
277.20 +XTerm*VT100.Background: gray85
277.21 +XTerm*VT100.Foreground: gray15
277.22 +XTerm*SaveLines: 1000
277.23 +Galeon*geometry: 600x600+0+0
277.24 +Netscape.TopLevelShell.geometry: =700x550+0+0
277.25 +Mozilla.TopLevelShell.geometry: =700x550+0+0
277.26 +Galeon.TopLevelShell.geometry: =700x550+0+0
277.27 +
277.28 +*customization: -color
277.29 +*VT100*colorBDMode: on
277.30 +
277.31 +*XTerm*color0: gray20
277.32 +*VT100*color1: IndianRed
277.33 +!*VT100*color2: green3
277.34 +*VT100*color2: aquamarine3
277.35 +*VT100*color3: pink4
277.36 +*VT100*color4: lightblue4
277.37 +*VT100*color5: magenta3
277.38 +!*VT100*color6: cyan3
277.39 +*VT100*color6: thistle
277.40 +*VT100*color7: lightyellow3
277.41 +*VT100*color8: gray30
277.42 +*VT100*color9: Red
277.43 +*VT100*color10: aquamarine4
277.44 +*VT100*color11: yellow2
277.45 +*VT100*color12: blue
277.46 +*VT100*color13: magenta
277.47 +!*VT100*color14: cyan
277.48 +*VT100*color14: navy
277.49 +!*VT100*color15: lightyellow3
277.50 +*VT100*colorUL: Brown
277.51 +*VT100*colorBD: navy
278.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
278.2 +++ b/usr/share/doc/isi/etc/skel/.alias Mon Apr 26 11:16:23 2010 +0200
278.3 @@ -0,0 +1,6 @@
278.4 +# $Id: .alias 23 2021-10-15 17:05:08Z root $
278.5 +# Luis Francisco Gonz�lez <[email protected]> based on that of Vadik Vygonets
278.6 +# Please check /usr/doc/tcsh/examples/alias to see other possible values.
278.7 +alias ls 'ls --color=auto'
278.8 +alias md mkdir
278.9 +alias rd rmdir
279.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
279.2 +++ b/usr/share/doc/isi/etc/skel/.bash_profile Mon Apr 26 11:16:23 2010 +0200
279.3 @@ -0,0 +1,24 @@
279.4 +# ~/.bash_profile: executed by bash(1) for login shells.
279.5 +# see /usr/share/doc/bash/examples/startup-files for examples.
279.6 +# the files are located in the bash-doc package.
279.7 +
279.8 +# the default umask is set in /etc/login.defs
279.9 +#umask 022
279.10 +
279.11 +# the rest of this file is commented out.
279.12 +
279.13 +# include .bashrc if it exists
279.14 +
279.15 +#if [ -f ~/.bashrc ]; then
279.16 +# source ~/.bashrc
279.17 +#fi
279.18 +
279.19 +# set PATH so it includes user's private bin if it exists
279.20 +#if [ -d ~/bin ] ; then
279.21 +# PATH=~/bin:"${PATH}"
279.22 +#fi
279.23 +
279.24 +# do the same with MANPATH
279.25 +#if [ -d ~/man ]; then
279.26 +# MANPATH=~/man:"${MANPATH}"
279.27 +#fi
280.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
280.2 +++ b/usr/share/doc/isi/etc/skel/.bashrc Mon Apr 26 11:16:23 2010 +0200
280.3 @@ -0,0 +1,41 @@
280.4 +# ~/.bashrc: executed by bash(1) for non-login shells.
280.5 +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
280.6 +# for examples
280.7 +
280.8 +# If running interactively, then:
280.9 +if [ "$PS1" ]; then
280.10 +
280.11 + # don't put duplicate lines in the history. See bash(1) for more options
280.12 + # export HISTCONTROL=ignoredups
280.13 +
280.14 + # enable color support of ls and also add handy aliases
280.15 + if [ "$TERM" != "dumb" ]; then
280.16 + eval `dircolors -b`
280.17 + alias ls='ls --color=auto'
280.18 + #alias dir='ls --color=auto --format=vertical'
280.19 + #alias vdir='ls --color=auto --format=long'
280.20 + fi
280.21 +
280.22 + # some more ls aliases
280.23 + #alias ll='ls -l'
280.24 + #alias la='ls -A'
280.25 + #alias l='ls -CF'
280.26 +
280.27 + # set a fancy prompt
280.28 + PS1='\u@\h:\w\$ '
280.29 +
280.30 + # If this is an xterm set the title to user@host:dir
280.31 + #case $TERM in
280.32 + #xterm*)
280.33 + # PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
280.34 + # ;;
280.35 + #*)
280.36 + # ;;
280.37 + #esac
280.38 +
280.39 + # enable programmable completion features (you don't need to enable
280.40 + # this, if it's already enabled in /etc/bash.bashrc).
280.41 + #if [ -f /etc/bash_completion ]; then
280.42 + # . /etc/bash_completion
280.43 + #fi
280.44 +fi
281.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
281.2 +++ b/usr/share/doc/isi/etc/skel/.bashrc-sd Mon Apr 26 11:16:23 2010 +0200
281.3 @@ -0,0 +1,38 @@
281.4 +# ~/.bashrc: executed by bash(1) for non-login shells.
281.5 +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
281.6 +# for examples
281.7 +
281.8 +# If running interactively, then:
281.9 +if [ "$PS1" ]; then
281.10 +
281.11 + # don't put duplicate lines in the history. See bash(1) for more options
281.12 + # export HISTCONTROL=ignoredups
281.13 +
281.14 + # enable color support of ls and also add handy aliases
281.15 + eval `dircolors -b`
281.16 + alias ls='ls --color=auto'
281.17 + #alias dir='ls --color=auto --format=vertical'
281.18 + #alias vdir='ls --color=auto --format=long'
281.19 +
281.20 + # some more ls aliases
281.21 + #alias ll='ls -l'
281.22 + #alias la='ls -A'
281.23 + #alias l='ls -CF'
281.24 +
281.25 + # set a fancy prompt
281.26 + PS1='\u@\h:\w\$ '
281.27 +
281.28 + # If this is an xterm set the title to user@host:dir
281.29 + #case $TERM in
281.30 + #xterm*)
281.31 + # PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
281.32 + # ;;
281.33 + #*)
281.34 + # ;;
281.35 + #esac
281.36 +
281.37 +fi
281.38 +
281.39 +[ -f /etc/bash.bashrc ] && . /etc/bash.bashrc
281.40 +
281.41 +
282.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
282.2 +++ b/usr/share/doc/isi/etc/skel/.cshrc Mon Apr 26 11:16:23 2010 +0200
282.3 @@ -0,0 +1,13 @@
282.4 +# $Id: .cshrc 23 2021-10-15 17:05:08Z root $
282.5 +# Luis Francisco Gonz�lez <[email protected]> based on that of Vadik Vygonets
282.6 +# Please check /usr/doc/tcsh/examples/cshrc to see other possible values.
282.7 +if ( $?prompt ) then
282.8 + set autoexpand
282.9 + set autolist
282.10 + set cdpath = ( ~ )
282.11 + set pushdtohome
282.12 +
282.13 +# Load aliases from ~/.alias
282.14 + if ( -e ~/.alias ) source ~/.alias
282.15 +
282.16 +endif
283.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
283.2 +++ b/usr/share/doc/isi/etc/skel/.emacs Mon Apr 26 11:16:23 2010 +0200
283.3 @@ -0,0 +1,395 @@
283.4 +;; FIRST: Do: M-x outline-minor-mode
283.5 +;; SECOND: try M-h too see the index of the file! (outline-minor-mode)
283.6 +; I don't know why it beahaves oddly if you force it w/ -*- line
283.7 +
283.8 +;;;; dir where to load & REMAPPING HELP!!! (C-h is to eat backword!!!)
283.9 +;; we add a dir where lo took for files when loading
283.10 +(setq load-path (cons "~/.emacsdir" load-path))
283.11 +(setq default-major-mode 'text-mode)
283.12 +
283.13 +;;;; Just for emacs21
283.14 +(if (string-equal "21" (substring (emacs-version) 10 12))
283.15 + (progn
283.16 + (blink-cursor-mode 0)
283.17 + ;; Insert newline when you press `C-n' (next-line)
283.18 + ;; at the end of the buffer
283.19 + (setq next-line-add-newlines t)
283.20 + ;; Turn on image viewing
283.21 + (auto-image-file-mode t)
283.22 + ;; Turn on menu bar (this bar has text)
283.23 + ;; (Use numeric argument to turn on)
283.24 + (menu-bar-mode 1)
283.25 + ;; Turn off tool bar (this bar has icons)
283.26 + ;; (Use numeric argument to turn on)
283.27 + (tool-bar-mode nil)
283.28 + ;; Turn off tooltip mode for tool bar
283.29 + ;; (This mode causes icon explanations to pop up)
283.30 + ;; (Use numeric argument to turn on)
283.31 + (tooltip-mode nil)
283.32 + ;; If tooltips turned on, make tips appear promptly
283.33 + (setq tooltip-delay 0.1) ; default is one second
283.34 + ))
283.35 +
283.36 +
283.37 +; (hscroll-global-mode nil)
283.38 +;;;; hilighting & fill
283.39 +;(server-start nil)
283.40 +;;(load-file "~/.emacs.elc")
283.41 +;; this remaps C-h -> C-xh
283.42 +(global-set-key "\C-xh" 'help-command) ;; overrides mark-whole-buffer
283.43 +(global-unset-key "\C-h" )
283.44 +; non perdere l' ultimo bit dell' input
283.45 +;(set-input-mode nil nil 1)
283.46 +;;;; look & feel: decoration & hiligting
283.47 +;; maximum decoration in hilighting
283.48 + (setq font-lock-maximum-decoration t)
283.49 + (global-font-lock-mode t)
283.50 +; auto-copress will correcly deal w/ tar.gz files (gunzip then tar t)
283.51 + (auto-compression-mode nil)
283.52 +;; autofill si ferma alla colonna 77
283.53 + (setq-default fill-column 76)
283.54 +;;;; Scrolling 1 row at a time
283.55 + (global-set-key "\C-z" (lambda () (interactive) (scroll-up 1)))
283.56 + (global-set-key "\M-z" (lambda () (interactive) (scroll-up -1)))
283.57 + (global-set-key "\C-h" 'delete-backward-char)
283.58 +;; C-u kill backward
283.59 + (global-set-key "\C-cu" [?\C- ?\C-a ?\C-w])
283.60 +;;;; Paren
283.61 + (require 'paren)
283.62 + (show-paren-mode 1)
283.63 +;;;; kill & yank / search & replace
283.64 +;; search & replace
283.65 + (global-set-key "\C-cr" 'query-replace-regexp)
283.66 +;;;; Font-Lock Mode - Add color to text moden
283.67 +; Here I add some colors for text mode (my default)
283.68 + (defvar text-font-lock-keywords
283.69 + (eval-when-compile
283.70 + (list
283.71 + ;;
283.72 + ;; Function name declarations.
283.73 +; '("\\<\\(proc\\|AA\-\\)\\>[ \t]*\\(\\sw+\\)?\\(.*\\)"
283.74 + '("^\\(#.*|\\)[ \t]*\\([A-z(){}._]+\\)?\\(.*\\)"
283.75 + (1 font-lock-comment-face) (2 font-lock-function-name-face nil t)
283.76 + (3 font-lock-keyword-face nil t))
283.77 + '("^\\s-*\\([-]\\S-*\\) +\\(\\sw+\\)" (1 font-lock-warning-face)
283.78 + (2 font-lock-keyword-face nil t))
283.79 + ; bold face for *words*
283.80 + '("\\s-\\(\\*[^*]+\\*\\)\\s-" . font-lock-string-face)
283.81 + ; italic face for _words*
283.82 + '("\\s-\\(\\_[^*]+\\*\\)\\s-" . font-lock-comment-face)
283.83 + ; title row for menu.lst in grub...
283.84 + '("^\\(title \\)\\(.*\\)"
283.85 + (1 font-lock-comment-face) (2 font-lock-function-name-face nil t))
283.86 + ;; NOTE: it is important the order of the lines defining color match
283.87 + ; the next colors a line beginning w/ >% but > is redefined below
283.88 + '("^\\(\\s-*>\\s-*>.*\\|%[^\n]*\\)" . font-lock-type-face)
283.89 + ; the next colors a line beginning w/ >>
283.90 + '("^\\(\\s-*>[^>\n]+\\)" . font-lock-comment-face)
283.91 + '("^\\([.']H +\\w+\\) \\(.+\\)" (1 font-lock-keyword-face)
283.92 + (2 font-lock-function-name-face nil t))
283.93 + ))
283.94 + "Default expressions to highlight in text mode.")
283.95 +
283.96 + (add-hook 'text-mode-hook
283.97 + (function (lambda ()
283.98 + (make-local-variable 'font-lock-defaults)
283.99 + (setq font-lock-defaults
283.100 + '(text-font-lock-keywords nil nil ))
283.101 +; questo pare non servire... (?: . "w") (?_ . "w")
283.102 + ; copiato senza capire gran che' da tcl-mode
283.103 +; (set-syntax-table (copy-syntax-table))
283.104 + (modify-syntax-entry ?# "<")
283.105 +; (modify-syntax-entry ?\n ">")
283.106 + (modify-syntax-entry ?| ">")
283.107 + (modify-syntax-entry ?\n ">")
283.108 +)))
283.109 + (add-hook 'tex-mode-hook
283.110 + (function (lambda ()
283.111 + (make-local-variable 'font-lock-defaults)
283.112 + (setq font-lock-defaults nil)
283.113 +)))
283.114 +
283.115 +
283.116 +;;;; Outline & related bind - use add-hooks for tcl, text, python, sh
283.117 + (set-variable (quote outline-minor-mode-prefix) (quote "\C-ch"))
283.118 + (require 'outline)
283.119 +;; (require 'allout)
283.120 +;; (outline-init t)
283.121 + (require 'foldout)
283.122 +; (outline-minor-mode t)
283.123 +; (require 'out-xtra)
283.124 +; (make-local-variable (quote outline-regexp))
283.125 +; (global-set-key "\C-chi" 'make-indirect-buffer)
283.126 +; (global-set-key "\C-chj" 'show-entry)
283.127 +; (global-set-key "\C-chb" 'show-branches)
283.128 +; (global-set-key "\C-chh" 'hide-sublevels)
283.129 + (global-set-key "\M-h" 'hide-sublevels)
283.130 + (global-set-key "\M-j" 'show-subtree)
283.131 + (global-set-key "\M-k" 'hide-subtree)
283.132 +; (global-set-key "\C-chk" 'hide-leaves)
283.133 +; (global-set-key "\C-ch2" 'make-indirect-buffer)
283.134 +; (global-set-key "\C-cht" 'hide-body)
283.135 +; (global-set-key "\C-cht" 'hide-body)
283.136 + (add-hook 'tcl-mode-hook
283.137 + (function
283.138 + (lambda ()
283.139 + (turn-on-follow-mode)
283.140 + (outline-minor-mode t)
283.141 +; (hscroll-mode t)
283.142 + (make-local-variable (quote outline-regexp))
283.143 + (setq outline-level 'outline-level)
283.144 + (set-variable (quote outline-regexp)
283.145 + (quote "proc\\|####?\\|# - #\\| +###\\| for\\| if ")))))
283.146 + (add-hook 'python-mode-hook
283.147 + (function
283.148 + (lambda ()
283.149 +; (turn-on-follow-mode)
283.150 + (outline-minor-mode t)
283.151 +; (hscroll-mode t)
283.152 + (make-local-variable (quote outline-regexp))
283.153 + (set-variable (quote outline-regexp)
283.154 + (quote " *def ..\\|####?\\|# - #\\|class")))))
283.155 + (add-hook 'text-mode-hook
283.156 + (function
283.157 + (lambda ()
283.158 + (turn-on-follow-mode)
283.159 + (outline-minor-mode t)
283.160 +; (set-variable (quote comment-start) (quote "# "))
283.161 + (set (make-local-variable 'comment-start) "# ")
283.162 + (set (make-local-variable 'comment-start-skip) "# *")
283.163 + (make-local-variable (quote outline-regexp))
283.164 + (set-variable (quote outline-regexp) (quote "\\.H *[0-9]")))))
283.165 + (add-hook 'sh-mode-hook
283.166 + (function
283.167 + (lambda ()
283.168 + (turn-on-follow-mode)
283.169 + (outline-minor-mode t)
283.170 + (setq outline-level 'sh-outline-level)
283.171 + (make-local-variable (quote outline-regexp))
283.172 + (set-variable (quote outline-regexp)
283.173 + (quote "### \\|func\\|.*()")))))
283.174 + (add-hook 'lisp-mode-hook
283.175 + (function
283.176 + (lambda ()
283.177 + (outline-minor-mode t))))
283.178 +; (make-local-variable (quote outline-regexp)))))
283.179 +
283.180 +
283.181 +
283.182 +;;;; functions
283.183 +;; this function forces all pattern of outline-regexp of a function to behave
283.184 +;; the same way, independent of thei length. Use it in cnjunction w/
283.185 +; -*- outline-regexp: "## # \\|.*()" -*-
283.186 +;; and all functions will be part of the "index" toghether w/ all the lines
283.187 +;; that have ## # at the beginning
283.188 +(defun sh-outline-level () 1)
283.189 +
283.190 +;; sst C-cs
283.191 +;; I repeat it twice so that colors get ok... this seem to depend on outline
283.192 +;; mode being requested by the -*- line at beginning!!!
283.193 +(fset 'sd-sost
283.194 + [?\C-a ?\C- ?\M-f escape ?1 escape ?| ?s ?s ?t return])
283.195 +; (fset 'sd-sost
283.196 +; [?\C-a ?\C- ?\M-f escape ?1 escape ?| ?s ?s ?t return])
283.197 + (global-set-key "\C-cs" 'sd-sost)
283.198 +;;;; EDIFF
283.199 + (global-set-key "\C-cer" 'ediff-revision)
283.200 + (global-set-key "\C-cef" 'ediff-files)
283.201 + (global-set-key "\C-ceb" 'ediff-buffers)
283.202 + (global-set-key "\C-cem" 'ediff-merge)
283.203 + (global-set-key "\C-ced" 'ediff-directories)
283.204 + ; the following position the control-frame for ediff 5 pixel lower than default
283.205 + (set-variable (quote ediff-control-frame-upward-shift) -5)
283.206 +;;;; Comment region
283.207 + (global-set-key "\C-cc" 'comment-region)
283.208 + (global-set-key "\C-cU" [escape ?- ?1 ?\C-c ?c])
283.209 + ; (global-set-key "\C-cu" '(comment-region -1))
283.210 +;;;; Text-mode - definig paragraph
283.211 +(add-hook 'text-mode-hook
283.212 + (function
283.213 + (lambda ()
283.214 + (set-variable (quote paragraph-start) "[ ]*$\\|^\\|^[ ]*-"))))
283.215 +
283.216 +;;;; TAGS
283.217 + (global-set-key "\C-ctv" 'visit-tags-table)
283.218 + (global-set-key "\C-ctr" 'tags-reset-tags-tables)
283.219 + (global-set-key "\C-cts" 'tags-search)
283.220 + (global-set-key "\C-ctq" 'tags-query-replace)
283.221 + (global-set-key "\C-cta" 'tags-apropos)
283.222 +;;;; MULE & iso-accent
283.223 +;; Sistemiamo MULE (internazionalizzazione)
283.224 + (standard-display-european t)
283.225 +; (set-input-mode nil nil 1)
283.226 + (load-library "iso-insert")
283.227 + (load-library "iso-acc")
283.228 + (add-hook 'text-mode-hook 'iso-accents-mode)
283.229 + ; Con la segg istruzione evito che // diventi �
283.230 +; (iso-accents-customize "french")
283.231 +; (iso-accents-customize "spanish")
283.232 + ;; non voglio che "a venga modificato: rinuncio anche alla dieresi: Tant pis
283.233 +(setq iso-accents-enable '(?' ?` ?^ ?~ ))
283.234 +;;;; Ispell (if .emacsdir is there)
283.235 +(if (file-exists-p "~/.emacsdir")
283.236 + (progn
283.237 + (require 'ispell)
283.238 + (load-library "ispell-patch.el")
283.239 + ; (setq ispell-dictionary-alist
283.240 + ; (append ispell-dictionary-alist
283.241 + ; '(("italian"
283.242 + ; "[A-Za-z]"
283.243 + ; "[^A-Za-z]"
283.244 + ; "[---']" t nil "~list" iso-8859-1))))
283.245 +
283.246 + (global-set-key "\C-cir" 'ispell-region)
283.247 + (global-set-key "\C-cib" 'ispell-buffer)
283.248 + (global-set-key "\C-cim" 'ispell-minor-mode)
283.249 + (global-set-key "\C-cid" 'ispell-change-dictionary)
283.250 + (global-set-key "\C-x\C-t" 'write-region)
283.251 + (set-default 'ispell-local-dictionary "italian-ge")))
283.252 +
283.253 +;;;; Misc: comint, repeat, goto...
283.254 + (add-hook 'text-mode-hook 'turn-on-auto-fill)
283.255 + ;; questo in origine e` C-x ESC ESC
283.256 + (global-set-key "\C-cx" 'repeat-complex-command)
283.257 + (global-set-key "\C-c " 'comint-dynamic-complete)
283.258 + (global-set-key "\C-\M-g" 'goto-line)
283.259 + (put 'downcase-region 'disabled nil)
283.260 +
283.261 + (setq auto-mode-alist
283.262 + (cons '("\\.py$" . python-mode) auto-mode-alist))
283.263 + (setq interpreter-mode-alist
283.264 + (cons '("python" . python-mode)
283.265 + interpreter-mode-alist))
283.266 + (autoload 'python-mode "python-mode" "Python editing mode." t)
283.267 + ;; psgml
283.268 + (autoload 'sgml-mode "psgml" "Major mode to edit SGML files." t)
283.269 + (autoload 'xml-mode "psgml" "Major mode to edit XML files." t)
283.270 +
283.271 +
283.272 +;;;; Desktop
283.273 + (load "desktop")
283.274 + (desktop-load-default)
283.275 + ; (desktop-read)
283.276 +;;;; ps-printing
283.277 + (setq ps-print-color-p t)
283.278 + ;; (setq ps-paper-type "a4")
283.279 + (set-variable (quote ps-paper-type) (quote a4))
283.280 + (setq ps-lpr-command "lpr")
283.281 + (setq ps-lpr-switches '("-Pfile"))
283.282 + (setq ps-bold-faces '(times))
283.283 + (setq ps-zebra-stripes t)
283.284 + (setq ps-build-face-reference t)
283.285 + (setq ps-zebra-stripe-height 4)
283.286 + (setq ps-line-number nil)
283.287 + (global-set-key "\C-cpb" 'ps-print-buffer-with-faces)
283.288 + (global-set-key "\C-cpr" 'ps-print-region-with-faces)
283.289 + (global-set-key "\C-cpxd" 'ps-despool)
283.290 + ;(global-set-key '(control f22) 'ps-despool)
283.291 +;;;; Latex & dvi
283.292 + (setq tex-dvi-view-command "tkdvi")
283.293 + ;(setq latex-run-command "lx -q")
283.294 + (setq latex-run-command "latex")
283.295 + ;;(setq tex-directory "./")
283.296 +;;;; custom set faces
283.297 +(custom-set-faces
283.298 + ;; custom-set-faces was added by Custom -- don't edit or cut/paste it!
283.299 + ;; Your init file should contain only one such instance.
283.300 + '(sh-heredoc-face ((((class color) (background light)) (:background "darkseagreen" :foreground "Navy")))))
283.301 +
283.302 +
283.303 +
283.304 +;;;; GNU Server
283.305 +(if (file-exists-p ".emacsdir/gnuserv")
283.306 + (progn
283.307 + (gnuserv-start)
283.308 + (global-set-key "\C-x\C-c" 'gnuserv-edit)))
283.309 +;(require 'preview)
283.310 +;;;; msb-mode - fancy buffer menu
283.311 +(msb-mode)
283.312 +(defconst msb--sd-many-menus
283.313 + '(((and (boundp 'server-buffer-clients)
283.314 + server-buffer-clients
283.315 + 'multi)
283.316 + 1010
283.317 + "Clients (%d)")
283.318 + ((and (boundp 'vc-mode) vc-mode 'multi)
283.319 + 1020
283.320 + "Version Control (%d)")
283.321 + ((and buffer-file-name
283.322 + (buffer-modified-p)
283.323 + 'multi)
283.324 + 1030
283.325 + "Changed files (%d)")
283.326 + ((and (get-buffer-process (current-buffer))
283.327 + 'multi)
283.328 + 1040
283.329 + "Processes (%d)")
283.330 + ((and msb-display-invisible-buffers-p
283.331 + (msb-invisible-buffer-p)
283.332 + 'multi)
283.333 + 1090
283.334 + "Invisible buffers (%d)")
283.335 + ((eq major-mode 'dired-mode)
283.336 + 2010
283.337 + "Dired (%d)"
283.338 + ;; Note this different menu-handler
283.339 + msb-dired-item-handler
283.340 + ;; Also note this item-sorter
283.341 + msb-sort-by-directory)
283.342 + ((eq major-mode 'Man-mode)
283.343 + 5030
283.344 + "Manuals (%d)")
283.345 + ((eq major-mode 'w3-mode)
283.346 + 5020
283.347 + "WWW (%d)")
283.348 + ((or (memq major-mode
283.349 + '(rmail-mode rmail-edit-mode vm-summary-mode vm-mode mail-mode))
283.350 + (memq major-mode '(mh-letter-mode mh-show-mode mh-folder-mode))
283.351 + (memq major-mode '(gnus-summary-mode message-mode gnus-group-mode
283.352 + gnus-article-mode score-mode
283.353 + gnus-browse-killed-mode)))
283.354 + 5010
283.355 + "Mail (%d)")
283.356 + ;; Catchup for all non-file buffers
283.357 + ((and (not buffer-file-name)
283.358 + 'no-multi)
283.359 + 5099
283.360 + "Other non-file buffers (%d)")
283.361 + ((and (string-match "/\\.[^/]*$" buffer-file-name)
283.362 + 'multi)
283.363 + 1080
283.364 + "Hidden Files (%d)")
283.365 + ((eq major-mode 'tcl-mode)
283.366 + 1071
283.367 + "Tcl Files (%d)")
283.368 + ((memq major-mode '(c-mode c++-mode))
283.369 + 3010
283.370 + "C/C++ Files (%d)")
283.371 + ((eq major-mode 'emacs-lisp-mode)
283.372 + 3020
283.373 + "Elisp Files (%d)")
283.374 + ((eq major-mode 'sh-mode)
283.375 + 3021
283.376 + "Shell Files (%d)")
283.377 + ((eq major-mode 'awk-mode)
283.378 + 3022
283.379 + "Awk Files (%d)")
283.380 + ((eq major-mode 'latex-mode)
283.381 + 3030
283.382 + "LaTex Files (%d)")
283.383 + ((eq major-mode 'nroff-mode)
283.384 + 3031
283.385 + "Nroff Files (%d)")
283.386 + ((eq major-mode 'text-mode)
283.387 + 3032
283.388 + "Text Files (%d)")
283.389 + ('no-multi
283.390 + 3099
283.391 + "Other files (%d)")))
283.392 +(custom-set-variables
283.393 + ;; custom-set-variables was added by Custom -- don't edit or cut/paste it!
283.394 + ;; Your init file should contain only one such instance.
283.395 + '(case-fold-search t)
283.396 + '(msb-display-most-recently-used 25)
283.397 + '(msb-max-menu-items 25)
283.398 + '(msb-menu-cond msb--sd-many-menus))
284.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
284.2 +++ b/usr/share/doc/isi/etc/skel/.xsession-sd Mon Apr 26 11:16:23 2010 +0200
284.3 @@ -0,0 +1,61 @@
284.4 +#!/bin/sh
284.5 +
284.6 +# Merge in defaults and keymaps
284.7 +
284.8 +# killall Xvnc
284.9 +# sleep 2
284.10 +# if [ "`pidof Xvnc`" = "" ]
284.11 +# then
284.12 +# /usr/bin/X11/Xvnc :1 -desktop X -httpd /usr/local/vnc/classes \
284.13 +# -alwaysshared \
284.14 +# -auth /.Xauthority -geometry 1024x768 \
284.15 +# -depth 24 -rfbwait 120000 -rfbauth /.vnc/passwd \
284.16 +# -rfbport 5901 &
284.17 +# sleep 5
284.18 +# fi
284.19 +
284.20 +userresources=$HOME/.Xresources
284.21 +usermodmap=$HOME/.Xmodmap
284.22 +sysmodmap=/etc/X11/Xmodmap
284.23 +
284.24 +if [ -f "$sysmodmap" ]; then xmodmap $sysmodmap; fi
284.25 +if [ -f "$userresources" ]; then xrdb -merge $userresources; fi
284.26 +if [ -f "$usermodmap" ]; then xmodmap $usermodmap; fi
284.27 +
284.28 +# turn mousekeys on and expiry (timeout) off
284.29 +if [ -f /usr/X11R6/bin/xkbse ] ; then
284.30 + xkbset m
284.31 + xkbset exp =m
284.32 + xmodmap -e "keycode 113 = Pointer_Button2"
284.33 + xmodmap -e "keycode 109 = Pointer_Button3"
284.34 + xmodmap -e "keycode 117 = Pointer_Button3"
284.35 +fi
284.36 +# this uses accessx
284.37 +# /home/local/bin/ax +mousekeys
284.38 +
284.39 +xmodmap -e "remove Lock = Caps_Lock"
284.40 +xmodmap -e "keycode 66 = grave asciitilde"
284.41 +
284.42 +PATH=$PATH:/usr/local/bin/X11
284.43 +MANPATH=`manpath`
284.44 +export MANPATH PATH
284.45 +
284.46 +#xauth extract - $DISPLAY | rsh remotehost /usr/bin/X11/xauth merge -
284.47 +
284.48 +xterm -geometry 80x43+1024+0 -T login -n login -ls -exec bash &
284.49 +xterm -geometry 80x43+1024+1536 -T Sotto -ls -exec bash &
284.50 +xterm -geometry 80x43+2048+1536 -T Sotto -ls -exec bash &
284.51 +
284.52 +# touch /tmp/ps
284.53 +# gv -geometry 1016x745+1024+768 /tmp/ps &
284.54 +
284.55 +xload -geometry 157x66+776+0 &
284.56 +rclock -bg gray90 -geometry 71x70-0+67 &
284.57 +xsysinfo -geometry 157x85+776+66 &
284.58 +
284.59 +xhost +bluff
284.60 +
284.61 +xsetroot -solid rgb:828f/43d9/43d9
284.62 +fvwm2 -f ~/.fvwm2rc
284.63 +
284.64 +#startkde
285.1 Binary file usr/share/doc/isi/etc/skel/public_html/immagini/bg_intro.jpg has changed
286.1 Binary file usr/share/doc/isi/etc/skel/public_html/immagini/folder.png has changed
287.1 Binary file usr/share/doc/isi/etc/skel/public_html/immagini/logo5.gif has changed
288.1 Binary file usr/share/doc/isi/etc/skel/public_html/immagini/tux.gif has changed
289.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
289.2 +++ b/usr/share/doc/isi/etc/skel/public_html/index.html Mon Apr 26 11:16:23 2010 +0200
289.3 @@ -0,0 +1,99 @@
289.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
289.5 +<html>
289.6 +<head>
289.7 + <meta http-equiv="content-type"
289.8 + content="text/html; charset=ISO-8859-1">
289.9 + <title>index</title>
289.10 +</head>
289.11 +<body
289.12 + style="background-image: url(file:///etc/skel/public_html/immagini/bg_intro.jpg);">
289.13 +<div style="text-align: center;"><big><big>Questa è la HOME PAGE
289.14 +del tuo web personale <br>
289.15 +</big></big><br>
289.16 +Essa si trova nella sottocartella speciale (invisibile da windows) <span
289.17 + style="font-weight: bold;">public_html</span> della tua home
289.18 +directory. <br>
289.19 +Per raggiungerla da qualunque macchina della rete basta utilizzare un
289.20 +browser e puntarlo all´indirizzo:<br>
289.21 +<big style="font-weight: bold; color: rgb(255, 0, 0);"><br>
289.22 +http://url_server/~nome_utente/index.html</big><br>
289.23 +Il carattere<big><big><big> <span style="color: rgb(255, 0, 0);">~</span>
289.24 +</big></big></big>(tilde) si ottiene sulle tastiere italiane delle
289.25 +macchine windows digitando la combinazione <br>
289.26 +<span style="font-weight: bold;">Alt126</span><br>
289.27 +(il numero 126 va composto sul tastierino numerico tenendo premuto il
289.28 +tasto ALT)<br>
289.29 +<br>
289.30 +Sei libero di modificarla come ti pare e di aggiungere tutte le pagine
289.31 +che vuoi ma dovrai rispettare strettamente le seguenti <a
289.32 + href="file:///avvertenze.html">avvertenze</a>.<br>
289.33 +<br>
289.34 +Puoi costruire pagine statiche HTML o dinamiche in PHP. Per
289.35 +facilitarti le cose, nella tua cartella personale, ti è stata
289.36 +preparata la seguente
289.37 +struttura che e' raggiungibile direttamente da <span
289.38 + style="font-weight: bold;">Risorse_del_computer, mioweb </span>ed e'
289.39 +vista come disco <span style="font-weight: bold;">W</span>.<br>
289.40 +Per pubblicare le tue pagine web ti basta quindi salvarle su <span
289.41 + style="font-weight: bold;">W:</span><br>
289.42 +<br>
289.43 +<table
289.44 + style="text-align: left; margin-left: auto; margin-right: auto; width: 80%;"
289.45 + border="1" cellspacing="2" cellpadding="2">
289.46 + <tbody>
289.47 + <tr>
289.48 + <td
289.49 + style="width: 25px; vertical-align: middle; text-align: center;"><img
289.50 + src="immagini/folder.png" alt="public_html"
289.51 + style="width: 22px; height: 19px;"><br>
289.52 + </td>
289.53 + <td
289.54 + style="width: 25px; vertical-align: middle; text-align: center;"><br>
289.55 + </td>
289.56 + <td
289.57 + style="vertical-align: middle; text-align: center; width: 60px;">public_html</td>
289.58 + <td style="vertical-align: top; width: 350px;">la directory
289.59 +radice del tuo sito
289.60 +personale (invisibile da windows) <span style="font-weight: bold;"></span><br>
289.61 + </td>
289.62 + </tr>
289.63 + <tr>
289.64 + <td style="vertical-align: middle; text-align: center;"><br>
289.65 + </td>
289.66 + <td
289.67 + style="width: 25px; vertical-align: middle; text-align: center;"><img
289.68 + style="width: 22px; height: 19px;" alt="public_html"
289.69 + src="immagini/folder.png"></td>
289.70 + <td
289.71 + style="vertical-align: middle; text-align: center; width: 60px;">immagini<br>
289.72 + </td>
289.73 + <td style="vertical-align: top; width: 350px;">tutte le immagini
289.74 +del sito<br>
289.75 + </td>
289.76 + </tr>
289.77 + <tr>
289.78 + <td style="vertical-align: middle; text-align: center;"><br>
289.79 + </td>
289.80 + <td
289.81 + style="width: 25px; vertical-align: middle; text-align: center;"><img
289.82 + style="width: 22px; height: 19px;" alt="public_html"
289.83 + src="immagini/folder.png"></td>
289.84 + <td
289.85 + style="vertical-align: middle; text-align: center; width: 60px;">templates<br>
289.86 + </td>
289.87 + <td style="vertical-align: top; width: 350px;">tutti i templates
289.88 +(al momento
289.89 +è vuota)<br>
289.90 + </td>
289.91 + </tr>
289.92 + </tbody>
289.93 +</table>
289.94 +<br>
289.95 +Buon divertimento!<br>
289.96 +<big><big><img src="immagini/tux.gif" alt="tux"
289.97 + style="width: 76px; height: 102px;"></big></big><br>
289.98 +<br>
289.99 +</div>
289.100 +<br>
289.101 +</body>
289.102 +</html>
290.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
290.2 +++ b/usr/share/doc/isi/etc/smbldap-tools/smbldap.conf Mon Apr 26 11:16:23 2010 +0200
290.3 @@ -0,0 +1,193 @@
290.4 +# $Source$
290.5 +# $Id: smbldap.conf 23 2021-10-15 17:05:08Z root $
290.6 +#
290.7 +# smbldap-tools.conf : Q & D configuration file for smbldap-tools
290.8 +
290.9 +# This code was developped by IDEALX (http://IDEALX.org/) and
290.10 +# contributors (their names can be found in the CONTRIBUTORS file).
290.11 +#
290.12 +# Copyright (C) 2001-2002 IDEALX
290.13 +#
290.14 +# This program is free software; you can redistribute it and/or
290.15 +# modify it under the terms of the GNU General Public License
290.16 +# as published by the Free Software Foundation; either version 2
290.17 +# of the License, or (at your option) any later version.
290.18 +#
290.19 +# This program is distributed in the hope that it will be useful,
290.20 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
290.21 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290.22 +# GNU General Public License for more details.
290.23 +#
290.24 +# You should have received a copy of the GNU General Public License
290.25 +# along with this program; if not, write to the Free Software
290.26 +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
290.27 +# USA.
290.28 +
290.29 +# Purpose :
290.30 +# . be the configuration file for all smbldap-tools scripts
290.31 +
290.32 +##############################################################################
290.33 +#
290.34 +# General Configuration
290.35 +#
290.36 +##############################################################################
290.37 +
290.38 +# Put your own SID
290.39 +# to obtain this number do: net getlocalsid
290.40 +SID="S-1-5-21-3440555123-2170259995-2169184781"
290.41 +##############################################################################
290.42 +#
290.43 +# LDAP Configuration
290.44 +#
290.45 +##############################################################################
290.46 +
290.47 +# Notes: to use to dual ldap servers backend for Samba, you must patch
290.48 +# Samba with the dual-head patch from IDEALX. If not using this patch
290.49 +# just use the same server for slaveLDAP and masterLDAP.
290.50 +# Those two servers declarations can also be used when you have
290.51 +# . one master LDAP server where all writing operations must be done
290.52 +# . one slave LDAP server where all reading operations must be done
290.53 +# (typically a replication directory)
290.54 +
290.55 +# Ex: slaveLDAP=127.0.0.1
290.56 +slaveLDAP="127.0.0.1"
290.57 +slavePort="389"
290.58 +
290.59 +# Master LDAP : needed for write operations
290.60 +# Ex: masterLDAP=127.0.0.1
290.61 +masterLDAP="127.0.0.1"
290.62 +masterPort="389"
290.63 +
290.64 +# Use TLS for LDAP
290.65 +# If set to 1, this option will use start_tls for connection
290.66 +# (you should also used the port 389)
290.67 +ldapTLS="0"
290.68 +
290.69 +# How to verify the server's certificate (none, optional or require)
290.70 +# see "man Net::LDAP" in start_tls section for more details
290.71 +#verify="require"
290.72 +
290.73 +# CA certificate
290.74 +# see "man Net::LDAP" in start_tls section for more details
290.75 +#cafile="/etc/smbldap-tools/ca.pem"
290.76 +
290.77 +# certificate to use to connect to the ldap server
290.78 +# see "man Net::LDAP" in start_tls section for more details
290.79 +#clientcert="/etc/smbldap-tools/smbldap-tools.pem"
290.80 +
290.81 +# key certificate to use to connect to the ldap server
290.82 +# see "man Net::LDAP" in start_tls section for more details
290.83 +#clientkey="/etc/smbldap-tools/smbldap-tools.key"
290.84 +
290.85 +# LDAP Suffix
290.86 +# Ex: suffix=dc=IDEALX,dc=ORG
290.87 +suffix="dc=isi,dc=lan"
290.88 +
290.89 +# Where are stored Users
290.90 +# Ex: usersdn="ou=People,dc=IDEALX,dc=ORG"
290.91 +usersdn="ou=People,dc=isi,dc=lan"
290.92 +
290.93 +# Where are stored Computers
290.94 +# Ex: computersdn="ou=Computers,dc=IDEALX,dc=ORG"
290.95 +computersdn="ou=Computers,dc=isi,dc=lan"
290.96 +
290.97 +# Where are stored Groups
290.98 +# Ex groupsdn="ou=Groups,dc=IDEALX,dc=ORG"
290.99 +groupsdn="ou=Groups,dc=isi,dc=lan"
290.100 +
290.101 +# Where are stored Idmap entries (used if samba is a domain member server)
290.102 +# Ex groupsdn="ou=Idmap,dc=IDEALX,dc=ORG"
290.103 +idmapdn="ou=Idmap,dc=isi,dc=lan"
290.104 +
290.105 +# Where to store next uidNumber and gidNumber available
290.106 +#sambaUnixIdPooldn="cn=NextFreeUnixId,${suffix}"
290.107 +sambaUnixIdPooldn="sambaDomainName=ISI-DOMAIN,dc=isi,dc=lan"
290.108 +
290.109 +# Default scope Used
290.110 +scope="sub"
290.111 +
290.112 +# Unix password encryption (CRYPT, MD5, SMD5, SSHA, SHA)
290.113 +hash_encrypt="SSHA"
290.114 +
290.115 +# if hash_encrypt is set to CRYPT, you may set a salt format.
290.116 +# default is "%s", but many systems will generate MD5 hashed
290.117 +# passwords if you use "$1$%.8s". This parameter is optional!
290.118 +crypt_salt_format="%s"
290.119 +
290.120 +##############################################################################
290.121 +#
290.122 +# Unix Accounts Configuration
290.123 +#
290.124 +##############################################################################
290.125 +
290.126 +# Login defs
290.127 +# Default Login Shell
290.128 +# Ex: userLoginShell="/bin/bash"
290.129 +userLoginShell="/bin/bash"
290.130 +
290.131 +# Home directory
290.132 +# Ex: userHome="/home/%U"
290.133 +userHome="/home/%U"
290.134 +
290.135 +# Gecos
290.136 +userGecos="System User"
290.137 +
290.138 +# Default User (POSIX and Samba) GID
290.139 +defaultUserGid="513"
290.140 +
290.141 +# Default Computer (Samba) GID
290.142 +defaultComputerGid="515"
290.143 +
290.144 +# Skel dir
290.145 +skeletonDir="/etc/skel"
290.146 +
290.147 +# Default password validation time (time in days) Comment the next line if
290.148 +# you don't want password to be enable for defaultMaxPasswordAge days (be
290.149 +# careful to the sambaPwdMustChange attribute's value)
290.150 +defaultMaxPasswordAge="99"
290.151 +
290.152 +##############################################################################
290.153 +#
290.154 +# SAMBA Configuration
290.155 +#
290.156 +##############################################################################
290.157 +
290.158 +# The UNC path to home drives location (%U username substitution)
290.159 +# Ex: \\My-PDC-netbios-name\homes\%U
290.160 +# Just set it to a null string if you want to use the smb.conf 'logon home'
290.161 +# directive and/or disable roaming profiles
290.162 +userSmbHome="\\ISI-PDC\%U"
290.163 +
290.164 +# The UNC path to profiles locations (%U username substitution)
290.165 +# Ex: \\My-PDC-netbios-name\profiles\%U
290.166 +# Just set it to a null string if you want to use the smb.conf 'logon path'
290.167 +# directive and/or disable roaming profiles
290.168 +userProfile="\\ISI-PDC\profiles"
290.169 +
290.170 +# The default Home Drive Letter mapping
290.171 +# (will be automatically mapped at logon time if home directory exist)
290.172 +# Ex: H: for H:
290.173 +userHomeDrive="H:"
290.174 +
290.175 +# The default user netlogon script name (%U username substitution)
290.176 +# if not used, will be automatically username.cmd
290.177 +# make sure script file is edited under dos
290.178 +# Ex: %U.cmd
290.179 +# userScript="startup.cmd" # make sure script file is edited under dos
290.180 +# userScript="%U.cmd"
290.181 +
290.182 +# Domain appended to the users "mail"-attribute
290.183 +# when smbldap-useradd -M is used
290.184 +mailDomain="isi.lan"
290.185 +
290.186 +##############################################################################
290.187 +#
290.188 +# SMBLDAP-TOOLS Configuration (default are ok for a RedHat)
290.189 +#
290.190 +##############################################################################
290.191 +
290.192 +# Allows not to use smbpasswd (if with_smbpasswd == 0 in smbldap_conf.pm) but
290.193 +# prefer Crypt::SmbHash library
290.194 +with_smbpasswd="0"
290.195 +smbpasswd="/usr/bin/smbpasswd"
290.196 +defaultComputerGid0="515"
291.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
291.2 +++ b/usr/share/doc/isi/etc/smbldap-tools/smbldap_bind.conf Mon Apr 26 11:16:23 2010 +0200
291.3 @@ -0,0 +1,12 @@
291.4 +############################
291.5 +# Credential Configuration #
291.6 +############################
291.7 +# Notes: you can specify two differents configuration if you use a
291.8 +# master ldap for writing access and a slave ldap server for reading access
291.9 +# By default, we will use the same DN (so it will work for standard Samba
291.10 +# release)
291.11 +slaveDN="cn=admin,dc=isi,dc=lan"
291.12 +slavePw="xxx"
291.13 +masterDN="cn=admin,dc=isi,dc=lan"
291.14 +masterPw="xxx"
291.15 +
292.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
292.2 +++ b/usr/share/doc/isi/etc/sudoers.isi Mon Apr 26 11:16:23 2010 +0200
292.3 @@ -0,0 +1,21 @@
292.4 +# sudoers file.
292.5 +#
292.6 +# This file MUST be edited with the 'visudo' command as root.
292.7 +#
292.8 +# See the sudoers man page for the details on how to write a sudoers file.
292.9 +#
292.10 +
292.11 +# Host alias specification
292.12 +
292.13 +# User alias specification
292.14 +User_Alias UPYAUTH = admin1, admin2
292.15 +
292.16 +# Cmnd alias specification
292.17 +
292.18 +Cmnd_Alias UPY = /usr/sbin/isi-users
292.19 +
292.20 +# User privilege specification
292.21 +root ALL=(ALL) ALL
292.22 +UPYAUTH ALL=(ALL) NOPASSWD: UPY
292.23 +
292.24 +
293.1 Binary file usr/share/doc/isi/grub4dos/win98/c/boot/grub/gpxe.iso has changed
294.1 Binary file usr/share/doc/isi/grub4dos/win98/c/grldr has changed
295.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
295.2 +++ b/usr/share/doc/isi/grub4dos/win98/c/menu.lst Mon Apr 26 11:16:23 2010 +0200
295.3 @@ -0,0 +1,15 @@
295.4 +color blue/white white/green white/blue white/blue
295.5 +timeout 10
295.6 +
295.7 +title gPXE (LTSP)
295.8 +find --set-root /boot/grub/gpxe.iso
295.9 +map /boot/grub/gpxe.iso (0xff) || map --mem /boot/grub/gpxe.iso (0xff)
295.10 +map --hook
295.11 +chainloader (0xff)
295.12 +
295.13 +title Windows 9x/Me
295.14 +find --set-root /io.sys
295.15 +chainloader /io.sys
295.16 +
295.17 +title halt
295.18 +halt
296.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
296.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/COPYING Mon Apr 26 11:16:23 2010 +0200
296.3 @@ -0,0 +1,340 @@
296.4 + GNU GENERAL PUBLIC LICENSE
296.5 + Version 2, June 1991
296.6 +
296.7 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
296.8 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
296.9 + Everyone is permitted to copy and distribute verbatim copies
296.10 + of this license document, but changing it is not allowed.
296.11 +
296.12 + Preamble
296.13 +
296.14 + The licenses for most software are designed to take away your
296.15 +freedom to share and change it. By contrast, the GNU General Public
296.16 +License is intended to guarantee your freedom to share and change free
296.17 +software--to make sure the software is free for all its users. This
296.18 +General Public License applies to most of the Free Software
296.19 +Foundation's software and to any other program whose authors commit to
296.20 +using it. (Some other Free Software Foundation software is covered by
296.21 +the GNU Library General Public License instead.) You can apply it to
296.22 +your programs, too.
296.23 +
296.24 + When we speak of free software, we are referring to freedom, not
296.25 +price. Our General Public Licenses are designed to make sure that you
296.26 +have the freedom to distribute copies of free software (and charge for
296.27 +this service if you wish), that you receive source code or can get it
296.28 +if you want it, that you can change the software or use pieces of it
296.29 +in new free programs; and that you know you can do these things.
296.30 +
296.31 + To protect your rights, we need to make restrictions that forbid
296.32 +anyone to deny you these rights or to ask you to surrender the rights.
296.33 +These restrictions translate to certain responsibilities for you if you
296.34 +distribute copies of the software, or if you modify it.
296.35 +
296.36 + For example, if you distribute copies of such a program, whether
296.37 +gratis or for a fee, you must give the recipients all the rights that
296.38 +you have. You must make sure that they, too, receive or can get the
296.39 +source code. And you must show them these terms so they know their
296.40 +rights.
296.41 +
296.42 + We protect your rights with two steps: (1) copyright the software, and
296.43 +(2) offer you this license which gives you legal permission to copy,
296.44 +distribute and/or modify the software.
296.45 +
296.46 + Also, for each author's protection and ours, we want to make certain
296.47 +that everyone understands that there is no warranty for this free
296.48 +software. If the software is modified by someone else and passed on, we
296.49 +want its recipients to know that what they have is not the original, so
296.50 +that any problems introduced by others will not reflect on the original
296.51 +authors' reputations.
296.52 +
296.53 + Finally, any free program is threatened constantly by software
296.54 +patents. We wish to avoid the danger that redistributors of a free
296.55 +program will individually obtain patent licenses, in effect making the
296.56 +program proprietary. To prevent this, we have made it clear that any
296.57 +patent must be licensed for everyone's free use or not licensed at all.
296.58 +
296.59 + The precise terms and conditions for copying, distribution and
296.60 +modification follow.
296.61 +
296.62 + GNU GENERAL PUBLIC LICENSE
296.63 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
296.64 +
296.65 + 0. This License applies to any program or other work which contains
296.66 +a notice placed by the copyright holder saying it may be distributed
296.67 +under the terms of this General Public License. The "Program", below,
296.68 +refers to any such program or work, and a "work based on the Program"
296.69 +means either the Program or any derivative work under copyright law:
296.70 +that is to say, a work containing the Program or a portion of it,
296.71 +either verbatim or with modifications and/or translated into another
296.72 +language. (Hereinafter, translation is included without limitation in
296.73 +the term "modification".) Each licensee is addressed as "you".
296.74 +
296.75 +Activities other than copying, distribution and modification are not
296.76 +covered by this License; they are outside its scope. The act of
296.77 +running the Program is not restricted, and the output from the Program
296.78 +is covered only if its contents constitute a work based on the
296.79 +Program (independent of having been made by running the Program).
296.80 +Whether that is true depends on what the Program does.
296.81 +
296.82 + 1. You may copy and distribute verbatim copies of the Program's
296.83 +source code as you receive it, in any medium, provided that you
296.84 +conspicuously and appropriately publish on each copy an appropriate
296.85 +copyright notice and disclaimer of warranty; keep intact all the
296.86 +notices that refer to this License and to the absence of any warranty;
296.87 +and give any other recipients of the Program a copy of this License
296.88 +along with the Program.
296.89 +
296.90 +You may charge a fee for the physical act of transferring a copy, and
296.91 +you may at your option offer warranty protection in exchange for a fee.
296.92 +
296.93 + 2. You may modify your copy or copies of the Program or any portion
296.94 +of it, thus forming a work based on the Program, and copy and
296.95 +distribute such modifications or work under the terms of Section 1
296.96 +above, provided that you also meet all of these conditions:
296.97 +
296.98 + a) You must cause the modified files to carry prominent notices
296.99 + stating that you changed the files and the date of any change.
296.100 +
296.101 + b) You must cause any work that you distribute or publish, that in
296.102 + whole or in part contains or is derived from the Program or any
296.103 + part thereof, to be licensed as a whole at no charge to all third
296.104 + parties under the terms of this License.
296.105 +
296.106 + c) If the modified program normally reads commands interactively
296.107 + when run, you must cause it, when started running for such
296.108 + interactive use in the most ordinary way, to print or display an
296.109 + announcement including an appropriate copyright notice and a
296.110 + notice that there is no warranty (or else, saying that you provide
296.111 + a warranty) and that users may redistribute the program under
296.112 + these conditions, and telling the user how to view a copy of this
296.113 + License. (Exception: if the Program itself is interactive but
296.114 + does not normally print such an announcement, your work based on
296.115 + the Program is not required to print an announcement.)
296.116 +
296.117 +These requirements apply to the modified work as a whole. If
296.118 +identifiable sections of that work are not derived from the Program,
296.119 +and can be reasonably considered independent and separate works in
296.120 +themselves, then this License, and its terms, do not apply to those
296.121 +sections when you distribute them as separate works. But when you
296.122 +distribute the same sections as part of a whole which is a work based
296.123 +on the Program, the distribution of the whole must be on the terms of
296.124 +this License, whose permissions for other licensees extend to the
296.125 +entire whole, and thus to each and every part regardless of who wrote it.
296.126 +
296.127 +Thus, it is not the intent of this section to claim rights or contest
296.128 +your rights to work written entirely by you; rather, the intent is to
296.129 +exercise the right to control the distribution of derivative or
296.130 +collective works based on the Program.
296.131 +
296.132 +In addition, mere aggregation of another work not based on the Program
296.133 +with the Program (or with a work based on the Program) on a volume of
296.134 +a storage or distribution medium does not bring the other work under
296.135 +the scope of this License.
296.136 +
296.137 + 3. You may copy and distribute the Program (or a work based on it,
296.138 +under Section 2) in object code or executable form under the terms of
296.139 +Sections 1 and 2 above provided that you also do one of the following:
296.140 +
296.141 + a) Accompany it with the complete corresponding machine-readable
296.142 + source code, which must be distributed under the terms of Sections
296.143 + 1 and 2 above on a medium customarily used for software interchange; or,
296.144 +
296.145 + b) Accompany it with a written offer, valid for at least three
296.146 + years, to give any third party, for a charge no more than your
296.147 + cost of physically performing source distribution, a complete
296.148 + machine-readable copy of the corresponding source code, to be
296.149 + distributed under the terms of Sections 1 and 2 above on a medium
296.150 + customarily used for software interchange; or,
296.151 +
296.152 + c) Accompany it with the information you received as to the offer
296.153 + to distribute corresponding source code. (This alternative is
296.154 + allowed only for noncommercial distribution and only if you
296.155 + received the program in object code or executable form with such
296.156 + an offer, in accord with Subsection b above.)
296.157 +
296.158 +The source code for a work means the preferred form of the work for
296.159 +making modifications to it. For an executable work, complete source
296.160 +code means all the source code for all modules it contains, plus any
296.161 +associated interface definition files, plus the scripts used to
296.162 +control compilation and installation of the executable. However, as a
296.163 +special exception, the source code distributed need not include
296.164 +anything that is normally distributed (in either source or binary
296.165 +form) with the major components (compiler, kernel, and so on) of the
296.166 +operating system on which the executable runs, unless that component
296.167 +itself accompanies the executable.
296.168 +
296.169 +If distribution of executable or object code is made by offering
296.170 +access to copy from a designated place, then offering equivalent
296.171 +access to copy the source code from the same place counts as
296.172 +distribution of the source code, even though third parties are not
296.173 +compelled to copy the source along with the object code.
296.174 +
296.175 + 4. You may not copy, modify, sublicense, or distribute the Program
296.176 +except as expressly provided under this License. Any attempt
296.177 +otherwise to copy, modify, sublicense or distribute the Program is
296.178 +void, and will automatically terminate your rights under this License.
296.179 +However, parties who have received copies, or rights, from you under
296.180 +this License will not have their licenses terminated so long as such
296.181 +parties remain in full compliance.
296.182 +
296.183 + 5. You are not required to accept this License, since you have not
296.184 +signed it. However, nothing else grants you permission to modify or
296.185 +distribute the Program or its derivative works. These actions are
296.186 +prohibited by law if you do not accept this License. Therefore, by
296.187 +modifying or distributing the Program (or any work based on the
296.188 +Program), you indicate your acceptance of this License to do so, and
296.189 +all its terms and conditions for copying, distributing or modifying
296.190 +the Program or works based on it.
296.191 +
296.192 + 6. Each time you redistribute the Program (or any work based on the
296.193 +Program), the recipient automatically receives a license from the
296.194 +original licensor to copy, distribute or modify the Program subject to
296.195 +these terms and conditions. You may not impose any further
296.196 +restrictions on the recipients' exercise of the rights granted herein.
296.197 +You are not responsible for enforcing compliance by third parties to
296.198 +this License.
296.199 +
296.200 + 7. If, as a consequence of a court judgment or allegation of patent
296.201 +infringement or for any other reason (not limited to patent issues),
296.202 +conditions are imposed on you (whether by court order, agreement or
296.203 +otherwise) that contradict the conditions of this License, they do not
296.204 +excuse you from the conditions of this License. If you cannot
296.205 +distribute so as to satisfy simultaneously your obligations under this
296.206 +License and any other pertinent obligations, then as a consequence you
296.207 +may not distribute the Program at all. For example, if a patent
296.208 +license would not permit royalty-free redistribution of the Program by
296.209 +all those who receive copies directly or indirectly through you, then
296.210 +the only way you could satisfy both it and this License would be to
296.211 +refrain entirely from distribution of the Program.
296.212 +
296.213 +If any portion of this section is held invalid or unenforceable under
296.214 +any particular circumstance, the balance of the section is intended to
296.215 +apply and the section as a whole is intended to apply in other
296.216 +circumstances.
296.217 +
296.218 +It is not the purpose of this section to induce you to infringe any
296.219 +patents or other property right claims or to contest validity of any
296.220 +such claims; this section has the sole purpose of protecting the
296.221 +integrity of the free software distribution system, which is
296.222 +implemented by public license practices. Many people have made
296.223 +generous contributions to the wide range of software distributed
296.224 +through that system in reliance on consistent application of that
296.225 +system; it is up to the author/donor to decide if he or she is willing
296.226 +to distribute software through any other system and a licensee cannot
296.227 +impose that choice.
296.228 +
296.229 +This section is intended to make thoroughly clear what is believed to
296.230 +be a consequence of the rest of this License.
296.231 +
296.232 + 8. If the distribution and/or use of the Program is restricted in
296.233 +certain countries either by patents or by copyrighted interfaces, the
296.234 +original copyright holder who places the Program under this License
296.235 +may add an explicit geographical distribution limitation excluding
296.236 +those countries, so that distribution is permitted only in or among
296.237 +countries not thus excluded. In such case, this License incorporates
296.238 +the limitation as if written in the body of this License.
296.239 +
296.240 + 9. The Free Software Foundation may publish revised and/or new versions
296.241 +of the General Public License from time to time. Such new versions will
296.242 +be similar in spirit to the present version, but may differ in detail to
296.243 +address new problems or concerns.
296.244 +
296.245 +Each version is given a distinguishing version number. If the Program
296.246 +specifies a version number of this License which applies to it and "any
296.247 +later version", you have the option of following the terms and conditions
296.248 +either of that version or of any later version published by the Free
296.249 +Software Foundation. If the Program does not specify a version number of
296.250 +this License, you may choose any version ever published by the Free Software
296.251 +Foundation.
296.252 +
296.253 + 10. If you wish to incorporate parts of the Program into other free
296.254 +programs whose distribution conditions are different, write to the author
296.255 +to ask for permission. For software which is copyrighted by the Free
296.256 +Software Foundation, write to the Free Software Foundation; we sometimes
296.257 +make exceptions for this. Our decision will be guided by the two goals
296.258 +of preserving the free status of all derivatives of our free software and
296.259 +of promoting the sharing and reuse of software generally.
296.260 +
296.261 + NO WARRANTY
296.262 +
296.263 + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
296.264 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
296.265 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
296.266 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
296.267 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
296.268 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
296.269 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
296.270 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
296.271 +REPAIR OR CORRECTION.
296.272 +
296.273 + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
296.274 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
296.275 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
296.276 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
296.277 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
296.278 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
296.279 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
296.280 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
296.281 +POSSIBILITY OF SUCH DAMAGES.
296.282 +
296.283 + END OF TERMS AND CONDITIONS
296.284 +
296.285 + How to Apply These Terms to Your New Programs
296.286 +
296.287 + If you develop a new program, and you want it to be of the greatest
296.288 +possible use to the public, the best way to achieve this is to make it
296.289 +free software which everyone can redistribute and change under these terms.
296.290 +
296.291 + To do so, attach the following notices to the program. It is safest
296.292 +to attach them to the start of each source file to most effectively
296.293 +convey the exclusion of warranty; and each file should have at least
296.294 +the "copyright" line and a pointer to where the full notice is found.
296.295 +
296.296 + <one line to give the program's name and a brief idea of what it does.>
296.297 + Copyright (C) 19yy <name of author>
296.298 +
296.299 + This program is free software; you can redistribute it and/or modify
296.300 + it under the terms of the GNU General Public License as published by
296.301 + the Free Software Foundation; either version 2 of the License, or
296.302 + (at your option) any later version.
296.303 +
296.304 + This program is distributed in the hope that it will be useful,
296.305 + but WITHOUT ANY WARRANTY; without even the implied warranty of
296.306 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
296.307 + GNU General Public License for more details.
296.308 +
296.309 + You should have received a copy of the GNU General Public License
296.310 + along with this program; if not, write to the Free Software
296.311 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
296.312 +
296.313 +
296.314 +Also add information on how to contact you by electronic and paper mail.
296.315 +
296.316 +If the program is interactive, make it output a short notice like this
296.317 +when it starts in an interactive mode:
296.318 +
296.319 + Gnomovision version 69, Copyright (C) 19yy name of author
296.320 + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
296.321 + This is free software, and you are welcome to redistribute it
296.322 + under certain conditions; type `show c' for details.
296.323 +
296.324 +The hypothetical commands `show w' and `show c' should show the appropriate
296.325 +parts of the General Public License. Of course, the commands you use may
296.326 +be called something other than `show w' and `show c'; they could even be
296.327 +mouse-clicks or menu items--whatever suits your program.
296.328 +
296.329 +You should also get your employer (if you work as a programmer) or your
296.330 +school, if any, to sign a "copyright disclaimer" for the program, if
296.331 +necessary. Here is a sample; alter the names:
296.332 +
296.333 + Yoyodyne, Inc., hereby disclaims all copyright interest in the program
296.334 + `Gnomovision' (which makes passes at compilers) written by James Hacker.
296.335 +
296.336 + <signature of Ty Coon>, 1 April 2022
296.337 + Ty Coon, President of Vice
296.338 +
296.339 +This General Public License does not permit incorporating your program into
296.340 +proprietary programs. If your program is a subroutine library, you may
296.341 +consider it more useful to permit linking proprietary applications with the
296.342 +library. If this is what you want to do, use the GNU Library General
296.343 +Public License instead of this License.
297.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
297.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/ChangeLog_GRUB4DOS.txt Mon Apr 26 11:16:23 2010 +0200
297.3 @@ -0,0 +1,572 @@
297.4 +2009-03-31(r66) 0.4.4 official release.
297.5 +2009-03-28 removed the problematic global variable "i"; reduced one open-file step for configfile on cdrom.
297.6 +2009-03-27 fixed memory overlap issue on "map --rehook".
297.7 +2009-03-25 disabled the search for DEFAULT file on cdrom(in cmain, stage2.c).
297.8 +2009-03-24 fixed problem of WRITE/DD on modifying internal variables. added dd options for user-defined buffer.
297.9 +2009-03-21 bug fix: turned errorcheck on in run_script and enter_cmdline.
297.10 +2009-03-20(r65) fixed `configfile not working in menu init command group'.
297.11 +2009-03-19 trying to fix problem of `configfile running slowly'.
297.12 +2009-03-18 fixed problem of `geometry-tune too slow' on vmware.
297.13 +2009-03-17 fixed endless loop problem while running "configfile (md)4+8".
297.14 +2009-03-15 added new option --sync for geometry command.
297.15 +2009-03-14 added new option --tune for geometry command.
297.16 +2009-03-12 rearranged preset-menu items.
297.17 +2009-03-11 changed geometry-tune code(aim to solve problem on vmware).
297.18 +2009-03-07 fixed a bug(in grldrstart.S) brought in since 2009-02-05.
297.19 +2009-03-03 fixed memory overflow issue with (rd). canceled restrictions on some disk write commands.
297.20 +2009-02-26 fixed geometry-tune issue(reportedly with Virtual PC).
297.21 +2009-02-21 changes made according to Simon's hiddenmenu patches.
297.22 +2009-02-20 documented the command line needed for chainloading stage2 of grub legacy.
297.23 +2009-02-19 now a range of drives can be unmapped.
297.24 +2009-02-18 possibility to run another menu.lst after gfxmenu.
297.25 +2009-02-17 fix graphics display issue generated last time.
297.26 +2009-02-15 improved color command to set color for help text and heading line.
297.27 +2009-02-13 fix problems booting Linux when there are mappings.
297.28 +2009-02-11 added ext4 support(in fsys_ext2fs.c).
297.29 +2009-02-09 isolinux.bin(version 3.73) gets chainloaded again.
297.30 +2009-02-08 Move some variables to a known address. The read command returns value at addess.
297.31 +2009-02-03 New initrd syntax loading multiple cpio files for Linux 2.6 kernels.
297.32 +2009-01-30 Supported per-menu-item help text.
297.33 +2009-01-28 Fixed printf issue. Allowed non-block files to be written with dd and write.
297.34 +2009-01-24 New syntax of WRITE support writing string to file.
297.35 +2009-01-16(r64) Added gfxmenu support
297.36 +2009-01-09 New commands dd and uuid. fixed a bug in disk emulation.
297.37 +2008-12-30 Work around for BIOSes lacking INT15/E820 support.
297.38 +2008-12-29(r63) Now the preset menu holds the highest priority. MSYS/MinGW support.
297.39 +2008-12-24 Added "detect" sub-command for the "pxe" command.
297.40 +2008-12-21 Fixed several bootlace bugs when running under DOS.
297.41 +2008-12-20 bootlace is now able to create triple MBR.
297.42 +2008-12-19 fixed problem of Disk Read Error on the last track.
297.43 +2008-12-16 under DOS bootlace can use a parameter file for its command-line arguments.
297.44 +2008-12-12 added a new option --chs-no-tune for bootlace.com.
297.45 +2008-12-07 workaround for buggy no-emulation-mode cdrom BIOSes.
297.46 +2008-12-04 fixed ext3 inode size issue on bootlace. fixed partition table check issue on bootlace.
297.47 +2008-12-03 cut off the MENU_BUF. removed the TESTLOAD command. added TITLES array.
297.48 +2008-12-01 added new program badgrub.exe. changed syntax of the find command.
297.49 +2008-11-19(r62) enable interrupt when DELAY. avoid disabling CPU cache in a20_test(a20.inc).
297.50 +2008-11-18p added STIs to better respond hardware interrupt(a20.inc, asm.S).
297.51 +2008-11-18 changed DELAY code(a20.inc). added JMPs in unreal mode for RAM disk emulation(asm.S).
297.52 +2008-11-15 loosened the check of the first FAT entry(fsys_fat.c). avoid using OUT instruction in DELAY(a20.inc).
297.53 +2008-11-11(r61) added --ignore-cd option for the find command.
297.54 +2008-11-08 read the boot file to determin the pxe block size. avoid running pxe_detect for non-pxe booting.
297.55 +2008-11-02 added a new option --mbr-no-bpb for bootlace.com.
297.56 +2008-11-01 changed PXE_MIN_BLKSIZE and PXE_MAX_BLKSIZE. allowed FAT cluster size larger than 32K.
297.57 +2008-10-26 fixed pxe block size issue.
297.58 +2008-10-21 fixed cylinder issue in int13/ah=8. Fixed stack conflict in bootlace.
297.59 +2008-10-17 added command line options --serial-number=SN and --restore-mbr to bootlace.
297.60 +2008-10-12 fixed a bug in fsys_fat.c causing FAT32 mount failure.
297.61 +2008-10-03 cancelled unnecessary initialisations for the root device.
297.62 +2008-10-02 improved int15 probing in probe_int.
297.63 +2008-10-01 before booting GRLDR, give the user a chance to boot previous mbr.
297.64 +2008-09-30 fixed a big bug in set_bootdev causing extra rawread executed and the geometry messed up.
297.65 +2008-09-29 fixed a big bug in get_diskinfo causing duplicate geometry calculation for each IO request on floppy.
297.66 +2008-09-27 fixed a new bug intrduced recently in get_diskinfo.
297.67 +2008-09-25 fixed an issue of uninitialised current_term in boot.c, causing the failure of the kernel command in graphics mode.
297.68 +2008-09-24 fixed the issue of "$BITMAP should be non-resident when in attribute list" in fsys_ntfs.c.
297.69 +2008-09-23 fixed virtual cdrom sector read issue(64K at a time) for a non-mem mapping.
297.70 +2008-09-21 added a new command "tpm --init".
297.71 +2008-09-21 fixed memory conflicts between graphics mode and linux kernel.
297.72 +2008-09-20 fixed a serious problem in grldrstart causing boot failure on FAT.
297.73 +2008-09-19 fixed a new bug intrduced last in get_diskinfo.
297.74 +2008-09-15 fixed a problem when different action occurs on a drive between chs and lba.
297.75 +2008-09-13 fixed a problem of reentering int13 handler from a virtual device on a real cdrom device driven by the builtin cdrom driver.
297.76 +2008-09-12 fixed an issue of whole cdrom mapping.
297.77 +2008-09-09 fixed virtual cdrom sector read issue when it is not a mem-mapping.
297.78 +2008-09-07 title delimitors(or comments) can be used in menu now.
297.79 +2008-08-27 save stack space occupation by the int13_handler.
297.80 +2008-08-26 fixed a bug relevant to iso emulation, causing disk read error.
297.81 +2008-08-24 save stack space occupation by the int13_handler.
297.82 +2008-08-14 enlarged stage2 stack space.
297.83 +2008-08-13 fixed again the bug on the root command.
297.84 +2008-08-12 fixed int5 in probe_int.
297.85 +2008-08-10 added a new command checkrange; fixed a bug on the root command.
297.86 +2008-08-08 added builtin stack for int13_handler to avoid stack overflow.
297.87 +2008-08-06 fixed a suspicious problem on the SCRATCH buffer in get_diskinfo.
297.88 +2008-08-04 fixed again error handling problem about operator && and ||; added STIs to better respond hardware interrupt.
297.89 +2008-08-03 fixed error handling problem about operator && and ||; grldr.mbr structure change; other small alterations.
297.90 +2008-07-28 added STIs to better respond hardware interrupt or to feed watchdog.
297.91 +2008-07-10(r60) let KEY_UP(KEY_DOWN) loop to the last(first) menu entry.
297.92 +2008-07-06 added backup_int13 and restore_int13 for a buggy usb bios f24a ver 1.00parttbl on compaq v5235tu(reporter: uleak). turn a20 debug on for memdrives.
297.93 +2008-06-28 fixed ext3-inode-size issue in grldr boot sector and bootlace.inc.
297.94 +2008-06-26 fixed int4C-4F in probe_int for Lenovo A6900.
297.95 +2008-06-24 fixed "256-byte ext3 inode size" issue in fsys_ext2fs.c.
297.96 +2008-06-23 added command ls.
297.97 +2008-06-22 disabled safe_int13 code for a buggy usb bios f24a ver 1.00parttbl on compaq v5235tu(reporter: uleak).
297.98 +2008-06-21 add A20 debug code to help locate a20 failure.
297.99 +2008-06-18 A20 test begins. Update version number to 0.4.4.
297.100 +2008-06-12 Let HIDE and UNHIDE respond with a message.
297.101 +2008-06-10 Let ROOT show correct filesystem info.
297.102 +2008-06-07 Let MAKEACTIVE and GEOMETRY show active partitions.
297.103 +2008-06-01 commented out the terminal-switching code in run_menu.
297.104 +2008-05-31 changed asm.S to avoid clearing out bss for the configfile command.
297.105 +2008-05-27 initialize saved_videomode/font8x16 for working across configfile.
297.106 +2008-05-25 fixed int76 in probe_int for a Tongfang.
297.107 +2008-05-22 fixed an issue of CPU cache wrongly disabled in GRUB.EXE for long.
297.108 +2008-05-21 fixed an issue of stack-overflow in real_get_cmdline.
297.109 +2008-05-17 enable the geometry_tune code for test only.
297.110 +2008-05-14 fix int5 and int8 in probe_int.
297.111 +2008-05-06 adjustment on probe_int for "pxe keep".
297.112 +2008-05-03 fixed problem on the commands setup and install.
297.113 +2008-05-02(r59) add new command checktime.
297.114 +2008-05-01 fixes on int vector probing, A20 control, configfile, find, etc.
297.115 +2008-03-14(r58) commented out the geometry-tune code. other fixes.
297.116 +2008-01-01(r57): mini build support
297.117 +2007-12-25(r56): created the test branch
297.118 +2007-12-25(r55) removed commands uppermem, ioprobe, impsprobe and displayapm.
297.119 +2007-12-14 test 3 of the geometry-tune.
297.120 +2007-12-10 cleanups on chainloader and errorcheck.
297.121 +2007-12-05 fixed a bug in ntfs file system module.
297.122 +2007-12-04 fixes on gzipped (rd) image support.
297.123 +2007-12-02 int13 emulation workaround for buggy BIOSes('Disk read error').
297.124 +2007-11-23 implemented cdrom emulation.
297.125 +2007-10-15(r54) version 0.4.3
297.126 +2007-10-08 implemented chainloading isolinux.
297.127 +2007-10-04 changed drive number of (md) to 0xffff.
297.128 +2007-10-02 reduced output messages for "debug off".
297.129 +2007-09-27 added a new map option of --a20-keep-on.
297.130 +2007-09-26 a workaround for buggy USB floppy BIOSes(hang at INT13/AH=48h).
297.131 +2007-08-27(r53) new notation () standing for the current root device.
297.132 +2007-08-26 new feature of root prefix for support of relative path.
297.133 +2007-08-25 fixed one more possible issue on A20.
297.134 +2007-08-24 fixed another possible issue on A20 for memdrives.
297.135 +2007-08-23 fixed a possible issue on A20 for memdrives.
297.136 +2007-08-21 expand memdrive size according to the probed CHS.
297.137 +2007-08-17 test A20 control for memory mapped disks.
297.138 +
297.139 + Updated code for hmload.
297.140 + Fixed a major problem of endless loop on enumeration of partitions.
297.141 + Fixed an issue in probe_mbr.
297.142 + Fixed a bug on compressed NTFS volume.
297.143 + Fixed a problem in probe_int by capturing int10.
297.144 +
297.145 +2007-07-25 version 0.4.3pre2
297.146 +
297.147 + Added a new command OUTLINE, and a new option --duce for GRUB.EXE.
297.148 + Changed PARTNEW syntax. Fixed a problem of OPEN_PARTITION.
297.149 + The arguments of PARTTYPE have changed to be optional.
297.150 +
297.151 + A Fault-Recovery-Handler was imposed on probe_int to fight against
297.152 + some very serious BIOS bugs(reportedly of DELL machines).
297.153 +
297.154 + The DEBUG command syntax was changed for verbosity control.
297.155 +
297.156 +2007-06-22 version 0.4.3pre1
297.157 +
297.158 + Fixed two problems on GRUB.EXE: preset_menu and FreeDOS related.
297.159 + Added a new command `hiddenflag'; Added BPB in GRLDR.MBR; Ignored the
297.160 + partition-ID check in filesystem modules; other fixes.
297.161 +
297.162 + PXE and NTFS fixes.
297.163 + Fixed a bug in probe_int for GRUB.EXE running in VM86 mode.
297.164 + Rewrite fsys_ntfs.c
297.165 + Fixed probe_int and init_pic in GRUB.EXE. Reduced warnings in bios.c.
297.166 + Added PXE support.
297.167 + NTFS code update for bootlace. Fixed timing functions.
297.168 + fix a bug in get_diskinfo; protect the MBR of an in-situ-mapped drive.
297.169 + Insert-key to debug on startup; polish graphics. NTFS boot record fix.
297.170 + Bugfixes on STAGE2_SIZE, arrow keys, and handling `&&'/`||' in menu.
297.171 + Move preset menu to the end/tail of pre_stage2.
297.172 + Numeric keys to select menu entry; fixed a bug of int13 harddrives.
297.173 + Code clean-ups on build script and keycode translation.
297.174 + F11/F12 hotkey handling.
297.175 + Added builtin NTFS boot sectors into GRLDR.
297.176 + Added 3 commands is64bit, errnum and errorcheck.
297.177 + Applied Robert Millan's patch of check_64bit.
297.178 + Implemented two syntactic operators `&&' and `||'.
297.179 + Added a new option --in-situ for the map command.
297.180 +
297.181 + Fixed an auto-probe-int problem of GRUB.EXE under "EMM386 noems".
297.182 +
297.183 + Workaround for buggy VirtualPC on a issue of floppy-emulation-mode
297.184 + bootable CDROM.
297.185 +
297.186 +2006-12-28 version 0.4.2
297.187 +
297.188 + Fixed a bug hidden deeply in memcheck.
297.189 + Fixed a bug hidden deeply in get_diskinfo.
297.190 + Fixed a bug in load_image.
297.191 + GRLDR(as a no-emulation-mode bootable CDROM image) was adapted to
297.192 + cope with some buggy BIOSes(e.g., VirtualPC).
297.193 + Added LBA-to-CHS geometry translation(in int13_handler) to simulate
297.194 + LBA(EBIOS)-enabled drives on CHS-only drives.
297.195 + Added a new feature of Unconditional Command-line Entrance.
297.196 + Applied Beverly Brown's patch to load_initrd.
297.197 + Added two new options to the map command to better serve Win9x.
297.198 + The default config file search path for GRUB.EXE was changed to
297.199 + (DOS file) .\menu.lst and then (DOS file) \menu.lst and then
297.200 + (GRUB file) /menu.lst.
297.201 + Other bug fixes.
297.202 +
297.203 +2006-10-24 version 0.4.2pre11
297.204 +
297.205 + Made a workaround for buggy USB-bootable board QDI 848E.
297.206 + Made a workaround for buggy 965 board with SATA CDROM connected.
297.207 +
297.208 +2006-10-07 version 0.4.2pre10
297.209 +
297.210 + Fixed a problem in GRUB shell which causes failure in grub-install.
297.211 + Enabled GRUB.EXE to run under FreeDOS with memdrives in use.
297.212 + Implemented an auto-probe mechanism to support all kinds of DOSes.
297.213 +
297.214 +2006-09-19 version 0.4.2pre9
297.215 +
297.216 + Resolved several problems:
297.217 + 1. (about kexec)Dropped the problematic kexec-tools-1.101-patch.
297.218 + 2. (about stack)Adjusted code in C files to use less stack.
297.219 + 3. (about cdrom)Fixed a few bugs in the cdrom driver.
297.220 +
297.221 +2006-08-29 version 0.4.2pre8
297.222 +
297.223 + Added a new command `setvbe'.
297.224 + Dropped the obsolete EZ-BIOS(with signature `AERMH') support.
297.225 + Fixed a bug in parsing Rock-Ridge extension.
297.226 + No-emulation-mode Bootable CD can be chainloaded now.
297.227 + Some work was done to improve remote/diskless boot.
297.228 + Fixed one more USB/Floppy EBIOS problem(in get_diskinfo).
297.229 + Merged protected mode stack into real mode stack at 0x2000.
297.230 + Code clean-up.
297.231 +
297.232 +2006-07-31 version 0.4.2pre7
297.233 +
297.234 + Imported ATAPI CDROM driver from Smart Boot Manager.
297.235 +
297.236 + Dropped the previous implementation of SCDROM/BIOSCDROM.
297.237 +
297.238 + Fixed a USB/Floppy EBIOS problem that could cause media access failure
297.239 + or even hang the machine when using USB storage devices.
297.240 +
297.241 + Fixed a bug in BOOTLACE.COM that had improperly set the LBA indicator
297.242 + byte(which is at offset 0x02 of the boot sector).
297.243 +
297.244 + Fixed a bug in GRLDR that caused failure in finding the associated
297.245 + MENU.LST config-file(which should be in the same directory as GRLDR).
297.246 +
297.247 +2006-06-18 version 0.4.2pre6
297.248 +
297.249 + Dropped the obsolete EZD disk map support.
297.250 + Fixed several bugs that may hang or slow the qemu virtual machine.
297.251 + Fixed a bug that causes the pause command not to respond any key-press.
297.252 + Fixed a bug that causes a command to accidentally fail if in a menu.
297.253 + Fixed a bug that causes the menu not to work once a cdrom had booted.
297.254 +
297.255 +2006-06-05 version 0.4.2pre5
297.256 +
297.257 + Added a static-linked binary executable file GRUB(a Linux utility).
297.258 +
297.259 + Fixed a gateA20 problem related to memdrive emulation.
297.260 +
297.261 + Boot GRUB.EXE directly off Windows9x/Me(experimental; might hang).
297.262 +
297.263 +2006-04-03 version 0.4.2pre4
297.264 +
297.265 + Made GRUB.EXE run under EMM386.
297.266 + Fixed a bug in splashimage_func().
297.267 + Made `ignore error' constant and removed the `--ignore-error' option,
297.268 + and renamed the option `--seconds=T' to `--wait=T' for savedefault.
297.269 + The sample menu.lst was modified accordingly.
297.270 +
297.271 +2006-03-28 version 0.4.2pre3
297.272 +
297.273 + New syntax for the `default' and `savedefault' commands was
297.274 + implemented.
297.275 +
297.276 + Changed `int' to `unsigned long' for filemax, filepos and fsmax, and
297.277 + modified all fsys_*.c files in order to open large files(2GB or
297.278 + longer).
297.279 +
297.280 +2006-03-09 version 0.4.2pre2
297.281 +
297.282 + The directory `boot/grub/' was removed from the release tree(GRUB4DOS
297.283 + does not use the stage files at boot time). The default config file for
297.284 + GRUB.EXE was changed to (hd0,0)/menu.lst(but preset_menu still locates
297.285 + (hd0,0)/boot/grub/menu.lst when (hd0,0)/menu.lst does not exist).
297.286 +
297.287 + Added DOS command-line options --bypass, --time-out=T and --hot-key=K
297.288 + for GRUB.EXE.
297.289 +
297.290 +2006-02-24 version 0.4.2pre1
297.291 + gcc-4 support by VirusCamp.
297.292 +
297.293 + Limited support for returning to DOS from GRUB.EXE.
297.294 +
297.295 + Implemented a new feature that GRUB.EXE can be used as a DOS device
297.296 + driver and be started in CONFIG.SYS with a DEVICE line.
297.297 +
297.298 + Better IODELAY was made for initialization of PIC to fix the
297.299 + keyboard-not-responding problem when running through KEXEC.
297.300 +
297.301 + Better A20 gate control was made to help fix various problems on the
297.302 + boot of grub.
297.303 +
297.304 +2005-12-14 version 0.4.1
297.305 + Fixed a partition enumeration bug(in disk_io.c). Fixed a bug of mapping
297.306 + partitions to harddrives(in builtins.c). Fixed a bug that causes
297.307 + failure when `find --set-root' on a CD-ROM device(in builtins.c). Added
297.308 + a new feature of directly chainloading ntldr and some dos kernels.
297.309 +
297.310 +2005-11-14 version 0.4.1pre32
297.311 + Fixed more bugs.
297.312 +
297.313 +2005-11-02 version 0.4.1pre31
297.314 + A few bugs were fixed.
297.315 +
297.316 +2005-10-23 version 0.4.1pre30
297.317 + A bug about "bootlace.com --floppy" was fixed.
297.318 +
297.319 +2005-10-18 version 0.4.1pre29
297.320 + Added ram disk device (rd) to access, typically, the initrd image.
297.321 + Added many new command-line options for bootlace.com to install GRLDR
297.322 + boot record onto the boot sector of a floppy. A few bugs about
297.323 + "map --mem" were fixed. Another bug about finding grldr in NTFS was
297.324 + also fixed. It may cause the machine to hang up when there is no ntfs
297.325 + boot record in the boot area of the NTFS partition.
297.326 +
297.327 +2005-09-25 version 0.4.1pre28
297.328 + Commandline option --config-file="FILENAME_OR_RAW_COMMANDS" was added
297.329 + for GRUB.EXE where GRUB.EXE is treated as a Linux kernel.
297.330 + Fixed a bug which causes installation failure when BOOTLACE.COM is
297.331 + used for large disks.
297.332 +
297.333 +2005-09-21 version 0.4.1pre27
297.334 + Added a patch to the kexec-tools-1.101. Kexec might fail to load
297.335 + grub.exe without this patch.
297.336 +
297.337 +2005-09-14 version 0.4.1pre26
297.338 + Fixed a bug for the DOS part of BOOTLACE.COM
297.339 +
297.340 +2005-09-11 version 0.4.1pre25
297.341 + GRUB4LIN has merged into GRUB.EXE; A new command-line option
297.342 + --read-only was added for BOOTLACE.COM; A few bug fixes.
297.343 +
297.344 +2005-09-01 version 0.4.1pre24
297.345 + BOOTLACE.COM runs under both DOS and Linux.
297.346 +
297.347 +2005-08-27 version 0.4.1pre23
297.348 + Added a utility BOOTLACE.COM for installing grldr bootstrap code to MBR
297.349 +
297.350 +2005-07-30 version 0.4.1pre22
297.351 + Added bootstrap file GRLDR.MBR for launching grldr from MBR.
297.352 +
297.353 +2005-07-24 version 0.4.1pre21
297.354 + Added Windows NT 4.0 support(actually fixed a bug reported by Stefan
297.355 + Baur). For other new features, see README.txt.
297.356 +
297.357 +2005-07-20 version 0.4.1pre20
297.358 + Added ext2/ext3 boot record code for loading grldr from the beginning
297.359 + sector of a floppy or a partition.
297.360 +
297.361 +2005-05-25 version 0.4.1pre5
297.362 + GRUB commands can be embedded into the command line of GRUB.EXE
297.363 +
297.364 +2005-05-20 version 0.4.1pre4
297.365 + Bug fixes: When the system has no floppies, some operations,
297.366 + e.g., the find command, will hang the machine.
297.367 +
297.368 +2005-05-17 version 0.4.1pre3
297.369 + Search for cdrom_drive from drive 0x88 to drive 0xff
297.370 +
297.371 +2005-05-11 version 0.4.1pre2
297.372 + Our base is now upgraded to GNU GRUB 0.97.
297.373 +
297.374 +2005-04-25 version 0.4.1pre
297.375 + Fixed a bug reported by Gilles van Ruymbeke
297.376 + <[email protected]> <[email protected]>:
297.377 +
297.378 + The map_func improperly opened the emulation image for 3 times, that
297.379 + might slow down the load speed heavily, especially for gzipped files.
297.380 +
297.381 +2005-04-15 version 0.4.0
297.382 + Add /boot/grub/menu.lst in preset menu. This is final.
297.383 +
297.384 +2005-04-07 version 0.4.0pre7
297.385 + config_file takes precedence over preset_menu.
297.386 +
297.387 +2005-04-06 version 0.4.0pre6
297.388 + GRLDR can be used with no-emulation-mode bootable CD-ROM.
297.389 +
297.390 +2005-03-09 version 0.4.0pre4
297.391 + Now preset menu find /menu.lst, no longer support /boot/grub/menu.lst
297.392 +
297.393 + Partition images can emulate a partition (hd?,0) with --mem option.
297.394 +
297.395 +2005-03-02 version 0.4.0pre3
297.396 + GRLDR startup code search all partitions in all harddrives for GRLDR.
297.397 +
297.398 + chainloader can boot images larger than 512 bytes, and can load image
297.399 + to a different location than 0000:7C00.
297.400 +
297.401 +2005-02-06 version 0.4.0pre
297.402 + Switched to GNU GRUB 0.96
297.403 + The --mem option of MAP command was added for memdrive emulation.
297.404 +
297.405 + Also announced 0.2.0 final.
297.406 +
297.407 +2004-10-23 version 0.2.0pre13
297.408 + GRUB.EXE runs in DOSBOX.
297.409 + GRUB4LIN is introduced to boot off LINUX.
297.410 + Fixed a bug reported by windrv: NTFS check contiguity failure
297.411 + Rearranged the patches.
297.412 +
297.413 +2004-08-31 version 0.2.0pre12
297.414 + Fixed a bug reported by szwp: cannot load GRLDR on partition that is
297.415 + not CHS-accessible.
297.416 +
297.417 + Fixed a bug reported by windrv: take too much time to check contiguity
297.418 +
297.419 +2004-08-15 version 0.2.0pre11
297.420 + Mark the scdrom module as experimental.
297.421 +
297.422 +2004-07-13 version 0.2.0pre9
297.423 + Merged GNU GRUB 0.95
297.424 +
297.425 + BOOTGRUB removed. Use BOOT.INI line C:\GRLDR="Start GRUB" instead.
297.426 +
297.427 + Patches from Gandalf: NTFS and ATAPI CDROM support(also thanks to
297.428 + Tobias Svensson <[email protected]>)
297.429 +
297.430 + Patches from Chris Semler <[email protected]>: findroot
297.431 +
297.432 +2004-04-12 version 0.2.0pre6
297.433 + Now GRUB.EXE can be used in CONFIG.SYS this way:
297.434 +
297.435 + shell=C:\some\where\grub.exe --config-file=(hd0,0)/boot/grub/menu.lst
297.436 +
297.437 + or
297.438 +
297.439 + shell=C:\some\where\grub.exe
297.440 +
297.441 + No other changes.
297.442 +
297.443 +2004-04-09 version 0.2.0pre5
297.444 + Now BOOTGRUB contains 4 sectors, i.e., 2048 bytes. Optionally, you may
297.445 + copy the 2nd, 3rd and 4th sectors of BOOTGRUB to the three sectors that
297.446 + immediately follow the MBR. Also Optionally, you may copy 446 bytes
297.447 + from the very beginning of BOOTGRUB to the very beginning of MBR. In
297.448 + this way, the GRLDR can be started out of MBR, without the presence of
297.449 + NTLDR.
297.450 +
297.451 + CAUTION: Don't copy 512 bytes to MBR. The partition table should not
297.452 + be overwritten. The partition table is in the end of MBR. If you make
297.453 + a mistake, you will lose your whole system!!
297.454 +
297.455 +2004-02-18 version 0.2.0pre4
297.456 + Arbitrary-size floppy and hard disk emulation finally implemented.
297.457 + GRUB for NTLDR is included. See README file.
297.458 + Splash image version is available in the SPLASH directory.
297.459 +
297.460 +2003-09-23 version 0.1.4 -- development unstable release
297.461 + Unfortunately 0.1.3 has an ugly bug. Fixed.
297.462 +
297.463 +2003-09-01 version 0.1.3 -- development unstable release
297.464 + Rewrite the code for guessing FreeDOS int vectors. Hopefully it works
297.465 + for all the future versions of FreeDOS :-)
297.466 +
297.467 +2003-08-25 version 0.1.2 -- development unstable release
297.468 + Fixed a small bug that affects the read of the emulated floppy sectors.
297.469 +
297.470 + Added some files (including the menu.lst file) for installing GRUB to
297.471 + MBR from DOS. Usage:
297.472 +
297.473 + Copy the boot directory to C:\ ; You must do this on Windows, NOT dos,
297.474 + because DOS cannot deal with the long filenames.
297.475 +
297.476 + Run grub to access the menu.lst file in C:\boot\grub ; Of cause on DOS.
297.477 +
297.478 + When menu occurs, select a proper menu item for installing GRUB to MBR.
297.479 +
297.480 + If the menu does not appear, you should get the "grub>" prompt. At the
297.481 + prompt, type the following commands:
297.482 +
297.483 + grub> configfile (hd0,1)/boot/grub/menu.lst
297.484 + grub> configfile (hd0,2)/boot/grub/menu.lst
297.485 + grub> configfile (hd0,3)/boot/grub/menu.lst
297.486 +
297.487 + Then, the menu should occur.
297.488 +
297.489 +2003-06-29 version 0.1.0.1 -- development unstable release
297.490 + Do some cleanups on 0.1.0, no important changes.
297.491 + BTW, it seems that the 0.1.0 is quite stable :-)
297.492 +
297.493 +2003-06-29 version 0.0.8
297.494 + Restore mapped int13 to the unmapped state while grub is invoked
297.495 + after a previously performed drive map operation.
297.496 +
297.497 +2003-05-29 version 0.1.0 -- development unstable release
297.498 + Floppy 1.44M drive emulation are OK. GOOD!!!! Usage:
297.499 +
297.500 + # boot Windows 98 SE
297.501 + map (hd1,0)/dos98se.img (fd0)
297.502 + chainloader (hd1,0)/dos98se.img
297.503 + rootnoverify (fd0)
297.504 + boot
297.505 +
297.506 + Another example:
297.507 +
297.508 + # boot Mandrake hard disk installer
297.509 + map (hd0,0)/hd.img (fd0)
297.510 + chainloader (hd0,0)/hd.img
297.511 + rootnoverify (fd0)
297.512 + boot
297.513 +
297.514 + Note that the floppy image file must size 1440KB, i.e., 1474560 bytes.
297.515 + _AND_ also, the file must consist of one contiguous disk area, no
297.516 + holes, no fragments. Use GRUB's blocklist command to determine whether
297.517 + or not an image file is contiguous. It is known that a 1440KB-file is
297.518 + always non-contiguous if it resides in an ext2 filesystem. But you may
297.519 + get a 1440KB contiguous file with an FAT32 partition(vfat filesystem).
297.520 +
297.521 + Floppy(and hard disk) with arbitrary sizes will be emulated in the
297.522 + future.
297.523 +
297.524 +2003-05-06 version 0.0.7
297.525 +
297.526 + Fixed a huge bug!! Read the following carefully!
297.527 +
297.528 + Using the drive map command(just as many distributions currently do)
297.529 +
297.530 + map TO_DRIVE FROM_DRIVE
297.531 +
297.532 + to boot your system could seriously _damage_ your hard disk data,
297.533 +
297.534 + totally and thoroughly!! This bug has just been fixed in 0.0.7 :-)
297.535 +
297.536 + This bug is not specific to grub_for_dos, but caused by the original
297.537 +
297.538 + grub-0.93 release. So do _NOT_ use map command any more until my fix is
297.539 +
297.540 + accepted by GRUB maintainers or a similar fix is made by other
297.541 +
297.542 + people. For now, do _NOT_ use map command in any kind of Linux
297.543 +
297.544 + distributions such as Red Hat or Mandrake or any others.
297.545 +
297.546 + Because GRUB_FOR_DOS-0.0.7 already applied the fix, so it
297.547 +
297.548 + should be safe to use the map command.
297.549 +
297.550 + Another small bug was also fixed in grub_for_dos-0.0.7 :-)
297.551 +
297.552 +2003-04-29 version 0.0.6
297.553 + Runs also on MS-DOS 3.30. No other changes.
297.554 +
297.555 +2003-04-26 version 0.0.5
297.556 + Runs on MS-DOS 4.0, 5.0, 6.0, 6.20, 6.21, 6.22, 7.0, 7.10, 8.0 and
297.557 + FreeDOS(build 2029). GOOD!!
297.558 +
297.559 +2003-04-20 version 0.0.4
297.560 + Running on FreeDOS(build 2029), GOOD!! (But currently GRUB.EXE only
297.561 + has limited FreeDOS support, maybe unstable.)
297.562 +
297.563 + Add a "Guess DOS Version" feature. The program now exit to DOS when
297.564 + guess failed. The previous versions of GRUB.EXE always hang when
297.565 + running on an unsupported DOS version.
297.566 +
297.567 +2003-04-13 version 0.0.3
297.568 + The option "--config-file=FILE" was added.
297.569 +
297.570 +2003-04-11 version 0.0.2
297.571 + Also runs on MS-DOS 8.0 (i.e., the DOS with WinMe/2000/XP), GOOD!!
297.572 + The GRUB.PIF file included, so GRUB.EXE can be started from Windows 9x
297.573 +
297.574 +2003-04-10 version 0.0.1
297.575 + Runs on MS-DOS 7.10(Win98)
298.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
298.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/README_GRUB4DOS.txt Mon Apr 26 11:16:23 2010 +0200
298.3 @@ -0,0 +1,3864 @@
298.4 +Please refer to http://grub4dos.sourceforge.net/wiki/ for DOCs on GRUB4DOS.
298.5 +
298.6 +Main project page: https://gna.org/projects/grub4dos/
298.7 +
298.8 +Download site: http://download.gna.org/grub4dos/
298.9 +Download site: http://grub4dos.sourceforge.net/
298.10 +Download site: http://sarovar.org/projects/grub4dos/
298.11 +Download site: http://grub4dos.nufans.net/
298.12 +Download site: http://sites.google.com/site/grubdos/
298.13 +Download site: ftp://grub4dos.sarovar.org/pub/grub4dos/
298.14 +
298.15 +Get the latest source code by using anonymous svn in this way:
298.16 +
298.17 + svn co svn://svn.gna.org/svn/grub4dos/trunk grub4dos
298.18 +
298.19 +or in this way:
298.20 +
298.21 + svn co http://svn.gna.org/svn/grub4dos/trunk grub4dos
298.22 +
298.23 +View the source code online with your web browser at:
298.24 +
298.25 + http://svn.gna.org/viewcvs/grub4dos/trunk/
298.26 +
298.27 +GRUB4DOS mailing list:
298.28 +
298.29 + [email protected]
298.30 +
298.31 +Subscription page:
298.32 +
298.33 + https://mail.gna.org/listinfo/grub4dos-devel/
298.34 +
298.35 +Discussion forum(Official technical support site):
298.36 +
298.37 + http://www.boot-land.net/forums/index.php?showforum=66
298.38 +
298.39 +------------------------------------------------------------------------------
298.40 +
298.41 +Usage:
298.42 + GRUB [--bypass] [--time-out=T] [--hot-key=K] [--config-file=FILE]
298.43 +
298.44 + The FILE, for example, can be (hd0,0)/menu.lst
298.45 +
298.46 + In CONFIG.SYS, the line looks like:
298.47 +
298.48 + install=c:\some\where\grub.exe --config-file=FILE
298.49 +
298.50 + If no options present, GRUB.EXE simply uses
298.51 +
298.52 + (hd0,0)/menu.lst
298.53 +
298.54 + as the configure file, if it exists. (Notice! We finally
298.55 + changed the default file from (hd0,0)/boot/grub/menu.lst to
298.56 + (hd0,0)/menu.lst) (Changed 2006-12-23. See Update 3 below.)
298.57 +
298.58 + The partition (hd0,0) can be of a Windows partition or a Linux
298.59 + partition, or any other partition type supported by GRUB.
298.60 +
298.61 + Only GRUB-style filename is acceptable here for FILE. A DOS
298.62 + filename won't work(it is certain we should use GRUB-style
298.63 + filenames because DOS-filenames won't access a file in a
298.64 + Linux ext2 partition for example).(See Update 2 below)
298.65 +
298.66 + Update: FILE can be the contents of a menu. Use semi-colon
298.67 + to delimitate the embedded commands here in FILE. The FILE
298.68 + can be enclosed with a pair of double-quotes. For example:
298.69 +
298.70 + GRUB --config-file="root (hd0,0);chainloader +1"
298.71 +
298.72 + This command will boot the system in (hd0,0).
298.73 +
298.74 + Another example:
298.75 +
298.76 + GRUB --config-file="reboot"
298.77 +
298.78 + This command will reboot the machine.
298.79 +
298.80 + One more example:
298.81 +
298.82 + GRUB --config-file="halt"
298.83 +
298.84 + This command will halt the machine.
298.85 +
298.86 + if --bypass is specified, GRUB will exit to DOS when
298.87 + timeout reached.
298.88 +
298.89 + The option `--time-out=T' specifies the timeout value in
298.90 + seconds. T defaults to 5 if --bypass is specified and defaults
298.91 + to 0 if --bypass is not specified.
298.92 +
298.93 + The default hot key value is 0x3920(for space bar). If this
298.94 + key is pressed, GRUB will boot normally. If another key is
298.95 + pressed, GRUB will terminate immediately and return back to
298.96 + DOS. See "int 16 keyboard scan codes" below.
298.97 +
298.98 + Each option can be specified only once at most.
298.99 +
298.100 + Update 2: DOS filenames have been supported(patched by John
298.101 + Cobb). If the beginning two characters of FILE are "#@", then
298.102 + the rest of FILE is taken as a DOS filename. Example:
298.103 +
298.104 + GRUB --config-file="#@c:\menu.lst"
298.105 +
298.106 + Only the beginning 4KB of the DOS file will be used. The file
298.107 + should be an uncompressed text file.
298.108 +
298.109 + Note: You may also use the `direct DOS file access' with the
298.110 + SHELL or INSTALL line in CONFIG.SYS, but should not use it
298.111 + with the DEVICE line. The DOS document said that a DOS device
298.112 + driver should not call the `open file' DOS call.
298.113 +
298.114 + Update 3(2021-12-23): By default, GRUB.EXE will locate its
298.115 + config file in the following order:
298.116 +
298.117 + (DOS file) .\menu.lst, the MENU.LST in the current dir.
298.118 +
298.119 + (DOS file) \menu.lst, the MENU.LST in the root dir of
298.120 + the current drive.
298.121 + (GRUB file) /menu.lst, the MENU.LST in the root dir of
298.122 + the boot device.
298.123 +
298.124 + The default boot device is still (hd0,0).
298.125 +
298.126 +
298.127 +--------------------------------------------------------
298.128 +
298.129 +Update 1: Version 0.2.0 also brings out a new thing, GRUB for NTLDR,
298.130 + which could be used to boot into GRUB from the boot menu
298.131 + of Windows NT/2000/XP. Copy GRLDR to the root directory of
298.132 + drive C: of Windows NT/2000/XP and append to C:\BOOT.INI
298.133 + this line:
298.134 +
298.135 + C:\GRLDR="Start GRUB"
298.136 +
298.137 + That will be done. The GRLDR should be in the same directory
298.138 + as BOOT.INI and NTLDR. Note that BOOT.INI is usually hidden
298.139 + and you must unhide it before you can see it. The filename
298.140 + GRLDR shouldn't be changed. If GRLDR is in a NTFS partition,
298.141 + it should be copied to the root directory of another non-NTFS
298.142 + partition(and likewise should the menu.lst file be). If GRLDR
298.143 + is compressed, e.g., in a NTFS partition, it will not work.
298.144 +
298.145 + Even if the drive letter of this disk has been changed to
298.146 + other than C by the Windows device manager, it seems you still
298.147 + have to use the letter C here in BOOT.INI, otherwise, NTLDR
298.148 + will fail to locate the GRLDR file.
298.149 +
298.150 + And what's more, if you are booting NTLDR from a floppy, you
298.151 + will have to write the GRLDR line in A:\BOOT.INI like this:
298.152 +
298.153 + C:\GRLDR="Start GRUB"
298.154 +
298.155 + and shouldn't use the letter A like this:
298.156 +
298.157 + A:\GRLDR="Start GRUB"
298.158 +
298.159 + (Note that in the case when BOOT.INI is on floppy A, the
298.160 + notation "C:\GRLDR" actually refer to the file A:\GRLDR).
298.161 +
298.162 +
298.163 +Update 2: GRUB for Linux is also introduced along with 0.2.0. You can
298.164 + boot grub using a linux loader KEXEC, LILO, SYSLINUX or another
298.165 + GRUB. (GRUB4LIN has merged into GRUB.EXE)
298.166 +
298.167 + To boot GRUB off Linux, use this pair of commands:
298.168 +
298.169 + kexec -l grub.exe
298.170 + kexec -e
298.171 +
298.172 + To boot GRUB via GRUB, use commands like the following:
298.173 +
298.174 + kernel (hd0,0)/grub.exe
298.175 + boot
298.176 +
298.177 + To boot GRUB via LILO, use these lines in lilo.conf:
298.178 +
298.179 + image=/boot/grub.exe
298.180 + label=grub.exe
298.181 +
298.182 + To boot GRUB via SYSLINUX, use these lines in syslinux.cfg:
298.183 +
298.184 + label grub.exe
298.185 + kernel grub.exe
298.186 +
298.187 + LOADLIN may encounter problems when loading grub.exe, because
298.188 + grub.exe requires some unchanged original BIOS interrupt
298.189 + vectors, but DOS has destroyed them, and loadlin does not
298.190 + recover them before it transfers control to grub.exe.
298.191 +
298.192 +Update 3: Beginning at version 0.4.0, GRUB for DOS supports memdrives.
298.193 + Example:
298.194 +
298.195 + # boot into a floppy image
298.196 + map --mem (hd0,0)/floppy.img (fd0)
298.197 + map --hook
298.198 + chainloader (fd0)+1
298.199 + rootnoverify (fd0)
298.200 + map --floppies=1
298.201 + boot
298.202 +
298.203 + Because the image will be copied to a memory area, the image
298.204 + itself can be non-contiguous and even gzipped.
298.205 +
298.206 + Another Example:
298.207 +
298.208 + map --mem=-2880 (hd0,0)/floppy.img (fd0)
298.209 +
298.210 + This memdrive (fd0) will occupy at least 1440 KB of memory.
298.211 + This is useful when the size of a 1.44M-floppy image is less
298.212 + than 1440 KB.
298.213 +
298.214 + One more example:
298.215 +
298.216 + map --mem --read-only (hd0,0)/hd.img (hd1)
298.217 +
298.218 + This memdrive is a hard drive, and read-only. That means you
298.219 + will not be able to write data to the memdrive (hd1).
298.220 +
298.221 + You can use many memdrives and many ordinary virtual emulated
298.222 + disk-based drives at the same time.
298.223 +
298.224 + If the BIOS does not support int15/EAX=e820h, you will not be
298.225 + able to use any memdrives.
298.226 +
298.227 +Update 4: For memdrive emulation, a single-partition image can be used
298.228 + instead of a whole-harddrive image. Example:
298.229 +
298.230 + map --mem (hd0,7)/win98.img (hd0)
298.231 + map --hook
298.232 + chainloader (hd0)+1
298.233 + rootnoverify (hd0)
298.234 + map --harddrives=1
298.235 + boot
298.236 +
298.237 + Here win98.img is a partition image without the leading MBR
298.238 + and partition table in it. Surely GRUB for DOS will build an
298.239 + MBR and partition table for the memdrive (hd0).
298.240 +
298.241 +Update 5: Now GRLDR can be used as a no-emulation-mode bootable CD-ROM
298.242 + boot image. Example for Linux users:
298.243 +
298.244 + mkdir iso_root
298.245 + cp grldr iso_root
298.246 + mkisofs -R -b grldr -no-emul-boot -boot-load-seg 0x1000 -o bootable.iso iso_root
298.247 +
298.248 + As an alternative, grldr can also be used the same way as
298.249 + stage2_eltorito. The -boot-info-table option is allowed but you
298.250 + can omit it:
298.251 +
298.252 + mkdir iso_root
298.253 + cp grldr iso_root
298.254 + mkisofs -R -b grldr -no-emul-boot -boot-load-size 4 -o grldr.iso iso_root
298.255 +
298.256 + Also note that the bootable.iso above must be created with the
298.257 + -boot-load-seg 0xHHHH option where HHHH is greater than or
298.258 + equal to 1000(hex). If HHHH < 1000(hex), QEMU will hang. This
298.259 + is a bug in QEMU. The grldr.iso can be created with or without
298.260 + -boot-load-seg 0xHHHH option.
298.261 +
298.262 + The menu.lst file should be placed in the root dir of the CD.
298.263 +
298.264 +Update 6: The Chinese special build is in the "chinese" subdirectory.
298.265 + (patched by Gandalf, 2021-06-27)
298.266 +
298.267 + The Chinese special build also has scdrom builtin.
298.268 + (update: scdrom has been dropped since 2021-07-20)
298.269 +
298.270 +Update 7: Added memory drive (md). Like (nd) for network drive and (cd)
298.271 + for CD-ROM drive, a new drive (md) is implemented for accessing
298.272 + the whole memory as a disk drive. (md) only works for systems
298.273 + with BIOS int15/EAX=E820h support.
298.274 +
298.275 + The cat command now has a few new options: --hex for hexdump,
298.276 + and --locate=STRING for string search in file.
298.277 +
298.278 + Typical examples:
298.279 +
298.280 + cat --hex (hd0)+1
298.281 +
298.282 + It will display the MBR sector in hex form.
298.283 +
298.284 + cat --hex (md)+2
298.285 +
298.286 + It will display 1KB of your memory(in fact, it is the real-mode
298.287 + IDT table), also in hexdump form.
298.288 +
298.289 + cat --hex (md)0x800+1
298.290 +
298.291 + It will display 1 sector of your extended memory.
298.292 +
298.293 + cat --hex (hd0,0)+1
298.294 +
298.295 + It will display the first sector of partition (hd0,0). Usually
298.296 + this sector contains the boot record of an operating system.
298.297 +
298.298 +Update 8: Added ram drive (rd). The (md) device accesses the memory
298.299 + starting at physical address 0. But (rd) accesses memory
298.300 + starting at any base address. The base and length of the ram
298.301 + drive can be specified through the map command. "help map" for
298.302 + details. You can even specify the BIOS drive number used for
298.303 + the (rd) drive, e.g., map --ram-drive=0xf0. The default drive
298.304 + number for (rd) is 0x7F which is a floppy. If (rd) is a hard
298.305 + drive image, you should change the drive number to a value
298.306 + greater than or equal to 0x80(but should avoid using 0xffff,
298.307 + because 0xffff is for the (md) device).
298.308 +
298.309 + The notation (rd)+1 always represents the file which contains
298.310 + all the bytes stored in (rd).
298.311 +
298.312 +Update 9: Directly boot NTLDR of WinNT/2K/XP and IO.SYS of Win9x/ME and
298.313 + KERNEL.SYS of FreeDOS. Examples:
298.314 +
298.315 + chainloader --edx=0xPPYY (hd0,0)/ntldr
298.316 + boot
298.317 +
298.318 + chainloader --edx=0xYY (hd0,0)/io.sys
298.319 + boot
298.320 +
298.321 + chainloader --ebx=0xYY (hd0,0)/kernel.sys
298.322 + boot
298.323 +
298.324 + Hex YY specifies the boot drive number, and hex PP specifies
298.325 + the boot partition number of NTLDR. If the boot drive is
298.326 + floppy, PP should be the hex value ff, i.e., decimal 255.
298.327 +
298.328 + For KERNEL.SYS of FreeDOS, the --edx won't work,
298.329 + use --ebx please.
298.330 +
298.331 + The option --edx ( --ebx ) can be omitted if the file is in
298.332 + its normal place. But in some cases, those options are needed.
298.333 +
298.334 + If, e.g., the ntldr file is in an ext2 partition called
298.335 + (hd2,8) while you want it to think of the Windows partition
298.336 + (hd0,7) as the boot partition, then --edx is required:
298.337 +
298.338 + chainloader --edx=0x0780 (hd2,8)/ntldr
298.339 +
298.340 + For DOS kernels(i.e., IO.SYS and KERNEL.SYS), the boot
298.341 + partition number is meaningless, so you only need to specify
298.342 + the correct boot drive number YY(but specifying the boot
298.343 + partition number is harmless).
298.344 +
298.345 + The above PPYY can also be specified by using a root or
298.346 + rootnoverify command after the chainloader command. Examples:
298.347 +
298.348 + chainloader (hd2,6)/kernel.sys
298.349 + rootnoverify (hd0) <-------- YY=80
298.350 + boot
298.351 +
298.352 + chainloader (hd0,0)/ntldr
298.353 + rootnoverify (hd0,5) <-------- YY=80, PP=05
298.354 + boot
298.355 +
298.356 + Tip: CMLDR (the ComMand LoaDeR, which is used to load the
298.357 + Windows Fault Recovery Console) can be chainloaded as well
298.358 + as NTLDR.
298.359 +
298.360 + Bean has successfully decompressed and booted IO.SYS of WinME.
298.361 + Thanks for the great job!
298.362 +
298.363 +Update 10: isolinux.bin (version 3.73) can be chainloaded as with build
298.364 + 2009-02-09.
298.365 +
298.366 + chainloader (cd)/isolinux.bin
298.367 +
298.368 + isolinux.bin must reside in a real or virtual cdrom.
298.369 +
298.370 +Update 11: stage2 of Grub Legacy can be chainloaded in this way:
298.371 +
298.372 + chainloader --force --load-segment=0 --load-offset=0x8000 --boot-cs=0 --boot-ip=0x8200 (...)/.../stage2
298.373 +
298.374 +--------------------------------------------------------
298.375 +
298.376 + There is no full documentation in English at present. Here are some
298.377 + examples showing the usage of disk emulation commands:
298.378 +
298.379 +1. Emulates HD partition C: as floppy drive A: and boot win98 from C:
298.380 +
298.381 + map --read-only (hd0,0)+1 (fd0)
298.382 + chainloader (hd0,0)+1
298.383 + rootnoverify (hd0)
298.384 + boot
298.385 +
298.386 + In the above example, (hd0,0) is drive C: with win98 on it. After win98
298.387 + boot complete, you will find that A: contains all files of C:, and if
298.388 + you delete files in A:, the files in C: will also disappear.
298.389 +
298.390 + At the map command line, the notation (hdm,n)+1 is interpreted to
298.391 + represent the whole partition (hdm,n), not just the first sector of the
298.392 + partition.
298.393 +
298.394 +2. Emulates HD partition C: as floppy drive A: and boot win98 from A:
298.395 +
298.396 + map --read-only (hd0,0)+1 (fd0)
298.397 + map --hook
298.398 + chainloader (fd0)+1
298.399 + rootnoverify (fd0)
298.400 + map --floppies=1
298.401 + boot
298.402 +
298.403 + After the "map --hook" command, the emulation takes effect instantly
298.404 + even in the GRUB command line.
298.405 +
298.406 + Note that the (fd0) in "chainloader (fd0)+1" is the emulated virtual
298.407 + floppy A:, not the real floppy diskette(because map is hooked now).
298.408 +
298.409 +
298.410 +3. Emulates an image file as floppy drive A: and boot win98 from C:
298.411 +
298.412 + map --read-only (hd0,0)/floppy.img (fd0)
298.413 + chainloader (hd0,0)+1
298.414 + rootnoverify (hd0)
298.415 + map --floppies=1
298.416 + map --harddrives=1
298.417 + boot
298.418 +
298.419 +4. Emulates an HD partition as the first hard disk and boot DOS from it:
298.420 +
298.421 + map --read-only (hd2,6)+1 (hd0)
298.422 + map --hook
298.423 + chainloader (hd0,0)+1
298.424 + rootnoverify (hd0)
298.425 + map --harddrives=1
298.426 + boot
298.427 +
298.428 + In this example, (hd2,6)+1 represents an extended logical DOS partition
298.429 + of the third BIOS hard disk (hd2).
298.430 +
298.431 + If a DOS partition is used to emulate a hard disk, GRUB for DOS will
298.432 + first try to locate the partition table, usually 63 sectors ahead of
298.433 + the DOS partition. GRUB for DOS will refuse the emulation if the
298.434 + partition table is not there.
298.435 +
298.436 +5. Emulates an image file as the first hard disk and boot DOS from it:
298.437 +
298.438 + map --read-only (hd0,0)/harddisk.img (hd0)
298.439 + chainloader --load-length=512 (hd0,0)/harddisk.img
298.440 + rootnoverify (hd0)
298.441 + map --harddrives=1
298.442 + boot
298.443 +
298.444 + If an image file is used to emulate a hard disk, the image file must
298.445 + contain an MBR. In other word, the first sector of HARDDISK.IMG must
298.446 + contain the partition table of the emulated virtual hard disk.
298.447 +
298.448 +Note: Counters for floppies and harddrives in the BIOS Data Area remain
298.449 + unchanged during the mapping. You should manually set them to proper
298.450 + values with `map --floppies=' and/or `map --harddrives=', especially,
298.451 + e.g., when there is no real floppy drive attached to the mother board.
298.452 + If not doing so, DOS might fail to start.
298.453 +
298.454 + `map --status' can report the values. Note also that `map --floppies='
298.455 + and `map --harddrives=' can be used independently without the
298.456 + appearance of mappings.
298.457 +
298.458 + 0.4.2 has introduced a new variable, memdisk_raw, to simulate the
298.459 + memdisk-like raw mode. If the BIOS has no int15/87h, or if it has
298.460 + buggy int15/87h support, you should set this variable before any
298.461 + memdrives are used. Here is an example:
298.462 +
298.463 + map --memdisk-raw=1
298.464 + map --mem (hd0,0)/floppy.img (fd0)
298.465 + map --hook
298.466 + chainloader (fd0)+1
298.467 + rootnoverify (fd0)
298.468 + boot
298.469 +
298.470 + If you encountered a memdrive failure without using
298.471 + map --memdisk-raw=1, you should have a try with `map --memdisk-raw=1'.
298.472 +
298.473 + If you `map --memdisk-raw=0' later, you should afterwards do a
298.474 + `map --unhook'(and followed by a `map --hook' if needed).
298.475 +
298.476 + Update: memdisk_raw now defaults to 1. You should `map --memdisk-raw=0'
298.477 + if you want to use int15/87h to access memdrives.
298.478 +
298.479 +--------------------------------------------------------
298.480 +
298.481 + Floppies/harddisks of any size can be emulated with GRUB for DOS 0.2.0.
298.482 +
298.483 + Image file must be contiguous, or else GRUB for DOS will refuse it.
298.484 +
298.485 + The `blocklist' command can list fragments or pieces of a file.
298.486 +
298.487 + Type "help map" at the GRUB prompt to get a brief description of the
298.488 + command.
298.489 +
298.490 + The form
298.491 +
298.492 + map ... (fd?)
298.493 +
298.494 + is a floppy emulation, and the form
298.495 +
298.496 + map ... (hd?)
298.497 +
298.498 + is a hard disk emulation.
298.499 +
298.500 + When a HARD DISK emulation is used, better not start Windows for
298.501 + security reasons. Windows may even destroy all data and all information
298.502 + on all your real hard disks!!!!!!!!
298.503 +
298.504 + Update for --mem: when --mem is used, it seems rather safe even after
298.505 + entering Windows. Win98 can operate the memdrive normally.
298.506 +
298.507 + Windows NT/2000/XP does not recognize the emulated drives no matter
298.508 + whether the --mem option is present.
298.509 +
298.510 +
298.511 +
298.512 +******************************************************************************
298.513 +*** Explanation of the grldr-bootable floppies or harddisk partitions ***
298.514 +******************************************************************************
298.515 +
298.516 +1. Ext2 Boot Sector/Boot Record Layout (for loading grldr)
298.517 +------------------------------------------------------------------------------
298.518 +An EXT2/EXT3 volume can be GRUB-bootable. Copy grldr and an optional menu.lst
298.519 +to the root dir of the EXT2/EXT3 volume, and build the boot sector based on the
298.520 +fifth sector of grldr(some fields need to be changed as detailed in the
298.521 +following table). And then the EXT2/EXT3 volume is GRUB-bootable.
298.522 +
298.523 +Update: bootlace.com is a DOS/Linux utility that can install the GRLDR boot
298.524 +record onto the first sector of an EXT2/EXT3 volume.
298.525 +
298.526 +Offset Length Description
298.527 +====== ====== ==============================================================
298.528 +00h 2 Machine code for short jump over the data.
298.529 +
298.530 +02h 1 LBA indicator. Valid values are 0x02 for CHS mode, or 0x42 for
298.531 + LBA mode.
298.532 +
298.533 + If the BIOS int13 supports LBA, this byte can be safely set to
298.534 + 0x42.
298.535 +
298.536 + Some USB BIOSes might have bugs when using CHS mode, so the
298.537 + format program should set this byte to 0x42. It seems that
298.538 + (generally) all USB BIOSes have LBA support.
298.539 +
298.540 + If the format program does not know whether the BIOS has LBA
298.541 + support, it may operate this way:
298.542 +
298.543 + if (partition_start + total_sectors_in_partition) exceeds the
298.544 + CHS addressing ability(especially when it is greater than
298.545 + 1024*256*63), the caller should set this byte to 0x42,
298.546 + otherwise, set to 0x02.
298.547 +
298.548 + Note that Windows98 uses the value 0x0e as the LBA indicator.
298.549 +
298.550 + Update: this byte of LBA indicator is ignored. The boot
298.551 + record can probe the LBA support of BIOS.
298.552 +
298.553 +03h 10 OEM name string (of OS which formatted the disk).
298.554 + Update: this field is now used for error message of "I/O error"
298.555 +
298.556 +0Dh 1 Sectors per block. Valid values are 2, 4, 8, 16 and 32.
298.557 +
298.558 +0Eh 2 Bytes per block. Valid values are 0x400, 0x800, 0x1000, 0x2000
298.559 + and 0x4000.
298.560 +
298.561 +10h 4 Pointers in pointers-per-block blocks, that is, number of
298.562 + blocks covered by a double-indirect block.
298.563 +
298.564 + Valid values are 0x10000, 0x40000, 0x100000, 0x400000 and
298.565 + 0x1000000.
298.566 +
298.567 +14h 4 Pointers per block, that is, number of blocks covered by an
298.568 + indirect block.
298.569 +
298.570 + Valid values are 0x100, 0x200, 0x400, 0x800, 0x1000.
298.571 +
298.572 +18h 2 Sectors per track.
298.573 +
298.574 +1Ah 2 Number of heads/sides.
298.575 +
298.576 +1Ch 4 Number of hidden sectors (those preceding the boot sector).
298.577 +
298.578 + Also referred to as the starting sector of the partition.
298.579 +
298.580 + For floppies, it should be 0.
298.581 +
298.582 +20h 4 Total number of sectors in the filesystem(or in the partition).
298.583 +
298.584 +24h 1 BIOS drive number of the boot device.
298.585 +
298.586 + Actually this byte is ignored for read. The boot code will
298.587 + write DL onto this byte. The BIOS or the caller should set
298.588 + drive number in DL.
298.589 +
298.590 + We assume all BIOSes pass correct drive number in DL.
298.591 + Buggy BIOSes are not supported!!
298.592 +
298.593 +25h 1 Partition number of this partition on the boot drive.
298.594 +
298.595 + 0, 1, 2, 3 are primary partitions.
298.596 + 4, 5, 6, ... are logical partitions in the extended partition.
298.597 +
298.598 + 0xff is for whole drive. So for floppies, it should be 0xff.
298.599 +
298.600 +26h 2 inode size in bytes. (Notice! We use the formerly reserved
298.601 + word here for inode size!)
298.602 +
298.603 +28h 4 Number of inodes per group.
298.604 +
298.605 + Normally a 1.44M floppy has only one group, and the total
298.606 + number of inodes is 184. So the value should be 184 or
298.607 + greater.
298.608 +
298.609 +2Ch 4 The block number for group descriptors.
298.610 +
298.611 + Valid values are 2 for 1024-byte blocks, and 1 otherwise.
298.612 +
298.613 + The value here is equal to (s_first_data_block + 1).
298.614 +
298.615 +30h 1 code for "cld"(0xFC).
298.616 +
298.617 +31h 2 code for "xor ax,ax"(0x31, 0xC0).
298.618 +
298.619 +33h 1 code for "nop"(0x90) or "cwd"(0x99)
298.620 +
298.621 +34h 458 The rest of the machine code.
298.622 +
298.623 +1FEh 2 Boot Signature AA55h.
298.624 +
298.625 +
298.626 +2. FAT12/FAT16 Boot Sector/Boot Record Layout (for loading grldr)
298.627 +------------------------------------------------------------------------------
298.628 +A FAT12/16 volume can be GRUB-bootable. Copy grldr and an optional menu.lst to
298.629 +the root dir of the FAT12/16 volume, and build the boot sector based on the
298.630 +fourth sector of grldr(some fields need to be changed as detailed in the
298.631 +following table). And then the FAT12/16 volume is GRUB-bootable.
298.632 +
298.633 +Update: bootlace.com is a DOS/Linux utility that can install the GRLDR boot
298.634 +record onto the boot sector of an FAT12/16 volume.
298.635 +
298.636 +Offset Length Description
298.637 +====== ====== ==============================================================
298.638 +00h 2 Machine code for short jump over the data.
298.639 +
298.640 +02h 1 LBA indicator. Valid values are 0x90 for CHS mode, or 0x0e for
298.641 + LBA mode.
298.642 +
298.643 + If the BIOS int13 supports LBA, this byte can be safely set to
298.644 + 0x0e.
298.645 +
298.646 + Some USB BIOSes might have bugs when using CHS mode, so the
298.647 + format program should set this byte to 0x0e. It seems that
298.648 + (generally) all USB BIOSes have LBA support.
298.649 +
298.650 + If the format program does not know whether the BIOS has LBA
298.651 + support, it may operate this way:
298.652 +
298.653 + if (partition_start + total_sectors_in_partition) exceeds the
298.654 + CHS addressing ability(especially when it is greater than
298.655 + 1024*256*63), the caller should set this byte to 0x0e,
298.656 + otherwise, set to 0x90.
298.657 +
298.658 + Update: this byte of LBA indicator is ignored. The boot
298.659 + record can probe the LBA support of BIOS.
298.660 +
298.661 + Update(2021-07-31): Though GRLDR won't use this LBA-indicator
298.662 + byte, Windows 98 uses it. Usually this byte should be 0x90 for
298.663 + CHS mode(especially for floppies). If this byte is not set
298.664 + properly, Windows 98 will not recognize the floppy or
298.665 + partition. This problem was reported by neiljoy. Many thanks!
298.666 +
298.667 +03h 8 OEM name string (of OS which formatted the disk).
298.668 +
298.669 +0Bh 2 Bytes per sector. Must be 512.
298.670 +
298.671 +0Dh 1 Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64
298.672 + and 128. But a cluster size larger than 32K should not occur.
298.673 +
298.674 +0Eh 2 Reserved sectors(number of sectors before the first FAT,
298.675 + including the boot sector), usually 1.
298.676 +
298.677 +10h 1 Number of FATs(nearly always 2).
298.678 +
298.679 +11h 2 Maximum number of root directory entries.
298.680 +
298.681 +13h 2 Total number of sectors (for small disks only, if the disk is
298.682 + too big this is set to 0 and offset 20h is used instead).
298.683 +
298.684 +15h 1 Media descriptor byte, pretty meaningless now (see below).
298.685 +
298.686 +16h 2 Sectors per FAT.
298.687 +
298.688 +18h 2 Sectors per track.
298.689 +
298.690 +1Ah 2 Total number of heads/sides.
298.691 +
298.692 +1Ch 4 Number of hidden sectors (those preceding the boot sector).
298.693 +
298.694 + Also referred to as the starting sector of the partition.
298.695 +
298.696 + For floppies, it should be 0.
298.697 +
298.698 +20h 4 Total number of sectors for large disks.
298.699 +
298.700 +24h 1 BIOS drive number of the boot device.
298.701 +
298.702 + Actually this byte is ignored for read. The boot code will
298.703 + write DL onto this byte. The BIOS or the caller should set
298.704 + drive number in DL.
298.705 +
298.706 + We assume all BIOSes pass correct drive number in DL.
298.707 + Buggy BIOSes are not supported!!
298.708 +
298.709 +25h 1 Partition number of this filesystem in the boot drive.
298.710 +
298.711 + This byte is ignored for read. The boot code will write
298.712 + partition number onto this byte. See offset 41h below.
298.713 +
298.714 +26h 1 Signature (must be 28h or 29h to be recognised by NT).
298.715 +
298.716 +27h 4 Volume serial number.
298.717 +
298.718 +2Bh 11 Volume label.
298.719 +
298.720 +36h 8 File system ID. "FAT12 ", "FAT16 " or "FAT ".
298.721 +
298.722 +3Eh 1 code for "cli".
298.723 +
298.724 +3Fh 1 code for "cld".
298.725 +
298.726 +40h 1 code for "mov dh, imm8".
298.727 +
298.728 +41h 1 Partition number of this partition on the boot drive.
298.729 +
298.730 + 0, 1, 2, 3 are primary partitions.
298.731 + 4, 5, 6, ... are logical partitions in the extended partition.
298.732 +
298.733 + 0xff is for whole drive. So for floppies, it should be 0xff.
298.734 +
298.735 +42h 442 The rest of the machine code.
298.736 +
298.737 +1FCh 4 Boot Signature AA550000h. (Win9x uses 4 bytes as magic value)
298.738 +
298.739 +
298.740 +3. FAT32 Boot Sector/Boot Record Layout (for loading grldr)
298.741 +------------------------------------------------------------------------------
298.742 +A FAT32 volume can be GRUB-bootable. Copy grldr and an optional menu.lst to
298.743 +the root dir of the FAT32 volume, and build the boot sector based on the
298.744 +third sector of grldr(some fields need to be changed as detailed in the
298.745 +following table). And then the FAT32 volume is GRUB-bootable.
298.746 +
298.747 +Update: bootlace.com is a DOS/Linux utility that can install the GRLDR boot
298.748 +record onto the boot sector of an FAT32 volume.
298.749 +
298.750 +Offset Length Description
298.751 +====== ====== ==============================================================
298.752 +00h 2 Machine code for short jump over the data.
298.753 +
298.754 +02h 1 LBA indicator. Valid values are 0x90 for CHS mode, or 0x0e for
298.755 + LBA mode.
298.756 +
298.757 + If the BIOS int13 supports LBA, this byte can be safely set to
298.758 + 0x0e.
298.759 +
298.760 + Some USB BIOSes might have bugs when using CHS mode, so the
298.761 + format program should set this byte to 0x0e. It seems that
298.762 + (generally) all USB BIOSes have LBA support.
298.763 +
298.764 + If the format program does not know whether the BIOS has LBA
298.765 + support, it may operate this way:
298.766 +
298.767 + if (partition_start + total_sectors_in_partition) exceeds the
298.768 + CHS addressing ability(especially when it is greater than
298.769 + 1024*256*63), the caller should set this byte to 0x0e,
298.770 + otherwise, set to 0x90.
298.771 +
298.772 + Update: this byte of LBA indicator is ignored. The boot
298.773 + record can probe the LBA support of BIOS.
298.774 +
298.775 + Update(2021-07-31): Though GRLDR won't use this LBA-indicator
298.776 + byte, Windows 98 uses it. Usually this byte should be 0x90 for
298.777 + CHS mode(especially for floppies). If this byte is not set
298.778 + properly, Windows 98 will not recognize the floppy or
298.779 + partition. This problem was reported by neiljoy. Many thanks!
298.780 +
298.781 +03h 8 OEM name string (of OS which formatted the disk).
298.782 +
298.783 +0Bh 2 Bytes per sector. Must be 512.
298.784 +
298.785 +0Dh 1 Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64
298.786 + and 128. But a cluster size larger than 32K should not occur.
298.787 +
298.788 +0Eh 2 Reserved sectors(number of sectors before the first FAT,
298.789 + including the boot sector), usually 1.
298.790 +
298.791 +10h 1 Number of FATs(nearly always 2).
298.792 +
298.793 +11h 2 (Maximum number of root directory entries)Must be 0.
298.794 +
298.795 +13h 2 (Total number of sectors for small disks only)Must be 0.
298.796 +
298.797 +15h 1 Media descriptor byte, pretty meaningless now (see below).
298.798 +
298.799 +16h 2 (Sectors per FAT)Must be 0.
298.800 +
298.801 +18h 2 Sectors per track.
298.802 +
298.803 +1Ah 2 Total number of heads/sides.
298.804 +
298.805 +1Ch 4 Number of hidden sectors (those preceding the boot sector).
298.806 +
298.807 + Also referred to as the starting sector of the partition.
298.808 +
298.809 + For floppies, it should be 0.
298.810 +
298.811 +20h 4 Total number of sectors for large disks.
298.812 +
298.813 +24h 4 FAT32 sectors per FAT.
298.814 +
298.815 +28h 2 If bit 7 is clear then all FATs are updated, otherwise bits
298.816 + 0-3 give the current active FAT, all other bits are reserved.
298.817 +
298.818 +2Ah 2 High byte is major revision number, low byte is minor revision
298.819 + number, currently both are 0.
298.820 +
298.821 +2Ch 4 Root directory starting cluster.
298.822 +
298.823 +30h 2 File system information sector.
298.824 +
298.825 +32h 2 If non-zero this gives the sector which holds a copy of the
298.826 + boot record, usually 6.
298.827 +
298.828 +34h 12 Reserved, set to 0.
298.829 +
298.830 +40h 1 BIOS drive number of the boot device.
298.831 +
298.832 + 80h is first HDD, 00h is first FDD.
298.833 +
298.834 + Actually this byte is ignored for read. The boot code will
298.835 + write DL onto this byte. The BIOS or the caller should set
298.836 + drive number in DL.
298.837 +
298.838 + We assume all BIOSes pass correct drive number in DL.
298.839 + Buggy BIOSes are not supported!!
298.840 +
298.841 +41h 1 Partition number of this filesystem in the boot drive.
298.842 +
298.843 + This byte is ignored for read. The boot code will write
298.844 + partition number onto this byte. See offset 5Dh below.
298.845 +
298.846 +42h 1 Signature (must be 28h or 29h to be recognised by NT).
298.847 +
298.848 +43h 4 Volume serial number.
298.849 +
298.850 +47h 11 Volume label.
298.851 +
298.852 +52h 8 File system ID. "FAT32 ".
298.853 +
298.854 +5Ah 1 opcode for "cli".
298.855 +
298.856 +5Bh 1 opcode for "cld".
298.857 +
298.858 +5Ch 1 opcode for "mov dh, imm8".
298.859 +
298.860 +5Dh 1 Partition number of this partition on the boot drive.
298.861 +
298.862 + 0, 1, 2, 3 are primary partitions.
298.863 + 4, 5, 6, ... are logical partitions in the extended partition.
298.864 +
298.865 + 0xff is for whole drive. So for floppies, it should be 0xff.
298.866 +
298.867 +5Eh 414 The rest of the machine code.
298.868 +
298.869 +1FCh 4 Boot Signature AA550000h. (Win9x uses 4 bytes as magic value)
298.870 +
298.871 +
298.872 +4. NTFS Boot Sector/Boot Record Layout (for loading grldr)
298.873 +------------------------------------------------------------------------------
298.874 +An NTFS volume can be GRUB-bootable. Copy grldr and an optional menu.lst to
298.875 +the root dir of the NTFS volume, and build the boot sector based on the
298.876 +6th-9th sectors of grldr(some fields need to be changed as detailed in the
298.877 +following table). And then the NTFS volume is GRUB-bootable.
298.878 +
298.879 +Update: bootlace.com is a DOS/Linux utility that can install the GRLDR boot
298.880 +record onto the leading 4 sectors of an NTFS volume.
298.881 +
298.882 +Offset Length Description
298.883 +====== ====== ==============================================================
298.884 +00h 2 Machine code for short jump over the data.
298.885 +
298.886 +02h 1 LBA indicator. Valid values are 0x90 for CHS mode, or 0x0e for
298.887 + LBA mode.
298.888 +
298.889 + If the BIOS int13 supports LBA, this byte can be safely set to
298.890 + 0x0e.
298.891 +
298.892 + Some USB BIOSes might have bugs when using CHS mode, so the
298.893 + format program should set this byte to 0x0e. It seems that
298.894 + (generally) all USB BIOSes have LBA support.
298.895 +
298.896 + If the format program does not know whether the BIOS has LBA
298.897 + support, it may operate this way:
298.898 +
298.899 + if (partition_start + total_sectors_in_partition) exceeds the
298.900 + CHS addressing ability(especially when it is greater than
298.901 + 1024*256*63), the caller should set this byte to 0x0e,
298.902 + otherwise, set to 0x90.
298.903 +
298.904 + Update: this byte of LBA indicator is ignored. The boot
298.905 + record can probe the LBA support of BIOS.
298.906 +
298.907 + Update(2021-07-31): Though GRLDR won't use this LBA-indicator
298.908 + byte, Windows 98 uses it. Usually this byte should be 0x90 for
298.909 + CHS mode(especially for floppies). If this byte is not set
298.910 + properly, Windows 98 will not recognize the floppy or
298.911 + partition. This problem was reported by neiljoy. Many thanks!
298.912 +
298.913 +03h 8 OEM name string (of OS which formatted the disk).
298.914 +
298.915 +0Bh 2 Bytes per sector. Must be 512.
298.916 +
298.917 +0Dh 1 Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64
298.918 + and 128. But a cluster size larger than 32K should not occur.
298.919 +
298.920 +0Eh 2 (Reserved sectors)Unused.
298.921 +
298.922 +10h 1 (Number of FATs)Must be 0.
298.923 +
298.924 +11h 2 (Maximum number of root directory entries)Must be 0.
298.925 +
298.926 +13h 2 (Total number of sectors for small disks only)Must be 0.
298.927 +
298.928 +15h 1 Media descriptor byte, pretty meaningless now (see below).
298.929 +
298.930 +16h 2 (Sectors per FAT)Must be 0.
298.931 +
298.932 +18h 2 Sectors per track.
298.933 +
298.934 +1Ah 2 Total number of heads/sides.
298.935 +
298.936 +1Ch 4 Number of hidden sectors (those preceding the boot sector).
298.937 +
298.938 + Also referred to as the starting sector of the partition.
298.939 +
298.940 + For floppies, it should be 0.
298.941 +
298.942 +20h 4 (Total number of sectors for large disks)Must be 0.
298.943 +
298.944 +24h 4 (FAT32 sectors per FAT) - Usually 80 00 80 00, A value of
298.945 + 80 00 00 00 has been seen on a USB thumb drive which is
298.946 + formatted with NTFS under Windows XP. Note this is removable
298.947 + media and is not partitioned, the drive as a whole is NTFS
298.948 + formatted.
298.949 +
298.950 +28h 8 Number of sectors in the volume.
298.951 +
298.952 +30h 8 LCN of VCN 0 of the $MFT.
298.953 +
298.954 +38h 8 LCN of VCN 0 of the $MFTMirr.
298.955 +
298.956 +40h 4 Clusters per MFT Record.
298.957 +
298.958 +44h 4 Clusters per Index Record.
298.959 +
298.960 +48h 8 Volume serial number.
298.961 +
298.962 +50h 4 Checksum, usually 0.
298.963 +
298.964 +54h 1 opcode for "cli".
298.965 +
298.966 +55h 1 opcode for "cld".
298.967 +
298.968 +56h 1 opcode for "mov dh, imm8".
298.969 +
298.970 +57h 1 Partition number of this partition on the boot drive.
298.971 +
298.972 + 0, 1, 2, 3 are primary partitions.
298.973 + 4, 5, 6, ... are logical partitions in the extended partition.
298.974 +
298.975 + 0xff is for whole drive. So for floppies, it should be 0xff.
298.976 +
298.977 +58h 420 The rest of the machine code in the first sector.
298.978 +
298.979 +1FCh 4 Boot Signature AA550000h. (Win9x uses 4 bytes as magic value)
298.980 +
298.981 +200h 1536 The rest of the machine code in the last 3 sectors.
298.982 +
298.983 +------------------------------------------------------------------------------
298.984 +
298.985 +Appendix A: File System Information Sector of FAT32(not used by grldr)
298.986 +
298.987 +Offset Length Description
298.988 +====== ====== ==============================================================
298.989 +0h 4 Leading Signature 41615252h.
298.990 +
298.991 +4h 480 Reserved, set to 0.
298.992 +
298.993 +1E4h 4 FSI structure signature 61417272h.
298.994 +
298.995 +1E8h 4 Contains the last known count of free clusters, if this is
298.996 + equal to FFFFFFFFh, then the count is unknown.
298.997 +
298.998 +1ECh 4 Cluster number at which you should begin a search for a free
298.999 + cluster, if this is equal to FFFFFFFFh then the field has not
298.1000 + been set.
298.1001 +
298.1002 +1F0h 12 Reserved, set to 0.
298.1003 +
298.1004 +1FCh 4 Trailing Signature AA550000h.
298.1005 +
298.1006 +------------------------------------------------------------------------------
298.1007 +
298.1008 +Appendix B: Media Descriptor Byte(not used by grldr)
298.1009 +
298.1010 +The Media descriptor byte is meaningless because of the duplications, F0h for
298.1011 +example.
298.1012 +
298.1013 +Byte Type of disk Sectors Heads Tracks Capacity
298.1014 +---- ------------ ------- ----- ------ --------
298.1015 +FFh 5 1/4" 8 2 40 320KB
298.1016 +FEh 5 1/4" 8 1 40 160KB
298.1017 +FDh 5 1/4" 9 2 40 360KB
298.1018 +FCh 5 1/4" 9 1 40 180KB
298.1019 +FBh both 9 2 80 640KB
298.1020 +FAh both 9 1 80 320KB
298.1021 +F9h 5 1/4" 15 2 80 1200KB
298.1022 +F9h 3 1/2" 9 2 80 720KB
298.1023 +F0h 3 1/2" 18 2 80 1440KB
298.1024 +F0h 3 1/2" 36 2 80 2880KB
298.1025 +F8h hard disk NA NA NA NA
298.1026 +
298.1027 +******************************************************************************
298.1028 +*** grldr.mbr - How to write it to Master Boot Track of the hard disk ***
298.1029 +******************************************************************************
298.1030 +
298.1031 +grldr.mbr contains code that can be used as Master Boot Record. The code is
298.1032 +responsible for searching all partitions for grldr and when found, loading it.
298.1033 +Currently supported partition types are: FAT12/FAT16/FAT32, NTFS, EXT2/EXT3.
298.1034 +Logical partitions in the extended partition are supported, provided that the
298.1035 +extended partition type is Microsoft-compatible. In fact, the Linux extended
298.1036 +partition type(0x85) is not fully tested for the search mechanism.
298.1037 +
298.1038 +How to write GRLDR.MBR to the Master Boot Track of a hard disk?
298.1039 +
298.1040 +First, read the Windows disk signature and partition information bytes
298.1041 +(72 bytes in total, from offset 0x01b8 to 0x01ff of the MBR sector), and put
298.1042 +them on the same range from offset 0x01b8 to 0x01ff of the beginning sector of
298.1043 +GRLDR.MBR.
298.1044 +
298.1045 +Optionally, if the MBR in the hard disk is a single sector MBR created by
298.1046 +Microsoft FDISK, it may be copied onto the second sector of GRLDR.MBR.
298.1047 +
298.1048 +The second sector of GRLDR.MBR is called "previous MBR". When GRLDR not found,
298.1049 +"previous MBR" will be started.
298.1050 +
298.1051 +No other steps needed, after all necessary changes stated above have been made,
298.1052 +now simply write GRLDR.MBR on to the Master Boot Track. That's all.
298.1053 +
298.1054 +Note: The Master Boot Track means the first track of the hard drive.
298.1055 +
298.1056 +Note: The bootstrap code of GRLDR.MBR only finds GRLDR file in the root dir of
298.1057 +a partition. You'd better place menu.lst file accompanying with GRLDR(i.e., in
298.1058 +the same root dir of the same partition as GRLDR).
298.1059 +
298.1060 +The filename "grldr" in an ext2 partition must be in lower case letters, and
298.1061 +the file type of grldr must be plain regular. Other types, e.g., a symbolic
298.1062 +link, won't work.
298.1063 +
298.1064 +Update: bootlace.com is a DOS/Linux utility for installing grldr.mbr to MBR.
298.1065 +The whole grldr.mbr is embedded in the body of the bootlace.com utility, so
298.1066 +bootlace.com can be used independently. See below.
298.1067 +
298.1068 +******************************************************************************
298.1069 +*** grldr.mbr - Details about the control bytes ***
298.1070 +******************************************************************************
298.1071 +
298.1072 +Six bytes can be used to control the boot process of GRLDR.MBR.
298.1073 +
298.1074 +Offset Length Description
298.1075 +====== ====== ==============================================================
298.1076 +02h 1 bit0=1: disable the search for GRLDR on floppy
298.1077 + bit0=0: enable the search for GRLDR on floppy
298.1078 +
298.1079 + bit1=1: disable the boot of PREVIOUS MBR with invalid
298.1080 + partition table(usually an OS boot sector)
298.1081 + bit1=0: enable the boot of PREVIOUS MBR with invalid
298.1082 + partition table(usually an OS boot sector)
298.1083 +
298.1084 + bit2=1: disable the feature of unconditional entrance to
298.1085 + the command-line(See below `--duce')
298.1086 + bit2=0: enable the feature of unconditional entrance to
298.1087 + the command-line(See below `--duce')
298.1088 +
298.1089 + bit3=1: disable geometry tune(See below `--chs-no-tune')
298.1090 + bit3=0: enable geometry tune(See below `--chs-no-tune')
298.1091 +
298.1092 + bit4 - bit6: reserved
298.1093 +
298.1094 + bit7=1: try to boot PREVIOUS MBR after the search for GRLDR
298.1095 + bit7=0: try to boot PREVIOUS MBR before the search for GRLDR
298.1096 +
298.1097 +03h 1 timeout in seconds to wait for a key press. 0xff stands for
298.1098 + waiting all the time(endless).
298.1099 +
298.1100 +04h 2 hot-key code. high byte is scan code, low byte is ASCII code.
298.1101 + the default value is 0x3920, which stands for the space bar.
298.1102 + if this key is pressed, GRUB will be started prior to the boot
298.1103 + of previous MBR. See "int 16 keyboard scan codes" below.
298.1104 +
298.1105 +06h 1 preferred boot drive number, 0xff for no-drive
298.1106 +07h 1 preferred partition number, 0xff for whole drive
298.1107 +
298.1108 + if the preferred boot drive number is 0xff, the order of the
298.1109 + search for GRLDR will be:
298.1110 +
298.1111 + (hd0,0), (hd0,1), ..., (hd0,L),(L=max partition number)
298.1112 + (hd1,0), (hd1,1), ..., (hd1,M),(M=max partition number)
298.1113 + ... ... ... ... ... ... ... ...
298.1114 + (hdX,0), (hdX,1), ..., (hdX,N),(N=max partition number)
298.1115 + (X=max harddrive number)
298.1116 + (fd0)
298.1117 +
298.1118 + otherwise, if the preferred boot drive number is Y(not equal to
298.1119 + 0xff) and the preferred partition number is K, then the order of
298.1120 + the search for GRLDR will be:
298.1121 +
298.1122 + (Y) if K=0xff; or (Y,K) otherwise
298.1123 + (hd0,0), (hd0,1), ..., (hd0,L),(L=max partition number)
298.1124 + (hd1,0), (hd1,1), ..., (hd1,M),(M=max partition number)
298.1125 + ... ... ... ... ... ... ... ...
298.1126 + (hdX,0), (hdX,1), ..., (hdX,N),(N=max partition number)
298.1127 + (X=max harddrive number)
298.1128 + (fd0)
298.1129 +
298.1130 + Note: if Y < 0x80, then (Y) is floppy, else (Y) is harddrive,
298.1131 + and (Y,K) is partition number K on harddrive (Y).
298.1132 +
298.1133 +
298.1134 +******************************************************************************
298.1135 +*** bootlace.com - Install GRLDR.MBR bootstrap code to MBR ***
298.1136 +******************************************************************************
298.1137 +
298.1138 +BOOTLACE.COM installs GRLDR.MBR boot record to the MBR of a harddrive or of a
298.1139 +harddrive image file, or to the boot sector of a floppy or a floppy image.
298.1140 +
298.1141 +Usage:
298.1142 +
298.1143 + bootlace.com [OPTIONS] DEVICE_OR_FILE
298.1144 +
298.1145 +OPTIONS:
298.1146 +
298.1147 + --read-only do everything except the actual write to the
298.1148 + specified DEVICE_OR_FILE.
298.1149 +
298.1150 + --restore-mbr restore the previous mbr.
298.1151 +
298.1152 + --mbr-no-bpb do not copy BPB in the boot sector of the
298.1153 + leading FAT partition to MBR.
298.1154 +
298.1155 + --no-backup-mbr do not copy the old MBR to the second sector of
298.1156 + DEVICE_OR_FILE.
298.1157 +
298.1158 + --force-backup-mbr force the copy of old MBR to the second sector
298.1159 + of DEVICE_OR_FILE.
298.1160 +
298.1161 + --mbr-enable-floppy enable the search for GRLDR on floppy.
298.1162 +
298.1163 + --mbr-disable-floppy disable the search for GRLDR on floppy.
298.1164 +
298.1165 + --mbr-enable-osbr enable the boot of PREVIOUS MBR with invalid
298.1166 + partition table(usually an OS boot sector).
298.1167 +
298.1168 + --mbr-disable-osbr disable the boot of PREVIOUS MBR with invalid
298.1169 + partition table(usually an OS boot sector).
298.1170 +
298.1171 + --duce disable the feature of unconditional entrance
298.1172 + to the command-line.
298.1173 +
298.1174 + Normally one can unconditionally get the
298.1175 + command-line console by a keypress of `C',
298.1176 + bypassing all config-files(including the
298.1177 + preset-menu). This is a security hole. So we
298.1178 + need this option to disable the feature.
298.1179 +
298.1180 + DUCE is for Disable Unconditional Command-line
298.1181 + Entrance.
298.1182 +
298.1183 + --chs-no-tune disable the feature of geometry tune.
298.1184 +
298.1185 + --boot-prevmbr-first try to boot PREVIOUS MBR before the search for
298.1186 + GRLDR.
298.1187 +
298.1188 + --boot-prevmbr-last try to boot PREVIOUS MBR after the search for
298.1189 + GRLDR.
298.1190 +
298.1191 + --preferred-drive=D preferred boot drive number, 0 <= D < 255.
298.1192 +
298.1193 + --preferred-partition=P preferred partition number, 0 <= P < 255.
298.1194 +
298.1195 + --serial-number=SN setup a new serial number for the hard drive.
298.1196 + SN must be non-zero.
298.1197 +
298.1198 + --time-out=T wait T seconds before booting PREVIOUS MBR. if
298.1199 + T is 0xff, wait forever. The default is 5.
298.1200 +
298.1201 + --hot-key=K if the desired key K is pressed, start GRUB
298.1202 + before booting PREVIOUS MBR. K is a word
298.1203 + value, just as the value in AX register
298.1204 + returned from int16/AH=1. The high byte is the
298.1205 + scan code and the low byte is ASCII code. The
298.1206 + default is 0x3920 for space bar. See "int 16
298.1207 + keyboard scan codes" below.
298.1208 +
298.1209 + --floppy if DEVICE_OR_FILE is floppy, use this option.
298.1210 +
298.1211 + --floppy=N if DEVICE_OR_FILE is a partition on a hard
298.1212 + drive, use this option. N is used to specify
298.1213 + the partition number: 0,1,2 and 3 for the
298.1214 + primary partitions, and 4,5,6,... for the
298.1215 + logical partitions.
298.1216 +
298.1217 + --sectors-per-track=S specifies sectors per track for --floppy.
298.1218 + 1 <= S <= 63, default is 63.
298.1219 +
298.1220 + --heads=H specifies number of heads for --floppy.
298.1221 + 1 <= H <= 256, default is 255.
298.1222 +
298.1223 + --start-sector=B specifies hidden sectors for --floppy=N.
298.1224 +
298.1225 + --total-sectors=C specifies total sectors for --floppy.
298.1226 + default is 0.
298.1227 +
298.1228 + --lba use lba mode for --floppy. If the floppy BIOS
298.1229 + has LBA support, you can specify --lba here.
298.1230 + It is assumed that all floppy BIOSes have CHS
298.1231 + support. So you would rather specify --chs.
298.1232 + If neither --chs nor --lba is specified, then
298.1233 + the LBA indicator(i.e., the third byte of the
298.1234 + boot sector) will not be touched.
298.1235 +
298.1236 + --chs use chs mode for --floppy. You should specify
298.1237 + --chs if the floppy BIOS does not support LBA.
298.1238 + We assume all floppy BIOSes have CHS support.
298.1239 + So it is likely you want to specify --chs.
298.1240 + If neither --chs nor --lba is specified, then
298.1241 + the LBA indicator(i.e., the third byte of the
298.1242 + boot sector) will not be touched.
298.1243 +
298.1244 + --fat12 FAT12 is allowed to be installed for --floppy.
298.1245 +
298.1246 + --fat16 FAT16 is allowed to be installed for --floppy.
298.1247 +
298.1248 + --fat32 FAT32 is allowed to be installed for --floppy.
298.1249 +
298.1250 + --vfat FAT12/16/32 are allowed to be installed for
298.1251 + --floppy.
298.1252 +
298.1253 + --ntfs NTFS is allowed to be installed for --floppy.
298.1254 +
298.1255 + --ext2 EXT2 is allowed to be installed for --floppy.
298.1256 +
298.1257 + --install-partition=I Install the boot record onto the boot area of
298.1258 + partition number I of the specified hard drive
298.1259 + or harddrive image DEVICE_OR_FILE.
298.1260 +
298.1261 +DEVICE_OR_FILE: Filename of the device or the image file. For DOS, a BIOS drive
298.1262 +number(hex 0xHH or decimal DDD) can be used to access the drive. BIOS drive
298.1263 +number 0 is for the first floppy, 1 is for the second floppy; 0x80 is for the
298.1264 +first hard drive, 0x81 is for the second hard drive, etc.
298.1265 +
298.1266 +Note: BOOTLACE.COM writes only the boot code to MBR. The boot code needs to
298.1267 +load GRLDR as the second(and last) stage of the GRUB boot process. Therefore
298.1268 +GRLDR should be copied to the root directory of one of the supported
298.1269 +partitions, either before or after a successful execution of BOOTLACE.COM.
298.1270 +Currently only partitions with filesystem type of FAT12, FAT16, FAT32, NTFS,
298.1271 +EXT2 or EXT3 are supported.
298.1272 +
298.1273 +Note 2: If DEVICE_OR_FILE is a harddisk device or a harddisk image file, it
298.1274 +must contain a valid partition table, otherwise, BOOTLACE.COM will fail. If
298.1275 +DEVICE_OR_FILE is a floppy device or a floppy image file, then it must contain
298.1276 +a supported filesystem(i.e., either of FAT12/FAT16/FAT32/NTFS/EXT2/EXT3).
298.1277 +
298.1278 +Note 3: If DEVICE_OR_FILE is a floppy device or a floppy image file, and it
298.1279 +was formated EXT2/EXT3, then you should specify --sectors-per-track and
298.1280 +--heads explicitly.
298.1281 +
298.1282 +
298.1283 +Important!! If you install GRLDR Boot Record to a floppy or a partition, the
298.1284 +floppy or partition will boot solely grldr, and your original
298.1285 +IO.SYS(DOS/Win9x/Me) and NTLDR(WinNT/2K/XP) will become unbootable. This is
298.1286 +because the original boot record of the floppy or partition was overwritten.
298.1287 +There is no such problem when installing GRLDR Boot Record onto the MBR.
298.1288 +Update: Some NTLDR/IO.SYS/KERNEL.SYS files can be directly chainloaded in the
298.1289 +latest GRUB4DOS.
298.1290 +
298.1291 +Tip: If the filename begins in a dash(-) or a digit, you may prefix a dirname
298.1292 +(./) or (.\) to it.
298.1293 +
298.1294 +Examples:
298.1295 +
298.1296 + Installing GRLDR boot code to MBR under Linux:
298.1297 +
298.1298 + bootlace.com /dev/hda
298.1299 +
298.1300 + Installing GRLDR boot code to MBR under DOS:
298.1301 +
298.1302 + bootlace.com 0x80
298.1303 +
298.1304 + Installing GRLDR boot code to a harddisk image under DOS or Linux:
298.1305 +
298.1306 + bootlace.com hd.img
298.1307 +
298.1308 + Installing GRLDR boot code to floppy under Linux:
298.1309 +
298.1310 + bootlace.com --floppy --chs /dev/fd0
298.1311 +
298.1312 + Installing GRLDR boot code to floppy under DOS:
298.1313 +
298.1314 + bootlace.com --floppy --chs 0x00
298.1315 +
298.1316 + Installing GRLDR boot code to a floppy image under DOS or Linux:
298.1317 +
298.1318 + bootlace.com --floppy --chs floppy.img
298.1319 +
298.1320 +BOOTLACE.COM cannot function well under Windows NT/2000/XP/2003. It is expected
298.1321 +(and designed) to run under DOS/Win9x and Linux. Update: For image FILES,
298.1322 +bootlace.com function well under Windows NT/2000/XP/2003. For devices,
298.1323 +bootlace.com will not work under Windows NT/2000/XP/2003 because bootlace.com
298.1324 +is a DOS utility and Windows NT/2000/XP/2003 does not allow bootlace.com to
298.1325 +access devices.
298.1326 +
298.1327 +******************************************************************************
298.1328 +*** kexec-tools should be patched for the 1.101 release ***
298.1329 +******************************************************************************
298.1330 +
298.1331 +The file kexec-tools-1.101-patch is a patch to the kexec-tools-1.101 release.
298.1332 +Kexec might fail to load grub.exe without this patch.
298.1333 +
298.1334 +The home page of kexec-tools is:
298.1335 +
298.1336 + http://www.xmission.com/~ebiederm/files/kexec/
298.1337 +
298.1338 +Note: The Linux kernel should be KEXEC enabled before kexec can be run.
298.1339 +
298.1340 + !! Important Update !!
298.1341 +
298.1342 +The patch `kexec-tools-1.101-patch' is not needed now and has been deleted.
298.1343 +Even worse, it fails in `kexec -l grub.exe --initrd=imgfile'. So please
298.1344 +do not use it any more.
298.1345 +
298.1346 +******************************************************************************
298.1347 +*** Direct transition to DOS/Win9x from within Linux ***
298.1348 +******************************************************************************
298.1349 +
298.1350 +By using kexec, we can easily boot into DOS/Win9x from a running Linux system.
298.1351 +
298.1352 +If WIN98.IMG is a bootable hard-disk image, do as follows:
298.1353 +
298.1354 +kexec -l grub.exe --initrd=WIN98.IMG --command-line="--config-file=map (rd) (hd0); map --hook; chainloader (hd0)+1; rootnoverify (hd0)"
298.1355 +
298.1356 +kexec -e
298.1357 +
298.1358 +If DOS.IMG is a bootable floppy image, do this way:
298.1359 +
298.1360 +kexec -l grub.exe --initrd=DOS.IMG --command-line="--config-file=map (rd) (fd0); map --hook; chainloader (fd0)+1; rootnoverify (fd0)"
298.1361 +
298.1362 +kexec -e
298.1363 +
298.1364 +Note that in this manner, we can boot DOS/Win9x without using a real DOS/Win9x
298.1365 +disk. We need no FAT partition but an image file.
298.1366 +
298.1367 +We have noticed that Linux itself can act as a big boot manager by using kexec
298.1368 +and grub.exe. This may be convenient to developers who write installation or
298.1369 +bootstrap or initialization programs.
298.1370 +
298.1371 +Certainly, grub.exe and the bootable disk image can also be loaded by a running
298.1372 +GRUB or LILO or syslinux. Examples:
298.1373 +
298.1374 +1. Loaded by GRUB:
298.1375 +
298.1376 + kernel (hd0,0)/grub.exe --config-file="map (rd) (fd0); map --hook; chainloader (fd0)+1; rootnoverify (fd0)"
298.1377 + initrd (hd0,0)/DOS.IMG
298.1378 + boot
298.1379 +
298.1380 +2. Loaded by LILO:
298.1381 +
298.1382 + image=/boot/grub.exe
298.1383 + label=grub.exe
298.1384 + initrd=/boot/DOS.IMG
298.1385 + append="--config-file=map (rd) (fd0); map --hook; chainloader (fd0)+1; rootnoverify (fd0)"
298.1386 +
298.1387 +3. Loaded by SYSLINUX:
298.1388 +
298.1389 + label grub.exe
298.1390 + kernel grub.exe
298.1391 + append initrd=DOS.IMG --config-file="map (rd) (fd0); map --hook; chainloader (fd0)+1; rootnoverify (fd0)"
298.1392 +
298.1393 +Note: If the above `map (rd) (...)' failed, you may use `map (rd)+1 (...)'
298.1394 +instead and try again.
298.1395 +
298.1396 +******************************************************************************
298.1397 +*** Keyboard BIOS Scan Code/ASCII code tables ***
298.1398 +******************************************************************************
298.1399 +
298.1400 +Keyboard bios scan code and ascii character code tables can be obtained from
298.1401 +the web by, for example, googling for "3920 372A 4A2D 4E2B 352F". Here are 2
298.1402 +main results:
298.1403 +
298.1404 +1. From "http://heim.ifi.uio.no/~stanisls/helppc/scan_codes.html":
298.1405 +
298.1406 +INT 16 - Keyboard Scan Codes
298.1407 +
298.1408 + Key Normal Shifted w/Ctrl w/Alt
298.1409 +
298.1410 + A 1E61 1E41 1E01 1E00
298.1411 + B 3062 3042 3002 3000
298.1412 + C 2E63 2E43 2E03 2E00
298.1413 + D 2064 2044 2004 2000
298.1414 + E 1265 1245 1205 1200
298.1415 + F 2166 2146 2106 2100
298.1416 + G 2267 2247 2207 2200
298.1417 + H 2368 2348 2308 2300
298.1418 + I 1769 1749 1709 1700
298.1419 + J 246A 244A 240A 2400
298.1420 + K 256B 254B 250B 2500
298.1421 + L 266C 264C 260C 2600
298.1422 + M 326D 324D 320D 3200
298.1423 + N 316E 314E 310E 3100
298.1424 + O 186F 184F 180F 1800
298.1425 + P 1970 1950 1910 1900
298.1426 + Q 1071 1051 1011 1000
298.1427 + R 1372 1352 1312 1300
298.1428 + S 1F73 1F53 1F13 1F00
298.1429 + T 1474 1454 1414 1400
298.1430 + U 1675 1655 1615 1600
298.1431 + V 2F76 2F56 2F16 2F00
298.1432 + W 1177 1157 1117 1100
298.1433 + X 2D78 2D58 2D18 2D00
298.1434 + Y 1579 1559 1519 1500
298.1435 + Z 2C7A 2C5A 2C1A 2C00
298.1436 +
298.1437 + Key Normal Shifted w/Ctrl w/Alt
298.1438 +
298.1439 + 1 0231 0221 7800
298.1440 + 2 0332 0340 0300 7900
298.1441 + 3 0433 0423 7A00
298.1442 + 4 0534 0524 7B00
298.1443 + 5 0635 0625 7C00
298.1444 + 6 0736 075E 071E 7D00
298.1445 + 7 0837 0826 7E00
298.1446 + 8 0938 092A 7F00
298.1447 + 9 0A39 0A28 8000
298.1448 + 0 0B30 0B29 8100
298.1449 +
298.1450 + Key Normal Shifted w/Ctrl w/Alt
298.1451 +
298.1452 + - 0C2D 0C5F 0C1F 8200
298.1453 + = 0D3D 0D2B 8300
298.1454 + [ 1A5B 1A7B 1A1B 1A00
298.1455 + ] 1B5D 1B7D 1B1D 1B00
298.1456 + ; 273B 273A 2700
298.1457 + ' 2827 2822
298.1458 + ` 2960 297E
298.1459 + \ 2B5C 2B7C 2B1C 2600 (same as Alt L)
298.1460 + , 332C 333C
298.1461 + . 342E 343E
298.1462 + / 352F 353F
298.1463 +
298.1464 + Key Normal Shifted w/Ctrl w/Alt
298.1465 +
298.1466 + F1 3B00 5400 5E00 6800
298.1467 + F2 3C00 5500 5F00 6900
298.1468 + F3 3D00 5600 6000 6A00
298.1469 + F4 3E00 5700 6100 6B00
298.1470 + F5 3F00 5800 6200 6C00
298.1471 + F6 4000 5900 6300 6D00
298.1472 + F7 4100 5A00 6400 6E00
298.1473 + F8 4200 5B00 6500 6F00
298.1474 + F9 4300 5C00 6600 7000
298.1475 + F10 4400 5D00 6700 7100
298.1476 + F11 8500 8700 8900 8B00
298.1477 + F12 8600 8800 8A00 8C00
298.1478 +
298.1479 + Key Normal Shifted w/Ctrl w/Alt
298.1480 +
298.1481 + BackSpace 0E08 0E08 0E7F 0E00
298.1482 + Del 5300 532E 9300 A300
298.1483 + Down Arrow 5000 5032 9100 A000
298.1484 + End 4F00 4F31 7500 9F00
298.1485 + Enter 1C0D 1C0D 1C0A A600
298.1486 + Esc 011B 011B 011B 0100
298.1487 + Home 4700 4737 7700 9700
298.1488 + Ins 5200 5230 9200 A200
298.1489 + Keypad 5 4C35 8F00
298.1490 + Keypad * 372A 9600 3700
298.1491 + Keypad - 4A2D 4A2D 8E00 4A00
298.1492 + Keypad + 4E2B 4E2B 4E00
298.1493 + Keypad / 352F 352F 9500 A400
298.1494 + Left Arrow 4B00 4B34 7300 9B00
298.1495 + PgDn 5100 5133 7600 A100
298.1496 + PgUp 4900 4939 8400 9900
298.1497 + PrtSc 7200
298.1498 + Right Arrow 4D00 4D36 7400 9D00
298.1499 + SpaceBar 3920 3920 3920 3920
298.1500 + Tab 0F09 0F00 9400 A500
298.1501 + Up Arrow 4800 4838 8D00 9800
298.1502 +
298.1503 +
298.1504 +- Some key combinations are not available on all systems. The PS/2
298.1505 + includes many that aren't available on the PC, XT and AT.
298.1506 +- To retrieve the character from a scan code logical AND the word
298.1507 + with 0x00FF.
298.1508 +- see INT 16 MAKE CODES
298.1509 +
298.1510 +
298.1511 +
298.1512 +2. From "http://www.hoppie.nl/ivan/keycodes.txt":
298.1513 +
298.1514 +
298.1515 +
298.1516 + Keystroke Keypress code
298.1517 +--------------------------------------------------
298.1518 + Esc 011B
298.1519 + 1 0231
298.1520 + 2 0332
298.1521 + 3 0433
298.1522 + 4 0534
298.1523 + 5 0635
298.1524 + 6 0736
298.1525 + 7 0837
298.1526 + 8 0938
298.1527 + 9 0A39
298.1528 + 0 0B30
298.1529 + - 0C2D
298.1530 + = 0D3D
298.1531 + Backspace 0E08
298.1532 + Tab 0F09
298.1533 + q 1071
298.1534 + w 1177
298.1535 + e 1265
298.1536 + r 1372
298.1537 + t 1474
298.1538 + y 1579
298.1539 + u 1675
298.1540 + i 1769
298.1541 + o 186F
298.1542 + p 1970
298.1543 + [ 1A5B
298.1544 + ] 1B5D
298.1545 + Enter 1C0D
298.1546 + Ctrl **
298.1547 + a 1E61
298.1548 + s 1F73
298.1549 + d 2064
298.1550 + f 2166
298.1551 + g 2267
298.1552 + h 2368
298.1553 + j 246A
298.1554 + k 256B
298.1555 + l 266C
298.1556 + ; 273B
298.1557 + ' 2827
298.1558 + ` 2960
298.1559 + Shift **
298.1560 + \ 2B5C
298.1561 + z 2C7A
298.1562 + x 2D78
298.1563 + c 2E63
298.1564 + v 2F76
298.1565 + b 3062
298.1566 + n 316E
298.1567 + m 326D
298.1568 + , 332C
298.1569 + . 342E
298.1570 + / 352F
298.1571 + Gray * 372A
298.1572 + Alt **
298.1573 + Space 3920
298.1574 + Caps Lock **
298.1575 + F1 3B00
298.1576 + F2 3C00
298.1577 + F3 3D00
298.1578 + F4 3E00
298.1579 + F5 3F00
298.1580 + F6 4000
298.1581 + F7 4100
298.1582 + F8 4200
298.1583 + F9 4300
298.1584 + F10 4400
298.1585 + F11 8500
298.1586 + F12 8600
298.1587 + Num Lock **
298.1588 + Scroll Lock **
298.1589 + White Home 4700
298.1590 + White Up Arrow 4800
298.1591 + White PgUp 4900
298.1592 + Gray - 4A2D
298.1593 + White Left Arrow 4B00
298.1594 + Center Key 4C00
298.1595 + White Right Arrow 4D00
298.1596 + Gray + 4E2B
298.1597 + White End 4F00
298.1598 + White Down Arrow 5000
298.1599 + White PgDn 5100
298.1600 + White Ins 5200
298.1601 + White Del 5300
298.1602 + SysReq **
298.1603 + Key 45 [1] 565C
298.1604 + Enter (number keypad) 1C0D
298.1605 + Gray / 352F
298.1606 + PrtSc **
298.1607 + Pause **
298.1608 + Gray Home 4700
298.1609 + Gray Up Arrow 4800
298.1610 + Gray Page Up 4900
298.1611 + Gray Left Arrow 4B00
298.1612 + Gray Right Arrow 4D00
298.1613 + Gray End 4F00
298.1614 + Gray Down Arrow 5000
298.1615 + Gray Page Down 5100
298.1616 + Gray Insert 5200
298.1617 + Gray Delete 5300
298.1618 +
298.1619 + Shift Esc 011B
298.1620 + ! 0221
298.1621 + @ 0340
298.1622 + # 0423
298.1623 + $ 0524
298.1624 + % 0625
298.1625 + ^ 075E
298.1626 + & 0826
298.1627 + * (white) 092A
298.1628 + ( 0A28
298.1629 + ) 0B29
298.1630 + _ 0C5F
298.1631 + + (white) 0D2B
298.1632 + Shift Backspace 0E08
298.1633 + Shift Tab (Backtab) 0F00
298.1634 + Q 1051
298.1635 + W 1157
298.1636 + E 1245
298.1637 + R 1352
298.1638 + T 1454
298.1639 + Y 1559
298.1640 + U 1655
298.1641 + I 1749
298.1642 + O 184F
298.1643 + P 1950
298.1644 + { 1A7B
298.1645 + } 1B7D
298.1646 + Shift Enter 1C0D
298.1647 + Shift Ctrl **
298.1648 + A 1E41
298.1649 + S 1F53
298.1650 + D 2044
298.1651 + F 2146
298.1652 + G 2247
298.1653 + H 2348
298.1654 + J 244A
298.1655 + K 254B
298.1656 + L 264C
298.1657 + : 273A
298.1658 + " 2822
298.1659 + ~ 297E
298.1660 + | 2B7C
298.1661 + Z 2C5A
298.1662 + X 2D58
298.1663 + C 2E43
298.1664 + V 2F56
298.1665 + B 3042
298.1666 + N 314E
298.1667 + M 324D
298.1668 + < 333C
298.1669 + > 343E
298.1670 + ? 353F
298.1671 + Shift Gray * 372A
298.1672 + Shift Alt **
298.1673 + Shift Space 3920
298.1674 + Shift Caps Lock **
298.1675 + Shift F1 5400
298.1676 + Shift F2 5500
298.1677 + Shift F3 5600
298.1678 + Shift F4 5700
298.1679 + Shift F5 5800
298.1680 + Shift F6 5900
298.1681 + Shift F7 5A00
298.1682 + Shift F8 5B00
298.1683 + Shift F9 5C00
298.1684 + Shift F10 5D00
298.1685 + Shift F11 8700
298.1686 + Shift F12 8800
298.1687 + Shift Num Lock **
298.1688 + Shift Scroll Lock **
298.1689 + Shift 7 (number pad) 4737
298.1690 + Shift 8 (number pad) 4838
298.1691 + Shift 9 (number pad) 4939
298.1692 + Shift Gray - 4A2D
298.1693 + Shift 4 (number pad) 4B34
298.1694 + Shift 5 (number pad) 4C35
298.1695 + Shift 6 (number pad) 4D36
298.1696 + Shift Gray + 4E2B
298.1697 + Shift 1 (number pad) 4F31
298.1698 + Shift 2 (number pad) 5032
298.1699 + Shift 3 (number pad) 5133
298.1700 + Shift 0 (number pad) 5230
298.1701 + Shift . (number pad) 532E
298.1702 + Shift SysReq **
298.1703 + Shift Key 45 [1] 567C
298.1704 + Shift Enter (number pad) 1C0D
298.1705 + Shift Gray / 352F
298.1706 + Shift PrtSc **
298.1707 + Shift Pause **
298.1708 + Shift Gray Home 4700
298.1709 + Shift Gray Up Arrow 4800
298.1710 + Shift Gray Page Up 4900
298.1711 + Shift Gray Left Arrow 4B00
298.1712 + Shift Gray Right Arrow 4D00
298.1713 + Shift Gray End 4F00
298.1714 + Shift Gray Down Arrow 5000
298.1715 + Shift Gray Page Down 5100
298.1716 + Shift Gray Insert 5200
298.1717 + Shift Gray Delete 5300
298.1718 +
298.1719 + Ctrl Esc 011B
298.1720 + Ctrl 1 --
298.1721 + Ctrl 2 (NUL) 0300
298.1722 + Ctrl 3 --
298.1723 + Ctrl 4 --
298.1724 + Ctrl 5 --
298.1725 + Ctrl 6 (RS) 071E
298.1726 + Ctrl 7 --
298.1727 + Ctrl 8 --
298.1728 + Ctrl 9 --
298.1729 + Ctrl 0 --
298.1730 + Ctrl - 0C1F
298.1731 + Ctrl = --
298.1732 + Ctrl Backspace (DEL) 0E7F
298.1733 + Ctrl Tab 9400
298.1734 + Ctrl q (DC1) 1011
298.1735 + Ctrl w (ETB) 1117
298.1736 + Ctrl e (ENQ) 1205
298.1737 + Ctrl r (DC2) 1312
298.1738 + Ctrl t (DC4) 1414
298.1739 + Ctrl y (EM) 1519
298.1740 + Ctrl u (NAK) 1615
298.1741 + Ctrl i (HT) 1709
298.1742 + Ctrl o (SI) 180F
298.1743 + Ctrl p (DEL) 1910
298.1744 + Ctrl [ (ESC) 1A1B
298.1745 + Ctrl ] (GS) 1B1D
298.1746 + Ctrl Enter (LF) 1C0A
298.1747 + Ctrl a (SOH) 1E01
298.1748 + Ctrl s (DC3) 1F13
298.1749 + Ctrl d (EOT) 2004
298.1750 + Ctrl f (ACK) 2106
298.1751 + Ctrl g (BEL) 2207
298.1752 + Ctrl h (Backspace) 2308
298.1753 + Ctrl j (LF) 240A
298.1754 + Ctrl k (VT) 250B
298.1755 + Ctrl l (FF) 260C
298.1756 + Ctrl ; --
298.1757 + Ctrl ' --
298.1758 + Ctrl ` --
298.1759 + Ctrl Shift **
298.1760 + Ctrl \ (FS) 2B1C
298.1761 + Ctrl z (SUB) 2C1A
298.1762 + Ctrl x (CAN) 2D18
298.1763 + Ctrl c (ETX) 2E03
298.1764 + Ctrl v (SYN) 2F16
298.1765 + Ctrl b (STX) 3002
298.1766 + Ctrl n (SO) 310E
298.1767 + Ctrl m (CR) 320D
298.1768 + Ctrl , --
298.1769 + Ctrl . --
298.1770 + Ctrl / --
298.1771 + Ctrl Gray * 9600
298.1772 + Ctrl Alt **
298.1773 + Ctrl Space 3920
298.1774 + Ctrl Caps Lock --
298.1775 + Ctrl F1 5E00
298.1776 + Ctrl F2 5F00
298.1777 + Ctrl F3 6000
298.1778 + Ctrl F4 6100
298.1779 + Ctrl F5 6200
298.1780 + Ctrl F6 6300
298.1781 + Ctrl F7 6400
298.1782 + Ctrl F8 6500
298.1783 + Ctrl F9 6600
298.1784 + Ctrl F10 6700
298.1785 + Ctrl F11 8900
298.1786 + Ctrl F12 8A00
298.1787 + Ctrl Num Lock --
298.1788 + Ctrl Scroll Lock --
298.1789 + Ctrl White Home 7700
298.1790 + Ctrl White Up Arrow 8D00
298.1791 + Ctrl White PgUp 8400
298.1792 + Ctrl Gray - 8E00
298.1793 + Ctrl White Left Arrow 7300
298.1794 + Ctrl 5 (number pad) 8F00
298.1795 + Ctrl White Right Arrow 7400
298.1796 + Ctrl Gray + 9000
298.1797 + Ctrl White End 7500
298.1798 + Ctrl White Down Arrow 9100
298.1799 + Ctrl White PgDn 7600
298.1800 + Ctrl White Ins 9200
298.1801 + Ctrl White Del 9300
298.1802 + Ctrl SysReq **
298.1803 + Ctrl Key 45 [1] --
298.1804 + Ctrl Enter (number pad) 1C0A
298.1805 + Ctrl / (number pad) 9500
298.1806 + Ctrl PrtSc 7200
298.1807 + Ctrl Break 0000
298.1808 + Ctrl Gray Home 7700
298.1809 + Ctrl Gray Up Arrow 8DE0
298.1810 + Ctrl Gray Page Up 8400
298.1811 + Ctrl Gray Left Arrow 7300
298.1812 + Ctrl Gray Right Arrow 7400
298.1813 + Ctrl Gray End 7500
298.1814 + Ctrl Gray Down Arrow 91E0
298.1815 + Ctrl Gray Page Down 7600
298.1816 + Ctrl Gray Insert 92E0
298.1817 + Ctrl Gray Delete 93E0
298.1818 +
298.1819 + Alt Esc 0100
298.1820 + Alt 1 7800
298.1821 + Alt 2 7900
298.1822 + Alt 3 7A00
298.1823 + Alt 4 7B00
298.1824 + Alt 5 7C00
298.1825 + Alt 6 7D00
298.1826 + Alt 7 7E00
298.1827 + Alt 8 7F00
298.1828 + Alt 9 8000
298.1829 + Alt 0 8100
298.1830 + Alt - 8200
298.1831 + Alt = 8300
298.1832 + Alt Backspace 0E00
298.1833 + Alt Tab A500
298.1834 + Alt q 1000
298.1835 + Alt w 1100
298.1836 + Alt e 1200
298.1837 + Alt r 1300
298.1838 + Alt t 1400
298.1839 + Alt y 1500
298.1840 + Alt u 1600
298.1841 + Alt i 1700
298.1842 + Alt o 1800
298.1843 + Alt p 1900
298.1844 + Alt [ 1A00
298.1845 + Alt ] 1B00
298.1846 + Alt Enter 1C00
298.1847 + Alt Ctrl **
298.1848 + Alt a 1E00
298.1849 + Alt s 1F00
298.1850 + Alt d 2000
298.1851 + Alt f 2100
298.1852 + Alt g 2200
298.1853 + Alt h 2300
298.1854 + Alt j 2400
298.1855 + Alt k 2500
298.1856 + Alt l 2600
298.1857 + Alt ; 2700
298.1858 + Alt ' 2800
298.1859 + Alt ` 2900
298.1860 + Alt Shift **
298.1861 + Alt \ 2B00
298.1862 + Alt z 2C00
298.1863 + Alt x 2D00
298.1864 + Alt c 2E00
298.1865 + Alt v 2F00
298.1866 + Alt b 3000
298.1867 + Alt n 3100
298.1868 + Alt m 3200
298.1869 + Alt , 3300
298.1870 + Alt . 3400
298.1871 + Alt / 3500
298.1872 + Alt Gray * 3700
298.1873 + Alt Space 3920
298.1874 + Alt Caps Lock **
298.1875 + Alt F1 6800
298.1876 + Alt F2 6900
298.1877 + Alt F3 6A00
298.1878 + Alt F4 6B00
298.1879 + Alt F5 6C00
298.1880 + Alt F6 6D00
298.1881 + Alt F7 6E00
298.1882 + Alt F8 6F00
298.1883 + Alt F9 7000
298.1884 + Alt F10 7100
298.1885 + Alt F11 8B00
298.1886 + Alt F12 8C00
298.1887 + Alt Num Lock **
298.1888 + Alt Scroll Lock **
298.1889 + Alt Gray - 4A00
298.1890 + Alt Gray + 4E00
298.1891 + Alt 7 (number pad) #
298.1892 + Alt 8 (number pad) #
298.1893 + Alt 9 (number pad) #
298.1894 + Alt 4 (number pad) #
298.1895 + Alt 5 (number pad) #
298.1896 + Alt 6 (number pad) #
298.1897 + Alt 1 (number pad) #
298.1898 + Alt 2 (number pad) #
298.1899 + Alt 3 (number pad) #
298.1900 + Alt Del --
298.1901 + Alt SysReq **
298.1902 + Alt Key 45 [1] --
298.1903 + Alt Enter (number pad) A600
298.1904 + Alt / (number pad) A400
298.1905 + Alt PrtSc **
298.1906 + Alt Pause **
298.1907 + Alt Gray Home 9700
298.1908 + Alt Gray Up Arrow 9800
298.1909 + Alt Gray Page Up 9900
298.1910 + Alt Gray Left Arrow 9B00
298.1911 + Alt Gray Right Arrow 9D00
298.1912 + Alt Gray End 9F00
298.1913 + Alt Gray Down Arrow A000
298.1914 + Alt Gray Page Down A100
298.1915 + Alt Gray Insert A200
298.1916 + Alt Gray Delete A300
298.1917 +
298.1918 + -------------------------------------------------------------------------
298.1919 +
298.1920 +Footnotes
298.1921 +
298.1922 + [1] In the United States, the 101/102-key keyboard is shipped
298.1923 + with 101 keys. Overseas versions have an additional key
298.1924 + sandwiched between the left Shift key and the Z key. This
298.1925 + additional key is identified by IBM (and in this table) as
298.1926 + "Key 45."
298.1927 +
298.1928 + [**] Keys and key combinations marked ** are used by the ROM BIOS
298.1929 + but do not put values into the keyboard buffer.
298.1930 +
298.1931 + [--] Keys and key combinations marked -- are ignored by the ROM
298.1932 + BIOS.
298.1933 +
298.1934 +
298.1935 +
298.1936 +
298.1937 +3. From "http://heim.ifi.uio.no/~stanisls/helppc/make_codes.html":
298.1938 +
298.1939 +
298.1940 +INT 9 - Hardware Keyboard Make/Break Codes
298.1941 +
298.1942 + Key Make Break Key Make Break
298.1943 +
298.1944 + Backspace 0E 8E F1 3B BB
298.1945 + Caps Lock 3A BA F2 3C BC
298.1946 + Enter 1C 9C F3 3D BD
298.1947 + Esc 01 81 F4 3E BE
298.1948 + Left Alt 38 B8 F7 41 C1
298.1949 + Left Ctrl 1D 9D F5 3F BF
298.1950 + Left Shift 2A AA F6 40 C0
298.1951 + Num Lock 45 C5 F8 42 C2
298.1952 + Right Shift 36 B6 F9 43 C3
298.1953 + Scroll Lock 46 C6 F10 44 C4
298.1954 + Space 39 B9 F11 57 D7
298.1955 + Sys Req (AT) 54 D4 F12 58 D8
298.1956 + Tab 0F 8F
298.1957 +
298.1958 + Keypad Keys Make Break
298.1959 +
298.1960 + Keypad 0 (Ins) 52 D2
298.1961 + Keypad 1 (End) 4F CF
298.1962 + Keypad 2 (Down arrow) 50 D0
298.1963 + Keypad 3 (PgDn) 51 D1
298.1964 + Keypad 4 (Left arrow) 4B CB
298.1965 + Keypad 5 4C CC
298.1966 + Keypad 6 (Right arrow) 4D CD
298.1967 + Keypad 7 (Home) 47 C7
298.1968 + Keypad 8 (Up arrow) 48 C8
298.1969 + Keypad 9 (PgUp) 49 C9
298.1970 + Keypad . (Del) 53 D3
298.1971 + Keypad * (PrtSc) 37 B7
298.1972 + Keypad - 4A CA
298.1973 + Keypad + 4E CE
298.1974 +
298.1975 + Key Make Break Key Make Break
298.1976 +
298.1977 + A 1E 9E N 31 B1
298.1978 + B 30 B0 O 18 98
298.1979 + C 2E AE P 19 99
298.1980 + D 20 A0 Q 10 90
298.1981 + E 12 92 R 13 93
298.1982 + F 21 A1 S 1F 9F
298.1983 + G 22 A2 T 14 94
298.1984 + H 23 A3 U 16 96
298.1985 + I 17 97 V 2F AF
298.1986 + J 24 A4 W 11 91
298.1987 + K 25 A5 X 2D AD
298.1988 + L 26 A6 Y 15 95
298.1989 + M 32 B2 Z 2C AC
298.1990 +
298.1991 + Key Make Break Key Make Break
298.1992 +
298.1993 + 1 02 82 - 0C 8C
298.1994 + 2 03 83 = 0D 8D
298.1995 + 3 04 84 [ 1A 9A
298.1996 + 4 05 85 ] 1B 9B
298.1997 + 5 06 86 ; 27 A7
298.1998 + 6 07 87 ' 28 A8
298.1999 + 7 08 88 ` 29 A9
298.2000 + 8 09 89 \ 2B AB
298.2001 + 9 0A 8A , 33 B3
298.2002 + 0 0B 8B . 34 B4
298.2003 + / 35 B5
298.2004 +
298.2005 +
298.2006 +Enhanced Keyboard Keys (101/102 keys)
298.2007 +
298.2008 + Control Keys Make Break
298.2009 +
298.2010 + Alt-PrtSc (SysReq) 54 D4
298.2011 + Ctrl-PrtSc E0 37 E0 B7
298.2012 + Enter E0 1C E0 9C
298.2013 + PrtSc E0 2A E0 37 E0 B7 E0 AA
298.2014 + Right Alt E0 38 E0 B8
298.2015 + Right Ctrl E0 1D E0 9D
298.2016 + Shift-PrtSc E0 37 E0 B7
298.2017 + / E0 35 E0 B5
298.2018 + Pause E1 1D 45 E1 9D C5 (not typematic)
298.2019 + Ctrl-Pause (Ctrl-Break) E0 46 E0 C6 (not typematic)
298.2020 +
298.2021 + - Keys marked as "not typematic" generate one stream of bytes
298.2022 + without corresponding break scan code bytes (actually the
298.2023 + break codes are part of the make code).
298.2024 +
298.2025 +
298.2026 + Normal Mode or
298.2027 + Shift w/Numlock
298.2028 + Key Make Break |----- Numlock on ------.
298.2029 + Make Break
298.2030 + Del E0 53 E0 D3 E0 2A E0 53 E0 D3 E0 AA
298.2031 + Down arrow E0 50 E0 D0 E0 2A E0 50 E0 D0 E0 AA
298.2032 + End E0 4F E0 CF E0 2A E0 4F E0 CF E0 AA
298.2033 + Home E0 47 E0 C7 E0 2A E0 47 E0 C7 E0 AA
298.2034 + Ins E0 52 E0 D2 E0 2A E0 52 E0 D2 E0 AA
298.2035 + Left arrow E0 4B E0 CB E0 2A E0 4B E0 CB E0 AA
298.2036 + PgDn E0 51 E0 D1 E0 2A E0 51 E0 D1 E0 AA
298.2037 + PgUp E0 49 E0 C9 E0 2A E0 49 E0 C9 E0 AA
298.2038 + Right arrow E0 4D E0 CD E0 2A E0 4D E0 CD E0 AA
298.2039 + Up arrow E0 48 E0 C8 E0 2A E0 48 E0 C8 E0 AA
298.2040 +
298.2041 + Key |--Left Shift Pressed--. |--Right Shift Pressed--.
298.2042 + Make Break Make Break
298.2043 + Del E0 AA E0 53 E0 D3 E0 2A E0 B6 E0 53 E0 D3 E0 36
298.2044 + Down arrow E0 AA E0 50 E0 D0 E0 2A E0 B6 E0 50 E0 D0 E0 36
298.2045 + End E0 AA E0 4F E0 CF E0 2A E0 B6 E0 4F E0 CF E0 36
298.2046 + Home E0 AA E0 47 E0 C7 E0 2A E0 B6 E0 47 E0 C7 E0 36
298.2047 + Ins E0 AA E0 52 E0 D2 E0 2A E0 B6 E0 52 E0 D2 E0 36
298.2048 + Left arrow E0 AA E0 4B E0 CB E0 2A E0 B6 E0 4B E0 CB E0 36
298.2049 + PgDn E0 AA E0 51 E0 D1 E0 2A E0 B6 E0 51 E0 D1 E0 36
298.2050 + PgUp E0 AA E0 49 E0 C9 E0 2A E0 B6 E0 49 E0 C9 E0 36
298.2051 + Right arrow E0 AA E0 4D E0 CD E0 2A E0 B6 E0 4D E0 CD E0 36
298.2052 + Up arrow E0 AA E0 48 E0 C8 E0 2A E0 B6 E0 48 E0 C8 E0 36
298.2053 + / E0 AA E0 35 E0 B5 E0 2A E0 B6 E0 35 E0 B5 E0 36
298.2054 +
298.2055 +
298.2056 + - The PS/2 models have three make/break scan code sets. The first
298.2057 + set matches the PC & XT make/break scan code set and is the one
298.2058 + listed here. Scan code sets are selected by writing the value F0
298.2059 + to the keyboard via the 8042 (port 60h). The following is a brief
298.2060 + description of the scan code sets (see the PS/2 Technical Reference
298.2061 + manuals for more information on scan code sets 2 and 3):
298.2062 +
298.2063 + / set 1, each key has a base scan code. Some keys generate
298.2064 + extra scan codes to generate artificial shift states. This
298.2065 + is similar to the standard scan code set used on the PC and XT.
298.2066 + / set 2, each key sends one make scan code and two break scan
298.2067 + codes bytes (F0 followed by the make code). This scan code
298.2068 + set is available on the IBM AT also.
298.2069 + / set 3, each key sends one make scan code and two break scan
298.2070 + codes bytes (F0 followed by the make code) and no keys are
298.2071 + altered by Shift/Alt/Ctrl keys.
298.2072 + / typematic scan codes are the same as the make scan code
298.2073 +
298.2074 + - Some Tandy 1000's do not handle Alt key combinations when multiple
298.2075 + shift keys are pressed. The Alt-Shift-H combination loses the Alt.
298.2076 + - extended keys like (F11, F12) can only be read with systems that
298.2077 + have extended keyboard BIOS support (or INT 9 extensions); to
298.2078 + read these special keys on these systems INT 16,10 must be used
298.2079 +
298.2080 +
298.2081 +******************************************************************************
298.2082 +*** GRLDR Error messages ***
298.2083 +******************************************************************************
298.2084 +
298.2085 +1. Missing MBR-helper.
298.2086 +
298.2087 + The helper function in the sectors that immediately follow the MBR is
298.2088 + not present, or it has been erased by a virus or by Windows XP/Vista.
298.2089 +
298.2090 + Run the bootlace.com utility to fix the problem.
298.2091 +
298.2092 +2. Buggy BIOS!
298.2093 +
298.2094 + Your BIOS is too buggy. It even has no support for INT13/AH=8.
298.2095 +
298.2096 + No solution except flashing your BIOS. Buggy BIOSes will encounter
298.2097 + more and more problems with grub4dos in the future.
298.2098 +
298.2099 +3. This partition is NTFS but with unknown boot record. Please install
298.2100 +Microsoft NTFS boot sectors to this partition correctly, or create an
298.2101 +FAT12/16/32 partition and place the same copy of GRLDR and MENU.LST there.
298.2102 +
298.2103 + The boot record was changed or erased by Microsoft Windows XP Service
298.2104 + Pack 2.
298.2105 +
298.2106 + You may install the old boot record introduced with the original clean
298.2107 + Windows 2K/XP. As another solution, you may create an FAT partition
298.2108 + for your system, and copy GRLDR and your MENU.LST to its root dir.
298.2109 +
298.2110 + While the startup code of grldr might fail to load GRLDR in NTFS
298.2111 + partitions, it always successfully loads GRLDR in FAT partitions(and
298.2112 + even in ext2/ext3 partitions).
298.2113 +
298.2114 + Note that NTLDR only loads the startup code of grldr(i.e., the leading
298.2115 + 16 sectors of grldr), not the whole grldr file.
298.2116 +
298.2117 + Thus, C:\GRLDR must exist(here C: can be NTFS), since it is used for
298.2118 + BOOT.INI and NTLDR. If C: is NTFS, X:\GRLDR should exist as well,
298.2119 + where X: stands for a certain FAT partition.
298.2120 +
298.2121 +
298.2122 +******************************************************************************
298.2123 +*** Known BIOS bugs ***
298.2124 +******************************************************************************
298.2125 +
298.2126 +1. Some newer Dell machines have no int13/AH=43h support. You may encounter
298.2127 + failure when trying to write-access an emulated disk.
298.2128 +
298.2129 + Note: This bug is serious! The old "root+setup" installation method
298.2130 + (in real mode grub environment) uses INT13 to write the first sector
298.2131 + of stage2. It will fail for the buggy DELL machine when stage2 is
298.2132 + accessed with LBA mode.
298.2133 +
298.2134 +2. Some buggy BIOSes won't boot bootable.iso(See above).(qemu can boot it fine)
298.2135 +
298.2136 +3. Some newer Dell machines violently destroyed the interrupt vectors for
298.2137 + hardware IRQs and will hang the machine when running GRUB.EXE
298.2138 + from DOS. You may try again with BADGRUB.EXE.
298.2139 +
298.2140 +4. Reports say some BIOSes will function abnormally after GRUB.EXE is started
298.2141 + by kexec of Linux. Some machines reportedly hang. Some others
298.2142 + reportedly cannot access USB drives.
298.2143 +
298.2144 +
298.2145 +******************************************************************************
298.2146 +*** Known Problems ***
298.2147 +******************************************************************************
298.2148 +
298.2149 +1. Running GRUB.EXE from a DOS box of Windows 9x/Me could hang the
298.2150 + machine, especially for some systems with USB support. You may
298.2151 + encounter the same problem when running GRUB.EXE through KEXEC under
298.2152 + Linux.
298.2153 +
298.2154 +Note: You don't have to run GRUB.EXE from protected mode of Win9x, which
298.2155 + could hang the machine; Instead, you usually want to run GRUB.EXE
298.2156 + after you have done a "Restart the computer in MS-DOS mode", which
298.2157 + is safe enough.
298.2158 +
298.2159 +2. The default chainloader action will keep A20 on. Some buggy DOS XMS
298.2160 + memory managers could hang the machine. You may use the --disable-a20
298.2161 + option in the chainloader line and try again. Anyway, you should avoid
298.2162 + using those buggy memory managers.
298.2163 +
298.2164 +3. THTF BIOS L4S5M Ver 1.1a(dated 2022-1-10) has a buggy int15 which
298.2165 + causes hang at the boot of a multi boot kernel(memdisk for example).
298.2166 +
298.2167 +4. A Chinese DOS system software, the TechWay SCS, will not work with
298.2168 + newer versions of GRUB.EXE. In general, TSRs that take antitracking
298.2169 + measures will not work with GRUB.EXE any more.
298.2170 +
298.2171 +
298.2172 +******************************************************************************
298.2173 +*** List of binary files and their corresponding source files ***
298.2174 +******************************************************************************
298.2175 +
298.2176 +binary file main source file other included source or binary files
298.2177 +------------- ---------------- -------------------------------------
298.2178 +
298.2179 +bootlace.com bootlacestart.S bootlace.inc, grldrstart.S
298.2180 +
298.2181 +grldr grldrstart.S pre_stage2(binary, See note below)
298.2182 +
298.2183 +grldr.mbr mbrstart.S grldrstart.S
298.2184 +
298.2185 +grub.exe dosstart.S pre_stage2(binary, See note below)
298.2186 +
298.2187 +hmload.com hmloadstart.S
298.2188 +
298.2189 +-----------------------------------------------------------------------------
298.2190 +
298.2191 +Note: pre_stage2 is the main body of GNU GRUB and it is simply appended to
298.2192 +grldrstart/dosstart in binary format to form our grldr/grub.exe.
298.2193 +
298.2194 +Note: The GRUB file(WITHOUT .EXE suffix) is a static-linked ELF executable
298.2195 +program for Linux, normally called the GRUB Shell. The GRUB Shell is a boot-
298.2196 +manager, but not a boot-loader(the "boot" command won't work in GRUB Shell).
298.2197 +GRUB.EXE(with KEXEC) can be used as a bootloader running directly under Linux.
298.2198 +
298.2199 +******************************************************************************
298.2200 +*** Memory Layout for Quiting to DOS from GRUB.EXE ***
298.2201 +******************************************************************************
298.2202 +
298.2203 +The quit command is implemented to return to DOS in the instance that GRUB.EXE
298.2204 +is started off DOS.
298.2205 +
298.2206 +1. Before GRUB.EXE transfers control to pre_stage2, it will copy 640KB of
298.2207 +conventional memory to physical address 0x200000(i.e., 2MB), and write 4 long
298.2208 +integers immediately follows the backup copy of the conventional memory:
298.2209 + At 0x2A0000: 0x50554B42, it is the "BKUP" signature.
298.2210 +
298.2211 + At 0x2A0004: Gate A20 status under DOS: non-zero means A20 on;
298.2212 + zero means A20 off. Update: A20 always on, see below.
298.2213 +
298.2214 + At 0x2A0008: high word is boot-CS, low word is boot-IP. The quit
298.2215 + command uses this entry point to return to DOS.
298.2216 +
298.2217 + At 0x2A000C: CheckSum: the sum of all long integers in the memory
298.2218 + range from 0x200000 to 0x2A000F is 0.
298.2219 +
298.2220 +2. If the above memory structure is corrupted by a grub command, the quit
298.2221 +command will issue an error message and refuse to exit from grub.
298.2222 +
298.2223 +3. Because GRUB may corrupt extended memory, you should better avoid using
298.2224 +extended memory under DOS before running GRUB.EXE.
298.2225 +
298.2226 +4. Gate A20 will be enabled by GRUB.EXE. Hopefully this would hurt nothing.
298.2227 +
298.2228 +
298.2229 +******************************************************************************
298.2230 +*** Memory usage in conventional/low memory area ***
298.2231 +******************************************************************************
298.2232 +
298.2233 +1. boot.c, fsys_reiserfs.c: 8K below 0x68000.
298.2234 +
298.2235 +2. fsys_ext2fs.c, fsys_minix.c: 1K below 0x68000.
298.2236 +
298.2237 +3. fsys_jfs.c: 4K + 256 bytes below 0x68000.
298.2238 +
298.2239 +4. fsys_reiserfs.c: 202 bytes at 0x600.
298.2240 +
298.2241 +5. fsys_xfs.c: 188 bytes at 0x600.
298.2242 +
298.2243 +6. fsys_xfs.c: (logical block size) bytes below 0x68000.
298.2244 +
298.2245 +7. geometry tune: 0x50000 - 0x5ffff.
298.2246 +
298.2247 +******************************************************************************
298.2248 +*** Command-line Length about GRUB.EXE ***
298.2249 +******************************************************************************
298.2250 +
298.2251 +GRUB.EXE now can be started in CONFIG.SYS with the **DEVICE** command:
298.2252 +
298.2253 + DEVICE=grub.exe [--config-file="FILENAME_OR_COMMANDS"]
298.2254 +
298.2255 +1. If GRUB.EXE is invoked with DEVICE command and FILENAME_OR_COMMANDS is a
298.2256 +collection of some GRUB commands separated by semi-colon, then the length of
298.2257 +FILENAME_OR_COMMANDS can be nearly 4KB ----Supprise? But true! MS-DOS 7+
298.2258 +even allows a much longer line, but 4KB seems enough for our use of GRUB.EXE.
298.2259 +This is very useful when we want to embed a big menu into the command line.
298.2260 +Note that GRLDR hasn't yet supported any command-line arguments.
298.2261 +
298.2262 +2. If GRUB.EXE is invoked with INSTALL command, the option length has a limit
298.2263 +of 80 characters(including the leading "--config-file=" part). An overflow may
298.2264 +hang up MS-DOS immediately.
298.2265 +
298.2266 +3. If GRUB.EXE is invoked with SHELL command, the option length has a limit of
298.2267 +126 characters(including the leading "--config-file=" part). Overflow won't
298.2268 +hang up MS-DOS, but the line will be cut short. This limit is the same as that
298.2269 +in the console-DOS-prompt or in a BAT file.
298.2270 +
298.2271 +4. The DOS editor EDIT does not allow to create a line of 4KB long. So use
298.2272 +another editor, for example, vi for Linux, please.
298.2273 +
298.2274 +5. The DEVICE=GRUB.EXE line can be used together with other DEVICE commands
298.2275 +such as DEVICE=HIMEM.SYS and DEVICE=EMM386.EXE. The GRUB.EXE line should
298.2276 +occur before the EMM386.EXE line in order to avoid the rejection by EMM386.
298.2277 +Update: Since 0.4.2, GRUB.EXE works well even after EMM386.EXE is loaded.
298.2278 +
298.2279 +6. In any case mentioned above, you can return back to DOS by quit command.
298.2280 +
298.2281 +7. Memory usage about command-line menu: The 4KB command-line menu starts at
298.2282 +physical address 0x0800 and ends at 0x17FF.
298.2283 +
298.2284 +******************************************************************************
298.2285 +*** New Syntax for the DEFAULT/SAVEDEFAULT Commands ***
298.2286 +******************************************************************************
298.2287 +
298.2288 +In addition to the original usage of "default NUM" and "default saved", now
298.2289 +there is a new usage of "default FILE", like this:
298.2290 +
298.2291 + default (hd0,0)/default
298.2292 +
298.2293 +Note that FILE must have a valid DEFAULT file format. A sample DEFAULT file
298.2294 +is included in the release. You may copy it to wherever you like, but you
298.2295 +should avoid modifying its content manually. The DEFAULT file may be used
298.2296 +in this way:
298.2297 +
298.2298 +(1) First, you should copy a default file with valid format to somewhere in
298.2299 +your operating system.
298.2300 +
298.2301 +(2) Secondly, you should use the "default FILE" command of GRUB to announce
298.2302 +the use of FILE as our new default file for being written by "savedefault".
298.2303 +
298.2304 +(3) Then, you may use "savedefault" command to save the desired entry number
298.2305 +into this new default file.
298.2306 +
298.2307 +(4) OK, at next boot, you may read the saved entry number by using the same
298.2308 +"default FILE" command as mentioned in above (2).
298.2309 +
298.2310 +And the SAVEDEFAULT command now accept an options `--wait=T', like this:
298.2311 +
298.2312 + savedefault --wait=5
298.2313 +
298.2314 +If `--wait=T' is specified and T is non-zero, savedefault will prompt
298.2315 +the user with a message just before it writes to disk. The write operation
298.2316 +will be cancelled in T seconds if the `Y' key was not pressed.
298.2317 +
298.2318 +Here is a sample menu.lst file:
298.2319 +
298.2320 +#--------------------begin menu.lst---------------------------------------
298.2321 +color black/cyan yellow/cyan
298.2322 +timeout 30
298.2323 +default /default
298.2324 +
298.2325 +title find and load NTLDR of Windows NT/2K/XP
298.2326 +find --set-root /ntldr
298.2327 +chainloader /ntldr
298.2328 +savedefault --wait=2
298.2329 +
298.2330 +title find and load CMLDR, the Recovery Console of Windows NT/2K/XP
298.2331 +fallback 2
298.2332 +find --set-root /cmldr
298.2333 +chainloader /cmldr
298.2334 +#####################################################################
298.2335 +# write string "cmdcons" to memory 0000:7C03 in 2 steps:
298.2336 +#####################################################################
298.2337 +# step 1. Write 4 chars "cmdc" at 0000:7C03
298.2338 +write 0x7C03 0x63646D63
298.2339 +# step 2. Write 3 chars "ons" and an ending null at 0000:7C07
298.2340 +write 0x7C07 0x00736E6F
298.2341 +savedefault --wait=2
298.2342 +
298.2343 +title find and load IO.SYS of Windows 9x/Me
298.2344 +find --set-root /io.sys
298.2345 +chainloader /io.sys
298.2346 +savedefault --wait=2
298.2347 +
298.2348 +title floppy (fd0)
298.2349 +chainloader (fd0)+1
298.2350 +rootnoverify (fd0)
298.2351 +savedefault --wait=2
298.2352 +
298.2353 +title find and boot Linux with menu.lst already installed
298.2354 +find --set-root /sbin/init
298.2355 +savedefault --wait=2
298.2356 +configfile /boot/grub/menu.lst
298.2357 +
298.2358 +title find and boot Mandriva with menu.lst already installed
298.2359 +find --set-root /etc/mandriva-release
298.2360 +savedefault --wait=2
298.2361 +configfile /boot/grub/menu.lst
298.2362 +
298.2363 +title back to dos
298.2364 +savedefault --wait=2
298.2365 +quit
298.2366 +
298.2367 +title commandline
298.2368 +savedefault --wait=2
298.2369 +commandline
298.2370 +
298.2371 +title reboot
298.2372 +savedefault --wait=2
298.2373 +reboot
298.2374 +
298.2375 +title halt
298.2376 +savedefault --wait=2
298.2377 +halt
298.2378 +#--------------------end menu.lst---------------------------------------
298.2379 +
298.2380 +Note 1: The file DEFAULT must exist and have a proper format as stated above.
298.2381 + Or else, the default/savedefault commands won't function well.
298.2382 +
298.2383 +Note 2: The file DEFAULT which is in the same dir as a certain MENU.LST file
298.2384 + is called associated with the MENU.LST file.
298.2385 +
298.2386 +Note 3: The associated DEFAULT file will take effect automatically if there
298.2387 + are no `default' commands present.
298.2388 +
298.2389 +Note 4: Just before a menu file gains control(e.g., it is the associated
298.2390 + MENU.LST of a GRLDR file, or it was specified via
298.2391 + `grub.exe --config-file=(DEVICE)/PATH/YOUR_MENU_FILE', or it was
298.2392 + specified by the `configfile' command of grub), its associated
298.2393 + DEFAULT file will be used if present, until an explicit `default'
298.2394 + command is encountered.
298.2395 +
298.2396 +******************************************************************************
298.2397 +*** The New `cdrom' Command Syntax ***
298.2398 +******************************************************************************
298.2399 +
298.2400 +1. Initialize the ATAPI CDROM devices:
298.2401 +
298.2402 + grub> cdrom --init
298.2403 +
298.2404 + This will display the number of atapi cdroms found: atapi_dev_count
298.2405 +
298.2406 +2. Stop the ATAPI CDROM devices:
298.2407 +
298.2408 + grub> cdrom --stop
298.2409 +
298.2410 + This will set atapi_dev_count to 0.
298.2411 +
298.2412 +3. Add IO ports for searching the atapi cdrom devices. For example:
298.2413 +
298.2414 + grub> cdrom --add-io-ports=0x03F601F0
298.2415 +
298.2416 +After running `cdrom --init' and `map --hook', the cdroms can be accessed
298.2417 +through devices (cd0), (cd1), ...
298.2418 +
298.2419 +Note 1: If the system does not fully support the ATAPI CD-ROM specifications,
298.2420 + you will encounter failure when trying to access the (cdX) devices.
298.2421 +
298.2422 +Note 2: After doing a `cdrom --stop', you should do a `map --unhook'. Of
298.2423 + course you may `map --hook' again if there are mapped drives.
298.2424 +
298.2425 +Note 3: After adding IO ports, you should do a `map --unhook' followed by a
298.2426 + `cdrom --init' and then followed by a `map --hook'.
298.2427 +
298.2428 + By default, these ports are used for searching cdroms(so they needn't
298.2429 + be added):
298.2430 +
298.2431 + 0x03F601F0, 0x03760170, 0x02F600F0,
298.2432 + 0x03860180, 0x6F006B00, 0x77007300.
298.2433 +
298.2434 +Note 4: The BIOS might have offered a cdrom interface. It would be (cd). After
298.2435 + `cdrom --init' and `map --hook', we might have our (cd0), (cd1), ...
298.2436 + available. It is likely that one of them could access the same media
298.2437 + as the BIOS-offered (cd).
298.2438 +
298.2439 +Note 5: You may access the (cd) and (cdX)'es in the blocklist way. Example:
298.2440 +
298.2441 + cat --hex (cd0)16+2
298.2442 +
298.2443 + The cdrom sectors are big sectors with a size of 2048 bytes.
298.2444 +
298.2445 +Note 6: The iso9660 filesystem driver has Rock-Ridge extension support, but
298.2446 + has no Joliet extension support. So you may encounter failure when
298.2447 + you attempt to read files on a Joliet CD.
298.2448 +
298.2449 +Note 7: The (cd) or (cdX)'es can be booted now. Examples:
298.2450 +
298.2451 + chainloader (cd)
298.2452 + boot
298.2453 +
298.2454 + chainloader (cd0)
298.2455 + boot
298.2456 +
298.2457 + chainloader (cd1)
298.2458 + boot
298.2459 +
298.2460 + You should already have access to the CD sectors before you can
298.2461 + chainload it.
298.2462 +
298.2463 +******************************************************************************
298.2464 +*** About the New `setvbe' Command ***
298.2465 +******************************************************************************
298.2466 +
298.2467 +Gerardo Richarte contributed the `setvbe' code and the following comment:
298.2468 +
298.2469 + New command is `setvbe', and can be used to change the video mode
298.2470 + before executing the kernel.
298.2471 +
298.2472 + For example, you can do
298.2473 +
298.2474 + setvbe 1024x768x32
298.2475 +
298.2476 + this will scan the list of available modes and set it, and
298.2477 + automatically append a `video=' option to each subsequent kernel
298.2478 + command-line. The appended `video=' option is like this:
298.2479 +
298.2480 + video=1024x768x32@0xf0000000,4096
298.2481 +
298.2482 + where 0xf0000000 is the video framebuffer address as reported by vbe,
298.2483 + and 4096 is the size of a scanline in bytes (also as reported by vbe).
298.2484 +
298.2485 + This is really useful if you want to give some graphics support to your
298.2486 + OS, but you don't want to implement any video functionality other than
298.2487 + writing a pixel to video memory.
298.2488 +
298.2489 +
298.2490 +******************************************************************************
298.2491 +*** About the DOS utility `hmload' ***
298.2492 +******************************************************************************
298.2493 +
298.2494 +This program was written by John Cobb (Queen Mary, University of London).
298.2495 +
298.2496 +John Cobb's note:
298.2497 +
298.2498 + To make use of the ram drive feature I wrote a program `hmload' to load
298.2499 + an arbitrary file to an arbitrary address in high memory. The program
298.2500 + is not very sophisticated and relies on XMS to turn on the A20 line.
298.2501 + (Also one must be very careful to steer clear of any areas of memory
298.2502 + already in use).
298.2503 +
298.2504 + Under Linux we generated a disk image `dskimg' (with the kernel and
298.2505 + Initrd and a partition table).
298.2506 +
298.2507 + Using this our boot procedure looked something like this:
298.2508 +
298.2509 + hmload -fdskimg -a128
298.2510 + fixrb
298.2511 + <unload network drivers>
298.2512 + grub
298.2513 +
298.2514 + map --ram-drive=0x81
298.2515 + map --rd-base=0x8000000
298.2516 + map --rd-size=0x400000
298.2517 + root (rd,0)
298.2518 + kernel /kernel root=/dev/ram0 rw ip=bootp ramdisk_size=32768 ...
298.2519 + initrd /initrd
298.2520 + boot
298.2521 +
298.2522 +See http://sysdocs.stu.qmul.ac.uk/sysdocs/Comment/GrubForDOS/ for details.
298.2523 +
298.2524 +Update 2007-12-05:
298.2525 +
298.2526 + Now the MAP command can handle gzipped (rd) image. One can use this
298.2527 + feature with the hmload utility. For example,
298.2528 +
298.2529 + step 1. Load the gzipped image under DOS at a relatively low address:
298.2530 +
298.2531 + hmload -fdskimg.gz -a16
298.2532 +
298.2533 + step 2. Unload network drivers.
298.2534 +
298.2535 + step 3. Run GRUB.EXE.
298.2536 +
298.2537 + step 4. At the grub prompt, run these commands:
298.2538 +
298.2539 + map --rd-base=0x1000000 # set rd-base address to be 16M
298.2540 + map --rd-size=<the accurate size of dskimg.gz in bytes>
298.2541 + map (rd)+1 (hd0) # This will decompress (rd) and place
298.2542 + # the decompressed image at the top end
298.2543 + # of the extended memory. The (rd)+1
298.2544 + # here has special meaning and stands
298.2545 + # for the whole (rd) device. You must
298.2546 + # use (rd)+1 instead of (rd).
298.2547 + map --hook
298.2548 + root (hd0,0)
298.2549 + kernel /kernel root=/dev/ram0 rw ip=bootp ramdisk_size=32768 ...
298.2550 + initrd /initrd
298.2551 + map --unhook
298.2552 + map (hd0) (hd0) # Delete the map; this is needed.
298.2553 + boot
298.2554 +
298.2555 +
298.2556 +******************************************************************************
298.2557 +*** Notes on the use of stack ***
298.2558 +******************************************************************************
298.2559 +
298.2560 +The protected-mode and real-mode stack are merged at physical address 0x2000.
298.2561 +
298.2562 +All functions should use at most 2K stack space(0x1800-0x2000). So each
298.2563 +subfunction should use as little stack as possible to avoid stack-overflow.
298.2564 +
298.2565 +Don't use recursive functions because they could expend too much stack space.
298.2566 +
298.2567 +The original protected mode stack at 0x68000(expand-down) is free now and can
298.2568 +be reused for any purposes.
298.2569 +
298.2570 +
298.2571 +******************************************************************************
298.2572 +*** A bug was found in the CDROM driver ***
298.2573 +******************************************************************************
298.2574 +
298.2575 +It seems the cdrom must be connected as the master device of an IDE controller.
298.2576 +
298.2577 +If cdrom is slave, the driver will fail to read the cdrom sectors. Hope someone
298.2578 +
298.2579 +could fix this problem.
298.2580 +
298.2581 +
298.2582 +******************************************************************************
298.2583 +*** BIOS and the (cd) drive ***
298.2584 +******************************************************************************
298.2585 +
298.2586 +When BIOS boots a no-emulation-mode bootable CD-ROM, it allocates a BIOS drive
298.2587 +number to the CD. If the boot image of the CD-ROM is grldr or stage2_eltorito,
298.2588 +then GRUB can access the CD-ROM media through the drive number allocated by
298.2589 +BIOS. The device name of the CD-ROM is (cd).
298.2590 +
298.2591 +BIOS can allocate a BIOS drive number to a no-emulation-mode CDROM even when
298.2592 +the CDROM is not bootable. QEMU has done so. At boot time, GRUB4DOS will
298.2593 +search drives 0x80-0xFF for a possible no-emulation-mode CDROM drive allocated
298.2594 +by BIOS. So if BIOS offered a CDROM interface of int13 EBIOS functions 41h-4Eh,
298.2595 +then the (cd) device will be automatically available in GRUB4DOS.
298.2596 +
298.2597 +
298.2598 +******************************************************************************
298.2599 +*** The way of disk emulation changed greatly ***
298.2600 +******************************************************************************
298.2601 +
298.2602 +The way of disk emulation has changed greatly since 0.4.2 final. Please don't
298.2603 +mix newer versions with older versions when disk emulation features are used.
298.2604 +
298.2605 +The newer versions won't automatically unhook emulations established in a
298.2606 +previous grub4dos environment. The GRUB.EXE of an older version will
298.2607 +automatically dismiss emulations established earlier, before transferring
298.2608 +control to the main grub program(i.e., pre_stage2).
298.2609 +
298.2610 +
298.2611 +******************************************************************************
298.2612 +*** FreeDOS EMM386 v2.26 (2021-08-27) VCPI problem ***
298.2613 +******************************************************************************
298.2614 +
298.2615 +The VCPI function "AX=DE0Ch - Switch From Protected Mode to V86 Mode" of
298.2616 +FreeDOS EMM386 v2.26 was not implemented properly(it always hangs). As an
298.2617 +alternative, you can use Microsoft's EMM386 instead.
298.2618 +
298.2619 +Even while emm386 is running, grub.exe can be started. But if you try to quit
298.2620 +to DOS from grub4dos by using the `quit' command, the VCPI function DE0C will
298.2621 +be called. If EMM386 is of Microsoft, everything goes ok. If EMM386 is of
298.2622 +FreeDOS, the machine will hang.
298.2623 +
298.2624 +
298.2625 +******************************************************************************
298.2626 +*** New options for map were added ***
298.2627 +******************************************************************************
298.2628 +
298.2629 +Along with 0.4.2 final, there are two new options for the map command. They
298.2630 +are --safe-mbr-hook=SMH and --int13-scheme=SCH. Both are related with disk
298.2631 +emulation for use(as smoothly as possible) in the Win9x environment.
298.2632 +
298.2633 +SMH can take either of the two values 0 and 1. By default, SMH is 1. If you
298.2634 +encountered problems of disk emulation under Win9x, you may insert a line of
298.2635 +
298.2636 + map --safe-mbr-hook=0
298.2637 +
298.2638 +before the `boot' command and try again.
298.2639 +
298.2640 +Also SCH may take either 0 or 1 at present. By default, SCH is 1. If you
298.2641 +encountered disk emulation problems under Win9x, you may insert a line of
298.2642 +
298.2643 + map --int13-scheme=0
298.2644 +
298.2645 +before the `boot' command and try again.
298.2646 +
298.2647 +Note by the way. Like --safe-mbr-hook and --int13-scheme, the MAP command has
298.2648 +a few other options that are used for setting global variables. They are here:
298.2649 +
298.2650 + map --floppies=M
298.2651 +
298.2652 +M can be 0, 1, or 2. MAP will set a proper value at 0040:0010 by using M.
298.2653 +
298.2654 + map --harddrives=N
298.2655 +
298.2656 +N can be between 0 and 127(inclusive). MAP will set 0040:0075 to N.
298.2657 +
298.2658 + map --memdisk-raw=RAW
298.2659 +
298.2660 +RAW default to 1. If RAW=0, `int15/ah=87h' will be used to access memdrives.
298.2661 +
298.2662 + map --ram-drive=RD
298.2663 +
298.2664 +RD default to 0x7F which is a floppy. If the RAM DRIVE is a hard drive image
298.2665 +(with partition table in the first sector), you should set RD >= 0x80 and RD
298.2666 +< 0xFF.
298.2667 +
298.2668 + map --rd-base=ADDR
298.2669 +
298.2670 + map --rd-size=SIZE
298.2671 +
298.2672 +ADDR specifies the physical base address of the ramdisk image. SIZE specifies
298.2673 +the size in bytes of the ramdisk image. ADDR default to 0. SIZE is also default
298.2674 +to 0, but a size of 0 means 4GB, not a zero-long disk. The RAM DRIVE can be
298.2675 +accessed in the GRUB environment using the (rd) device.
298.2676 +
298.2677 +
298.2678 +******************************************************************************
298.2679 +*** About the new map option --in-situ ***
298.2680 +******************************************************************************
298.2681 +
298.2682 +--in-situ is used with hard drive images or hardrive partitions. With an
298.2683 +in-situ map, we can typically use a logical partition as a primary partition.
298.2684 +
298.2685 +In-situ map is a whole drive map. It only virtualize the partition table and
298.2686 +the number of hidden sectors in the BPB of the DOS Boot Record.
298.2687 +
298.2688 +While disk emulation may encounter various problems with win9x, the in-situ map
298.2689 +works fine with win9x.
298.2690 +
298.2691 +Note that --in-situ will not change the real partition table.
298.2692 +
298.2693 +Example:
298.2694 +
298.2695 + map --in-situ (hd0,4)+1 (hd0)
298.2696 +
298.2697 +
298.2698 +******************************************************************************
298.2699 +*** The PARTNEW Command Syntax ***
298.2700 +******************************************************************************
298.2701 +
298.2702 +Besides the mappings in the above section, you may instead choose to create a
298.2703 +new primary partition with the PARTNEW command. PARTNEW can generate a primary
298.2704 +partition entry (in the partition table) for a logical partition.
298.2705 +
298.2706 +For example,
298.2707 +
298.2708 + partnew (hd0,3) 0x07 (hd0,4)+1
298.2709 +
298.2710 +where the file (hd0,4)+1 stands for the whole partition (hd0,4). This command
298.2711 +will create a new primary partition (hd0,3) whose type is 0x07 and whose
298.2712 +contents/data is the same as that of the logical partition (hd0,4).
298.2713 +
298.2714 +Just like a whole logical partition, a contiguous partition image file can
298.2715 +also be used with PARTNEW:
298.2716 +
298.2717 + partnew (hd0,3) 0x00 (hd0,0)/my_partition.img
298.2718 +
298.2719 +The type 0x00 indicates a type-auto-detection of the image MY_PARTITION.IMG.
298.2720 +The above command will create a new primary partition (hd0,3) with a proper
298.2721 +type and with contents/data being exactly that of the contiguous file
298.2722 +(hd0,0)/my_partition.img.
298.2723 +
298.2724 +PARTNEW will automatically correct the "hidden sectors" in the BPB and the
298.2725 +modification will be permanent. And PARTNEW modifies the partition table
298.2726 +permanently.
298.2727 +
298.2728 +In addition to creating new partition entries, PARTNEW can also be used to
298.2729 +delete(erase, or wipe) a primary partition entry. For example,
298.2730 +
298.2731 + partnew (hd0,3) 0 0 0
298.2732 +
298.2733 +which will empty the last entry in the partition table in MBR. Generally,
298.2734 +you should use the form of "partnew PARTITION 0 0 0" to erase the entry.
298.2735 +Note that only the entry would be erased, and the data stored in the partition
298.2736 +will not be touched.
298.2737 +
298.2738 +******************************************************************************
298.2739 +*** Newly implemented operators `&&' and `||' ***
298.2740 +******************************************************************************
298.2741 +
298.2742 +This implementation is very simple. It does not handle operator nesting.
298.2743 +
298.2744 +Usage of `&&':
298.2745 +
298.2746 + command1 && command2
298.2747 +
298.2748 +Description:
298.2749 +
298.2750 + If command1 returns true, then command2 will be executed.
298.2751 +
298.2752 +Usage of `||':
298.2753 +
298.2754 + command1 || command2
298.2755 +
298.2756 +Description:
298.2757 +
298.2758 + If command1 returns false, then command2 will be executed.
298.2759 +
298.2760 +Examples:
298.2761 +
298.2762 + is64bit && default 0
298.2763 + is64bit || default 1
298.2764 +
298.2765 +******************************************************************************
298.2766 +*** Three new commands is64bit, errnum and errorcheck ***
298.2767 +******************************************************************************
298.2768 +
298.2769 +is64bit and errnum retrieve the value of is64bit and errnum respectively.
298.2770 +
298.2771 +errorcheck controls whether or not the error will be handled. By default,
298.2772 +errorcheck is on, and menu script execution will stop on error. If errorcheck
298.2773 +is off, the script will continue to execute upto a boot command. A boot command
298.2774 +will turn the errorcheck on.
298.2775 +
298.2776 +
298.2777 +******************************************************************************
298.2778 +*** Use numeric keys to select a menu entry ***
298.2779 +******************************************************************************
298.2780 +
298.2781 +If, for example, you intend to goto entry #25, you may press 2 followed by 5.
298.2782 +
298.2783 +
298.2784 +******************************************************************************
298.2785 +*** Use the INSERT key to debug step by step at startup ***
298.2786 +******************************************************************************
298.2787 +
298.2788 +Some buggy machines could fail to enter grub4dos environment. They might hang
298.2789 +or reboot unexpectedly. Press INSERT as quickly as possible on startup, and
298.2790 +you can get a chance to single-step the boot process and see how far it can
298.2791 +go, and then report bugs.
298.2792 +
298.2793 +
298.2794 +******************************************************************************
298.2795 +*** The debug command syntax has been changed ***
298.2796 +******************************************************************************
298.2797 +
298.2798 +The DEBUG command now can be used to control the verbosity of command output:
298.2799 +
298.2800 + debug [ on | off | normal | status | INTEGER ]
298.2801 +
298.2802 +0 or off for silent
298.2803 +1 or normal for normal
298.2804 +2 to 0x7FFFFFFF or on for verbose
298.2805 +
298.2806 +
298.2807 +******************************************************************************
298.2808 +*** GRUB4DOS and Windows Vista ***
298.2809 +******************************************************************************
298.2810 +
298.2811 +First, use the following command to create a boot entry:
298.2812 +
298.2813 + bcdedit /create /d "GRUB for DOS" /application bootsector
298.2814 +
298.2815 +The result will look like this:
298.2816 +
298.2817 +The entry {05d33150-3fde-11dc-a457-00021cf82fb0} was successfully created.
298.2818 +
298.2819 +The long string {05d33150-3fde-11dc-a457-00021cf82fb0} is the id for this
298.2820 +entry.
298.2821 +
298.2822 +Then, use the following commands to set boot parameters:
298.2823 +
298.2824 + bcdedit /set {id} device boot
298.2825 + bcdedit /set {id} path \grldr.mbr
298.2826 + bcdedit /displayorder {id} /addlast
298.2827 +
298.2828 +Please replace {id} with the actual id returned from the previous command.
298.2829 +
298.2830 +Finally, copy GRLDR.MBR to C:\ or wherever your boot drive is, and copy GRLDR
298.2831 +and menu.lst to the root directory of any FAT16/FAT32/EXT2/NTFS partition.
298.2832 +
298.2833 +Note: A boot partition should be the active primary partition with BOOTMGR
298.2834 + inside. The `device boot' indicates grldr.mbr should be in the boot
298.2835 + partition.
298.2836 +
298.2837 +Lianjiang has written down a script to automate the tasks:
298.2838 +
298.2839 + @echo off
298.2840 + rem by lianjiang
298.2841 + cls
298.2842 + echo.
298.2843 + echo Please run as administrator
298.2844 + echo.
298.2845 + pause
298.2846 + set gname=GRUB for DOS
298.2847 + set vid=
298.2848 + set timeout=5
298.2849 + bcdedit >bcdtemp.txt
298.2850 + type bcdtemp.txt | find "\grldr.mbr" >nul && echo. && echo BCD entry existing, no need to install. && pause && goto exit
298.2851 + bcdedit /export "Bcd_Backup" >nul
298.2852 + bcdedit /create /d "%gname%" /application bootsector >vid.ini
298.2853 + for,/f,"tokens=2 delims={",%%i,In (vid.ini) Do (
298.2854 + set vida=%%i
298.2855 + )
298.2856 + for,/f,"tokens=1 delims=}",%%i,In ("%vida%") Do (
298.2857 + set vid={%%i}
298.2858 + )
298.2859 + echo %vid%>vid.ini
298.2860 + bcdedit /set %vid% device boot >nul
298.2861 + bcdedit /set %vid% path \grldr.mbr >nul
298.2862 + bcdedit /displayorder %vid% /addlast >nul
298.2863 + bcdedit /timeout %timeout% >nul
298.2864 + if exist grldr.mbr copy grldr.mbr %systemdrive%\ /y && goto exit
298.2865 + echo.
298.2866 + echo Please copy grldr.mbr to %systemdrive%\
298.2867 + echo.
298.2868 + pause
298.2869 + :exit
298.2870 + del bcdtemp.txt >nul
298.2871 +-------------------------------------------------------------------
298.2872 +Update: Fujianabc pointed out that
298.2873 +
298.2874 + bcdedit /set %vid% device boot >nul
298.2875 +
298.2876 +should be changed to
298.2877 +
298.2878 + bcdedit /set %vid% device partition=%SystemDrive% >nul
298.2879 +-------------------------------------------------------------------
298.2880 +
298.2881 +You still need to copy grldr yourself.
298.2882 +
298.2883 +Notice: It's possible to modify the BCD entry from a different OS, you just
298.2884 +need to specify the location of BCD:
298.2885 +
298.2886 + bcdedit /store D:\boot\BCD ...
298.2887 +
298.2888 +Notice: These commands need elevated privileges, they should be used inside
298.2889 +cmd.exe which is started with "Run as administrator".
298.2890 +
298.2891 +Notice: People has reported that some version of Vista doesn't support
298.2892 +creating file in C:\ with no extension, even with administrator privileges.
298.2893 +This means grldr can't be placed in C:\. You can solve this by either copy
298.2894 +grldr to another partition, or rename grldr to something like grub.bin. Please
298.2895 +see the following section on how to do this.
298.2896 +
298.2897 +
298.2898 +******************************************************************************
298.2899 +*** How to rename grldr ***
298.2900 +******************************************************************************
298.2901 +
298.2902 +grldr and grldr.mbr use internal boot file name to decide which file to load,
298.2903 +so if you want to change the name, you must also change the embeded setting.
298.2904 +You can do this with the help of grubinst, which can be downloaded at:
298.2905 +
298.2906 +http://download.gna.org/grubutil/
298.2907 +
298.2908 +grubinst can generate customized grldr.mbr:
298.2909 +
298.2910 + grubinst -o -b=mygrldr C:\mygrldr.mbr
298.2911 +
298.2912 +grubinst can also edit existing grldr/grldr.mbr:
298.2913 +
298.2914 + grubinst -e -b=mygrldr C:\mygrldr
298.2915 +
298.2916 + grubinst -e -b=mygrldr C:\mygrldr.mbr
298.2917 +
298.2918 +In this case, you must use a grubinst that is compatible with the version of
298.2919 +grub4dos, otherwise the edit will fail.
298.2920 +
298.2921 +So, in order to load mygrldr instead of grldr, you can use one of the
298.2922 +following methods:
298.2923 +
298.2924 +1. Use customized grldr.mbr to load mygrldr. In this case, you need to change
298.2925 +the embeded boot file name in grldr.mbr. The name of grldr.mbr can be changed
298.2926 +at will.
298.2927 +
298.2928 +2. Use mygrldr directly. In this case, you need to change the embeded boot
298.2929 +file name in mygrldr to match its new name.
298.2930 +
298.2931 +Notice: The boot file name must conform to the 8.3 naming convention.
298.2932 +
298.2933 +
298.2934 +******************************************************************************
298.2935 +*** PXE device ***
298.2936 +******************************************************************************
298.2937 +
298.2938 +If PXE service is found at startup, GRUB4DOS will create a virtual device
298.2939 +(pd), through which files from the tftp server can be accessed. You can setup
298.2940 +a diskless boot environment using the following steps:
298.2941 +
298.2942 +Client side
298.2943 +
298.2944 +You need to boot from PXE ROM.
298.2945 +
298.2946 +Server side
298.2947 +
298.2948 +You need to configure a dhcp server and a tftp server. In the dhcp server, use
298.2949 +grldr as boot file.
298.2950 +
298.2951 +You may also want to load a different menu.lst for different client. GRUB4DOS
298.2952 +will scan the following location for configuration file:
298.2953 +
298.2954 + [/mybootdir]/menu.lst/01-88-99-AA-BB-CC-DD
298.2955 + [/mybootdir]/menu.lst/C000025B
298.2956 + [/mybootdir]/menu.lst/C000025
298.2957 + [/mybootdir]/menu.lst/C00002
298.2958 + [/mybootdir]/menu.lst/C0000
298.2959 + [/mybootdir]/menu.lst/C000
298.2960 + [/mybootdir]/menu.lst/C00
298.2961 + [/mybootdir]/menu.lst/C0
298.2962 + [/mybootdir]/menu.lst/C
298.2963 + [/mybootdir]/menu.lst/default
298.2964 +
298.2965 +Here, we assume the network card mac for the client machine is
298.2966 +88:99:AA:BB:CC:DD, and the ip address is 192.0.2.91 (C000025B). /mybootdir is
298.2967 +the directory of the boot file, for example, if boot file is /tftp/grldr, then
298.2968 +mybootdir=tftp.
298.2969 +
298.2970 +If none of the above files is present, grldr will use its embeded menu.lst.
298.2971 +
298.2972 +This is a menu.lst to illstrate how to use files from the tftp server.
298.2973 +
298.2974 + title Create ramdisk using map
298.2975 + map --mem (pd)/floppy.img (fd0)
298.2976 + map --hook
298.2977 + rootnoverify (fd0)
298.2978 + chainloader (fd0)+1
298.2979 +
298.2980 + title Create ramdisk using memdisk
298.2981 + kernel (pd)/memdisk
298.2982 + initrd (pd)/floppy.img
298.2983 +
298.2984 +You can see that the menu.lst is very similar to normal disk boot, you just
298.2985 +need to replace device like (hd0,0) with (pd).
298.2986 +
298.2987 +There are some differences between disk device and pxe device:
298.2988 +
298.2989 +1. You can't list files in the pxe device.
298.2990 +
298.2991 +2. The blocklist command will not work with a file in the pxe device.
298.2992 +
298.2993 +3. You must use --mem option if you want to map a file in the pxe device.
298.2994 +
298.2995 +When you use chainloader to load file from the pxe device, there is a option
298.2996 +you can use:
298.2997 +
298.2998 + chainloader --raw (pd)/BOOT_FILE
298.2999 +
298.3000 +Option --raw works just like --force, but it load file in one go. This can
298.3001 +improve performance in some situation.
298.3002 +
298.3003 +You can use the pxe command to control the pxe device.
298.3004 +
298.3005 +1. pxe
298.3006 +
298.3007 + If used without any parameter, pxe command will display current
298.3008 + settings.
298.3009 +
298.3010 +2. pxe blksize N
298.3011 +
298.3012 + Set the packet size for tftp transmission. Minimum value is 512,
298.3013 + maximum value is 1432. This parameter is used primarily for very old
298.3014 + tftp server where packet larger than 512 byte is not supported.
298.3015 +
298.3016 +3. pxe basedir /dir
298.3017 +
298.3018 + Set the base directory for files in the tftp server. If
298.3019 +
298.3020 + pxe basedir /tftp
298.3021 +
298.3022 + then all files in the pxe device is related to directory /tftp, for
298.3023 + example, (pd)/aa.img correspond to /tftp/aa.img in the server.
298.3024 +
298.3025 + The default value of base directory is the directory of the boot file,
298.3026 + for example, if boot file is /tftp/grldr, then default base directory
298.3027 + is /tftp.
298.3028 +
298.3029 +4. pxe keep
298.3030 +
298.3031 + Keep the PXE stack. The default behaviour of GRUB4DOS is to unload
298.3032 + the PXE stack just before it exits.
298.3033 +
298.3034 +5. pxe unload
298.3035 +
298.3036 + Unload the PXE stack immediately.
298.3037 +
298.3038 +
298.3039 +
298.3040 +******************************************************************************
298.3041 +*** New Feature of Relative Path Support ***
298.3042 +******************************************************************************
298.3043 +
298.3044 +Use the `root' or `rootnoverify' command to specify the `working directory'.
298.3045 +
298.3046 +For example:
298.3047 +
298.3048 + root (hd0,0)/boot/grub
298.3049 +
298.3050 +This specifies that the working dir is (hd0,0)/boot/grub. So all subsequent
298.3051 +filenames of the form "/..." will actually refer to (hd0,0)/boot/grub/...
298.3052 +
298.3053 +That is to say:
298.3054 +
298.3055 + cat /menu.lst
298.3056 +
298.3057 +will be equivalent to
298.3058 +
298.3059 + cat (hd0,0)/boot/grub/menu.lst
298.3060 +
298.3061 +
298.3062 +
298.3063 +******************************************************************************
298.3064 +*** Notation For The Current Root Device ***
298.3065 +******************************************************************************
298.3066 +
298.3067 +
298.3068 +The notation `()' can be used to access the current root device. You may use
298.3069 +`find --set-root ...' to set the current root device, but the find command
298.3070 +does not set the `working dir' of the root device. In this case you should
298.3071 +use `()' to set the working dir after the find command:
298.3072 +
298.3073 + root ()/boot/grub
298.3074 +
298.3075 +Update 2008-05-01:
298.3076 +
298.3077 + FIND can also set the `working directory' now. For example:
298.3078 +
298.3079 + find --set-root=/tmp /boot/grub/menu.lst
298.3080 +
298.3081 + It is equivalent to this pair of commands:
298.3082 +
298.3083 + find --set-root /boot/grub/menu.lst
298.3084 + root ()/tmp
298.3085 +
298.3086 +
298.3087 +******************************************************************************
298.3088 +*** The new map option --a20-keep-on ***
298.3089 +******************************************************************************
298.3090 +
298.3091 +
298.3092 +Along with 0.4.3 final, map has a new option --a20-keep-on which is related to
298.3093 +A20 control after a memdrive sector access. Usage:
298.3094 +
298.3095 + map --a20-keep-on=0
298.3096 +
298.3097 +It should be used before the "map --hook" command.
298.3098 +
298.3099 +By default, A20 will be always on after an RAM INT13 sector access. If
298.3100 +"map --a20-keep-on=0" is used, the A20 status after the INT13 call will be the
298.3101 +same as that before the INT13 call.
298.3102 +
298.3103 +
298.3104 +******************************************************************************
298.3105 +*** The CDROM emulation (virtualization) ***
298.3106 +******************************************************************************
298.3107 +
298.3108 +The CDROM emulation is sometimes called ISO emulation. Here is an example:
298.3109 +
298.3110 + map (hd0,0)/myiso.iso (hd32)
298.3111 + map --hook
298.3112 + chainloader (hd32)
298.3113 + boot
298.3114 +
298.3115 +if myiso.iso is not contiguous and you have enough memory, add a --mem option:
298.3116 +
298.3117 + map --mem (hd0,0)/myiso.iso (hd32)
298.3118 + map --hook
298.3119 + chainloader (hd32)
298.3120 + boot
298.3121 +
298.3122 +Note: (hd32) is a grub drive number equivalent to (0xA0). If a virtual drive is
298.3123 +specified with a drive number greater than or equal to 0xA0, then it will be
298.3124 +treated as a cdrom (i.e., with 2048-byte big sectors).
298.3125 +
298.3126 +Like normal disk emulations, the CDROM emulation also (mainly) works with
298.3127 +real-mode OSes. After a protected-mode OS kernel (such as
298.3128 +WinNT/2K/XP/VISTA/LINUX) gains control, the OS would have no ability to access
298.3129 +the virtual CDROM through BIOS int13.
298.3130 +
298.3131 +DOS/Win9x users may google for ELTORITO.SYS and use it in CONFIG.SYS as a
298.3132 +device driver for the virtual cdrom.
298.3133 +
298.3134 +Example usage of eltorito.sys in CONFIG.SYS:
298.3135 +
298.3136 + device=eltorito.sys /D:oemcd001
298.3137 +
298.3138 +Corresponding MSCDEX command which can be placed in AUTOEXEC.BAT:
298.3139 +
298.3140 + MSCDEX /D:oemcd001 /L:D
298.3141 +
298.3142 +
298.3143 +Due to some bugs found in eltorito.sys, the driver could fail to load. If you
298.3144 +encounter such problems, then you may replace (hd32) with (0xFF) for the
298.3145 +virtual cdrom drive number and try again.
298.3146 +
298.3147 +
298.3148 +******************************************************************************
298.3149 +*** The New Command CHECKRANGE ***
298.3150 +******************************************************************************
298.3151 +
298.3152 +Checkrange checks whether or not the return value of a command is in the
298.3153 +specified range or ranges.
298.3154 +
298.3155 +Usage: checkrange RANGE COMMAND
298.3156 +
298.3157 +Here are some examples for RANGE:
298.3158 +
298.3159 + 3 is a range containing only the number 3
298.3160 + 3:3 is equivalent to 3
298.3161 + 3:8 is a range containing the numbers 3, 4, 5, 6, 7, 8
298.3162 + 3,4,5,6,7,8 is equivalent to 3:8
298.3163 + 3:5,6:8 is also equivalent to 3:8
298.3164 + 3,4:7,8 is also equivalent to 3:8
298.3165 +
298.3166 +Note: You should not insert spaces into a range.
298.3167 +
298.3168 +Here is an example showing where the checkrange can be used:
298.3169 +
298.3170 + checkrange 0x05,0x0F,0x85 parttype (hd0,1) || hide (hd0,1)
298.3171 +
298.3172 +which means: if (hd0,1) is not an extended partition, then hide it.
298.3173 +
298.3174 +
298.3175 +******************************************************************************
298.3176 +*** The New Command TPM ***
298.3177 +******************************************************************************
298.3178 +
298.3179 +The "tpm --init" uses 512-byte data at 0000:7C00 as buffer to initialise TPM.
298.3180 +
298.3181 +Before you boot VISTA's BOOTMGR, you might have to use the "tpm --init"
298.3182 +command on some machines. Normally you want to issue the "tpm --init" command
298.3183 +after a CHAINLOADER command.
298.3184 +
298.3185 +
298.3186 +******************************************************************************
298.3187 +*** Delimitors or comments between titles ***
298.3188 +******************************************************************************
298.3189 +
298.3190 +It is possible to use titles as delimitors or comments. A title(or menu item)
298.3191 +is called unbootable if all of its menu commands are not boot-sensitive.
298.3192 +
298.3193 +The following commands are boot-sensitive(and others are not boot-sensitive):
298.3194 +
298.3195 + boot
298.3196 + bootp
298.3197 + chainloader
298.3198 + configfile
298.3199 + embed
298.3200 + commandline
298.3201 + halt
298.3202 + install
298.3203 + kernel
298.3204 + pxe
298.3205 + quit
298.3206 + reboot
298.3207 + setup
298.3208 +
298.3209 +An unbootable title will be skipped when the user presses the Up Arrow or Down
298.3210 +Arrow keys. Even the unbootable menu item can get accessed(and executed) by
298.3211 +using the Left Arrow and/or Right Arrow keys. Examples:
298.3212 +
298.3213 + title This is an UNBOOTABLE entry(so this line is also a comment)
298.3214 + pause --wait=0 This title is a comment. Nothing to do.
298.3215 + pause --wait=0 You can use non-boot-sensitive commands here
298.3216 + pause --wait=0 of any kind and as many as you would like.
298.3217 + help
298.3218 + help root
298.3219 + help chainloader
298.3220 + help parttype
298.3221 + clear
298.3222 + title ------------------------------------------------------------
298.3223 + pause --wait=0 This title is a delimitor. Nothing to do.
298.3224 + pause --wait=0 You can use non-boot-sensitive commands here
298.3225 + pause --wait=0 of any kind and as many as you would like.
298.3226 + clear
298.3227 + help
298.3228 + help boot
298.3229 + title ============================================================
298.3230 + pause --wait=0 This title is a delimitor. Nothing to do.
298.3231 + pause --wait=0 You can use non-boot-sensitive commands here
298.3232 + pause --wait=0 of any kind and as many as you would like.
298.3233 + help
298.3234 + clear
298.3235 + help pause
298.3236 + title ************************************************************
298.3237 + pause --wait=0 This title is a delimitor. Nothing to do.
298.3238 + pause --wait=0 You can use non-boot-sensitive commands here
298.3239 + pause --wait=0 of any kind and as many as you would like.
298.3240 + help kernel
298.3241 + help
298.3242 + clear
298.3243 +
298.3244 +Note: An unbootable menu item must contain at least one command. If there
298.3245 +are no commands for a title, the title will be simply discarded and disappear.
298.3246 +
298.3247 +
298.3248 +******************************************************************************
298.3249 +*** Bifurcate drives ***
298.3250 +******************************************************************************
298.3251 +
298.3252 +Some machines apply different actions to a drive between CHS and LBA mode.
298.3253 +When you read sectors using standard BIOS call int13/AH=02h, you might find
298.3254 +out the drive is a floppy. But when you read sectors using extended BIOS
298.3255 +call(EBIOS) int13/AH=42h, you could know the drive is a cdrom. Such a drive
298.3256 +is called bifurcate.
298.3257 +
298.3258 +A bifurcate drive can have two drive numbers: one is the normal BIOS drive
298.3259 +number between 00 and FF in hexa, and this drive uses only CHS mode disk
298.3260 +access(standard BIOS int13/AH=02h); the other is the normal BIOS drive number
298.3261 +(Bitwise) OR'ed by 0x100(i.e., 256 in decimal), and this drive uses only
298.3262 +LBA mode disk access(EBIOS int13/AH=42h). For example, if the drive 0x00
298.3263 +(i.e., the first floppy) is bifurcate, then the drive (0x00) uses CHS mode
298.3264 +to access its sectors, and the drive (0x100) uses LBA (meaning EBIOS) mode
298.3265 +to access its sectors.
298.3266 +
298.3267 +The geometry command can report the disk access mode for bifurcate drives as
298.3268 +BIF instead of the conventional CHS or LBA.
298.3269 +
298.3270 +Known bifurcate drives. Virtual PC and some real machines are found to create
298.3271 +a bifurcate floppy drive when they boot from a floppy-emulation mode bootable
298.3272 +cdrom. The "geometry (fd0)" will show
298.3273 +
298.3274 + drive 0x00(BIF): C/H/S=...Sector Count/Size=.../512
298.3275 +
298.3276 +and "geometry (0x100)" will show
298.3277 +
298.3278 + drive 0x100(BIF): C/H/S=...Sector Count/Size=.../2048
298.3279 +
298.3280 +Actually (0x100) can access the whole cdrom, you may "ls (0x100)/" and find
298.3281 +your files on the cdrom(not the files inside the booted floppy image). Of
298.3282 +course "ls (fd0)/" will list the files inside the booted floppy image.
298.3283 +
298.3284 +Note that only some (real or virtual) machines have this action, others
298.3285 +will not produce bifurcate drives.
298.3286 +
298.3287 +
298.3288 +******************************************************************************
298.3289 +*** GRLDR as PXE boot file ***
298.3290 +******************************************************************************
298.3291 +
298.3292 +GRLDR can be used as the PXE boot file on a remote/network server. The (pd)
298.3293 +device is used to access files on the server. When GRLDR is booted through
298.3294 +network, it will use its preset menu as the config file. However, you may use
298.3295 +a "pxe detect" command, which acts the same way as PXELINUX:
298.3296 +
298.3297 + * First, it will search for the config file using the hardware type (using
298.3298 + its ARP type code) and address, all in hexadecimal with dash separators;
298.3299 + for example, for an Ethernet (ARP type 1) with address 88:99:AA:BB:CC:DD
298.3300 + it would search for the filename 01-88-99-AA-BB-CC-DD.
298.3301 +
298.3302 + * Next, it will search for the config file using its own IP address in
298.3303 + upper case hexadecimal, e.g. 192.0.2.91 -> C000025B. If that file is not
298.3304 + found, it will remove one hex digit and try again. At last, it will try
298.3305 + looking for a file named default (in lower case). As an example, if the
298.3306 + boot file name is /mybootdir/grldr, the Ethernet MAC address is
298.3307 + 88:99:AA:BB:CC:DD and the IP address 192.0.2.91, it will try following
298.3308 + files (in that order):
298.3309 +
298.3310 + /mybootdir/menu.lst/01-88-99-AA-BB-CC-DD
298.3311 + /mybootdir/menu.lst/C000025B
298.3312 + /mybootdir/menu.lst/C000025
298.3313 + /mybootdir/menu.lst/C00002
298.3314 + /mybootdir/menu.lst/C0000
298.3315 + /mybootdir/menu.lst/C000
298.3316 + /mybootdir/menu.lst/C00
298.3317 + /mybootdir/menu.lst/C0
298.3318 + /mybootdir/menu.lst/C
298.3319 + /mybootdir/menu.lst/default
298.3320 +
298.3321 +You cannot directly map an image file on (pd). You must map it in memory using
298.3322 +the --mem option. For example,
298.3323 +
298.3324 + map --mem (pd)/images/floppy.img (fd0)
298.3325 + map --hook
298.3326 + chainloader (fd0)+1
298.3327 + rootnoverify (fd0)
298.3328 + boot
298.3329 +
298.3330 +One more example,
298.3331 +
298.3332 + map --mem (pd)/images/cdimage.iso (0xff)
298.3333 + map --hook
298.3334 + chainloader (0xff)
298.3335 + boot
298.3336 +
298.3337 +
298.3338 +******************************************************************************
298.3339 +*** New program badgrub.exe ***
298.3340 +******************************************************************************
298.3341 +
298.3342 +The new program badgrub.exe is intended to serve 'bad' machines(typically some
298.3343 +DELL models) that cannot run the normal grub.exe.
298.3344 +
298.3345 +
298.3346 +******************************************************************************
298.3347 +*** Conditional find ***
298.3348 +******************************************************************************
298.3349 +
298.3350 +The new find syntax allows to find a device conditionally.
298.3351 +
298.3352 + find [OPTIONS] [FILENAME] [CONDITION]
298.3353 +
298.3354 +CONDITION is a normal grub command which returns TRUE or FALSE.
298.3355 +
298.3356 + Example 1:
298.3357 +
298.3358 + find
298.3359 +
298.3360 + This will list all partitions, all floppies and the (cd).
298.3361 +
298.3362 + Example 2:
298.3363 +
298.3364 + find +1
298.3365 +
298.3366 + This will list all devices with a known filesystem.
298.3367 +
298.3368 + Example 3:
298.3369 +
298.3370 + find checkrange 0xAF parttype
298.3371 +
298.3372 + This will list all partitions with ID=0xAF.
298.3373 +
298.3374 + Example 4:
298.3375 +
298.3376 + find /ntldr checkrange 0x07 parttype
298.3377 +
298.3378 + This will list all partitions with ID=0x07 and existing /ntldr.
298.3379 +
298.3380 +
298.3381 +
298.3382 +******************************************************************************
298.3383 +*** How to build grldr boot images ***
298.3384 +******************************************************************************
298.3385 +
298.3386 +1. build 1.44M floppy image ext2grldr.img
298.3387 +
298.3388 + dd if=/dev/zero of=ext2grldr.img bs=512 count=2880
298.3389 + mke2fs ext2grldr.img
298.3390 + mkdir ext2tmp
298.3391 + mount -o loop ext2grldr.img ext2tmp
298.3392 + cp default ext2tmp
298.3393 + cp menu.lst ext2tmp
298.3394 + cp grldr ext2tmp
298.3395 + umount ext2tmp
298.3396 + bootlace.com --floppy --chs --sectors-per-track=18 --heads=2 --start-sector=0 --total-sectors=2880 ext2grldr.img
298.3397 +
298.3398 +2. build 1.44M floppy image fat12grldr.img
298.3399 +
298.3400 + dd if=/dev/zero of=fat12grldr.img bs=512 count=2880
298.3401 + mkdosfs fat12grldr.img
298.3402 + mkdir fat12tmp
298.3403 + mount -o loop fat12grldr.img fat12tmp
298.3404 + cp default fat12tmp
298.3405 + cp menu.lst fat12tmp
298.3406 + cp grldr fat12tmp
298.3407 + umount fat12tmp
298.3408 + bootlace.com --floppy --chs fat12grldr.img
298.3409 +
298.3410 +3. build iso9660 CDROM image grldr.iso
298.3411 +
298.3412 + mkdir iso_root
298.3413 + cp grldr iso_root
298.3414 + cp menu.lst iso_root
298.3415 + mkisofs -R -b grldr -no-emul-boot -boot-load-size 4 -o grldr.iso iso_root
298.3416 +
298.3417 +
298.3418 +******************************************************************************
298.3419 +*** Use bootlace.com to install partition boot record ***
298.3420 +******************************************************************************
298.3421 +
298.3422 +Since bootlace.com has not implemented the --install-partition option, you
298.3423 +need to use the already implemented --floppy=PartitionNumber option instead.
298.3424 +
298.3425 +Hear is a way you might want to follow:
298.3426 +
298.3427 +Step 1. Get the boot sectors of the partition and save to a file MYPART.TMP.
298.3428 + For NTFS, you need to get the beginning 16 sectors. For other type of
298.3429 + filesystems, you only need to get one sector, but getting more sectors
298.3430 + is also ok.
298.3431 +
298.3432 +Step 2. Run this:
298.3433 +
298.3434 + bootlace.com --floppy=Y --sectors-per-track=S --heads=H --start-sector=B --total-sectors=C --vfat --ext2 --ntfs MYPART.TMP
298.3435 +
298.3436 + where we suppose MYPART.TMP is for (hdX,Y) and the partition number Y
298.3437 + should be specified as in the --floppy=Y option.
298.3438 +
298.3439 + Note that for FAT12/16/32/NTFS partitions, you can omit these options:
298.3440 +
298.3441 + --sectors-per-track, --heads, --start-sector, --total-sectors,
298.3442 + --vfat and --ext2.
298.3443 +
298.3444 + For NTFS partitions, you must specify --ntfs option.
298.3445 +
298.3446 + For ext2 partitions, you can omit --vfat, --ntfs and --ext2 options,
298.3447 + but other options should be specified.
298.3448 +
298.3449 +Step 3. Put MYPART.TMP back on to the boot sector(s) of your original partition
298.3450 + (hdX,Y).
298.3451 +
298.3452 +
298.3453 +Note: Only a few file systems(FAT12/16/32/NTFS/ext2/ext3) are supported by now.
298.3454 +
298.3455 +Note2: Under Linux you may directly write the partition. That is to say, Step
298.3456 + 1 and Step 3 are not needed. Simply use its device name instead of
298.3457 + MYPART.TMP.
298.3458 +
298.3459 +Note3: grubinst has the feature of installing grldr boot code onto a
298.3460 + partition boot area.
298.3461 +
298.3462 +******************************************************************************
298.3463 +*** Use a single key to select menu item ***
298.3464 +******************************************************************************
298.3465 +
298.3466 +Some machines have a simplified keyboard. The keyborad might have only the
298.3467 +number keys 0 .. 9 plus a few other keys. When the menu displayed, the user
298.3468 +can strike a key for 8 times. When the menu handler detects the continuous
298.3469 +single keypress, it will assume the user want to use this key to select a menu
298.3470 +item and boot. This single key will act as the RIGHT-ARROW key for the user to
298.3471 +select a menu item. And 5 seconds later after the user stops the keypress,
298.3472 +the selected menu item will automatically boot. Any normal keys can be used as
298.3473 +a single key for this purpose, except for a few functional keys like b, e,
298.3474 +Enter, etc. Once another key is pressed, the feature of Single-Key-Selection
298.3475 +will disappear immediately.
298.3476 +
298.3477 +
298.3478 +******************************************************************************
298.3479 +*** Parameter file for bootlace running under DOS ***
298.3480 +******************************************************************************
298.3481 +
298.3482 +You may move all or part of the command-line arguments into a file. The file
298.3483 +can have multi lines. Just like SPACEs and TABs, the CRs and LFs can also
298.3484 +delimit the commandline arguments in the parameter file.
298.3485 +
298.3486 +Example:
298.3487 +
298.3488 + bootlace < my_parafile
298.3489 + bootlace --read-only my_mbr < my_other_options
298.3490 +
298.3491 +Note: Pipes do not work. You have to use the input-redirection operator(<).
298.3492 +
298.3493 +
298.3494 +******************************************************************************
298.3495 +*** Use bootlace to create a triple MBR ***
298.3496 +******************************************************************************
298.3497 +
298.3498 +This is typically used for USB drives, though it also works with hard drives.
298.3499 +
298.3500 +Steps to create triple MBR:
298.3501 +
298.3502 +1. Do a fresh FDISK to create a FAT12/16/32 partition starting at sector 95
298.3503 +(in LBA, that is, the begginning sector(MBR) is sector 0).
298.3504 +
298.3505 +2. Install grldr boot sector onto the boot sector of this partition. See
298.3506 +section "Use bootlace.com to install partition boot record" above.
298.3507 +
298.3508 +3. Get 96 sectors of the drive starting at sector 0(MBR), and save to file
298.3509 +MYMBR96.TMP.
298.3510 +
298.3511 +4. Run bootlace.com:
298.3512 +
298.3513 + bootlace.com MYMBR96.TMP
298.3514 +
298.3515 +5. Put MYMBR96.TMP back onto the drive starting at MBR(sector 0).
298.3516 +
298.3517 +Note: If the drive already has a triple MBR, then bootlace will cancel it
298.3518 +and restore the original partition layout.
298.3519 +
298.3520 +
298.3521 +******************************************************************************
298.3522 +*** Use 'pxe detect' in preset-menu ***
298.3523 +******************************************************************************
298.3524 +
298.3525 +Now the "pxe" command has a new subcommand "detect":
298.3526 +
298.3527 + pxe detect [BLOCK_SIZE] [MENU_FILE]
298.3528 +
298.3529 +BLOCK_SIZE specifies the block size for PXE. If it is not specified or it is
298.3530 +0, then grub4dos will go through a probing process and get a proper value
298.3531 +for data transfer.
298.3532 +
298.3533 +MENU_FILE specifies the config file on the PXE server. If omitted, a standard
298.3534 +config file in the menu.lst sub-dir will gain control. For a description on
298.3535 +the config files in the menu.lst sub-dir, please refer to the section
298.3536 +"GRLDR as PXE boot file" above.
298.3537 +If MENU_FILE starts in a "/", then the MENU_FILE on the PXE server will gain
298.3538 +control, else(if MENU_FILE does not start in a "/") no menu will be executed.
298.3539 +
298.3540 +Normally you want to use a "pxe blksize ..." or a "pxe detect ..." command
298.3541 +before you access the (pd) device, since the default blocksize of 512 might
298.3542 +not work on your system.
298.3543 +
298.3544 +
298.3545 +******************************************************************************
298.3546 +*** Use 'configfile' in preset-menu ***
298.3547 +******************************************************************************
298.3548 +
298.3549 +Now the preset menu holds the highest priority. It will gain control prior to
298.3550 +the menu.lst on the boot device. If a 'configfile' command(without specifying
298.3551 +any file as the parameter) occurs in the menu init command group of the preset
298.3552 +menu, then control will go to the menu.lst on the boot device.
298.3553 +
298.3554 +Note: You should better not use "configfile ANOTHER_MENU" frequently in your
298.3555 +menu.lst file, because it could create infinite loop and thus hang your
298.3556 +computer.
298.3557 +
298.3558 +
298.3559 +******************************************************************************
298.3560 +*** New command 'dd' to copy files ***
298.3561 +******************************************************************************
298.3562 +
298.3563 +Usage:
298.3564 +
298.3565 +dd if=IF of=OF [bs=BS] [count=C] [skip=IN] [seek=OUT] [buf=ADDR] [buflen=SIZE]
298.3566 +
298.3567 +Copy file IF to OF. BS is blocksize in bytes, default to 512. C is blocks to
298.3568 +copy, default is total blocks in IF. IN specifies number of blocks to skip
298.3569 +when read, default is 0. OUT specifies number of blocks to skip when write,
298.3570 +default is 0. Skipped blocks are not touched. Both IF and OF must exist.
298.3571 +
298.3572 +Both IF and OF must have a leading device name, i.e., of the form `(...)'.
298.3573 +You may use `()' for the current root device.
298.3574 +
298.3575 +dd can neither enlarge nor reduce the size of OF, the leftover tail of IF
298.3576 +will be discarded. OF cannot be a gzipped file. If IF is a gzipped file,
298.3577 +it will be decompressed automatically when copying.
298.3578 +
298.3579 +dd is dangerous, use at your own risk. To be on the safe side, you should
298.3580 +only use dd to write a file in memory.
298.3581 +
298.3582 +In some cases when writing a file in a NTFS volume, dd might fail.
298.3583 +
298.3584 +If you attempt to write a device or a block file that is not in memory by
298.3585 +starting dd in a menu, you will safely be refused :-) (Update: no restrictions
298.3586 +now)
298.3587 +
298.3588 +Update: New options are implemented for user defined buffer. By default,
298.3589 +the buffer is at address 0x50000, and length is 0x10000(=64KB). You cannot
298.3590 +specify ADDR to be lower than 0x100000(=1MB). Besides, you must specify SIZE
298.3591 +larger than 0x10000(=64KB). Normally you want ADDR >= 0x1000000(=16MB), and
298.3592 +SIZE also >= 16MB. A large SIZE could speed up the progression of dd.
298.3593 +
298.3594 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298.3595 +!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!!
298.3596 +!!!! Caution! Both IF and OF can be a device name which stands for !!!!
298.3597 +!!!! all the sectors on the device. Take utmost care! !!!!
298.3598 +!!!!______________________________________________________________________!!!!
298.3599 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298.3600 +
298.3601 +
298.3602 +******************************************************************************
298.3603 +*** New command 'uuid' to identify partitions ***
298.3604 +******************************************************************************
298.3605 +
298.3606 +Usage:
298.3607 +
298.3608 + uuid [DEVICE] [UUID]
298.3609 +
298.3610 +If DEVICE is not specified, search for filesystem with UUID in all partitions
298.3611 +and set the partition containing the filesystem as new root (if UUID is
298.3612 +specified), or just list uuid's of all filesystems on all devices (if UUID is
298.3613 +not specified). If DEVICE is specified, return true or false according to
298.3614 +whether or not the DEVICE matches the specified UUID (if UUID is specified),
298.3615 +or just list the uuid of DEVICE (if UUID is not specified).
298.3616 +
298.3617 +Example 1:
298.3618 +
298.3619 + find --set-root uuid () 7f95820f-5e33-4e6c-8f50-0760bf06d79c
298.3620 +
298.3621 +which will find a partition with uuid=7f95820f-5e33-4e6c-8f50-0760bf06d79c
298.3622 +and set the partition as root if found.
298.3623 +
298.3624 +Example 2:
298.3625 +
298.3626 + uuid ()
298.3627 +
298.3628 +which will print the uuid of the current root device.
298.3629 +
298.3630 +
298.3631 +******************************************************************************
298.3632 +*** gfxmenu support in grub4dos ***
298.3633 +******************************************************************************
298.3634 +
298.3635 +Gfxmenu support has been added to grub4dos. To use it, you must first find the
298.3636 +message file you need, then load it in menu.lst with command like this:
298.3637 +
298.3638 + gfxmenu /message
298.3639 +
298.3640 +This should be a gloabl command, that is, not inside any menu item. Also, it
298.3641 +can only be used in configure file, running it in console mode does not work.
298.3642 +
298.3643 +gfxmenu does not work in conjunction with the password feature.
298.3644 +
298.3645 +There are two major format of message file. Old format is created with gfxboot
298.3646 +3.2.* or older (size of message file is normally about 150K), while new format
298.3647 +is created with gfxboot 3.3.* and later (size of message file is normally above
298.3648 +300K). Both format are supported in grub4dos.
298.3649 +
298.3650 +
298.3651 +******************************************************************************
298.3652 +*** Use 'write' to write a string into a device or file ***
298.3653 +******************************************************************************
298.3654 +
298.3655 +Usage:
298.3656 +
298.3657 + write [--offset=SKIP] ADDR_OR_FILE INTEGER_OR_STRING
298.3658 +
298.3659 +SKIP is an integer and defaults to 0.
298.3660 +
298.3661 +If ADDR_OR_FILE is an integer, then it is treated as a memory address, and
298.3662 +INTEGER_OR_STRING must be an integer value. The integer INTEGER_OR_STRING
298.3663 +will be written to address (ADDR_OR_FILE + SKIP).
298.3664 +
298.3665 +If ADDR_OR_FILE is a device or a file, then INTEGER_OR_STRING is treated as
298.3666 +a string which will be written to ADDR_OR_FILE at offset SKIP (in bytes).
298.3667 +
298.3668 +The string is quoted with nothing, that is, neither with the single quote
298.3669 +char(') nor with the double quote char(").
298.3670 +
298.3671 +Space char must be quoted with back slash(\). (Update: need not now)
298.3672 +
298.3673 +Single quote char(') and double quote char(") are not interpreted specially
298.3674 +and can be used directly in the string.
298.3675 +
298.3676 +Some C-style quote sequences are interpreted as follows:
298.3677 +
298.3678 + \NNN character with octal value NNN (1 to 3 digits)
298.3679 +
298.3680 + \\ backslash
298.3681 +
298.3682 + \a alert (BEL)
298.3683 +
298.3684 + \b backspace
298.3685 +
298.3686 + \f form feed
298.3687 +
298.3688 + \n new line
298.3689 +
298.3690 + \r carriage return
298.3691 +
298.3692 + \t horizontal tab
298.3693 +
298.3694 + \v vertical tab
298.3695 +
298.3696 + \xHH byte with hexadecimal value HH (1 to 2 digits)
298.3697 +
298.3698 +Just like dd, the write can neither enlarge nor reduce the size of the
298.3699 +destination file, the leftover tail of the string will be discarded.
298.3700 +The destination file cannot be a gzipped file.
298.3701 +
298.3702 +Again like dd, the write command is also dangerous, use at your own risk.
298.3703 +And to be on the safe side, you should only write to memory files.
298.3704 +
298.3705 +In some cases when writing a file in a NTFS volume, the write might fail.
298.3706 +
298.3707 +If you attempt to write a device or a block file that is not in memory by
298.3708 +using write in a menu, you will safely be refused :-) (Update: no restrictions
298.3709 +now)
298.3710 +
298.3711 +
298.3712 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298.3713 +!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!!
298.3714 +!!!! Caution! The file to write can be a device name which stands !!!!
298.3715 +!!!! for all the sectors on the device. Take utmost care! !!!!
298.3716 +!!!!______________________________________________________________________!!!!
298.3717 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298.3718 +
298.3719 +
298.3720 +******************************************************************************
298.3721 +*** Item-by-item help text for menu entries ***
298.3722 +******************************************************************************
298.3723 +
298.3724 +
298.3725 +The help message at the bottom of the screen will vary as you choose the menu.
298.3726 +
298.3727 +You may append your help text to the title line. The help text must begin
298.3728 +with "\n", for example:
298.3729 +
298.3730 + title This is the title\nThis is the help text.\nAnd this is the 2nd line of the help text.
298.3731 +
298.3732 +Some C-style quote sequences are interpreted as stated in the section above.
298.3733 +
298.3734 +
298.3735 +******************************************************************************
298.3736 +*** initrd can load multiple cpio files for Linux 2.6 kernels ***
298.3737 +******************************************************************************
298.3738 +
298.3739 +Usage:
298.3740 +
298.3741 + initrd FILE [FILE ...]
298.3742 +
298.3743 +Note 1: You should not load more than one oldstyle disk images in this way,
298.3744 +because this is not supported by Linux kernel.
298.3745 +
298.3746 +Note 2: The FILEs should be specified in the same order as with syslinux.
298.3747 +
298.3748 +******************************************************************************
298.3749 +*** access some internel variables at a fixed location ***
298.3750 +******************************************************************************
298.3751 +
298.3752 +Address Length Description
298.3753 +========= ======== ==============================================
298.3754 +0000:8208 4 (DWORD) install_partition (the boot partition)
298.3755 +0000:8280 4 (DWORD) boot_drive (the boot drive)
298.3756 +0000:8284 4 (DWORD) pxe_yip (your ip)
298.3757 +0000:8288 4 (DWORD) pxe_sip (server ip)
298.3758 +0000:828C 4 (DWORD) pxe_gip (gateway ip)
298.3759 +0000:8290 8 (QWORD) filesize (file size by last "cat --length=0")
298.3760 +0000:8298 4 (DWORD) saved_mem_upper (extended memory size in KB)
298.3761 +0000:829C 4 (DWORD) saved_partition (current root partition)
298.3762 +0000:82A0 4 (DWORD) saved_drive (current root drive)
298.3763 +0000:82A4 4 (DWORD) no_decompression (no auto gunzip)
298.3764 +
298.3765 +Note 1: Filesize can be initialised/modified by using "cat --length=0 FILE".
298.3766 +Note 2: You should not write these variables by hand(should read only).
298.3767 +Note 3: You may use 1K at 6000:0000 for your own varibles(See note 4).
298.3768 +Note 4: The read command now returns the integer value at the given address.
298.3769 +Note 5: Grub4dos does not have the variable expansion feature. You can only
298.3770 + use integer variables. You need not declare them, but use the memory
298.3771 + address directly. Usually you want to use variables as a logical
298.3772 + value or in a command for conditional test, e.g., of this form:
298.3773 + "checkrange RANGE read ADDR"
298.3774 +Note 6: no_decompression, saved_drive and saved_partition are writable.
298.3775 +
298.3776 +
298.3777 +******************************************************************************
298.3778 +*** possibility to run another menu.lst after gfxmenu ***
298.3779 +******************************************************************************
298.3780 +
298.3781 +Notice the use of CONFIGFILE after GFXMENU in the following example:
298.3782 +
298.3783 + # The menu.lst file for gfxmenu
298.3784 + default=0
298.3785 + timeout=5
298.3786 + gfxmenu /message
298.3787 + configfile /another.lst
298.3788 + title 0..........
298.3789 + ................
298.3790 + title 1..........
298.3791 + ................
298.3792 + title 2..........
298.3793 + ................
298.3794 + # End of menu.lst
298.3795 +
298.3796 + # Begin another.lst
298.3797 + default=0
298.3798 + timeout=5
298.3799 + title 0..........
298.3800 + ................
298.3801 + title 1..........
298.3802 + ................
298.3803 + title 2..........
298.3804 + ................
298.3805 + # End of another.lst
298.3806 +
298.3807 +This will try gfxmenu command first. On exit(or on failure) control will go
298.3808 +to another.lst file.
298.3809 +
298.3810 +
298.3811 +******************************************************************************
298.3812 +*** a range of drives can be unmapped ***
298.3813 +******************************************************************************
298.3814 +
298.3815 +Usage:
298.3816 +
298.3817 + map --unmap=RANGE
298.3818 +
298.3819 +RANGE is a range of BIOS drive numbers to be unmapped. BIOS drive number 0
298.3820 +is for the first floppy, 1 is for the second floppy; 0x80 is for the first
298.3821 +hard drive, 0x81 is for the second hard drive, etc; virtual cdrom (hd32)
298.3822 +corresponds to BIOS drive number 0xA0, (hd33) corresponds to 0xA1, etc.
298.3823 +
298.3824 +For description on RANGE, please refer to section `The New Command CHECKRANGE'
298.3825 +above.
298.3826 +
298.3827 +Example 1:
298.3828 +
298.3829 + map --unmap=0,0x80,0xff
298.3830 +
298.3831 +This will unmap virtual floppy (fd0), virtual hard drive (hd0) and virtual
298.3832 +cdrom (0xff).
298.3833 +
298.3834 +Example 2:
298.3835 +
298.3836 + map --unmap=0:0xff
298.3837 +
298.3838 +This will unmap all virtual floppies, all virtual hard drives and all virtual
298.3839 +cdroms.
298.3840 +
298.3841 +Note 1: Normally a `map' command will add an item in the drive map table for
298.3842 + a virtual drive. But `--unmap' means items in the drive map table
298.3843 + (for the specified virtual drives) will be deleted.
298.3844 +Note 2: The --unhook option only breaks the INT13 hook(to the inerrupt
298.3845 + vector table). It will not affect the drive map table. And later on
298.3846 + execution of a `boot' command, the INT13 disk emulation routine will
298.3847 + automatically get hooked(to the interrupt vector table) when needed
298.3848 + (e.g., the drive map table is non-empty) even if it has been unhooked.
298.3849 +Note 3: Usually you want to do a `map --rehook' after you have changed the
298.3850 + drive map table.
298.3851 +
298.3852 +
298.3853 +******************************************************************************
298.3854 +*** geometry tune and sync ***
298.3855 +******************************************************************************
298.3856 +
298.3857 +When a USB storage device is connected to a (or another) machine, the geometry
298.3858 +in the partition table or in the BPB of the volume could be invalid, and the
298.3859 +machine could hang at boot time. So you need to find out the correct geometry
298.3860 +for the drive (use `geometry --tune'), and then update the geometry in
298.3861 +partition table and BPB of the drive(use `geometry --sync').
298.3862 +
298.3863 +The above steps are required if you are going to boot DOS, because DOS
298.3864 +requires the right geometry in the partition table and BPB. Windows/Linux may
298.3865 +also require it, since the boot process could run in real-mode.
298.3866 +
298.3867 +
299.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/badgrub.exe has changed
300.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/bootlace.com has changed
301.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/chinese/badgrub.exe has changed
302.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/chinese/grldr has changed
303.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/chinese/grub.exe has changed
304.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
304.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/config.sys Mon Apr 26 11:16:23 2010 +0200
304.3 @@ -0,0 +1,6 @@
304.4 +rem load grub.exe before emm386.exe
304.5 +device=grub.exe --bypass --time-out=5 --config-file="color black/cyan yellow/cyan;timeout 60;default 0;title find and load NTLDR of Windows NT/2K/XP;find --set-root /ntldr;chainloader /ntldr;title find and load CMLDR, the Recovery Console of Windows NT/2K/XP;find --set-root /cmldr;chainloader /cmldr;write 0x7C03 0x63646D63;write 0x7C07 0x00736E6F;title find and load IO.SYS of Windows 9x/Me;find --set-root /io.sys;chainloader /io.sys;title floppy (fd0);chainloader (fd0)+1;rootnoverify (fd0);title find and boot Linux with menu.lst already installed;find --set-root /sbin/init;configfile /boot/grub/menu.lst;title find and boot Mandriva with menu.lst already installed;find --set-root /etc/mandriva-release;configfile /boot/grub/menu.lst;title back to dos;quit;title commandline;commandline;title reboot;reboot;title halt;halt;"
304.6 +
304.7 +device=c:\windows\himem.sys
304.8 +device=c:\windows\emm386.exe
304.9 +
305.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
305.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/default Mon Apr 26 11:16:23 2010 +0200
305.3 @@ -0,0 +1,46 @@
305.4 +
305.5 +#
305.6 +#
305.7 +#
305.8 +#
305.9 +#
305.10 +#
305.11 +#
305.12 +#
305.13 +#
305.14 +#
305.15 +# !!!!!!! The file size is 2048 bytes. Don't change the file size !!!!!!!
305.16 +# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
305.17 +# XXXXXXXXXXXXXXXXXXXXX
305.18 +# WARNING: If you want to edit this file directly, do not remove any line
305.19 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.20 +# XXXXXXXXXXXXXXXXXXXXX
305.21 +# WARNING: If you want to edit this file directly, do not remove any line
305.22 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.23 +# XXXXXXXXXXXXXXXXXXXXX
305.24 +# WARNING: If you want to edit this file directly, do not remove any line
305.25 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.26 +# XXXXXXXXXXXXXXXXXXXXX
305.27 +# WARNING: If you want to edit this file directly, do not remove any line
305.28 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.29 +# XXXXXXXXXXXXXXXXXXXXX
305.30 +# WARNING: If you want to edit this file directly, do not remove any line
305.31 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.32 +# XXXXXXXXXXXXXXXXXXXXX
305.33 +# WARNING: If you want to edit this file directly, do not remove any line
305.34 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.35 +# XXXXXXXXXXXXXXXXXXXXX
305.36 +# WARNING: If you want to edit this file directly, do not remove any line
305.37 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.38 +# XXXXXXXXXXXXXXXXXXXXX
305.39 +# WARNING: If you want to edit this file directly, do not remove any line
305.40 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.41 +# XXXXXXXXXXXXXXXXXXXXX
305.42 +# WARNING: If you want to edit this file directly, do not remove any line
305.43 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.44 +# XXXXXXXXXXXXXXXXXXXXX
305.45 +# WARNING: If you want to edit this file directly, do not remove any line
305.46 +# from this file, including this warning. XXXXXXXXXXXXXXXXXXXXXXXXXXX
305.47 +# XXXXXXXXXXXXXXXXXXXXX
305.48 +# !!!!!!! The file size is 2048 bytes. Don't change the file size !!!!!!!
305.49 +# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
306.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/grldr has changed
307.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/grldr.mbr has changed
308.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/grub.exe has changed
309.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/grub.pif has changed
310.1 Binary file usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/hmload.com has changed
311.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
311.2 +++ b/usr/share/doc/isi/grub4dos/win98/grub4dos-0.4.4/menu.lst Mon Apr 26 11:16:23 2010 +0200
311.3 @@ -0,0 +1,96 @@
311.4 +# This is a sample menu.lst file. You should make some changes to it.
311.5 +# The old install method of booting via the stage-files has been removed.
311.6 +# Please install GRLDR boot strap code to MBR with the bootlace.com
311.7 +# utility under DOS/Win9x or Linux.
311.8 +
311.9 +color blue/green yellow/red white/magenta white/magenta
311.10 +timeout 30
311.11 +default /default
311.12 +
311.13 +title find and load NTLDR of Windows NT/2K/XP
311.14 +fallback 1
311.15 +find --set-root --ignore-floppies /ntldr
311.16 +chainloader /ntldr
311.17 +savedefault --wait=2
311.18 +
311.19 +title find and load BOOTMGR of Windows VISTA
311.20 +fallback 2
311.21 +find --set-root --ignore-floppies /bootmgr
311.22 +chainloader /bootmgr
311.23 +savedefault --wait=2
311.24 +
311.25 +title find and load CMLDR, the Recovery Console of Windows NT/2K/XP
311.26 +fallback 3
311.27 +find --set-root --ignore-floppies /cmldr
311.28 +chainloader /cmldr
311.29 +#####################################################################
311.30 +# write string "cmdcons" to memory 0000:7C03 in 2 steps:
311.31 +#####################################################################
311.32 +# step 1. Write 4 chars "cmdc" at 0000:7C03
311.33 +write 0x7C03 0x63646D63
311.34 +# step 2. Write 3 chars "ons" and an ending null at 0000:7C07
311.35 +write 0x7C07 0x00736E6F
311.36 +savedefault --wait=2
311.37 +
311.38 +title find and load IO.SYS of Windows 9x/Me
311.39 +fallback 4
311.40 +find --set-root /io.sys
311.41 +chainloader /io.sys
311.42 +savedefault --wait=2
311.43 +
311.44 +title find and boot 0PE.ISO
311.45 +fallback 5
311.46 +find --set-root /0PE/0PE.ISO
311.47 +map /0PE/0PE.ISO (0xff) || map --mem /0PE/0PE.ISO (0xff)
311.48 +map --hook
311.49 +chainloader (0xff)
311.50 +savedefault --wait=2
311.51 +
311.52 +title find and boot MicroPE.ISO
311.53 +fallback 6
311.54 +find --set-root /boot/MicroPE.ISO
311.55 +map /boot/MicroPE.ISO (0xff) || map --mem /boot/MicroPE.ISO (0xff)
311.56 +map --hook
311.57 +chainloader (0xff)
311.58 +savedefault --wait=2
311.59 +
311.60 +title Parted Magic ISO
311.61 +fallback 7
311.62 +find --set-root /pmagic.iso
311.63 +map /pmagic.iso (0xff) || map --mem /pmagic.iso (0xff)
311.64 +map --hook
311.65 +chainloader (0xff)
311.66 +savedefault --wait=2
311.67 +
311.68 +title Ultimate Boot CD ISO
311.69 +fallback 8
311.70 +find --set-root /ubcd.iso
311.71 +map /ubcd.iso (0xff) || map --mem /ubcd.iso (0xff)
311.72 +map --hook
311.73 +chainloader (0xff)
311.74 +savedefault --wait=2
311.75 +
311.76 +title commandline
311.77 +commandline
311.78 +
311.79 +title floppy (fd0)
311.80 +chainloader (fd0)+1
311.81 +rootnoverify (fd0)
311.82 +
311.83 +title back to dos
311.84 +quit
311.85 +
311.86 +title reboot
311.87 +reboot
311.88 +
311.89 +title halt
311.90 +halt
311.91 +
311.92 +title MAXDOS.IMG
311.93 +find --set-root --ignore-floppies /boot/MAXDOS.IMG
311.94 +map --mem /boot/MAXDOS.IMG (fd0)
311.95 +map --hook
311.96 +chainloader (fd0)+1
311.97 +rootnoverify (fd0)
311.98 +
311.99 +
312.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
312.2 +++ b/usr/share/doc/isi/grub4dos/win98/installa_grub.bat.bat Mon Apr 26 11:16:23 2010 +0200
312.3 @@ -0,0 +1,15 @@
312.4 +@echo off
312.5 +
312.6 +:: DISCO=0x80 : MBR del primo disco
312.7 +:: DISCO=0x81 : MBR del secondo disco
312.8 +
312.9 +SET BOOTLACE=grub4dos-0.4.4\bootlace.com
312.10 +SET DISCO=0x80
312.11 +
312.12 +echo Installo grub nel MBR del disco %DISCO% ...
312.13 +%BOOTLACE% %DISCO%
312.14 +
312.15 +echo Copio i file necessari ...
312.16 +xcopy /E /Y /Q c\* c:\
312.17 +
312.18 +exit
313.1 Binary file usr/share/doc/isi/grub4dos/xp/c/boot/grub/gpxe.iso has changed
314.1 Binary file usr/share/doc/isi/grub4dos/xp/c/grldr has changed
315.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
315.2 +++ b/usr/share/doc/isi/grub4dos/xp/c/menu.lst Mon Apr 26 11:16:23 2010 +0200
315.3 @@ -0,0 +1,16 @@
315.4 +color blue/white white/green white/blue white/blue
315.5 +timeout 10
315.6 +default 0
315.7 +
315.8 +title Linux (LTSP via gPXE)
315.9 +find --set-root /boot/grub/gpxe.iso
315.10 +map /boot/grub/gpxe.iso (0xff) || map --mem /boot/grub/gpxe.iso (0xff)
315.11 +map --hook
315.12 +chainloader (0xff)
315.13 +
315.14 +title Windows XP/2K/NT
315.15 +find --set-root --ignore-floppies /ntldr
315.16 +chainloader /ntldr
315.17 +
315.18 +title halt
315.19 +halt
316.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
316.2 +++ b/usr/share/doc/isi/grub4dos/xp/grubinst/COPYING Mon Apr 26 11:16:23 2010 +0200
316.3 @@ -0,0 +1,674 @@
316.4 + GNU GENERAL PUBLIC LICENSE
316.5 + Version 3, 29 June 2021
316.6 +
316.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
316.8 + Everyone is permitted to copy and distribute verbatim copies
316.9 + of this license document, but changing it is not allowed.
316.10 +
316.11 + Preamble
316.12 +
316.13 + The GNU General Public License is a free, copyleft license for
316.14 +software and other kinds of works.
316.15 +
316.16 + The licenses for most software and other practical works are designed
316.17 +to take away your freedom to share and change the works. By contrast,
316.18 +the GNU General Public License is intended to guarantee your freedom to
316.19 +share and change all versions of a program--to make sure it remains free
316.20 +software for all its users. We, the Free Software Foundation, use the
316.21 +GNU General Public License for most of our software; it applies also to
316.22 +any other work released this way by its authors. You can apply it to
316.23 +your programs, too.
316.24 +
316.25 + When we speak of free software, we are referring to freedom, not
316.26 +price. Our General Public Licenses are designed to make sure that you
316.27 +have the freedom to distribute copies of free software (and charge for
316.28 +them if you wish), that you receive source code or can get it if you
316.29 +want it, that you can change the software or use pieces of it in new
316.30 +free programs, and that you know you can do these things.
316.31 +
316.32 + To protect your rights, we need to prevent others from denying you
316.33 +these rights or asking you to surrender the rights. Therefore, you have
316.34 +certain responsibilities if you distribute copies of the software, or if
316.35 +you modify it: responsibilities to respect the freedom of others.
316.36 +
316.37 + For example, if you distribute copies of such a program, whether
316.38 +gratis or for a fee, you must pass on to the recipients the same
316.39 +freedoms that you received. You must make sure that they, too, receive
316.40 +or can get the source code. And you must show them these terms so they
316.41 +know their rights.
316.42 +
316.43 + Developers that use the GNU GPL protect your rights with two steps:
316.44 +(1) assert copyright on the software, and (2) offer you this License
316.45 +giving you legal permission to copy, distribute and/or modify it.
316.46 +
316.47 + For the developers' and authors' protection, the GPL clearly explains
316.48 +that there is no warranty for this free software. For both users' and
316.49 +authors' sake, the GPL requires that modified versions be marked as
316.50 +changed, so that their problems will not be attributed erroneously to
316.51 +authors of previous versions.
316.52 +
316.53 + Some devices are designed to deny users access to install or run
316.54 +modified versions of the software inside them, although the manufacturer
316.55 +can do so. This is fundamentally incompatible with the aim of
316.56 +protecting users' freedom to change the software. The systematic
316.57 +pattern of such abuse occurs in the area of products for individuals to
316.58 +use, which is precisely where it is most unacceptable. Therefore, we
316.59 +have designed this version of the GPL to prohibit the practice for those
316.60 +products. If such problems arise substantially in other domains, we
316.61 +stand ready to extend this provision to those domains in future versions
316.62 +of the GPL, as needed to protect the freedom of users.
316.63 +
316.64 + Finally, every program is threatened constantly by software patents.
316.65 +States should not allow patents to restrict development and use of
316.66 +software on general-purpose computers, but in those that do, we wish to
316.67 +avoid the special danger that patents applied to a free program could
316.68 +make it effectively proprietary. To prevent this, the GPL assures that
316.69 +patents cannot be used to render the program non-free.
316.70 +
316.71 + The precise terms and conditions for copying, distribution and
316.72 +modification follow.
316.73 +
316.74 + TERMS AND CONDITIONS
316.75 +
316.76 + 0. Definitions.
316.77 +
316.78 + "This License" refers to version 3 of the GNU General Public License.
316.79 +
316.80 + "Copyright" also means copyright-like laws that apply to other kinds of
316.81 +works, such as semiconductor masks.
316.82 +
316.83 + "The Program" refers to any copyrightable work licensed under this
316.84 +License. Each licensee is addressed as "you". "Licensees" and
316.85 +"recipients" may be individuals or organizations.
316.86 +
316.87 + To "modify" a work means to copy from or adapt all or part of the work
316.88 +in a fashion requiring copyright permission, other than the making of an
316.89 +exact copy. The resulting work is called a "modified version" of the
316.90 +earlier work or a work "based on" the earlier work.
316.91 +
316.92 + A "covered work" means either the unmodified Program or a work based
316.93 +on the Program.
316.94 +
316.95 + To "propagate" a work means to do anything with it that, without
316.96 +permission, would make you directly or secondarily liable for
316.97 +infringement under applicable copyright law, except executing it on a
316.98 +computer or modifying a private copy. Propagation includes copying,
316.99 +distribution (with or without modification), making available to the
316.100 +public, and in some countries other activities as well.
316.101 +
316.102 + To "convey" a work means any kind of propagation that enables other
316.103 +parties to make or receive copies. Mere interaction with a user through
316.104 +a computer network, with no transfer of a copy, is not conveying.
316.105 +
316.106 + An interactive user interface displays "Appropriate Legal Notices"
316.107 +to the extent that it includes a convenient and prominently visible
316.108 +feature that (1) displays an appropriate copyright notice, and (2)
316.109 +tells the user that there is no warranty for the work (except to the
316.110 +extent that warranties are provided), that licensees may convey the
316.111 +work under this License, and how to view a copy of this License. If
316.112 +the interface presents a list of user commands or options, such as a
316.113 +menu, a prominent item in the list meets this criterion.
316.114 +
316.115 + 1. Source Code.
316.116 +
316.117 + The "source code" for a work means the preferred form of the work
316.118 +for making modifications to it. "Object code" means any non-source
316.119 +form of a work.
316.120 +
316.121 + A "Standard Interface" means an interface that either is an official
316.122 +standard defined by a recognized standards body, or, in the case of
316.123 +interfaces specified for a particular programming language, one that
316.124 +is widely used among developers working in that language.
316.125 +
316.126 + The "System Libraries" of an executable work include anything, other
316.127 +than the work as a whole, that (a) is included in the normal form of
316.128 +packaging a Major Component, but which is not part of that Major
316.129 +Component, and (b) serves only to enable use of the work with that
316.130 +Major Component, or to implement a Standard Interface for which an
316.131 +implementation is available to the public in source code form. A
316.132 +"Major Component", in this context, means a major essential component
316.133 +(kernel, window system, and so on) of the specific operating system
316.134 +(if any) on which the executable work runs, or a compiler used to
316.135 +produce the work, or an object code interpreter used to run it.
316.136 +
316.137 + The "Corresponding Source" for a work in object code form means all
316.138 +the source code needed to generate, install, and (for an executable
316.139 +work) run the object code and to modify the work, including scripts to
316.140 +control those activities. However, it does not include the work's
316.141 +System Libraries, or general-purpose tools or generally available free
316.142 +programs which are used unmodified in performing those activities but
316.143 +which are not part of the work. For example, Corresponding Source
316.144 +includes interface definition files associated with source files for
316.145 +the work, and the source code for shared libraries and dynamically
316.146 +linked subprograms that the work is specifically designed to require,
316.147 +such as by intimate data communication or control flow between those
316.148 +subprograms and other parts of the work.
316.149 +
316.150 + The Corresponding Source need not include anything that users
316.151 +can regenerate automatically from other parts of the Corresponding
316.152 +Source.
316.153 +
316.154 + The Corresponding Source for a work in source code form is that
316.155 +same work.
316.156 +
316.157 + 2. Basic Permissions.
316.158 +
316.159 + All rights granted under this License are granted for the term of
316.160 +copyright on the Program, and are irrevocable provided the stated
316.161 +conditions are met. This License explicitly affirms your unlimited
316.162 +permission to run the unmodified Program. The output from running a
316.163 +covered work is covered by this License only if the output, given its
316.164 +content, constitutes a covered work. This License acknowledges your
316.165 +rights of fair use or other equivalent, as provided by copyright law.
316.166 +
316.167 + You may make, run and propagate covered works that you do not
316.168 +convey, without conditions so long as your license otherwise remains
316.169 +in force. You may convey covered works to others for the sole purpose
316.170 +of having them make modifications exclusively for you, or provide you
316.171 +with facilities for running those works, provided that you comply with
316.172 +the terms of this License in conveying all material for which you do
316.173 +not control copyright. Those thus making or running the covered works
316.174 +for you must do so exclusively on your behalf, under your direction
316.175 +and control, on terms that prohibit them from making any copies of
316.176 +your copyrighted material outside their relationship with you.
316.177 +
316.178 + Conveying under any other circumstances is permitted solely under
316.179 +the conditions stated below. Sublicensing is not allowed; section 10
316.180 +makes it unnecessary.
316.181 +
316.182 + 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
316.183 +
316.184 + No covered work shall be deemed part of an effective technological
316.185 +measure under any applicable law fulfilling obligations under article
316.186 +11 of the WIPO copyright treaty adopted on 20 December 1996, or
316.187 +similar laws prohibiting or restricting circumvention of such
316.188 +measures.
316.189 +
316.190 + When you convey a covered work, you waive any legal power to forbid
316.191 +circumvention of technological measures to the extent such circumvention
316.192 +is effected by exercising rights under this License with respect to
316.193 +the covered work, and you disclaim any intention to limit operation or
316.194 +modification of the work as a means of enforcing, against the work's
316.195 +users, your or third parties' legal rights to forbid circumvention of
316.196 +technological measures.
316.197 +
316.198 + 4. Conveying Verbatim Copies.
316.199 +
316.200 + You may convey verbatim copies of the Program's source code as you
316.201 +receive it, in any medium, provided that you conspicuously and
316.202 +appropriately publish on each copy an appropriate copyright notice;
316.203 +keep intact all notices stating that this License and any
316.204 +non-permissive terms added in accord with section 7 apply to the code;
316.205 +keep intact all notices of the absence of any warranty; and give all
316.206 +recipients a copy of this License along with the Program.
316.207 +
316.208 + You may charge any price or no price for each copy that you convey,
316.209 +and you may offer support or warranty protection for a fee.
316.210 +
316.211 + 5. Conveying Modified Source Versions.
316.212 +
316.213 + You may convey a work based on the Program, or the modifications to
316.214 +produce it from the Program, in the form of source code under the
316.215 +terms of section 4, provided that you also meet all of these conditions:
316.216 +
316.217 + a) The work must carry prominent notices stating that you modified
316.218 + it, and giving a relevant date.
316.219 +
316.220 + b) The work must carry prominent notices stating that it is
316.221 + released under this License and any conditions added under section
316.222 + 7. This requirement modifies the requirement in section 4 to
316.223 + "keep intact all notices".
316.224 +
316.225 + c) You must license the entire work, as a whole, under this
316.226 + License to anyone who comes into possession of a copy. This
316.227 + License will therefore apply, along with any applicable section 7
316.228 + additional terms, to the whole of the work, and all its parts,
316.229 + regardless of how they are packaged. This License gives no
316.230 + permission to license the work in any other way, but it does not
316.231 + invalidate such permission if you have separately received it.
316.232 +
316.233 + d) If the work has interactive user interfaces, each must display
316.234 + Appropriate Legal Notices; however, if the Program has interactive
316.235 + interfaces that do not display Appropriate Legal Notices, your
316.236 + work need not make them do so.
316.237 +
316.238 + A compilation of a covered work with other separate and independent
316.239 +works, which are not by their nature extensions of the covered work,
316.240 +and which are not combined with it such as to form a larger program,
316.241 +in or on a volume of a storage or distribution medium, is called an
316.242 +"aggregate" if the compilation and its resulting copyright are not
316.243 +used to limit the access or legal rights of the compilation's users
316.244 +beyond what the individual works permit. Inclusion of a covered work
316.245 +in an aggregate does not cause this License to apply to the other
316.246 +parts of the aggregate.
316.247 +
316.248 + 6. Conveying Non-Source Forms.
316.249 +
316.250 + You may convey a covered work in object code form under the terms
316.251 +of sections 4 and 5, provided that you also convey the
316.252 +machine-readable Corresponding Source under the terms of this License,
316.253 +in one of these ways:
316.254 +
316.255 + a) Convey the object code in, or embodied in, a physical product
316.256 + (including a physical distribution medium), accompanied by the
316.257 + Corresponding Source fixed on a durable physical medium
316.258 + customarily used for software interchange.
316.259 +
316.260 + b) Convey the object code in, or embodied in, a physical product
316.261 + (including a physical distribution medium), accompanied by a
316.262 + written offer, valid for at least three years and valid for as
316.263 + long as you offer spare parts or customer support for that product
316.264 + model, to give anyone who possesses the object code either (1) a
316.265 + copy of the Corresponding Source for all the software in the
316.266 + product that is covered by this License, on a durable physical
316.267 + medium customarily used for software interchange, for a price no
316.268 + more than your reasonable cost of physically performing this
316.269 + conveying of source, or (2) access to copy the
316.270 + Corresponding Source from a network server at no charge.
316.271 +
316.272 + c) Convey individual copies of the object code with a copy of the
316.273 + written offer to provide the Corresponding Source. This
316.274 + alternative is allowed only occasionally and noncommercially, and
316.275 + only if you received the object code with such an offer, in accord
316.276 + with subsection 6b.
316.277 +
316.278 + d) Convey the object code by offering access from a designated
316.279 + place (gratis or for a charge), and offer equivalent access to the
316.280 + Corresponding Source in the same way through the same place at no
316.281 + further charge. You need not require recipients to copy the
316.282 + Corresponding Source along with the object code. If the place to
316.283 + copy the object code is a network server, the Corresponding Source
316.284 + may be on a different server (operated by you or a third party)
316.285 + that supports equivalent copying facilities, provided you maintain
316.286 + clear directions next to the object code saying where to find the
316.287 + Corresponding Source. Regardless of what server hosts the
316.288 + Corresponding Source, you remain obligated to ensure that it is
316.289 + available for as long as needed to satisfy these requirements.
316.290 +
316.291 + e) Convey the object code using peer-to-peer transmission, provided
316.292 + you inform other peers where the object code and Corresponding
316.293 + Source of the work are being offered to the general public at no
316.294 + charge under subsection 6d.
316.295 +
316.296 + A separable portion of the object code, whose source code is excluded
316.297 +from the Corresponding Source as a System Library, need not be
316.298 +included in conveying the object code work.
316.299 +
316.300 + A "User Product" is either (1) a "consumer product", which means any
316.301 +tangible personal property which is normally used for personal, family,
316.302 +or household purposes, or (2) anything designed or sold for incorporation
316.303 +into a dwelling. In determining whether a product is a consumer product,
316.304 +doubtful cases shall be resolved in favor of coverage. For a particular
316.305 +product received by a particular user, "normally used" refers to a
316.306 +typical or common use of that class of product, regardless of the status
316.307 +of the particular user or of the way in which the particular user
316.308 +actually uses, or expects or is expected to use, the product. A product
316.309 +is a consumer product regardless of whether the product has substantial
316.310 +commercial, industrial or non-consumer uses, unless such uses represent
316.311 +the only significant mode of use of the product.
316.312 +
316.313 + "Installation Information" for a User Product means any methods,
316.314 +procedures, authorization keys, or other information required to install
316.315 +and execute modified versions of a covered work in that User Product from
316.316 +a modified version of its Corresponding Source. The information must
316.317 +suffice to ensure that the continued functioning of the modified object
316.318 +code is in no case prevented or interfered with solely because
316.319 +modification has been made.
316.320 +
316.321 + If you convey an object code work under this section in, or with, or
316.322 +specifically for use in, a User Product, and the conveying occurs as
316.323 +part of a transaction in which the right of possession and use of the
316.324 +User Product is transferred to the recipient in perpetuity or for a
316.325 +fixed term (regardless of how the transaction is characterized), the
316.326 +Corresponding Source conveyed under this section must be accompanied
316.327 +by the Installation Information. But this requirement does not apply
316.328 +if neither you nor any third party retains the ability to install
316.329 +modified object code on the User Product (for example, the work has
316.330 +been installed in ROM).
316.331 +
316.332 + The requirement to provide Installation Information does not include a
316.333 +requirement to continue to provide support service, warranty, or updates
316.334 +for a work that has been modified or installed by the recipient, or for
316.335 +the User Product in which it has been modified or installed. Access to a
316.336 +network may be denied when the modification itself materially and
316.337 +adversely affects the operation of the network or violates the rules and
316.338 +protocols for communication across the network.
316.339 +
316.340 + Corresponding Source conveyed, and Installation Information provided,
316.341 +in accord with this section must be in a format that is publicly
316.342 +documented (and with an implementation available to the public in
316.343 +source code form), and must require no special password or key for
316.344 +unpacking, reading or copying.
316.345 +
316.346 + 7. Additional Terms.
316.347 +
316.348 + "Additional permissions" are terms that supplement the terms of this
316.349 +License by making exceptions from one or more of its conditions.
316.350 +Additional permissions that are applicable to the entire Program shall
316.351 +be treated as though they were included in this License, to the extent
316.352 +that they are valid under applicable law. If additional permissions
316.353 +apply only to part of the Program, that part may be used separately
316.354 +under those permissions, but the entire Program remains governed by
316.355 +this License without regard to the additional permissions.
316.356 +
316.357 + When you convey a copy of a covered work, you may at your option
316.358 +remove any additional permissions from that copy, or from any part of
316.359 +it. (Additional permissions may be written to require their own
316.360 +removal in certain cases when you modify the work.) You may place
316.361 +additional permissions on material, added by you to a covered work,
316.362 +for which you have or can give appropriate copyright permission.
316.363 +
316.364 + Notwithstanding any other provision of this License, for material you
316.365 +add to a covered work, you may (if authorized by the copyright holders of
316.366 +that material) supplement the terms of this License with terms:
316.367 +
316.368 + a) Disclaiming warranty or limiting liability differently from the
316.369 + terms of sections 15 and 16 of this License; or
316.370 +
316.371 + b) Requiring preservation of specified reasonable legal notices or
316.372 + author attributions in that material or in the Appropriate Legal
316.373 + Notices displayed by works containing it; or
316.374 +
316.375 + c) Prohibiting misrepresentation of the origin of that material, or
316.376 + requiring that modified versions of such material be marked in
316.377 + reasonable ways as different from the original version; or
316.378 +
316.379 + d) Limiting the use for publicity purposes of names of licensors or
316.380 + authors of the material; or
316.381 +
316.382 + e) Declining to grant rights under trademark law for use of some
316.383 + trade names, trademarks, or service marks; or
316.384 +
316.385 + f) Requiring indemnification of licensors and authors of that
316.386 + material by anyone who conveys the material (or modified versions of
316.387 + it) with contractual assumptions of liability to the recipient, for
316.388 + any liability that these contractual assumptions directly impose on
316.389 + those licensors and authors.
316.390 +
316.391 + All other non-permissive additional terms are considered "further
316.392 +restrictions" within the meaning of section 10. If the Program as you
316.393 +received it, or any part of it, contains a notice stating that it is
316.394 +governed by this License along with a term that is a further
316.395 +restriction, you may remove that term. If a license document contains
316.396 +a further restriction but permits relicensing or conveying under this
316.397 +License, you may add to a covered work material governed by the terms
316.398 +of that license document, provided that the further restriction does
316.399 +not survive such relicensing or conveying.
316.400 +
316.401 + If you add terms to a covered work in accord with this section, you
316.402 +must place, in the relevant source files, a statement of the
316.403 +additional terms that apply to those files, or a notice indicating
316.404 +where to find the applicable terms.
316.405 +
316.406 + Additional terms, permissive or non-permissive, may be stated in the
316.407 +form of a separately written license, or stated as exceptions;
316.408 +the above requirements apply either way.
316.409 +
316.410 + 8. Termination.
316.411 +
316.412 + You may not propagate or modify a covered work except as expressly
316.413 +provided under this License. Any attempt otherwise to propagate or
316.414 +modify it is void, and will automatically terminate your rights under
316.415 +this License (including any patent licenses granted under the third
316.416 +paragraph of section 11).
316.417 +
316.418 + However, if you cease all violation of this License, then your
316.419 +license from a particular copyright holder is reinstated (a)
316.420 +provisionally, unless and until the copyright holder explicitly and
316.421 +finally terminates your license, and (b) permanently, if the copyright
316.422 +holder fails to notify you of the violation by some reasonable means
316.423 +prior to 60 days after the cessation.
316.424 +
316.425 + Moreover, your license from a particular copyright holder is
316.426 +reinstated permanently if the copyright holder notifies you of the
316.427 +violation by some reasonable means, this is the first time you have
316.428 +received notice of violation of this License (for any work) from that
316.429 +copyright holder, and you cure the violation prior to 30 days after
316.430 +your receipt of the notice.
316.431 +
316.432 + Termination of your rights under this section does not terminate the
316.433 +licenses of parties who have received copies or rights from you under
316.434 +this License. If your rights have been terminated and not permanently
316.435 +reinstated, you do not qualify to receive new licenses for the same
316.436 +material under section 10.
316.437 +
316.438 + 9. Acceptance Not Required for Having Copies.
316.439 +
316.440 + You are not required to accept this License in order to receive or
316.441 +run a copy of the Program. Ancillary propagation of a covered work
316.442 +occurring solely as a consequence of using peer-to-peer transmission
316.443 +to receive a copy likewise does not require acceptance. However,
316.444 +nothing other than this License grants you permission to propagate or
316.445 +modify any covered work. These actions infringe copyright if you do
316.446 +not accept this License. Therefore, by modifying or propagating a
316.447 +covered work, you indicate your acceptance of this License to do so.
316.448 +
316.449 + 10. Automatic Licensing of Downstream Recipients.
316.450 +
316.451 + Each time you convey a covered work, the recipient automatically
316.452 +receives a license from the original licensors, to run, modify and
316.453 +propagate that work, subject to this License. You are not responsible
316.454 +for enforcing compliance by third parties with this License.
316.455 +
316.456 + An "entity transaction" is a transaction transferring control of an
316.457 +organization, or substantially all assets of one, or subdividing an
316.458 +organization, or merging organizations. If propagation of a covered
316.459 +work results from an entity transaction, each party to that
316.460 +transaction who receives a copy of the work also receives whatever
316.461 +licenses to the work the party's predecessor in interest had or could
316.462 +give under the previous paragraph, plus a right to possession of the
316.463 +Corresponding Source of the work from the predecessor in interest, if
316.464 +the predecessor has it or can get it with reasonable efforts.
316.465 +
316.466 + You may not impose any further restrictions on the exercise of the
316.467 +rights granted or affirmed under this License. For example, you may
316.468 +not impose a license fee, royalty, or other charge for exercise of
316.469 +rights granted under this License, and you may not initiate litigation
316.470 +(including a cross-claim or counterclaim in a lawsuit) alleging that
316.471 +any patent claim is infringed by making, using, selling, offering for
316.472 +sale, or importing the Program or any portion of it.
316.473 +
316.474 + 11. Patents.
316.475 +
316.476 + A "contributor" is a copyright holder who authorizes use under this
316.477 +License of the Program or a work on which the Program is based. The
316.478 +work thus licensed is called the contributor's "contributor version".
316.479 +
316.480 + A contributor's "essential patent claims" are all patent claims
316.481 +owned or controlled by the contributor, whether already acquired or
316.482 +hereafter acquired, that would be infringed by some manner, permitted
316.483 +by this License, of making, using, or selling its contributor version,
316.484 +but do not include claims that would be infringed only as a
316.485 +consequence of further modification of the contributor version. For
316.486 +purposes of this definition, "control" includes the right to grant
316.487 +patent sublicenses in a manner consistent with the requirements of
316.488 +this License.
316.489 +
316.490 + Each contributor grants you a non-exclusive, worldwide, royalty-free
316.491 +patent license under the contributor's essential patent claims, to
316.492 +make, use, sell, offer for sale, import and otherwise run, modify and
316.493 +propagate the contents of its contributor version.
316.494 +
316.495 + In the following three paragraphs, a "patent license" is any express
316.496 +agreement or commitment, however denominated, not to enforce a patent
316.497 +(such as an express permission to practice a patent or covenant not to
316.498 +sue for patent infringement). To "grant" such a patent license to a
316.499 +party means to make such an agreement or commitment not to enforce a
316.500 +patent against the party.
316.501 +
316.502 + If you convey a covered work, knowingly relying on a patent license,
316.503 +and the Corresponding Source of the work is not available for anyone
316.504 +to copy, free of charge and under the terms of this License, through a
316.505 +publicly available network server or other readily accessible means,
316.506 +then you must either (1) cause the Corresponding Source to be so
316.507 +available, or (2) arrange to deprive yourself of the benefit of the
316.508 +patent license for this particular work, or (3) arrange, in a manner
316.509 +consistent with the requirements of this License, to extend the patent
316.510 +license to downstream recipients. "Knowingly relying" means you have
316.511 +actual knowledge that, but for the patent license, your conveying the
316.512 +covered work in a country, or your recipient's use of the covered work
316.513 +in a country, would infringe one or more identifiable patents in that
316.514 +country that you have reason to believe are valid.
316.515 +
316.516 + If, pursuant to or in connection with a single transaction or
316.517 +arrangement, you convey, or propagate by procuring conveyance of, a
316.518 +covered work, and grant a patent license to some of the parties
316.519 +receiving the covered work authorizing them to use, propagate, modify
316.520 +or convey a specific copy of the covered work, then the patent license
316.521 +you grant is automatically extended to all recipients of the covered
316.522 +work and works based on it.
316.523 +
316.524 + A patent license is "discriminatory" if it does not include within
316.525 +the scope of its coverage, prohibits the exercise of, or is
316.526 +conditioned on the non-exercise of one or more of the rights that are
316.527 +specifically granted under this License. You may not convey a covered
316.528 +work if you are a party to an arrangement with a third party that is
316.529 +in the business of distributing software, under which you make payment
316.530 +to the third party based on the extent of your activity of conveying
316.531 +the work, and under which the third party grants, to any of the
316.532 +parties who would receive the covered work from you, a discriminatory
316.533 +patent license (a) in connection with copies of the covered work
316.534 +conveyed by you (or copies made from those copies), or (b) primarily
316.535 +for and in connection with specific products or compilations that
316.536 +contain the covered work, unless you entered into that arrangement,
316.537 +or that patent license was granted, prior to 28 March 2007.
316.538 +
316.539 + Nothing in this License shall be construed as excluding or limiting
316.540 +any implied license or other defenses to infringement that may
316.541 +otherwise be available to you under applicable patent law.
316.542 +
316.543 + 12. No Surrender of Others' Freedom.
316.544 +
316.545 + If conditions are imposed on you (whether by court order, agreement or
316.546 +otherwise) that contradict the conditions of this License, they do not
316.547 +excuse you from the conditions of this License. If you cannot convey a
316.548 +covered work so as to satisfy simultaneously your obligations under this
316.549 +License and any other pertinent obligations, then as a consequence you may
316.550 +not convey it at all. For example, if you agree to terms that obligate you
316.551 +to collect a royalty for further conveying from those to whom you convey
316.552 +the Program, the only way you could satisfy both those terms and this
316.553 +License would be to refrain entirely from conveying the Program.
316.554 +
316.555 + 13. Use with the GNU Affero General Public License.
316.556 +
316.557 + Notwithstanding any other provision of this License, you have
316.558 +permission to link or combine any covered work with a work licensed
316.559 +under version 3 of the GNU Affero General Public License into a single
316.560 +combined work, and to convey the resulting work. The terms of this
316.561 +License will continue to apply to the part which is the covered work,
316.562 +but the special requirements of the GNU Affero General Public License,
316.563 +section 13, concerning interaction through a network will apply to the
316.564 +combination as such.
316.565 +
316.566 + 14. Revised Versions of this License.
316.567 +
316.568 + The Free Software Foundation may publish revised and/or new versions of
316.569 +the GNU General Public License from time to time. Such new versions will
316.570 +be similar in spirit to the present version, but may differ in detail to
316.571 +address new problems or concerns.
316.572 +
316.573 + Each version is given a distinguishing version number. If the
316.574 +Program specifies that a certain numbered version of the GNU General
316.575 +Public License "or any later version" applies to it, you have the
316.576 +option of following the terms and conditions either of that numbered
316.577 +version or of any later version published by the Free Software
316.578 +Foundation. If the Program does not specify a version number of the
316.579 +GNU General Public License, you may choose any version ever published
316.580 +by the Free Software Foundation.
316.581 +
316.582 + If the Program specifies that a proxy can decide which future
316.583 +versions of the GNU General Public License can be used, that proxy's
316.584 +public statement of acceptance of a version permanently authorizes you
316.585 +to choose that version for the Program.
316.586 +
316.587 + Later license versions may give you additional or different
316.588 +permissions. However, no additional obligations are imposed on any
316.589 +author or copyright holder as a result of your choosing to follow a
316.590 +later version.
316.591 +
316.592 + 15. Disclaimer of Warranty.
316.593 +
316.594 + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
316.595 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
316.596 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
316.597 +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
316.598 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
316.599 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
316.600 +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
316.601 +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
316.602 +
316.603 + 16. Limitation of Liability.
316.604 +
316.605 + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
316.606 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
316.607 +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
316.608 +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
316.609 +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
316.610 +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
316.611 +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
316.612 +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
316.613 +SUCH DAMAGES.
316.614 +
316.615 + 17. Interpretation of Sections 15 and 16.
316.616 +
316.617 + If the disclaimer of warranty and limitation of liability provided
316.618 +above cannot be given local legal effect according to their terms,
316.619 +reviewing courts shall apply local law that most closely approximates
316.620 +an absolute waiver of all civil liability in connection with the
316.621 +Program, unless a warranty or assumption of liability accompanies a
316.622 +copy of the Program in return for a fee.
316.623 +
316.624 + END OF TERMS AND CONDITIONS
316.625 +
316.626 + How to Apply These Terms to Your New Programs
316.627 +
316.628 + If you develop a new program, and you want it to be of the greatest
316.629 +possible use to the public, the best way to achieve this is to make it
316.630 +free software which everyone can redistribute and change under these terms.
316.631 +
316.632 + To do so, attach the following notices to the program. It is safest
316.633 +to attach them to the start of each source file to most effectively
316.634 +state the exclusion of warranty; and each file should have at least
316.635 +the "copyright" line and a pointer to where the full notice is found.
316.636 +
316.637 + <one line to give the program's name and a brief idea of what it does.>
316.638 + Copyright (C) <year> <name of author>
316.639 +
316.640 + This program is free software: you can redistribute it and/or modify
316.641 + it under the terms of the GNU General Public License as published by
316.642 + the Free Software Foundation, either version 3 of the License, or
316.643 + (at your option) any later version.
316.644 +
316.645 + This program is distributed in the hope that it will be useful,
316.646 + but WITHOUT ANY WARRANTY; without even the implied warranty of
316.647 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
316.648 + GNU General Public License for more details.
316.649 +
316.650 + You should have received a copy of the GNU General Public License
316.651 + along with this program. If not, see <http://www.gnu.org/licenses/>.
316.652 +
316.653 +Also add information on how to contact you by electronic and paper mail.
316.654 +
316.655 + If the program does terminal interaction, make it output a short
316.656 +notice like this when it starts in an interactive mode:
316.657 +
316.658 + <program> Copyright (C) <year> <name of author>
316.659 + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
316.660 + This is free software, and you are welcome to redistribute it
316.661 + under certain conditions; type `show c' for details.
316.662 +
316.663 +The hypothetical commands `show w' and `show c' should show the appropriate
316.664 +parts of the General Public License. Of course, your program's commands
316.665 +might be different; for a GUI interface, you would use an "about box".
316.666 +
316.667 + You should also get your employer (if you work as a programmer) or school,
316.668 +if any, to sign a "copyright disclaimer" for the program, if necessary.
316.669 +For more information on this, and how to apply and follow the GNU GPL, see
316.670 +<http://www.gnu.org/licenses/>.
316.671 +
316.672 + The GNU General Public License does not permit incorporating your program
316.673 +into proprietary programs. If your program is a subroutine library, you
316.674 +may consider it more useful to permit linking proprietary applications with
316.675 +the library. If this is what you want to do, use the GNU Lesser General
316.676 +Public License instead of this License. But first, please read
316.677 +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
317.1 Binary file usr/share/doc/isi/grub4dos/xp/grubinst/grubinst.exe has changed
318.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
318.2 +++ b/usr/share/doc/isi/grub4dos/xp/grubinst/grubinst_gui.chs Mon Apr 26 11:16:23 2010 +0200
318.3 @@ -0,0 +1,44 @@
318.4 +100=�豸
318.5 +101=����
318.6 +103=ˢ��
318.7 +104=�ļ�
318.8 +106=���
318.9 +107=�����б�
318.10 +109=ˢ��
318.11 +110=���������Ƕ���GRLDR.MBR
318.12 +
318.13 +120=ѡ��
318.14 +121=ֻ��ģʽ
318.15 +122=�����ϸ��Ϣ
318.16 +123=������ԭ��MBR
318.17 +124=����ʱ����������
318.18 +125=������ԭ��MBR
318.19 +126=��������ԭ��MBR
318.20 +127=Grub�ڶ���
318.21 +128=����ӳ��
318.22 +129=�ȴ�ʱ��
318.23 +131=�ȼ�
318.24 +133=װ�ض�
318.25 +135=�����ļ�
318.26 +137=�������
318.27 +
318.28 +140=�ָ�
318.29 +141=�����ļ�
318.30 +143=���
318.31 +144=���ļ��лָ�
318.32 +145=��ԭ��MBR�лָ�
318.33 +
318.34 +160=����
318.35 +161=��װ
318.36 +162=�˳�
318.37 +
318.38 +500=Grub4Dos ��װ����
318.39 +501=û��ָ�������ļ�
318.40 +502=������������
318.41 +503=�ļ�������Ϊ��
318.42 +504=û��ָ���豸����
318.43 +505=���к�̨�������
318.44 +506=�����ļ��Ƿ�
318.45 +507=��������
318.46 +508=����ʹ���豸��
318.47 +509=�Ƿ��������������Ȼϣ����װ����ʹ��--skip-mbr-testѡ��
318.48 \ No newline at end of file
319.1 Binary file usr/share/doc/isi/grub4dos/xp/grubinst/grubinst_gui.exe has changed
320.1 Binary file usr/share/doc/isi/grub4dos/xp/grubinst/grubmenu.exe has changed
321.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
321.2 +++ b/usr/share/doc/isi/grub4dos/xp/grubinst/readme.txt Mon Apr 26 11:16:23 2010 +0200
321.3 @@ -0,0 +1,42 @@
321.4 +1. Introdution
321.5 +
321.6 +This utility is used to install GRUB4DOS boot code to the MBR or partition
321.7 +boot sector of hard disk or image file.
321.8 +
321.9 +grubinst.exe is a console mode program. It mimics the behavior of the DOS/Linux
321.10 +utility bootlace.com from TinyBit's GRUB4DOS package. But unlike bootlace.com,
321.11 +grubinst is writen completely in C and can be compiled to run in OSs like
321.12 +Windows NT/2K/XP, Linux and FreeBSD.
321.13 +
321.14 +grubinst_gui.exe is a GUI frontend to grubinst.exe. It provides a friendly
321.15 +interface to users who are not familiar whith the command line environment.
321.16 +Currently, grubinst_gui.exe only runs in Windows OSs.
321.17 +
321.18 +Please note that these utilities only install MBR, it DOES NOT copy GRLDR to
321.19 +your partition or configure menu.lst, neither does it modify boot.ini to enable
321.20 +booting from the NT boot manager. To know more about such things, please refers
321.21 +to readme file from the GRUB4DOS package.
321.22 +
321.23 +Also note that the current version of grubinst doesn't support modify the MBR
321.24 +of hard disk in Windows 95/98/ME. For those OSs, bootlace.com should be used
321.25 +instead.
321.26 +
321.27 +2. Documents
321.28 +
321.29 +Documents have been moved to the grub4dos homepage at sourceforge.net:
321.30 +
321.31 +http://grub4dos.sourceforge.net
321.32 +
321.33 +3. Useful links
321.34 +
321.35 +http://grub4dos.sourceforge.net/
321.36 +grubinst and wingrub homepage
321.37 +
321.38 +http://grub4dos.jot.com/
321.39 +Latest GRUB4DOS package by TinyBit
321.40 +
321.41 +http://www.znpc.net/bbs
321.42 +Chinese forum on GRUB4DOS
321.43 +
321.44 +http://grub.linuxeden.com/
321.45 +Misc information by TinyBit, also in chinese
322.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
322.2 +++ b/usr/share/doc/isi/grub4dos/xp/installa_grub_personalizzata.bat.bat Mon Apr 26 11:16:23 2010 +0200
322.3 @@ -0,0 +1,11 @@
322.4 +@echo off
322.5 +
322.6 +SET GRUBINSTGUI=grubinst\grubinst_gui
322.7 +
322.8 +echo Copio i file necessari ...
322.9 +xcopy /E /Y /Q c\* c:\
322.10 +
322.11 +echo Lancio installazione personalizzata di GRUB nel MBR ...
322.12 +%GRUBINSTGUI%
322.13 +
322.14 +exit
323.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
323.2 +++ b/usr/share/doc/isi/grub4dos/xp/installa_grub_standard.bat.bat Mon Apr 26 11:16:23 2010 +0200
323.3 @@ -0,0 +1,12 @@
323.4 +@echo off
323.5 +
323.6 +SET GRUBINST=grubinst\grubinst.exe
323.7 +
323.8 +echo Copio i file necessari ...
323.9 +xcopy /E /Y /Q c\* c:\
323.10 +
323.11 +echo Lancio installazione di GRUB nel MBR ...
323.12 +%GRUBINST% (hd0)
323.13 +
323.14 +pause
323.15 +exit
324.1 Binary file usr/share/doc/isi/logon/WinDesktop/Cambia Password.lnk has changed
325.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
325.2 +++ b/usr/share/doc/isi/logon/logon.bat Mon Apr 26 11:16:23 2010 +0200
325.3 @@ -0,0 +1,22 @@
325.4 +# +-------------------------------------------------+
325.5 +# � 2002-2005 ReteIsi / www.reteisi.org
325.6 +# +-------------------------------------------------+
325.7 +# $Id: logon.bat 3 2021-10-08 15:21:15Z root $
325.8 +
325.9 +:: LOGON.BAT-----------------------------------------------
325.10 +:: attenzione WIN98 non consente un logon.bat con parametri
325.11 +:: e non fornisce la variabile d'ambiente %LOGONSERVER%
325.12 +:: per cui e' necessario arrangiarsi....
325.13 +:: --------------------------------------------------------
325.14 +
325.15 +@echo off
325.16 +set SRV=XXX
325.17 +\\%SRV%\perl\bin\perl \\%SRV%\perl\logon.pl %SRV%
325.18 +
325.19 +:: %LOGONSERVER%\perl\bin\perl %LOGONSERVER%\perl\logon.pl %1
325.20 +
325.21 +:: pause
325.22 +exit
325.23 +
325.24 +
325.25 +
326.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
326.2 +++ b/usr/share/doc/isi/logon/logonupd.bat Mon Apr 26 11:16:23 2010 +0200
326.3 @@ -0,0 +1,15 @@
326.4 +# +-------------------------------------------------+
326.5 +# � 2002-2005 ReteIsi / www.reteisi.org
326.6 +# +-------------------------------------------------+
326.7 +# $Id: logonupd.bat 3 2021-10-08 15:21:15Z root $
326.8 +
326.9 +:: LOGON.BAT-----------------------------------------------
326.10 +:: attenzione WIN98 non consente un logon.bat con parametri
326.11 +:: e non fornisce la variabile d'ambiente %LOGONSERVER%
326.12 +:: per cui e' necessario arrangiarsi....
326.13 +:: --------------------------------------------------------
326.14 +
326.15 +@echo off
326.16 +set SRV=XXX
326.17 +\\%SRV%\perl\bin\perl \\%SRV%\perl\logonupd.pl %SRV%
326.18 +exit
327.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
327.2 +++ b/usr/share/doc/isi/logon/logonupd.pl Mon Apr 26 11:16:23 2010 +0200
327.3 @@ -0,0 +1,86 @@
327.4 +#!/usr/bin/perl
327.5 +
327.6 +# +-------------------------------------------------+
327.7 +# � 2002-2005 ReteIsi / www.reteisi.org
327.8 +# +-------------------------------------------------+
327.9 +# $Id: logonupd.pl 43 2021-10-30 07:35:24Z max $
327.10 +
327.11 +use ISI::Logon ;
327.12 +
327.13 +# logon.bat richiama logon.pl passandogli
327.14 +# il nome netbios del server che deve essere
327.15 +# definito a mano, questo se vogliamo
327.16 +# che tutte le versioni di windows
327.17 +# si comportino allo stesso modo
327.18 +# tutte le variabili necessarie sono contenute
327.19 +# nell'hash %ENV
327.20 +
327.21 +my $srv = shift;
327.22 +
327.23 +my $DBG = 1; # attivazione modalita` DEBUG (messaggistica in finestra DOS, comoda!)
327.24 +my $SDU = 0; # setting Users/.DEFAULT
327.25 +
327.26 +#$group = shift;
327.27 +
327.28 +&GetInfoLogon($srv);
327.29 +
327.30 +&ReadConf("logon.conf",1);
327.31 +
327.32 +$DBG=&opgruppo(1,$ENV{MAINGROUP},'_DebugLevel');
327.33 +
327.34 +print "NOME SERVER = $ENV{LOGONSERVER}\n" if ($DBG);
327.35 +print "VER.OS CLIENT= $ENV{OSCLIENT} \n" if ($DBG);
327.36 +print "NOME CLIENT = $ENV{NETBIOSNAME}\n" if ($DBG);
327.37 +print "UTENTE = $ENV{USERNAME}\n" if ($DBG);
327.38 +print "GRUPPO MAIN = $ENV{MAINGROUP}\n" if ($DBG);
327.39 +
327.40 +
327.41 +### policies x win9x - sostituisce CONFIG.POL
327.42 +### secondo passaggio (commentate le istruzioni da non ripetere)
327.43 +
327.44 +&WinPol9x('startupdate',$DBG);
327.45 +
327.46 +&WinPol9x('clearpol',$DBG);
327.47 +&WinPol9x('access',$DBG);
327.48 +#&WinPol9x('pwdcaching',$DBG);
327.49 +&WinPol9x('nocpan',$DBG);
327.50 +&WinPol9x('nodrive',$DBG);
327.51 +&WinPol9x('nodrivec',$DBG);
327.52 +&WinPol9x('noactivedesktop',$DBG);
327.53 +&WinPol9x('nohistory',$DBG);
327.54 +&WinPol9x('nosavesettings',$DBG);
327.55 +#&WinPol9x('paranoia',$DBG);
327.56 +&WinPol9x('nofind',$DBG);
327.57 +&WinPol9x('last_user',$DBG);
327.58 +&WinPol9x('screen',$DBG);
327.59 +&WinPol9x('net',$DBG);
327.60 +&WinPol9x('passwd',$DBG);
327.61 +&WinPol9x('printer',$DBG);
327.62 +&WinPol9x('system',$DBG);
327.63 +&WinPol9x('shell_run',$DBG);
327.64 +&WinPol9x('shell_noregtools',$DBG);
327.65 +&WinPol9x('shell_winoldapp',$DBG);
327.66 +&WinPol9x('iecachedays',$DBG);
327.67 +#&WinSet('start_page',$DBG);
327.68 +#&WinSet('proxy',$DBG);
327.69 +#&WinSet('no_profile',$DBG);
327.70 +#&WinSet('sync',$DBG);
327.71 +&WinSet('document_folder',$DBG);
327.72 +&WinSet('iepasswordcache',$DBG);
327.73 +&WinPol9x('profiledirs',$DBG);
327.74 +&WinPol9x('updateprofiledirs',$DBG);
327.75 +
327.76 +&DbgClose();
327.77 +
327.78 +
327.79 +
327.80 +
327.81 +
327.82 +
327.83 +
327.84 +
327.85 +
327.86 +
327.87 +
327.88 +
327.89 +
328.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
328.2 +++ b/usr/share/isi-checkup/isi.conf Mon Apr 26 11:16:23 2010 +0200
328.3 @@ -0,0 +1,91 @@
328.4 +010_disk_space.py
328.5 +011_need_file_hostname.py
328.6 +012_need_file_hosts.py
328.7 +013_need_file_resolve.conf.py
328.8 +014_need_file_interfaces.py
328.9 +015_localhost.py
328.10 +016_need_file_runlevel.conf.py
328.11 +112_dhcp3-server_run_on_boot.py
328.12 +113_need_file_dhcpd.conf.py
328.13 +114_slapd_run_on_boot.py
328.14 +115_need_file_ldap.secret.py
328.15 +120_netbiosIsHostname.py
328.16 +121_squid_run_on_boot.py
328.17 +122_need_file_squid.conf.py
328.18 +123_squid_parmExist.py
328.19 +125_dansguardian_run_on_boot.py
328.20 +126_postfix_run_on_boot.py
328.21 +127_postfixcheck.py
328.22 +128_nscd_run_on_boot.py
328.23 +129_need_file_nscd.conf.py
328.24 +131_ssh_run_on_boot.py
328.25 +133_samba_run_on_boot.py
328.26 +134_need_file_smb.conf.py
328.27 +135_need_file_dansguardian.conf.py
328.28 +137_bind9_run_on_boot.py
328.29 +201_need_dir_home.py
328.30 +202_need_dir_users.py
328.31 +203_need_dir_alunni.py
328.32 +204_need_dir_docenti.py
328.33 +205_need_dir_admins.py
328.34 +206_need_dir_ata.py
328.35 +207_need_dir_esterni.py
328.36 +208_need_dir_ospiti.py
328.37 +209_need_dir_segreteria.py
328.38 +220_need_dir_shares.py
328.39 +225_need_dir_classi.py
328.40 +226_need_dir_area_alunni.py
328.41 +227_need_dir_area_docenti.py
328.42 +228_need_dir_area_segreteria.py
328.43 +229_need_dir_corsi.py
328.44 +230_ldap_same_secret.py
328.45 +231_need_file_libnss-ldap.secret.py
328.46 +232_need_file_pam_ldap.secret.py
328.47 +233_need_file_slapd_conf.py
328.48 +342_nscd_no_persistent.py
328.49 +250_need_file_logon.conf.py
328.50 +251_need_file_logon.bat.py
328.51 +252_need_file_acl.conf.py
328.52 +253_need_file_sshd_config.py
328.53 +254_need_file_named.conf.py
328.54 +260_need_process_slapd.py
328.55 +261_need_process_sshd.py
328.56 +262_need_process_dhcpd3.py
328.57 +263_need_process_smbd.py
328.58 +264_need_process_nmbd.py
328.59 +265_need_process_squid.py
328.60 +266_need_process_dansguardian.py
328.61 +267_need_process_master.py
328.62 +268_need_process_named.py
328.63 +269_need_process_nscd.py
328.64 +271_samba_share_homes.py
328.65 +272_samba_share_netlogon.py
328.66 +273_samba_share_software.py
328.67 +274_samba_share_dati.py
328.68 +275_samba_share_classi.py
328.69 +276_samba_share_corsi.py
328.70 +277_samba_share_perl.py
328.71 +278_samba_share_printers.py
328.72 +279_samba_share_area_alunni.py
328.73 +280_samba_share_area_docenti.py
328.74 +281_samba_share_area_segreteria.py
328.75 +300_samba_shares_paths.py
328.76 +301_class_path_name.py
328.77 +307_ldap_connect.py
328.78 +308_user_exists_administrator.py
328.79 +309_administrator_credential.py
328.80 +310_DomainAdmins_group_priv.py
328.81 +320_ldap_sizelimit.py
328.82 +321_checkgunum.sh
328.83 +325_smbldap_homePath.py
328.84 +330_group_exists_docenti.py
328.85 +331_group_exists_alunni.py
328.86 +332_group_exists_admins.py
328.87 +333_group_exists_ata.py
328.88 +334_group_exists_esterni.py
328.89 +335_group_exists_ospiti.py
328.90 +336_group_exists_segreteria.py
328.91 +340_logon-bat.py
328.92 +341_logonupd-bat.py
328.93 +342_nscd_no_persistent.py
328.94 +502_check_permission_rwx.sh
329.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
329.2 +++ b/usr/share/isi-checkup/lib/checkup.py Mon Apr 26 11:16:23 2010 +0200
329.3 @@ -0,0 +1,572 @@
329.4 +"""
329.5 +Prototype class for a test
329.6 +
329.7 +"""
329.8 +import re
329.9 +import os
329.10 +import sys
329.11 +from dry.functions import execute
329.12 +import isi
329.13 +
329.14 +class TestError(Exception): pass
329.15 +
329.16 +class IsiTest(object):
329.17 + """If a user is passed as argument, the user is set as an instance
329.18 + attribute. This way a test can use it (and presumably limit tests to that
329.19 + user
329.20 + """
329.21 + skip = ()
329.22 + skip_range = ('0', '0')
329.23 + run = False
329.24 + _name = None
329.25 +
329.26 + def __init__(self, user=None):
329.27 + self.user = user
329.28 +
329.29 + def set_name(self, value):
329.30 + self._name = value
329.31 +
329.32 + def get_name(self):
329.33 + if not self._name:
329.34 + return '%s' % self.__class__.__name__
329.35 + return self._name
329.36 +
329.37 + name = property(get_name, set_name)
329.38 +
329.39 + def report(self):
329.40 + pass
329.41 +
329.42 + def __str__(self):
329.43 + return "%s" % self.name
329.44 +
329.45 +class InputStream(object):
329.46 + """ Simple Wrapper for File-like objects. [c]StringIO doesn't provide
329.47 + a readline function for use with generate_tokens.
329.48 + Using a iterator-like interface doesn't succeed, because the readline
329.49 + function isn't used in such a context. (see <python-lib>/tokenize.py)
329.50 + """
329.51 + def __init__(self, filename=None, data=None):
329.52 + if filename:
329.53 + f = open(file)
329.54 + data = f.read()
329.55 + f.close()
329.56 + data = re.sub(':(.*=)', r'|\1', data)
329.57 + self.__data = [ '%s\n' % x for x in data.splitlines() ]
329.58 + self.__lcount = 0
329.59 +
329.60 + def readline(self):
329.61 + try:
329.62 + line = self.__data[self.__lcount]
329.63 + self.__lcount += 1
329.64 + except IndexError:
329.65 + line = ''
329.66 + self.__lcount = 0
329.67 + line = re.sub(r'^ +', '', line)
329.68 + line = re.sub(r'^\t+', '', line)
329.69 + line = re.sub(r'#.*', '', line)
329.70 + return line
329.71 +
329.72 +class IsiTestProcess(IsiTest):
329.73 + PROCESS_NAME = None
329.74 +
329.75 + def __init__(self, user=None):
329.76 + self.missing = []
329.77 +
329.78 + def test_needed_process(self):
329.79 + process = self.PROCESS_NAME
329.80 + cmd = "pgrep %s" % process
329.81 + ret_code, out, err = execute(cmd)
329.82 + if not ret_code:
329.83 + return True
329.84 + self.missing += [process]
329.85 +
329.86 + def report(self):
329.87 + if self.missing:
329.88 + print 'Processo non in esecuzione:', ",".join(self.missing)
329.89 +# for process in self.missing:
329.90 +# print ' ', process
329.91 +
329.92 + def __str__(self):
329.93 + return "test process: %s" % (self.PROCESS_NAME)
329.94 +
329.95 +class IsiTestFile(IsiTest):
329.96 + FILE_NAME = None
329.97 +
329.98 + def __init__(self, user=None):
329.99 + self.missing = []
329.100 +
329.101 + def test_needed_file(self):
329.102 + filename = self.FILE_NAME
329.103 + try:
329.104 + open(filename)
329.105 + except IOError:
329.106 + readable = False
329.107 + else:
329.108 + readable = True
329.109 +
329.110 + if os.path.isfile(filename) and readable:
329.111 + return True
329.112 + else:
329.113 + self.missing += [filename]
329.114 + return False
329.115 +
329.116 + def report(self):
329.117 + if self.missing:
329.118 + for filename in self.missing:
329.119 + print 'File non presente: "%s"' % filename
329.120 +
329.121 + def __str__(self):
329.122 + return "test file: %s" % (self.FILE_NAME)
329.123 +
329.124 +class IsiTestDir(IsiTest):
329.125 + DIR_NAME = None
329.126 +
329.127 + def __init__(self, user=None):
329.128 + self.missing = []
329.129 +
329.130 + def test_needed_dir(self):
329.131 + directory = self.DIR_NAME
329.132 + if os.path.isdir(directory):
329.133 + return True
329.134 + self.missing += [directory]
329.135 +
329.136 + def report(self):
329.137 + if self.missing:
329.138 + print 'Directory non presente :\n'
329.139 + for directory in self.missing:
329.140 + print ' ', directory
329.141 +
329.142 + def __str__(self):
329.143 + return "test dir: %s" % (self.DIR_NAME)
329.144 +
329.145 +class IsiTestSambaShare(IsiTest):
329.146 + SAMBA_SHARE_NAME = None
329.147 +
329.148 + def __init__(self, user=None):
329.149 + self.missing = []
329.150 +
329.151 + def get_samba_share(self):
329.152 + """ Returns System Samba Shares """
329.153 +
329.154 + smb_conf_dir = '/etc/isi/samba'
329.155 + smb_conf_files = [ "%s/%s" % (smb_conf_dir, f) \
329.156 + for f in os.listdir(smb_conf_dir) if f.endswith('.conf') ]
329.157 + smb_conf_files.insert(0,'/etc/samba/smb.conf')
329.158 + shares = []
329.159 +
329.160 + for conf_file in smb_conf_files:
329.161 + try:
329.162 + f = open(conf_file)
329.163 + except TestError:
329.164 + pass
329.165 + for line in f.readlines():
329.166 + m = re.search('^\[(.*)\].*',line)
329.167 + if m:
329.168 + share = m.group(1)
329.169 + shares.append(share)
329.170 +# ret_code, out, err = execute(cmd)
329.171 +# print out, err
329.172 +# for samba_share in out.split():
329.173 +# if samba_share.startswith('Disk'):
329.174 +# return samba_share.split('|')[1]
329.175 + return shares
329.176 +
329.177 + def test_samba_share(self):
329.178 + samba_shares = self.get_samba_share()
329.179 + share = self.SAMBA_SHARE_NAME
329.180 + if share in samba_shares:
329.181 + return True
329.182 + self.missing += [share]
329.183 +
329.184 + def report(self):
329.185 + if self.missing:
329.186 + print 'Samba Share non definita:\n'
329.187 + for share in self.missing:
329.188 + print ' ', share
329.189 +
329.190 + def __str__(self):
329.191 + return "test share: %s" % (self.SAMBA_SHARE_NAME)
329.192 +
329.193 +class BootProcess(IsiTest):
329.194 + """
329.195 + Formato /etc/runlevel.conf
329.196 +
329.197 + # <sort> <off-> <on-levels> <command>
329.198 + 01 - S /etc/init.d/glibc.sh
329.199 + 02 - S /etc/init.d/mountkernfs.sh
329.200 + 20 0,1,6 2,3,4,5 /etc/init.d/inetd
329.201 + 10 - 2,3,4,5 /etc/init.d/sysklogd
329.202 + 90 0,1,6 - /etc/init.d/sysklogd
329.203 + """
329.204 + #process = "slapd ssh dhcp3-server samba squid dansguardian postfix bind9"
329.205 + INIT_SCRIPTS = None
329.206 +
329.207 + def __init__(self, user=None):
329.208 + self.NOT_BOOTING = []
329.209 +
329.210 + def using_runlevel_conf(self):
329.211 + """ return True if using runlevel.conf """
329.212 + cmd = 'grep runlevel.conf /etc/init.d/rcS'
329.213 + ret_code, out, err = execute(cmd)
329.214 +
329.215 + if ret_code:
329.216 + return False
329.217 + #elif os.path.isfile('/etc/runlevel.conf'):
329.218 + # return True
329.219 + return True
329.220 +
329.221 + def get_sys_runlevel_default(self):
329.222 + """ returns default system boot runlevel """
329.223 + f = open('/etc/inittab')
329.224 + for line in f:
329.225 + m = re.search('^id:(?P<runlevel>.*):initdefault:$',line)
329.226 + if not m: continue
329.227 + m = m.groupdict()
329.228 + runlevel = m['runlevel']
329.229 + return runlevel
329.230 +
329.231 + def get_sys_runlevel(self):
329.232 + """ returns actual runlevel """
329.233 + ret_code, out, err = execute('runlevel')
329.234 + n, runlevel = out.split()
329.235 + return runlevel
329.236 +
329.237 + def init_d_booting(self, process):
329.238 + """
329.239 + checks in /etc/init.d/rc*.d/
329.240 + ============================
329.241 + Returns True if process is configured to run at boot
329.242 + """
329.243 + sys_runlevel = self.get_sys_runlevel()
329.244 + path = '/etc/rc%s.d' % sys_runlevel
329.245 + boot_process = [s[3:] for s in os.listdir(path) if s.startswith('S')]
329.246 + if process in boot_process:
329.247 + return True
329.248 + else:
329.249 + return False
329.250 +
329.251 + def runlevel_conf_booting(self, process):
329.252 + """
329.253 + checks in /etc/runlevel.conf
329.254 + ============================
329.255 + Test if a process is configured to run at boot
329.256 + """
329.257 + filename = "/etc/runlevel.conf"
329.258 + sys_runlevel = self.get_sys_runlevel()
329.259 + runlevel = open(filename).read().split('\n')
329.260 + commented = []
329.261 + found = False
329.262 +
329.263 + for line in runlevel:
329.264 + if re.search('/etc/init.d/%s' % process, line):
329.265 + if re.search('\s*#', line):
329.266 + commented += line
329.267 + else:
329.268 + level, stop, start, path = line.split()
329.269 + if sys_runlevel in start:
329.270 + found = True
329.271 + if found:
329.272 + return True
329.273 + return False
329.274 +
329.275 + def test_will_boot(self):
329.276 + """ Test if a process is properly configured to automatically boot """
329.277 + process = self.INIT_SCRIPTS
329.278 +
329.279 + if self.using_runlevel_conf():
329.280 + if self.runlevel_conf_booting(process):
329.281 + return True
329.282 + self.NOT_BOOTING += [process]
329.283 + else:
329.284 + if self.init_d_booting(process):
329.285 + return True
329.286 + self.NOT_BOOTING += [process]
329.287 +
329.288 + def report(self):
329.289 + if self.NOT_BOOTING:
329.290 + for process in self.NOT_BOOTING:
329.291 + print "Servizio non configurato per partire al boot: %s" % process
329.292 +
329.293 + def __str__(self):
329.294 + return "test process: %s" % (self.INIT_SCRIPTS)
329.295 +
329.296 +
329.297 +class SambaGroupPrivs(IsiTest):
329.298 + """
329.299 + Checks if a particular group has needed privs
329.300 +
329.301 + Privilege definition
329.302 + ====================
329.303 +
329.304 + SeMachineAccountPrivilege Add machines to domain
329.305 + SeTakeOwnershipPrivilege Take ownership of files or other objects
329.306 + SeBackupPrivilege Back up files and directories
329.307 + SeRestorePrivilege Restore files and directories
329.308 + SeRemoteShutdownPrivilege Force shutdown from a remote system
329.309 + SePrintOperatorPrivilege Manage printers
329.310 + SeAddUsersPrivilege Add users and groups to the domain
329.311 + SeDiskOperatorPrivilege Manage disk shares
329.312 + """
329.313 +
329.314 + NEEDED_PRIV_LIST = None
329.315 + GROUP = None
329.316 + AUTH_USER = None
329.317 + AUTH_PW = None
329.318 +
329.319 + def __init__(self, user=None):
329.320 + if not self.NEEDED_PRIV_LIST:
329.321 + self.NEEDED_PRIV_LIST = ['SeMachineAccountPrivilege',
329.322 + 'SeTakeOwnershipPrivilege',
329.323 + 'SeBackupPrivilege',
329.324 + 'SeRestorePrivilege',
329.325 + 'SeRemoteShutdownPrivilege',
329.326 + 'SePrintOperatorPrivilege',
329.327 + 'SeAddUsersPrivilege',
329.328 + 'SeDiskOperatorPrivilege',
329.329 + ]
329.330 + self.miss_priv = []
329.331 + self.err = None
329.332 +
329.333 + def test_net_group_privs(self):
329.334 + cmd = ['net', 'rpc', 'rights', 'list', '%s' % self.GROUP,\
329.335 + '-U', '%s%%%s' % (self.AUTH_USER, self.AUTH_PW)]
329.336 + ret_code, out, err = execute(cmd)
329.337 +
329.338 + if 'NT_STATUS_LOGON_FAILURE' in err:
329.339 + self.err = err
329.340 + return False
329.341 +
329.342 + LOAD_PRIV_LIST = out
329.343 +
329.344 + for priv in self.NEEDED_PRIV_LIST:
329.345 + if not priv in LOAD_PRIV_LIST:
329.346 + self.miss_priv += [priv]
329.347 + continue
329.348 + if not self.miss_priv:
329.349 + return True
329.350 + return False
329.351 +
329.352 + def report(self):
329.353 + if self.miss_priv and not self.err:
329.354 + print 'Privilegi mancanti al gruppo "%s" :' % self.GROUP
329.355 + for priv in self.miss_priv:
329.356 + print ' ', priv
329.357 + if self.err:
329.358 + print 'Errori durante esecuzione comando\n ', self.err
329.359 +
329.360 + def __str__(self):
329.361 + return "test privilege for: %s" % (self.GROUP)
329.362 +
329.363 +class IsiLdapTest(IsiTest):
329.364 + TEST_NAME = None
329.365 +
329.366 + def __init__(self, user=None):
329.367 + self.user = user
329.368 + self.srv = isi.IsiConn()
329.369 + self.isi_user = isi.Manager(self.srv)
329.370 +
329.371 + def __str__(self):
329.372 + return "%s" % self.TEST_NAME
329.373 +
329.374 +class IsiTestGroup(IsiLdapTest):
329.375 + GROUP = None
329.376 +
329.377 + def __init__(self, user=None):
329.378 + self.user = user
329.379 + self.srv = isi.IsiConn()
329.380 + self.isi_user = isi.Manager(self.srv)
329.381 +
329.382 + def test_group_exists(self):
329.383 + return self.isi_user.group_exists(self.GROUP)
329.384 +
329.385 + def __str__(self):
329.386 + return "test Group Existence: %s" % (self.GROUP)
329.387 +
329.388 +class IsiTestUserExist(IsiLdapTest):
329.389 + USER = None
329.390 +
329.391 + def __init__(self, user=None):
329.392 + self.user = user
329.393 + self.srv = isi.IsiConn()
329.394 + self.isi_user = isi.Manager(self.srv)
329.395 +
329.396 + def test_user_exists(self):
329.397 + return self.isi_user.user_exists(self.USER)
329.398 +
329.399 + def __str__(self):
329.400 + return "test User Existence: %s" % (self.USER)
329.401 +
329.402 +### Inizio Colorize
329.403 +# Color definition for the Colorize Class. Add below your colors =)
329.404 +COLORS = {
329.405 + 'BOLD_BLACK' : '39,48,1',
329.406 + 'BOLD_RED' : '31,48,1',
329.407 + 'BOLD_GREEN' : '32,48,1',
329.408 + 'BOLD_YELLOW' : '33,48,1',
329.409 + 'BOLD_RED' : '31,48,1',
329.410 + 'BOLD_BLUE' : '34,48,1',
329.411 + 'BOLD_VIOLET' : '35,48,1',
329.412 + 'BOLD_CIANO' : '36,48,1',
329.413 +
329.414 + 'BLACK' : '30,30,2',
329.415 + 'GREEN' : '30,32,2',
329.416 + 'OCRA' : '30,33,2',
329.417 + 'BLUE' : '30,34,2',
329.418 + 'VIOLET' : '30,35,2',
329.419 + 'CIANO' : '30,36,2',
329.420 + 'GREY' : '30,37,2',
329.421 +
329.422 + 'GRAY_LIGHT' : '37,48,1',
329.423 + }
329.424 +
329.425 +class Colorize(object):
329.426 + """
329.427 + Returns Colorized versions of the same message
329.428 + for every color defined.
329.429 +
329.430 + Example:
329.431 +
329.432 + message = 'hey wazzupp??'
329.433 +
329.434 + c = Colorize()
329.435 + c.set_msg(message)
329.436 + print c.GREEN # prints the message using green color
329.437 +
329.438 + OR
329.439 +
329.440 + c = Colorize(message)
329.441 + print c.GREEN # prints the message using green color
329.442 +
329.443 + You can get a list of available color using the self.list_colors() method.
329.444 + It may be useful with ipython.
329.445 +
329.446 + Example:
329.447 + Colorize().list_colors()
329.448 +
329.449 + """
329.450 +
329.451 + def __init__(self, msg=None):
329.452 + """ Constructor """
329.453 + if msg:
329.454 + self.set_msg(msg)
329.455 +
329.456 + def get_ansi(self, code):
329.457 + """ Returns the Ansi Code of the color"""
329.458 + x, y, z = code.split(',')
329.459 + ESC = '\033['
329.460 + return '%s;%s;%s;%sm' % (ESC, x, y, z)
329.461 +
329.462 + def set_msg(self, msg=None):
329.463 + """ Store given message in color's attributes"""
329.464 + NOR = '\033[0m'
329.465 +
329.466 + for key in COLORS.iterkeys():
329.467 + value = COLORS[key]
329.468 + value_ansi = self.get_ansi(value)
329.469 + setattr(self, '%s' % key, '%s%s%s' % (value_ansi, msg, NOR))
329.470 +
329.471 + def list_colors(self):
329.472 + """ print colorized list of available colors """
329.473 +
329.474 + NOR = '\033[0m'
329.475 +
329.476 + print '\n Available colors'
329.477 +
329.478 + for key in COLORS.iterkeys():
329.479 + value = COLORS[key]
329.480 + value_ansi = self.get_ansi(value)
329.481 + print '%s#### %11s (code: %s) ####%s' % (value_ansi, key, value, NOR)
329.482 +
329.483 + def write_color_list(self, filename=None):
329.484 + """
329.485 + 1) prints out "all" ansi color available
329.486 +
329.487 + 2) writes all ansi color available in "file". If not "file" argument given
329.488 +
329.489 + It'll write to /tmp/ansi_colors
329.490 + You can browse colors using "less -R @file"
329.491 +
329.492 + Note: this method may overload old machines. Generated file size will be
329.493 + about 712 Kb
329.494 + """
329.495 +
329.496 + NOR = '\033[0m'
329.497 +
329.498 + if not filename:
329.499 + f = open("/tmp/ansi_colors", "w")
329.500 + else:
329.501 + try:
329.502 + f = open(filename, "w")
329.503 + except Exception:
329.504 + print "Error opening: %s" % filename
329.505 +
329.506 + range_x = range(1,12)
329.507 + range_x += range(29,49)
329.508 + range_y = range(1,40)
329.509 + range_z = range(1,10)
329.510 +
329.511 + for z in range_z:
329.512 + for y in range_y:
329.513 + for x in range_x:
329.514 + code = '%s,%s,%s' % (x, y, z)
329.515 + msg = 'Browse colors using "less -R /tmp/colori"'
329.516 + output = '\033[%s;%s;%sm (%s) %s %s' % \
329.517 + (x, y, z, code, msg, NOR)
329.518 + print output
329.519 + f.writelines('%s\n' % output)
329.520 + f.close()
329.521 +
329.522 +
329.523 +#### DEMO - begin ####
329.524 +
329.525 +# prova test_needed_process
329.526 +# x = IsiTestProcess()
329.527 +# x.PROCESS_NAME='ssx'
329.528 +# x.PROCESS_NAME='ssh'
329.529 +# x.test_needed_process()
329.530 +# x.report()
329.531 +
329.532 +# # prova test_needed_file
329.533 +# x = IsiTestFile()
329.534 +# x.FILE_NAME = '/etc/ldap.secret'
329.535 +# x.FILE_NAME = '/etc/xxxxx'
329.536 +# x.test_needed_file()
329.537 +# x.report()
329.538 +
329.539 +# # prova test_needed_dir
329.540 +# x = IsiTestDir()
329.541 +# x.DIR_NAME = '/home/shares/area_docenti'
329.542 +# x.DIR_NAME = '/home/shares/area_docuuuu'
329.543 +# x.test_needed_dir()
329.544 +# x.report()
329.545 +
329.546 +# prova test_samba_share
329.547 +# x = IsiTestSambaShare()
329.548 +# x.SAMBA_SHARE_NAME = 'xnetlogon'
329.549 +# x.test_samba_share()
329.550 +# x.report()
329.551 +
329.552 +# prova test_boot_process
329.553 +# x = BootProcess()
329.554 +# x.INIT_SCRIPTS = 'sshx'
329.555 +# x.test_will_boot()
329.556 +# x.report()
329.557 +
329.558 +
329.559 +#prova test_net_group_privs
329.560 +# x = SambaGroupPrivs()
329.561 +# x.NEEDED_PRIV_LIST = ['SeMachineAccountPrivilege','asdasd']
329.562 +# x.GROUP = 'Domain Admins'
329.563 +# x.AUTH_USER = 'administrator'
329.564 +# x.AUTH_PW = ''
329.565 +# x.test_net_group_privs()
329.566 +# x.report()
329.567 +
329.568 +# # prova classe Colorize
329.569 +# c = Colorize()
329.570 +# message = 'Messaggio di prova'
329.571 +# c.set_msg(message)
329.572 +# print c.GREEN # prints the message using green color
329.573 +
329.574 +#### DEMO - end ####
329.575 +
330.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
330.2 +++ b/usr/share/isi-checkup/lib/colorize.py Mon Apr 26 11:16:23 2010 +0200
330.3 @@ -0,0 +1,153 @@
330.4 +#!/usr/bin/python
330.5 +"""
330.6 +
330.7 +Simone Castellazzi <[email protected]>
330.8 +
330.9 +Description
330.10 +===========
330.11 +
330.12 +
330.13 +TODO:
330.14 +
330.15 +??
330.16 +msg.title.D_GREEN
330.17 +msg.title.L_GREEN
330.18 +"""
330.19 +
330.20 +# Color definition. Add below your colors =)
330.21 +COLORS = {
330.22 + 'BOLD_BLACK' : '39,48,1',
330.23 + 'BOLD_RED' : '31,48,1',
330.24 + 'BOLD_GREEN' : '32,48,1',
330.25 + 'BOLD_YELLOW' : '33,48,1',
330.26 + 'BOLD_RED' : '31,48,1',
330.27 + 'BOLD_BLUE' : '34,48,1',
330.28 + 'BOLD_VIOLET' : '35,48,1',
330.29 + 'BOLD_CIANO' : '36,48,1',
330.30 +
330.31 + 'BOLD_RED_U' : '31,4,1',
330.32 + 'BOLD_GREEN_U' : '32,4,1',
330.33 + 'BOLD_BLUE_U' : '34,4,1',
330.34 +
330.35 + 'BLACK' : '30,30,2',
330.36 + 'GREEN' : '30,32,2',
330.37 + 'OCRA' : '30,33,2',
330.38 + 'BLUE' : '30,34,2',
330.39 + 'VIOLET' : '30,35,2',
330.40 + 'CIANO' : '30,36,2',
330.41 + 'GREY' : '30,37,2',
330.42 +
330.43 + 'GRAY_LIGHT' : '37,48,1',
330.44 +
330.45 + 'WHITE_BLUE' : '7,34,3',
330.46 + 'WHITE_RED' : '7,31,3',
330.47 + 'WHITE_OCRA' : '7,33,3',
330.48 + 'WHITE_VIOLA' : '7,35,2',
330.49 + 'YELLOW' : '1,33,1',
330.50 +
330.51 + 'RED_U' : '31,19,4',
330.52 + 'GREEN_U' : '32,19,4',
330.53 + 'YELLOW_U' : '33,19,4',
330.54 + 'BLUE_U' : '34,19,4',
330.55 + 'VIOLA_U' : '35,19,4',
330.56 + 'CIANO_U' : '36,19,4',
330.57 +
330.58 + }
330.59 +
330.60 +class Colorize(object):
330.61 + """
330.62 + Returns Colorized versions of the same message
330.63 + for every color defined.
330.64 +
330.65 + Example:
330.66 +
330.67 + message = 'hey wazzupp??'
330.68 +
330.69 + c = Colorize()
330.70 + c.set_msg(message)
330.71 + print c.GREEN # prints the message using green color
330.72 +
330.73 + OR
330.74 +
330.75 + c = Colorize(message)
330.76 + print c.GREEN # prints the message using green color
330.77 +
330.78 + You can get a list of available color using the self.list_colors() method.
330.79 + It may be useful with ipython.
330.80 +
330.81 + Example:
330.82 + Colorize().list_colors()
330.83 +
330.84 + """
330.85 +
330.86 + def __init__(self, msg=None):
330.87 + """ Constructor """
330.88 + if msg:
330.89 + self.set_msg(msg)
330.90 +
330.91 + def get_ansi(self, code):
330.92 + """ Returns the Ansi Code of the color"""
330.93 + x, y, z = code.split(',')
330.94 + ESC = '\033['
330.95 + return '%s;%s;%s;%sm' % (ESC, x, y, z)
330.96 +
330.97 + def set_msg(self, msg=None):
330.98 + """ Store given message in color's attributes"""
330.99 + NOR = '\033[0m'
330.100 +
330.101 + for key in COLORS.iterkeys():
330.102 + value = COLORS[key]
330.103 + value_ansi = self.get_ansi(value)
330.104 + setattr(self, '%s' % key, '%s%s%s' % (value_ansi, msg, NOR))
330.105 +
330.106 + def list_colors(self):
330.107 + """ print colorized list of available colors """
330.108 +
330.109 + NOR = '\033[0m'
330.110 +
330.111 + print '\n Available colors'
330.112 +
330.113 + for key in COLORS.iterkeys():
330.114 + value = COLORS[key]
330.115 + value_ansi = self.get_ansi(value)
330.116 + print '%s#### %11s (code: %s) ####%s' % (value_ansi, key, value, NOR)
330.117 +
330.118 + def write_color_list(self, filename=None):
330.119 + """
330.120 + 1) prints out "all" ansi color available
330.121 +
330.122 + 2) writes all ansi color available in "file". If not "file" argument given
330.123 +
330.124 + It'll write to /tmp/ansi_colors
330.125 + You can browse colors using "less -R @file"
330.126 +
330.127 + Note: this method may overload old machines. Generated file size will be
330.128 + about 712 Kb
330.129 + """
330.130 +
330.131 + NOR = '\033[0m'
330.132 +
330.133 + if not filename:
330.134 + f = open("/tmp/ansi_colors", "w")
330.135 + else:
330.136 + try:
330.137 + f = open(filename, "w")
330.138 + except Exception:
330.139 + print "Error opening: %s" % filename
330.140 +
330.141 + range_x = range(1,12)
330.142 + range_x += range(29,49)
330.143 + range_y = range(1,40)
330.144 + range_z = range(1,10)
330.145 +
330.146 + for z in range_z:
330.147 + for y in range_y:
330.148 + for x in range_x:
330.149 + code = '%s,%s,%s' % (x, y, z)
330.150 + msg = 'Browse colors using "less -R /tmp/colori"'
330.151 + output = '\033[%s;%s;%sm (%s) %s %s' % \
330.152 + (x, y, z, code, msg, NOR)
330.153 + print output
330.154 + f.writelines('%s\n' % output)
330.155 + f.close()
330.156 +
331.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
331.2 +++ b/usr/share/isi-checkup/tests/010_disk_space.py Mon Apr 26 11:16:23 2010 +0200
331.3 @@ -0,0 +1,114 @@
331.4 +#!/usr/bin/python
331.5 +"""
331.6 +Filesystem Size Used Avail Use% Mounted on
331.7 +/dev/md3 2.5G 1.3G 1.3G 100% /
331.8 +tmpfs 507M 0 507M 0% /lib/init/rw
331.9 +udev 10M 80K 10M 1% /dev
331.10 +tmpfs 507M 4.0K 507M 1% /dev/shm
331.11 +/dev/md0 23M 19M 2.6M 97% /boot
331.12 +/dev/md4 178G 27G 151G 55% /home
331.13 +/dev/md5 178G 27G 151G 55% /test
331.14 +"""
331.15 +
331.16 +import re
331.17 +from dry.functions import execute
331.18 +import sys
331.19 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
331.20 +from checkup import IsiTest, TestError
331.21 +
331.22 +class T_diskspace(IsiTest):
331.23 + run = True
331.24 + skip = ""
331.25 + name = 'disk_space'
331.26 + WARNING = False
331.27 + ERROR = False
331.28 +
331.29 + def __init__(self, user=None):
331.30 + pass
331.31 +
331.32 + def test_diskspace(self):
331.33 +
331.34 + level_warn = 90
331.35 + level_error = 95
331.36 + dev = {}
331.37 +
331.38 + ret_code, out, err = execute('df -h')
331.39 +
331.40 + out = out.split("\n")
331.41 + out.sort(reverse = True)
331.42 +
331.43 + for line in out:
331.44 + if line.startswith('/dev/'):
331.45 + line = re.split(" +", line)
331.46 + """
331.47 + modello contenuto "line"
331.48 + ['/dev/md3', '2.5G', '1.3G', '1.3G', '51%', '/']
331.49 + ['/dev/md0', '23M', '19M', '2.6M', '94%', '/boot']
331.50 + ['/dev/md4', '178G', '27G', '151G', '15%', '/home']
331.51 + """
331.52 + k = line[0]
331.53 + v = [ int(line[4].strip('%s')), line[5] ]
331.54 + dev[k] = v
331.55 +
331.56 + for k, v in dev.items():
331.57 + self.mnt = k
331.58 + self.dev = v[1]
331.59 + self.usage = v[0]
331.60 +
331.61 + if self.usage >= level_error:
331.62 + self.ERROR = True
331.63 + elif self.usage >= level_warn:
331.64 + self.WARNING = True
331.65 + else:
331.66 + return True
331.67 +
331.68 + def report(self):
331.69 + if self.WARNING:
331.70 + print " WARNING\t %s \t %s \t occupato al %s%%" % (self.dev, self.mnt, self.usage)
331.71 + if self.ERROR:
331.72 + print " *ERROR*\t %s \t %s \t occupato al %s%%" % (self.dev, self.mnt, self.usage)
331.73 +
331.74 + def __str__(self):
331.75 + return "test %s" % (self.name)
331.76 +
331.77 +
331.78 +
331.79 +
331.80 +
331.81 +
331.82 +
331.83 +
331.84 +
331.85 +
331.86 +
331.87 +
331.88 +
331.89 +
331.90 +
331.91 +
331.92 +
331.93 +
331.94 +
331.95 +
331.96 +
331.97 +
331.98 +
331.99 +
331.100 +
331.101 +
331.102 +
331.103 +
331.104 +
331.105 +
331.106 +
331.107 +
331.108 +
331.109 +
331.110 +
331.111 +
331.112 +
331.113 +
331.114 +
331.115 +
331.116 +
331.117 +
332.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
332.2 +++ b/usr/share/isi-checkup/tests/011_need_file_hostname.py Mon Apr 26 11:16:23 2010 +0200
332.3 @@ -0,0 +1,7 @@
332.4 +from checkup import IsiTestFile
332.5 +
332.6 +class FileHostname(IsiTestFile):
332.7 + run = True
332.8 + skip = ""
332.9 + FILE_NAME = '/etc/hostname'
332.10 +
333.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
333.2 +++ b/usr/share/isi-checkup/tests/012_need_file_hosts.py Mon Apr 26 11:16:23 2010 +0200
333.3 @@ -0,0 +1,7 @@
333.4 +from checkup import IsiTestFile
333.5 +
333.6 +class FileHosts(IsiTestFile):
333.7 + run = True
333.8 + skip = ""
333.9 + FILE_NAME = '/etc/hosts'
333.10 +
334.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
334.2 +++ b/usr/share/isi-checkup/tests/013_need_file_resolve.conf.py Mon Apr 26 11:16:23 2010 +0200
334.3 @@ -0,0 +1,7 @@
334.4 +from checkup import IsiTestFile
334.5 +
334.6 +class FileResolvConf(IsiTestFile):
334.7 + run = True
334.8 + skip = ""
334.9 + FILE_NAME = '/etc/resolv.conf'
334.10 +
335.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
335.2 +++ b/usr/share/isi-checkup/tests/014_need_file_interfaces.py Mon Apr 26 11:16:23 2010 +0200
335.3 @@ -0,0 +1,7 @@
335.4 +from checkup import IsiTestFile
335.5 +
335.6 +class FileInterfaces(IsiTestFile):
335.7 + run = True
335.8 + skip = "260 261 262 263 264 265 266 267 268"
335.9 + FILE_NAME = '/etc/network/interfaces'
335.10 +
336.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
336.2 +++ b/usr/share/isi-checkup/tests/015_localhost.py Mon Apr 26 11:16:23 2010 +0200
336.3 @@ -0,0 +1,104 @@
336.4 +#/usr/bin/python
336.5 +"""
336.6 +127.0.0.1 localhost
336.7 +127.0.1.1 dream0ne
336.8 +
336.9 +###############################
336.10 +# Network Dreamnet
336.11 +###############################
336.12 +192.168.1.100 pa-zulu
336.13 +192.168.1.102 pa-nb
336.14 +192.168.1.10 hp1320
336.15 +###############################
336.16 +
336.17 +# The following lines are desirable for IPv6 capable hosts
336.18 +::1 ip6-localhost ip6-loopback
336.19 +fe00::0 ip6-localnet
336.20 +ff00::0 ip6-mcastprefix
336.21 +ff02::1 ip6-allnodes
336.22 +ff02::2 ip6-allrouters
336.23 +ff02::3 ip6-allhosts
336.24 +
336.25 +"""
336.26 +from checkup import IsiTest
336.27 +import re
336.28 +
336.29 +errors = []
336.30 +
336.31 +class check_localhost(IsiTest):
336.32 + """ Checks configuration of the"/etc/hosts" file """
336.33 + run = True
336.34 + skip = ""
336.35 + name = 'localhost'
336.36 + errors = []
336.37 +
336.38 + def read_etc_hosts(self):
336.39 + """
336.40 + Parse /etc/hosts and returns dictionary
336.41 +
336.42 + es.
336.43 + key, value = ip, ['host1','...']
336.44 + """
336.45 + hosts = {}
336.46 + #for line in __doc__.split('\n'): # per test
336.47 + f = open('/etc/hosts')
336.48 + for line in f.readlines():
336.49 + if re.search('^$', line): continue
336.50 + if re.match('^\s*#.*$', line): continue
336.51 + line = line.strip('\n').split()
336.52 + ip = line[0]
336.53 + hostnames = line[1:]
336.54 + hosts[ip] = hostnames
336.55 +
336.56 + return hosts
336.57 +
336.58 + def read_etc_hostname(self):
336.59 + """ returns hostname """
336.60 + f = open('/etc/hostname')
336.61 + for line in f.readlines():
336.62 + #for line in __doc__.split('\n'):
336.63 + if re.search('^$', line): continue
336.64 + if re.match('^\s*#.*$', line): continue
336.65 + return line.strip()
336.66 +
336.67 + def test_localhost(self):
336.68 + """ Perform series of test on /etc/hosts """
336.69 + etc_hosts = self.read_etc_hosts()
336.70 + etc_hostname = self.read_etc_hostname()
336.71 + errors = []
336.72 +
336.73 + # check if 127.0.0.1 is NOT defined
336.74 + if not etc_hosts.has_key('127.0.0.1'):
336.75 + errors.append("127.0.0.1 non definito.")
336.76 + else:
336.77 + # check if 127.0.0.1 is NOT associated to at least one host
336.78 + if not etc_hosts['127.0.0.1']:
336.79 + errors.append("127.0.0.1 non e' associato a nessun hostname.")
336.80 + # check if 127.0.0.1 is associated to *localhost*
336.81 + if not 'localhost' in etc_hosts['127.0.0.1']:
336.82 + errors.append("127.0.0.1 non e' associato a 'localhost'.")
336.83 + # check if '/etc/hostname' is associated *lo*
336.84 + if not etc_hostname in etc_hosts['127.0.0.1']:
336.85 + if etc_hosts.has_key('127.0.1.1') and etc_hostname in etc_hosts['127.0.1.1']:
336.86 + pass
336.87 + else:
336.88 + errors.append("hostname di sistema %s non associato all'interfaccia 'lo'." % etc_hostname)
336.89 + # check for multiple definition of 127.0.0.1 or 127.0.1.1
336.90 + if etc_hosts.keys().count("127.0.0.1") > 1 or \
336.91 + etc_hosts.keys().count("127.0.0.1") > 1:
336.92 + errors.append("127.0.0.1 e' ripetuto piu' volte all'interno del file.")
336.93 +
336.94 + if errors:
336.95 + self.errors = errors
336.96 + return False
336.97 + return True
336.98 +
336.99 + def report(self):
336.100 + if self.errors:
336.101 + print 'Errori di configurazione in \"/etc/hosts\" :'
336.102 + for e in self.errors:
336.103 + print '- ', e
336.104 +
336.105 + def __str__(self):
336.106 + return "test %s" % (self.name)
336.107 +
337.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
337.2 +++ b/usr/share/isi-checkup/tests/016_need_file_runlevel.conf.py Mon Apr 26 11:16:23 2010 +0200
337.3 @@ -0,0 +1,26 @@
337.4 +from checkup import IsiTest, BootProcess
337.5 +import os
337.6 +
337.7 +class FileRunlevelConf(IsiTest):
337.8 + run = True
337.9 + name = "FileRunlevelConfExist"
337.10 + file_missing = False
337.11 +
337.12 + run = True
337.13 + file_missing = False
337.14 +
337.15 + def __init__(self, user=None):
337.16 + self.runlevel_conf = BootProcess().using_runlevel_conf()
337.17 +
337.18 + def test_RunlevelConfExist(self):
337.19 + if not self.runlevel_conf:
337.20 + # Returns True if not using runlevel.conf (lenny)
337.21 + return True
337.22 + if not os.path.isfile('/etc/runlevel.conf'):
337.23 + self.file_missing = True
337.24 + return False
337.25 + return True
337.26 +
337.27 + def report(self):
337.28 + if self.file_missing:
337.29 + print "/etc/runlevel.conf non trovato"
338.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
338.2 +++ b/usr/share/isi-checkup/tests/112_dhcp3-server_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
338.3 @@ -0,0 +1,6 @@
338.4 +from checkup import BootProcess
338.5 +
338.6 +class BootProcessDhcp3Server(BootProcess):
338.7 + skip = "113 262"
338.8 + run = True
338.9 + INIT_SCRIPTS = 'dhcp3-server'
339.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
339.2 +++ b/usr/share/isi-checkup/tests/113_need_file_dhcpd.conf.py Mon Apr 26 11:16:23 2010 +0200
339.3 @@ -0,0 +1,7 @@
339.4 +from checkup import IsiTestFile
339.5 +
339.6 +class FileDhcpdConf(IsiTestFile):
339.7 + skip = "262"
339.8 + run = True
339.9 + FILE_NAME = '/etc/dhcp3/dhcpd.conf'
339.10 +
340.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
340.2 +++ b/usr/share/isi-checkup/tests/114_slapd_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
340.3 @@ -0,0 +1,6 @@
340.4 +from checkup import BootProcess
340.5 +
340.6 +class BootProcessSlapd(BootProcess):
340.7 + run = True
340.8 + skip = "115 230 231 232 233 260 307 308 309 310 325 320 321 325 330 331 332 333 334 335 336"
340.9 + INIT_SCRIPTS = 'slapd'
341.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
341.2 +++ b/usr/share/isi-checkup/tests/115_need_file_ldap.secret.py Mon Apr 26 11:16:23 2010 +0200
341.3 @@ -0,0 +1,7 @@
341.4 +from checkup import IsiTestFile
341.5 +
341.6 +class FileLdapSecret(IsiTestFile):
341.7 + run = True
341.8 + skip = "230 231 232 260 325 320 307 308 309 320 325 330 331 332 333 334 335 336"
341.9 + FILE_NAME = '/etc/ldap.secret'
341.10 +
342.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
342.2 +++ b/usr/share/isi-checkup/tests/120_netbiosIsHostname.py Mon Apr 26 11:16:23 2010 +0200
342.3 @@ -0,0 +1,51 @@
342.4 +#!/usr/bin/python
342.5 +
342.6 +from checkup import IsiTest
342.7 +import re
342.8 +
342.9 +class HostnameIsNetbiosName(IsiTest):
342.10 + """
342.11 + Tests if hostname configured in /etc/hostname is
342.12 + the netbios name configured in /etc/samba/smb.conf
342.13 + """
342.14 + name = 'localhost = netbios name'
342.15 + run = True
342.16 + skip = ''
342.17 + check_failed = False
342.18 +
342.19 + def get_netbios_name(self):
342.20 + """ returns netbios_name configured in /etc/samba/smb.conf """
342.21 + f = open('/etc/samba/smb.conf')
342.22 + for line in f.readlines():
342.23 + m = re.match('^\s*netbios name\s*=\s*(.+)\s*$', line)
342.24 + if m:
342.25 + netbios_name = m.groups()[0]
342.26 + return netbios_name
342.27 +
342.28 + def get_hostname(self):
342.29 + """ returns hostname configured in /etc/hostname """
342.30 + f = open('/etc/hostname')
342.31 + for line in f.readlines():
342.32 + #for line in __doc__.split('\n'):
342.33 + if re.search('^$', line): continue
342.34 + if re.match('^\s*#.*$', line): continue
342.35 + return line.strip()
342.36 +
342.37 + def test_hostname_is_netbiosname(self):
342.38 + """ returns True if netbios_name == hostname """
342.39 + netbios_name = self.get_netbios_name()
342.40 + hostname = self.get_hostname()
342.41 + if netbios_name == hostname :
342.42 + return True
342.43 + else:
342.44 + self.check_failed = True
342.45 + return False
342.46 +
342.47 + def report(self):
342.48 + if self.check_failed:
342.49 + print "\nIl nome host della macchina configurato in '/etc/hostname'\n"\
342.50 + +"non coincide con il nome netbios configurato in '/etc/samba/smb.conf'."
342.51 +
342.52 + def __str__(self):
342.53 + return "test %s" % (self.name)
342.54 +
343.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
343.2 +++ b/usr/share/isi-checkup/tests/121_squid_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
343.3 @@ -0,0 +1,6 @@
343.4 +from checkup import BootProcess
343.5 +
343.6 +class BootProcessSquid(BootProcess):
343.7 + skip = "122 123 265"
343.8 + run = True
343.9 + INIT_SCRIPTS = 'squid'
344.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
344.2 +++ b/usr/share/isi-checkup/tests/122_need_file_squid.conf.py Mon Apr 26 11:16:23 2010 +0200
344.3 @@ -0,0 +1,7 @@
344.4 +from checkup import IsiTestFile
344.5 +
344.6 +class FileSquidConf(IsiTestFile):
344.7 + run = True
344.8 + skip = "123 265"
344.9 + FILE_NAME = '/etc/squid/squid.conf'
344.10 +
345.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
345.2 +++ b/usr/share/isi-checkup/tests/123_squid_parmExist.py Mon Apr 26 11:16:23 2010 +0200
345.3 @@ -0,0 +1,60 @@
345.4 +#!/usr/bin/python
345.5 +'''
345.6 +squid-log.py
345.7 +
345.8 +Test che verifica che alcuni parametri siano presenti
345.9 +in /etc/squid/squid.conf.
345.10 +'''
345.11 +
345.12 +import sys
345.13 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
345.14 +import os
345.15 +import re
345.16 +from checkup import IsiTest
345.17 +
345.18 +class TestSquidLog(IsiTest):
345.19 + run = True
345.20 + name = 'squid_parmExist'
345.21 + def __init__(self, user=None):
345.22 +
345.23 + self.squid_config = "/etc/squid/squid.conf"
345.24 +
345.25 + self.parmExist = 'access_log http_port'.split()
345.26 + self.missing = []
345.27 +
345.28 + def parm_exist(self, parm):
345.29 + '''
345.30 + Se il parametro non esiste ritorna False
345.31 + Se non esiste il file /etc/squid/squid.conf ritorna False
345.32 + '''
345.33 + if not os.path.isfile(self.squid_config):
345.34 + return False
345.35 +
345.36 + f = open(self.squid_config)
345.37 + for line in f:
345.38 + if not parm in line:
345.39 + continue
345.40 + if re.match('\s*%s\s+.+\s*' % parm, line):
345.41 + return True
345.42 + return False
345.43 + def test_squid_parmExist(self):
345.44 + for parm in self.parmExist:
345.45 + if self.parm_exist(parm):
345.46 + continue
345.47 + self.missing += [parm]
345.48 + if not self.missing:
345.49 + return True
345.50 +
345.51 + def report(self):
345.52 + if self.missing:
345.53 + print 'squid.conf: Parametri assenti'
345.54 + print '-----------------------------'
345.55 + for i in self.missing:
345.56 + print ' %s' % i
345.57 +
345.58 + def __str__(self):
345.59 + return "test %s" % (self.name)
345.60 +
345.61 +
345.62 +
345.63 +
346.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
346.2 +++ b/usr/share/isi-checkup/tests/125_dansguardian_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
346.3 @@ -0,0 +1,6 @@
346.4 +from checkup import BootProcess
346.5 +
346.6 +class BootProcessDansguardian(BootProcess):
346.7 + run = True
346.8 + skip = "135 266"
346.9 + INIT_SCRIPTS = 'dansguardian'
347.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
347.2 +++ b/usr/share/isi-checkup/tests/126_postfix_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
347.3 @@ -0,0 +1,6 @@
347.4 +from checkup import BootProcess
347.5 +
347.6 +class BootProcessPostfix(BootProcess):
347.7 + run = True
347.8 + skip = "127 267"
347.9 + INIT_SCRIPTS = 'postfix'
348.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
348.2 +++ b/usr/share/isi-checkup/tests/127_postfixcheck.py Mon Apr 26 11:16:23 2010 +0200
348.3 @@ -0,0 +1,27 @@
348.4 +#!/bin/bin/python
348.5 +
348.6 +import re
348.7 +from dry.functions import execute
348.8 +import sys
348.9 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
348.10 +from checkup import IsiTest, TestError
348.11 +
348.12 +class CheckPostfix(IsiTest):
348.13 + run = True
348.14 + ERROR = False
348.15 +
348.16 + def test_check_postfix(self):
348.17 + cmd = 'postfix check'
348.18 + ret_code, out, self.err = execute(cmd)
348.19 +
348.20 + if not ret_code:
348.21 + return True
348.22 + self.ERROR = True
348.23 +
348.24 + def report(self):
348.25 + if self.ERROR:
348.26 + print ' "postfix check" ha restituito errori:\n%s' % self.err
348.27 +
348.28 + def __str__(self):
348.29 + return "test %s" % (self.name)
348.30 +
348.31 \ No newline at end of file
349.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
349.2 +++ b/usr/share/isi-checkup/tests/128_nscd_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
349.3 @@ -0,0 +1,6 @@
349.4 +from checkup import BootProcess
349.5 +
349.6 +class BootProcessNscd(BootProcess):
349.7 + skip = "129 269 342"
349.8 + run = True
349.9 + INIT_SCRIPTS = 'nscd'
350.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
350.2 +++ b/usr/share/isi-checkup/tests/129_need_file_nscd.conf.py Mon Apr 26 11:16:23 2010 +0200
350.3 @@ -0,0 +1,7 @@
350.4 +from checkup import IsiTestFile
350.5 +
350.6 +class FileNscdConf(IsiTestFile):
350.7 + run = True
350.8 + skip = "342"
350.9 + FILE_NAME = '/etc/nscd.conf'
350.10 +
351.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
351.2 +++ b/usr/share/isi-checkup/tests/131_ssh_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
351.3 @@ -0,0 +1,6 @@
351.4 +from checkup import BootProcess
351.5 +
351.6 +class BootProcessSsh(BootProcess):
351.7 + run = True
351.8 + skip = "253 261"
351.9 + INIT_SCRIPTS = 'ssh'
352.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
352.2 +++ b/usr/share/isi-checkup/tests/133_samba_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
352.3 @@ -0,0 +1,6 @@
352.4 +from checkup import BootProcess
352.5 +
352.6 +class BootProcessSamba(BootProcess):
352.7 + run = True
352.8 + skip = "134 220 225 226 227 228 229 249 250 251 263 264 271 272 273 274 275 276 277 278 279 280 281 300 301 310 325 321 340 341 343"
352.9 + INIT_SCRIPTS = 'samba'
353.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
353.2 +++ b/usr/share/isi-checkup/tests/134_need_file_smb.conf.py Mon Apr 26 11:16:23 2010 +0200
353.3 @@ -0,0 +1,7 @@
353.4 +from checkup import IsiTestFile
353.5 +
353.6 +class FileSmbConf(IsiTestFile):
353.7 + run = True
353.8 + skip = "263 264 271 272 273 274 275 276 277 278 279 280 281 300 310 325"
353.9 + FILE_NAME = '/etc/samba/smb.conf'
353.10 +
354.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
354.2 +++ b/usr/share/isi-checkup/tests/135_need_file_dansguardian.conf.py Mon Apr 26 11:16:23 2010 +0200
354.3 @@ -0,0 +1,7 @@
354.4 +from checkup import IsiTestFile
354.5 +
354.6 +class FileDansguardianConf(IsiTestFile):
354.7 + run = True
354.8 + skip = "266"
354.9 + FILE_NAME = '/etc/dansguardian/dansguardian.conf'
354.10 +
355.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
355.2 +++ b/usr/share/isi-checkup/tests/137_bind9_run_on_boot.py Mon Apr 26 11:16:23 2010 +0200
355.3 @@ -0,0 +1,6 @@
355.4 +from checkup import BootProcess
355.5 +
355.6 +class BootProcessBind9(BootProcess):
355.7 + run = True
355.8 + skip = "254 268"
355.9 + INIT_SCRIPTS = 'bind9'
356.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
356.2 +++ b/usr/share/isi-checkup/tests/201_need_dir_home.py Mon Apr 26 11:16:23 2010 +0200
356.3 @@ -0,0 +1,7 @@
356.4 +from checkup import IsiTestDir
356.5 +
356.6 +class DirHome(IsiTestDir):
356.7 + run = True
356.8 + skip = "202 203 204 205 206 207 208 209 220 225 226 227 228 229 301 502 501"
356.9 + DIR_NAME = '/home'
356.10 +
357.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
357.2 +++ b/usr/share/isi-checkup/tests/202_need_dir_users.py Mon Apr 26 11:16:23 2010 +0200
357.3 @@ -0,0 +1,7 @@
357.4 +from checkup import IsiTestDir
357.5 +
357.6 +class DirHomeUsers(IsiTestDir):
357.7 + run = True
357.8 + skip = "203 204 205 206 207 208 209"
357.9 + DIR_NAME = '/home/users'
357.10 +
358.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
358.2 +++ b/usr/share/isi-checkup/tests/203_need_dir_alunni.py Mon Apr 26 11:16:23 2010 +0200
358.3 @@ -0,0 +1,6 @@
358.4 +from checkup import IsiTestDir
358.5 +
358.6 +class DirHomeUsersAlunni(IsiTestDir):
358.7 + run = True
358.8 + DIR_NAME = '/home/users/alunni'
358.9 +
359.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
359.2 +++ b/usr/share/isi-checkup/tests/204_need_dir_docenti.py Mon Apr 26 11:16:23 2010 +0200
359.3 @@ -0,0 +1,5 @@
359.4 +from checkup import IsiTestDir
359.5 +
359.6 +class DirHomeUsersDocenti(IsiTestDir):
359.7 + run = True
359.8 + DIR_NAME = '/home/users/docenti'
360.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
360.2 +++ b/usr/share/isi-checkup/tests/205_need_dir_admins.py Mon Apr 26 11:16:23 2010 +0200
360.3 @@ -0,0 +1,5 @@
360.4 +from checkup import IsiTestDir
360.5 +
360.6 +class DirHomeUsersAdmins(IsiTestDir):
360.7 + run = True
360.8 + DIR_NAME = '/home/users/admins'
361.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
361.2 +++ b/usr/share/isi-checkup/tests/206_need_dir_ata.py Mon Apr 26 11:16:23 2010 +0200
361.3 @@ -0,0 +1,5 @@
361.4 +from checkup import IsiTestDir
361.5 +
361.6 +class DirHomeUsersAta(IsiTestDir):
361.7 + run = True
361.8 + DIR_NAME = '/home/users/ata'
362.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
362.2 +++ b/usr/share/isi-checkup/tests/207_need_dir_esterni.py Mon Apr 26 11:16:23 2010 +0200
362.3 @@ -0,0 +1,5 @@
362.4 +from checkup import IsiTestDir
362.5 +
362.6 +class DirHomeUsersEsterni(IsiTestDir):
362.7 + run = True
362.8 + DIR_NAME = '/home/users/esterni'
363.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
363.2 +++ b/usr/share/isi-checkup/tests/208_need_dir_ospiti.py Mon Apr 26 11:16:23 2010 +0200
363.3 @@ -0,0 +1,5 @@
363.4 +from checkup import IsiTestDir
363.5 +
363.6 +class DirHomeUsersOspiti(IsiTestDir):
363.7 + run = True
363.8 + DIR_NAME = '/home/users/ospiti'
364.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
364.2 +++ b/usr/share/isi-checkup/tests/209_need_dir_segreteria.py Mon Apr 26 11:16:23 2010 +0200
364.3 @@ -0,0 +1,5 @@
364.4 +from checkup import IsiTestDir
364.5 +
364.6 +class DirHomeUsersSegreteria(IsiTestDir):
364.7 + run = True
364.8 + DIR_NAME = '/home/users/segreteria'
365.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
365.2 +++ b/usr/share/isi-checkup/tests/220_need_dir_shares.py Mon Apr 26 11:16:23 2010 +0200
365.3 @@ -0,0 +1,7 @@
365.4 +from checkup import IsiTestDir
365.5 +
365.6 +class DirHomeShares(IsiTestDir):
365.7 + run = True
365.8 + skip = "301"
365.9 + DIR_NAME = '/home/shares'
365.10 +
366.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
366.2 +++ b/usr/share/isi-checkup/tests/225_need_dir_classi.py Mon Apr 26 11:16:23 2010 +0200
366.3 @@ -0,0 +1,7 @@
366.4 +from checkup import IsiTestDir
366.5 +
366.6 +class DirHomeSharesClassi(IsiTestDir):
366.7 + run = True
366.8 + skip = "301"
366.9 + DIR_NAME = '/home/shares/classi'
366.10 +
367.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
367.2 +++ b/usr/share/isi-checkup/tests/226_need_dir_area_alunni.py Mon Apr 26 11:16:23 2010 +0200
367.3 @@ -0,0 +1,6 @@
367.4 +from checkup import IsiTestDir
367.5 +
367.6 +class DirHomeSharesAreaAlunni(IsiTestDir):
367.7 + run = True
367.8 + DIR_NAME = '/home/shares/area_alunni'
367.9 +
368.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
368.2 +++ b/usr/share/isi-checkup/tests/227_need_dir_area_docenti.py Mon Apr 26 11:16:23 2010 +0200
368.3 @@ -0,0 +1,6 @@
368.4 +from checkup import IsiTestDir
368.5 +
368.6 +class DirHomeSharesAreaDocenti(IsiTestDir):
368.7 + run = True
368.8 + DIR_NAME = '/home/shares/area_docenti'
368.9 +
369.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
369.2 +++ b/usr/share/isi-checkup/tests/228_need_dir_area_segreteria.py Mon Apr 26 11:16:23 2010 +0200
369.3 @@ -0,0 +1,6 @@
369.4 +from checkup import IsiTestDir
369.5 +
369.6 +class DirHomeSharesAreaSegreteria(IsiTestDir):
369.7 + run = True
369.8 + DIR_NAME = '/home/shares/area_segreteria'
369.9 +
370.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
370.2 +++ b/usr/share/isi-checkup/tests/229_need_dir_corsi.py Mon Apr 26 11:16:23 2010 +0200
370.3 @@ -0,0 +1,7 @@
370.4 +from checkup import IsiTestDir
370.5 +
370.6 +class DirHomeSharesCorsi(IsiTestDir):
370.7 + run = True
370.8 + skip = "301"
370.9 + DIR_NAME = '/home/shares/corsi'
370.10 +
371.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
371.2 +++ b/usr/share/isi-checkup/tests/230_ldap_same_secret.py Mon Apr 26 11:16:23 2010 +0200
371.3 @@ -0,0 +1,32 @@
371.4 +#!/usr/bin/python
371.5 +
371.6 +import sys,os
371.7 +import re
371.8 +
371.9 +from checkup import IsiTest
371.10 +
371.11 +class TestSamePw(IsiTest):
371.12 + run = True
371.13 + skip = "260"
371.14 + differences = False
371.15 + def __init__(self, user=None):
371.16 + pass
371.17 +
371.18 + def test_checkPw(self):
371.19 + self.pwLdap = open("/etc/ldap.secret" ).readline().strip()
371.20 + self.pwNss = open("/etc/libnss-ldap.secret").readline().strip()
371.21 + self.pwPam = open("/etc/pam_ldap.secret" ).readline().strip()
371.22 +
371.23 + if (self.pwLdap == self.pwNss == self.pwPam): return True
371.24 +
371.25 + self.differences = True
371.26 +
371.27 + def report(self):
371.28 + if self.differences:
371.29 + print " Password dei files ldap.secret differenti:"
371.30 + print " /etc/ldap.secret : "+self.pwLdap
371.31 + print " /etc/libnss-ldap.secret : "+self.pwNss
371.32 + print " /etc/pam_ldap.secret : "+self.pwPam
371.33 +
371.34 + def __str__(self):
371.35 + return "test %s" % (self.name)
372.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
372.2 +++ b/usr/share/isi-checkup/tests/231_need_file_libnss-ldap.secret.py Mon Apr 26 11:16:23 2010 +0200
372.3 @@ -0,0 +1,7 @@
372.4 +from checkup import IsiTestFile
372.5 +
372.6 +class FileLibNssLdapSecret(IsiTestFile):
372.7 + run = True
372.8 + skip = "232 260 325 320 307 308 309 320 325 330 331 332 333 334 335 336"
372.9 + FILE_NAME = '/etc/libnss-ldap.secret'
372.10 +
373.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
373.2 +++ b/usr/share/isi-checkup/tests/232_need_file_pam_ldap.secret.py Mon Apr 26 11:16:23 2010 +0200
373.3 @@ -0,0 +1,6 @@
373.4 +from checkup import IsiTestFile
373.5 +
373.6 +class FilePamLdapSecret(IsiTestFile):
373.7 + run = True
373.8 + FILE_NAME = '/etc/pam_ldap.secret'
373.9 +
374.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
374.2 +++ b/usr/share/isi-checkup/tests/233_need_file_slapd_conf.py Mon Apr 26 11:16:23 2010 +0200
374.3 @@ -0,0 +1,7 @@
374.4 +from checkup import IsiTestFile
374.5 +
374.6 +class FileSlapdConf(IsiTestFile):
374.7 + run = True
374.8 + skip = "260 325 320 307 308 309 320 325 330 331 332 333 334 335 336"
374.9 + FILE_NAME = "/etc/ldap/slapd.conf"
374.10 +
375.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
375.2 +++ b/usr/share/isi-checkup/tests/250_need_file_logon.conf.py Mon Apr 26 11:16:23 2010 +0200
375.3 @@ -0,0 +1,6 @@
375.4 +from checkup import IsiTestFile
375.5 +
375.6 +class FileLogonConf(IsiTestFile):
375.7 + run = True
375.8 + FILE_NAME = '/etc/isi/logon.conf'
375.9 +
376.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
376.2 +++ b/usr/share/isi-checkup/tests/251_need_file_logon.bat.py Mon Apr 26 11:16:23 2010 +0200
376.3 @@ -0,0 +1,6 @@
376.4 +from checkup import IsiTestFile
376.5 +
376.6 +class FileLogonBat(IsiTestFile):
376.7 + run = True
376.8 + FILE_NAME = '/etc/isi/logon.bat'
376.9 +
377.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
377.2 +++ b/usr/share/isi-checkup/tests/252_need_file_acl.conf.py Mon Apr 26 11:16:23 2010 +0200
377.3 @@ -0,0 +1,6 @@
377.4 +from checkup import IsiTestFile
377.5 +
377.6 +class FileAclConf(IsiTestFile):
377.7 + run = True
377.8 + FILE_NAME = '/etc/isi/acl.conf'
377.9 +
378.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
378.2 +++ b/usr/share/isi-checkup/tests/253_need_file_sshd_config.py Mon Apr 26 11:16:23 2010 +0200
378.3 @@ -0,0 +1,7 @@
378.4 +from checkup import IsiTestFile
378.5 +
378.6 +class FileSshdConfig(IsiTestFile):
378.7 + run = True
378.8 + skip = "261"
378.9 + FILE_NAME = '/etc/ssh/sshd_config'
378.10 +
379.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
379.2 +++ b/usr/share/isi-checkup/tests/254_need_file_named.conf.py Mon Apr 26 11:16:23 2010 +0200
379.3 @@ -0,0 +1,7 @@
379.4 +from checkup import IsiTestFile
379.5 +
379.6 +class FileNamedConf(IsiTestFile):
379.7 + run = True
379.8 + skip = "268"
379.9 + FILE_NAME = '/etc/bind/named.conf'
379.10 +
380.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
380.2 +++ b/usr/share/isi-checkup/tests/260_need_process_slapd.py Mon Apr 26 11:16:23 2010 +0200
380.3 @@ -0,0 +1,6 @@
380.4 +from checkup import IsiTestProcess
380.5 +
380.6 +class ProcessSlapd(IsiTestProcess):
380.7 + run = True
380.8 + skip = '260 261 262 263 264 265 266 267 268 269 271 272 273 274 275 276 277 278 279 280 281 300 301 307 310'
380.9 + PROCESS_NAME='slapd'
381.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
381.2 +++ b/usr/share/isi-checkup/tests/261_need_process_sshd.py Mon Apr 26 11:16:23 2010 +0200
381.3 @@ -0,0 +1,5 @@
381.4 +from checkup import IsiTestProcess
381.5 +
381.6 +class ProcessSshd(IsiTestProcess):
381.7 + run = True
381.8 + PROCESS_NAME='sshd'
382.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
382.2 +++ b/usr/share/isi-checkup/tests/262_need_process_dhcpd3.py Mon Apr 26 11:16:23 2010 +0200
382.3 @@ -0,0 +1,5 @@
382.4 +from checkup import IsiTestProcess
382.5 +
382.6 +class ProcessDhcpd3(IsiTestProcess):
382.7 + run = True
382.8 + PROCESS_NAME='dhcpd3'
383.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
383.2 +++ b/usr/share/isi-checkup/tests/263_need_process_smbd.py Mon Apr 26 11:16:23 2010 +0200
383.3 @@ -0,0 +1,5 @@
383.4 +from checkup import IsiTestProcess
383.5 +
383.6 +class ProcessSmbd(IsiTestProcess):
383.7 + run = True
383.8 + PROCESS_NAME='smbd'
384.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384.2 +++ b/usr/share/isi-checkup/tests/264_need_process_nmbd.py Mon Apr 26 11:16:23 2010 +0200
384.3 @@ -0,0 +1,5 @@
384.4 +from checkup import IsiTestProcess
384.5 +
384.6 +class ProcessNmbd(IsiTestProcess):
384.7 + run = True
384.8 + PROCESS_NAME='nmbd'
385.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
385.2 +++ b/usr/share/isi-checkup/tests/265_need_process_squid.py Mon Apr 26 11:16:23 2010 +0200
385.3 @@ -0,0 +1,5 @@
385.4 +from checkup import IsiTestProcess
385.5 +
385.6 +class ProcessSquid(IsiTestProcess):
385.7 + run = True
385.8 + PROCESS_NAME='squid'
386.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
386.2 +++ b/usr/share/isi-checkup/tests/266_need_process_dansguardian.py Mon Apr 26 11:16:23 2010 +0200
386.3 @@ -0,0 +1,5 @@
386.4 +from checkup import IsiTestProcess
386.5 +
386.6 +class ProcessDansguardian(IsiTestProcess):
386.7 + run = True
386.8 + PROCESS_NAME='dansguardian'
387.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
387.2 +++ b/usr/share/isi-checkup/tests/267_need_process_master.py Mon Apr 26 11:16:23 2010 +0200
387.3 @@ -0,0 +1,5 @@
387.4 +from checkup import IsiTestProcess
387.5 +
387.6 +class ProcessPostfix(IsiTestProcess):
387.7 + run = True
387.8 + PROCESS_NAME='master'
388.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
388.2 +++ b/usr/share/isi-checkup/tests/268_need_process_named.py Mon Apr 26 11:16:23 2010 +0200
388.3 @@ -0,0 +1,5 @@
388.4 +from checkup import IsiTestProcess
388.5 +
388.6 +class ProcessBind9(IsiTestProcess):
388.7 + run = True
388.8 + PROCESS_NAME='named'
389.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
389.2 +++ b/usr/share/isi-checkup/tests/269_need_process_nscd.py Mon Apr 26 11:16:23 2010 +0200
389.3 @@ -0,0 +1,5 @@
389.4 +from checkup import IsiTestProcess
389.5 +
389.6 +class ProcessNscd(IsiTestProcess):
389.7 + run = True
389.8 + PROCESS_NAME='nscd'
390.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
390.2 +++ b/usr/share/isi-checkup/tests/271_samba_share_homes.py Mon Apr 26 11:16:23 2010 +0200
390.3 @@ -0,0 +1,6 @@
390.4 +from checkup import IsiTestSambaShare
390.5 +
390.6 +class ShareHomes(IsiTestSambaShare):
390.7 + run = True
390.8 + SAMBA_SHARE_NAME = 'homes'
390.9 +
391.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
391.2 +++ b/usr/share/isi-checkup/tests/272_samba_share_netlogon.py Mon Apr 26 11:16:23 2010 +0200
391.3 @@ -0,0 +1,6 @@
391.4 +from checkup import IsiTestSambaShare
391.5 +
391.6 +class ShareNetlogon(IsiTestSambaShare):
391.7 + run = True
391.8 + SAMBA_SHARE_NAME = 'netlogon'
391.9 +
392.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
392.2 +++ b/usr/share/isi-checkup/tests/273_samba_share_software.py Mon Apr 26 11:16:23 2010 +0200
392.3 @@ -0,0 +1,6 @@
392.4 +from checkup import IsiTestSambaShare
392.5 +
392.6 +class ShareSoftware(IsiTestSambaShare):
392.7 + run = True
392.8 + SAMBA_SHARE_NAME = 'software'
392.9 +
393.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
393.2 +++ b/usr/share/isi-checkup/tests/274_samba_share_dati.py Mon Apr 26 11:16:23 2010 +0200
393.3 @@ -0,0 +1,6 @@
393.4 +from checkup import IsiTestSambaShare
393.5 +
393.6 +class ShareDati(IsiTestSambaShare):
393.7 + run = True
393.8 + SAMBA_SHARE_NAME = 'dati'
393.9 +
394.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
394.2 +++ b/usr/share/isi-checkup/tests/275_samba_share_classi.py Mon Apr 26 11:16:23 2010 +0200
394.3 @@ -0,0 +1,6 @@
394.4 +from checkup import IsiTestSambaShare
394.5 +
394.6 +class ShareClassi(IsiTestSambaShare):
394.7 + run = True
394.8 + SAMBA_SHARE_NAME = 'classi'
394.9 +
395.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
395.2 +++ b/usr/share/isi-checkup/tests/276_samba_share_corsi.py Mon Apr 26 11:16:23 2010 +0200
395.3 @@ -0,0 +1,6 @@
395.4 +from checkup import IsiTestSambaShare
395.5 +
395.6 +class ShareCorsi(IsiTestSambaShare):
395.7 + run = True
395.8 + SAMBA_SHARE_NAME = 'corsi'
395.9 +
396.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
396.2 +++ b/usr/share/isi-checkup/tests/277_samba_share_perl.py Mon Apr 26 11:16:23 2010 +0200
396.3 @@ -0,0 +1,6 @@
396.4 +from checkup import IsiTestSambaShare
396.5 +
396.6 +class SharePerl(IsiTestSambaShare):
396.7 + run = True
396.8 + SAMBA_SHARE_NAME = 'perl'
396.9 +
397.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
397.2 +++ b/usr/share/isi-checkup/tests/278_samba_share_printers.py Mon Apr 26 11:16:23 2010 +0200
397.3 @@ -0,0 +1,6 @@
397.4 +from checkup import IsiTestSambaShare
397.5 +
397.6 +class SharePrinters(IsiTestSambaShare):
397.7 + run = True
397.8 + SAMBA_SHARE_NAME = 'printers'
397.9 +
398.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
398.2 +++ b/usr/share/isi-checkup/tests/279_samba_share_area_alunni.py Mon Apr 26 11:16:23 2010 +0200
398.3 @@ -0,0 +1,6 @@
398.4 +from checkup import IsiTestSambaShare
398.5 +
398.6 +class ShareAreaAlunni(IsiTestSambaShare):
398.7 + run = True
398.8 + SAMBA_SHARE_NAME = 'area_alunni'
398.9 +
399.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
399.2 +++ b/usr/share/isi-checkup/tests/280_samba_share_area_docenti.py Mon Apr 26 11:16:23 2010 +0200
399.3 @@ -0,0 +1,6 @@
399.4 +from checkup import IsiTestSambaShare
399.5 +
399.6 +class ShareAreaDocenti(IsiTestSambaShare):
399.7 + run = True
399.8 + SAMBA_SHARE_NAME = 'area_docenti'
399.9 +
400.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
400.2 +++ b/usr/share/isi-checkup/tests/281_samba_share_area_segreteria.py Mon Apr 26 11:16:23 2010 +0200
400.3 @@ -0,0 +1,13 @@
400.4 +from checkup import IsiTestSambaShare
400.5 +
400.6 +class ShareAreaSegreteria(IsiTestSambaShare):
400.7 + run = True
400.8 + SAMBA_SHARE_NAME = 'area_segreteria'
400.9 +
400.10 +
400.11 +
400.12 +
400.13 +
400.14 +
400.15 +
400.16 +
401.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
401.2 +++ b/usr/share/isi-checkup/tests/300_samba_shares_paths.py Mon Apr 26 11:16:23 2010 +0200
401.3 @@ -0,0 +1,56 @@
401.4 +#!/usr/bin/python
401.5 +import sys
401.6 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
401.7 +from checkup import IsiTest, InputStream
401.8 +
401.9 +from dry.functions import execute
401.10 +import re
401.11 +import ConfigParser
401.12 +import os
401.13 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
401.14 +from checkup import IsiTest, TestError
401.15 +
401.16 +class SharesHavePath(IsiTest):
401.17 + run = True
401.18 +
401.19 + def __init__(self, user=None):
401.20 + ret_code, sambaconf, err = execute('testparm -s')
401.21 + f = InputStream(data=sambaconf)
401.22 + self.parser = ConfigParser.ConfigParser()
401.23 + self.parser.readfp(f, 'cfg')
401.24 + self.sections = self.parser.sections()
401.25 + self.missing = []
401.26 +
401.27 + def get_share_paths(self):
401.28 + """ Returns samba shares paths """
401.29 + sharePaths = []
401.30 + for section in self.parser.sections():
401.31 + items = self.parser.items(section)
401.32 + item_with_path = ([item[1] for item in items\
401.33 + if 'path' in item])
401.34 + # filtering env variable elements
401.35 + if re.search('%', str(item_with_path)): continue
401.36 + sharePaths += item_with_path
401.37 + return sharePaths
401.38 +
401.39 + def test_share_paths_exist(self):
401.40 + """ check if defined samba share paths exist """
401.41 + share_paths = self.get_share_paths()
401.42 + for path in share_paths:
401.43 + if os.path.isdir(path): continue
401.44 + self.missing += [path]
401.45 + if not self.missing:
401.46 + return True
401.47 + return False
401.48 +
401.49 + def report(self):
401.50 + if self.missing:
401.51 + #msg = 'PATH richiesti da shares definite assenti\n'
401.52 + #msg += '-'*len(msg)
401.53 + #print msg
401.54 + print 'PATH richiesti da shares definite assenti'
401.55 + for share in self.missing:
401.56 + print " ", share
401.57 +
401.58 + def __str__(self):
401.59 + return "test %s" % (self.name)
402.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
402.2 +++ b/usr/share/isi-checkup/tests/301_class_path_name.py Mon Apr 26 11:16:23 2010 +0200
402.3 @@ -0,0 +1,75 @@
402.4 +#!/usr/bin/python
402.5 +import sys
402.6 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
402.7 +from checkup import IsiTest, InputStream
402.8 +
402.9 +from dry.functions import execute
402.10 +import re
402.11 +import ConfigParser
402.12 +import os
402.13 +#from isi.srv import CLASSES, COURSES
402.14 +from isi import srv
402.15 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
402.16 +from checkup import IsiTest, TestError
402.17 +CLASSES = srv.get_classes()
402.18 +COURSES = srv.get_courses()
402.19 +
402.20 +class SharesHavePath(IsiTest):
402.21 + run = True
402.22 +
402.23 + def __init__(self, user=None):
402.24 + ret_code, sambaconf, err = execute('testparm -s')
402.25 + f = InputStream(data=sambaconf)
402.26 + self.parser = ConfigParser.ConfigParser()
402.27 + self.parser.readfp(f, 'cfg')
402.28 + self.sections = self.parser.sections()
402.29 +
402.30 + self.bad_classes = []
402.31 + self.bad_courses = []
402.32 +
402.33 + def get_share_paths_last(self):
402.34 + """ Returns samba shares paths """
402.35 + share_paths_last = []
402.36 + for section in self.parser.sections():
402.37 + items = self.parser.items(section)
402.38 + item_with_path = ([item[1] for item in items\
402.39 + if 'path' in item])
402.40 + # filtering env variable elements with '%' character
402.41 + if re.search('%', str(item_with_path)): continue
402.42 +
402.43 + # get last last path name element
402.44 + item_without_path = [ el.split('/')[-1] for el in item_with_path]
402.45 + share_paths_last += item_without_path
402.46 +
402.47 + return share_paths_last
402.48 +
402.49 + def test_class_path_name(self):
402.50 + """
402.51 + Checks if the defined "CLASS/COURSE NAME" is the last element of the
402.52 + defined "PATH NAME"
402.53 + """
402.54 + share_paths_name = self.get_share_paths_last()
402.55 +
402.56 + for CLASS in CLASSES:
402.57 + if CLASS not in share_paths_name:
402.58 + self.bad_classes += [CLASS]
402.59 +
402.60 + for COURSE in COURSES:
402.61 + if not COURSE in share_paths_name:
402.62 + self.bad_courses += [COURSE]
402.63 +
402.64 + if not self.bad_courses or self.bad_classes:
402.65 + return True
402.66 +
402.67 + def report(self):
402.68 + if self.bad_classes:
402.69 + print 'Le segg. CLASSI hanno nomi samba non coincidenti con il PATH:'
402.70 + for bad_class in self.bad_classes:
402.71 + print " ", bad_class
402.72 + if self.bad_courses:
402.73 + print 'I segg. CORSI hanno nomi samba non coincidenti con il PATH:'
402.74 + for bad_course in self.bad_courses:
402.75 + print " ", bad_course
402.76 +
402.77 + def __str__(self):
402.78 + return "test %s" % (self.name)
403.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
403.2 +++ b/usr/share/isi-checkup/tests/307_ldap_connect.py Mon Apr 26 11:16:23 2010 +0200
403.3 @@ -0,0 +1,14 @@
403.4 +from checkup import IsiTest
403.5 +from ldap import INVALID_CREDENTIALS
403.6 +import isi
403.7 +
403.8 +class LdapConnect(IsiTest):
403.9 + skip = "308 309 330 331 332 333 334 335 336 501"
403.10 + run = True
403.11 +
403.12 + def test_slapd_conn_parameter(self):
403.13 + try:
403.14 + self.srv = isi.IsiConn()
403.15 + return True
403.16 + except INVALID_CREDENTIALS:
403.17 + return False
404.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
404.2 +++ b/usr/share/isi-checkup/tests/308_user_exists_administrator.py Mon Apr 26 11:16:23 2010 +0200
404.3 @@ -0,0 +1,6 @@
404.4 +from checkup import IsiTestUserExist
404.5 +
404.6 +class UserAdministrator(IsiTestUserExist):
404.7 + run = True
404.8 + USER = 'administrator'
404.9 + skip = '309 310'
405.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
405.2 +++ b/usr/share/isi-checkup/tests/309_administrator_credential.py Mon Apr 26 11:16:23 2010 +0200
405.3 @@ -0,0 +1,39 @@
405.4 +import isi
405.5 +import os
405.6 +from checkup import IsiTest
405.7 +I = isi.IsiConn()
405.8 +
405.9 +class CheckAdministratorCredential(IsiTest):
405.10 + """
405.11 + Checks if administrator password == /etc/ldap.secret
405.12 + or
405.13 + administrator password == /etc/administrator.secret
405.14 + """
405.15 + name = 'Check Administrator Credential'
405.16 + run = True
405.17 + skip = '310'
405.18 + MATCH = False
405.19 +
405.20 + def __init__(self, user=None):
405.21 + if os.path.isfile('/etc/administrator.secret'):
405.22 + self.AUTH_PW = open('/etc/administrator.secret').read().strip()
405.23 + else:
405.24 + self.AUTH_PW = open('/etc/ldap.secret').read().strip()
405.25 +
405.26 + def test_administrator_credential(self):
405.27 + if I.test_password('administrator', self.AUTH_PW):
405.28 + self.MATCH = True
405.29 + return True
405.30 + else:
405.31 + return False
405.32 +
405.33 +
405.34 + def report(self):
405.35 + if not self.MATCH:
405.36 + print "\nLa password di 'administrator' differisce da quella trovata in \n"+\
405.37 + "/etc/ldap.secret. Non e' un errore ma alcuni test necessitano di \n"+\
405.38 + "conoscere la password di 'administrator'.\n"+\
405.39 + "Inseriscila in '/etc/administrator.secret'\n"
405.40 +
405.41 + def __str__(self):
405.42 + return "test %s" % (self.name)
406.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
406.2 +++ b/usr/share/isi-checkup/tests/310_DomainAdmins_group_priv.py Mon Apr 26 11:16:23 2010 +0200
406.3 @@ -0,0 +1,37 @@
406.4 +import os
406.5 +from checkup import SambaGroupPrivs
406.6 +
406.7 +class DomainAdminsPrivs(SambaGroupPrivs):
406.8 + """
406.9 + Checks if a particular group has needed privs
406.10 +
406.11 + Privilege definition
406.12 + ====================
406.13 +
406.14 + SeMachineAccountPrivilege Add machines to domain
406.15 + SeTakeOwnershipPrivilege Take ownership of files or other objects
406.16 + SeBackupPrivilege Back up files and directories
406.17 + SeRestorePrivilege Restore files and directories
406.18 + SeRemoteShutdownPrivilege Force shutdown from a remote system
406.19 + SePrintOperatorPrivilege Manage printers
406.20 + SeAddUsersPrivilege Add users and groups to the domain
406.21 + SeDiskOperatorPrivilege Manage disk shares
406.22 + """
406.23 + run = True
406.24 +
406.25 + NEEDED_PRIV_LIST = ['SeMachineAccountPrivilege',
406.26 + 'SeTakeOwnershipPrivilege',
406.27 + 'SeBackupPrivilege',
406.28 + 'SeRestorePrivilege',
406.29 + 'SeRemoteShutdownPrivilege',
406.30 + 'SePrintOperatorPrivilege',
406.31 + 'SeAddUsersPrivilege',
406.32 + 'SeDiskOperatorPrivilege',]
406.33 + GROUP = 'Domain Admins'
406.34 + AUTH_USER = 'administrator'
406.35 +
406.36 + if os.path.isfile('/etc/administrator.secret'):
406.37 + AUTH_PW = open('/etc/administrator.secret').read().strip()
406.38 + else:
406.39 + AUTH_PW = open('/etc/ldap.secret').read().strip()
406.40 +
407.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
407.2 +++ b/usr/share/isi-checkup/tests/320_ldap_sizelimit.py Mon Apr 26 11:16:23 2010 +0200
407.3 @@ -0,0 +1,53 @@
407.4 +import re
407.5 +from dry.functions import execute
407.6 +import sys
407.7 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
407.8 +from checkup import IsiTest, TestError
407.9 +
407.10 +class LdapSizelimit(IsiTest):
407.11 + """ Checks if ldap < 1500 """
407.12 + run = True
407.13 +
407.14 + def __init__(self, user=None):
407.15 + self.LOW_SIZELIMIT = False
407.16 +
407.17 + def get_ldap_sizelimit(self):
407.18 + pattern = '^\S*sizelimit\S*(?P<sizelimit>.+)'
407.19 + f = open('/etc/ldap/slapd.conf')
407.20 + for line in f.readlines():
407.21 + m = re.match(pattern, line)
407.22 + if m:
407.23 + m = m.groupdict()
407.24 + sizelimit = m['sizelimit']
407.25 + return int(sizelimit)
407.26 +
407.27 + def test_ldap_lowSizelimit(self):
407.28 + self.SIZE_LIMIT = self.get_ldap_sizelimit()
407.29 + if not self.SIZE_LIMIT < 1500:
407.30 + return True
407.31 + self.LOW_SIZELIMIT = True
407.32 +
407.33 + def report(self):
407.34 + if self.LOW_SIZELIMIT:
407.35 + print 'Parametro ldap "sizelimit" inferiore a 1500'
407.36 + print ' sizelimit : ', self.SIZE_LIMIT
407.37 +
407.38 + def __str__(self):
407.39 + return "test %s" % (self.name)
407.40 +
407.41 +
407.42 +
407.43 +
407.44 +
407.45 +
407.46 +
407.47 +
407.48 +
407.49 +
407.50 +
407.51 +
407.52 +
407.53 +
407.54 +
407.55 +
407.56 +
408.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
408.2 +++ b/usr/share/isi-checkup/tests/321_checkgunum.sh Mon Apr 26 11:16:23 2010 +0200
408.3 @@ -0,0 +1,25 @@
408.4 +#!/bin/bash
408.5 +
408.6 +domain=$(grep 'workgroup' /etc/samba/smb.conf | awk {'print $3'})
408.7 +
408.8 +uidNumber=$(ldapsearch -xLLL sambaDomainName=$domain dn uidNumber | grep uid)
408.9 +gidNumber=$(ldapsearch -xLLL sambaDomainName=$domain dn gidNumber | grep gid)
408.10 +
408.11 +if [ -z "$uidNumber" ]; then
408.12 +
408.13 + if [ -z "$gidNumber" ]; then
408.14 + echo 'Campi ldap uidNumber e gidNumber assenti !!!'
408.15 + exit 1
408.16 + else
408.17 + echo 'Campo ldap uidNumber assente !!!'
408.18 + exit 1
408.19 + fi
408.20 +else
408.21 + if [ -z "$gidNumber" ]; then
408.22 + echo 'Campo ldap gidNumber assente !!!'
408.23 + exit 1
408.24 + fi
408.25 +fi
408.26 +
408.27 +exit 0
408.28 +
409.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
409.2 +++ b/usr/share/isi-checkup/tests/325_smbldap_homePath.py Mon Apr 26 11:16:23 2010 +0200
409.3 @@ -0,0 +1,97 @@
409.4 +#!/usr/bin/python
409.5 +"""
409.6 +SID="S-1-5-21-3099135007-616077390-1994049917"
409.7 +slaveLDAP="127.0.0.1"
409.8 +slavePort="389"
409.9 +masterLDAP="127.0.0.1"
409.10 +masterPort="389"
409.11 +ldapTLS="0"
409.12 +suffix="dc=isi,dc=lan"
409.13 +usersdn="ou=People,dc=isi,dc=lan"
409.14 +computersdn="ou=Computers,dc=isi,dc=lan"
409.15 +groupsdn="ou=Groups,dc=isi,dc=lan"
409.16 +idmapdn="ou=Idmap,dc=isi,dc=lan"
409.17 +sambaUnixIdPooldn="sambaDomainName=ITIS-RIVA,dc=isi,dc=lan"
409.18 +scope="sub"
409.19 +hash_encrypt="SSHA"
409.20 +crypt_salt_format="%s"
409.21 +userLoginShell="/bin/bash"
409.22 +userHome="/home/%U"
409.23 +userGecos="System User"
409.24 +defaultUserGid="513"
409.25 +defaultComputerGid="515"
409.26 +skeletonDir="/etc/skel"
409.27 +defaultMaxPasswordAge="99"
409.28 +userSmbHome="\\ISI-PDC\%U"
409.29 +userProfile="\\ISI-PDC\profiles"
409.30 +userHomeDrive="H:"
409.31 +mailDomain="isi.lan"
409.32 +with_smbpasswd="0"
409.33 +smbpasswd="/usr/bin/smbpasswd"
409.34 +SID for domain SARGO is: S-1-5-21-1479175027-3375466229-471917732
409.35 +"""
409.36 +
409.37 +import re
409.38 +from dry.functions import execute
409.39 +import sys
409.40 +sys.path.insert(0, '/usr/share/isi-checkup/lib')
409.41 +from checkup import IsiTest, TestError
409.42 +
409.43 +class Smbldap_homePath(IsiTest):
409.44 + run = True
409.45 + name = 'smbldap_homePath'
409.46 +
409.47 + paramToFind = 'userSmbHome userProfile'
409.48 + paramFound = {}
409.49 +
409.50 + def __init__(self, user=None):
409.51 + pass
409.52 +
409.53 + def parse_smbldap_conf(self):
409.54 + """
409.55 + return /etc/smbldap-tools/smbldap.conf par
409.56 +
409.57 + TODO: affinare regexp (matcha grossolanamente)
409.58 + """
409.59 + cfg_parsed = {}
409.60 + f = open('/etc/smbldap-tools/smbldap.conf')
409.61 +
409.62 + pattern = '^\s*(?P<key>.+)\s*=+\s*(?P<value>.+)\s*$'
409.63 + for line in f.readlines():
409.64 + #for line in __doc__.split('\n'):
409.65 + if re.match('^\s*$', line):
409.66 + continue
409.67 + m = re.search(pattern, line)
409.68 + if m:
409.69 + key = m.group('key')
409.70 + value = m.group('value')
409.71 +
409.72 + cfg_parsed[key] = value
409.73 +
409.74 + return cfg_parsed
409.75 +
409.76 + def findParam(self):
409.77 + cfg = self.parse_smbldap_conf()
409.78 +
409.79 + for key in self.paramToFind.split():
409.80 + if cfg.has_key(key) and cfg[key].strip('"\''):
409.81 + self.paramFound[key] = cfg[key]
409.82 +
409.83 + return self.paramFound
409.84 +
409.85 + def test_smbldap_homePath(self):
409.86 + if not self.findParam():
409.87 + return True
409.88 + return False
409.89 +
409.90 + def report(self):
409.91 + if self.paramFound:
409.92 + paramFound = self.paramFound
409.93 + print "WARNING '/etc/smbldap-tools/smbldap.conf'"+\
409.94 + "presenta i seguenti campi obsoleti:\n"
409.95 + for key in paramFound.keys():
409.96 + print "%s = %s" % (key, paramFound[key])
409.97 +
409.98 + def __str__(self):
409.99 + return "test %s" % (self.name)
409.100 +
410.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
410.2 +++ b/usr/share/isi-checkup/tests/330_group_exists_docenti.py Mon Apr 26 11:16:23 2010 +0200
410.3 @@ -0,0 +1,5 @@
410.4 +from checkup import IsiTestGroup
410.5 +
410.6 +class GroupDocenti(IsiTestGroup):
410.7 + GROUP = 'docenti'
410.8 + run = True
411.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
411.2 +++ b/usr/share/isi-checkup/tests/331_group_exists_alunni.py Mon Apr 26 11:16:23 2010 +0200
411.3 @@ -0,0 +1,5 @@
411.4 +from checkup import IsiTestGroup
411.5 +
411.6 +class GroupDocenti(IsiTestGroup):
411.7 + GROUP = 'alunni'
411.8 + run = True
412.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
412.2 +++ b/usr/share/isi-checkup/tests/332_group_exists_admins.py Mon Apr 26 11:16:23 2010 +0200
412.3 @@ -0,0 +1,5 @@
412.4 +from checkup import IsiTestGroup
412.5 +
412.6 +class GroupDocenti(IsiTestGroup):
412.7 + GROUP = 'admins'
412.8 + run = True
413.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
413.2 +++ b/usr/share/isi-checkup/tests/333_group_exists_ata.py Mon Apr 26 11:16:23 2010 +0200
413.3 @@ -0,0 +1,5 @@
413.4 +from checkup import IsiTestGroup
413.5 +
413.6 +class GroupDocenti(IsiTestGroup):
413.7 + GROUP = 'ata'
413.8 + run = True
414.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
414.2 +++ b/usr/share/isi-checkup/tests/334_group_exists_esterni.py Mon Apr 26 11:16:23 2010 +0200
414.3 @@ -0,0 +1,5 @@
414.4 +from checkup import IsiTestGroup
414.5 +
414.6 +class GroupDocenti(IsiTestGroup):
414.7 + GROUP = 'esterni'
414.8 + run = True
415.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
415.2 +++ b/usr/share/isi-checkup/tests/335_group_exists_ospiti.py Mon Apr 26 11:16:23 2010 +0200
415.3 @@ -0,0 +1,5 @@
415.4 +from checkup import IsiTestGroup
415.5 +
415.6 +class GroupDocenti(IsiTestGroup):
415.7 + GROUP = 'ospiti'
415.8 + run = True
416.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
416.2 +++ b/usr/share/isi-checkup/tests/336_group_exists_segreteria.py Mon Apr 26 11:16:23 2010 +0200
416.3 @@ -0,0 +1,5 @@
416.4 +from checkup import IsiTestGroup
416.5 +
416.6 +class GroupDocenti(IsiTestGroup):
416.7 + GROUP = 'segreteria'
416.8 + run = True
417.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
417.2 +++ b/usr/share/isi-checkup/tests/340_logon-bat.py Mon Apr 26 11:16:23 2010 +0200
417.3 @@ -0,0 +1,66 @@
417.4 +from checkup import IsiTest
417.5 +import re
417.6 +
417.7 +class LogonBat(IsiTest):
417.8 + name = 'logon_bat'
417.9 + skip = ''
417.10 + run = True
417.11 +
417.12 + def __init__(self, user=None):
417.13 + self.no_match = False
417.14 + self.netbios_name = self.get_netbios_name()
417.15 +
417.16 + def get_netbios_name(self):
417.17 + """Returns the netbios name configured in smb.conf"""
417.18 +
417.19 + exclude_match = '^\s*#|^\s*;|^$'
417.20 + match = '^\s*(?P<key>netbios name)\s*=\s*(?P<value>.+)$'
417.21 +
417.22 + try:
417.23 + f = open('/etc/samba/smb.conf').read().split('\n')
417.24 + except Exception:
417.25 + pass
417.26 +
417.27 + for line in f:
417.28 + if re.search(exclude_match, line):
417.29 + continue
417.30 + m = re.search(match, line)
417.31 + if m:
417.32 + return m.group('value')
417.33 +
417.34 + def test_logon_bat(self):
417.35 + """
417.36 + Checks if the netbios name is missing in /etc/isi/logon.conf
417.37 + """
417.38 + netbios_name = self.get_netbios_name()
417.39 + share_perl = '\\\\%s\\perl\\bin\\perl' % netbios_name
417.40 + share_logon_pl = '\\\\%s\\perl\\logon.pl' % netbios_name
417.41 + self.cfg_expected = " ".join([share_perl, share_logon_pl, netbios_name])
417.42 +
417.43 + try:
417.44 + f = open('/etc/isi/logon.bat').read().split('\n')
417.45 + except Exception:
417.46 + pass
417.47 + for line in f:
417.48 + if not re.search('^\s*\\\\', line):
417.49 + continue
417.50 + self.line = line
417.51 +
417.52 + for element in line.split():
417.53 + if element != share_perl and\
417.54 + element != share_logon_pl and\
417.55 + element != netbios_name:
417.56 + self.no_match = True
417.57 +
417.58 + if self.no_match:
417.59 + return False
417.60 + return True
417.61 +
417.62 + def report(self):
417.63 + if self.no_match:
417.64 + print 'Configurazione di "/etc/isi/logon.bat" non coerente'
417.65 + print ' attuale: %s' % self.line
417.66 + print ' attesa: %s' % self.cfg_expected
417.67 +
417.68 + def __str__(self):
417.69 + return "test %s" % (self.name)
418.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
418.2 +++ b/usr/share/isi-checkup/tests/341_logonupd-bat.py Mon Apr 26 11:16:23 2010 +0200
418.3 @@ -0,0 +1,66 @@
418.4 +from checkup import IsiTest
418.5 +import re
418.6 +
418.7 +class LogonupdBat(IsiTest):
418.8 + name = 'logonupd_bat'
418.9 + skip = ''
418.10 + run = True
418.11 +
418.12 + def __init__(self, user=None):
418.13 + self.no_match = False
418.14 + self.netbios_name = self.get_netbios_name()
418.15 +
418.16 + def get_netbios_name(self):
418.17 + """Returns the netbios name configured in smb.conf"""
418.18 +
418.19 + exclude_match = '^\s*#|^\s*;|^$'
418.20 + match = '^\s*(?P<key>netbios name)\s*=\s*(?P<value>.+)$'
418.21 +
418.22 + try:
418.23 + f = open('/etc/samba/smb.conf').read().split('\n')
418.24 + except Exception:
418.25 + pass
418.26 +
418.27 + for line in f:
418.28 + if re.search(exclude_match, line):
418.29 + continue
418.30 + m = re.search(match, line)
418.31 + if m:
418.32 + return m.group('value')
418.33 +
418.34 + def test_logonupd_bat(self):
418.35 + """
418.36 + Checks if the netbios name is missing in /etc/isi/logonupd.conf
418.37 + """
418.38 + netbios_name = self.get_netbios_name()
418.39 + share_perl = '\\\\%s\\perl\\bin\\perl' % netbios_name
418.40 + share_logonupd_pl = '\\\\%s\\perl\\logonupd.pl' % netbios_name
418.41 + self.cfg_expected = " ".join([share_perl, share_logonupd_pl, netbios_name])
418.42 +
418.43 + try:
418.44 + f = open('/etc/isi/logonupd.bat').read().split('\n')
418.45 + except Exception:
418.46 + pass
418.47 + for line in f:
418.48 + if not re.search('^\s*\\\\', line):
418.49 + continue
418.50 + self.line = line
418.51 +
418.52 + for element in line.split():
418.53 + if element != share_perl and\
418.54 + element != share_logonupd_pl and\
418.55 + element != netbios_name:
418.56 + self.no_match = True
418.57 +
418.58 + if self.no_match:
418.59 + return False
418.60 + return True
418.61 +
418.62 + def report(self):
418.63 + if self.no_match:
418.64 + print 'Configurazione di "/etc/isi/logonupd.bat" non coerente'
418.65 + print ' attuale: %s' % self.line
418.66 + print ' attesa: %s' % self.cfg_expected
418.67 +
418.68 + def __str__(self):
418.69 + return "test %s" % (self.name)
419.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
419.2 +++ b/usr/share/isi-checkup/tests/342_nscd_no_persistent.py Mon Apr 26 11:16:23 2010 +0200
419.3 @@ -0,0 +1,45 @@
419.4 +#!/usr/bin/python
419.5 +
419.6 +from checkup import IsiTest
419.7 +import re
419.8 +import os
419.9 +
419.10 +class nscd_persistent(IsiTest):
419.11 + run = True
419.12 + name = 'check nscd persistent'
419.13 + bad_services = []
419.14 +
419.15 + def check_persistent(self):
419.16 + """
419.17 + Returns bad_services list of services found
419.18 + or bad_services=None.
419.19 + """
419.20 + f = open('/etc/nscd.conf').read()
419.21 +
419.22 + for line in f.split('\n'):
419.23 + if re.match('^\s*#', line):
419.24 + continue
419.25 + if not 'persistent' in line:
419.26 + continue
419.27 + persistent, service, active = line.split()
419.28 + if active == 'yes':
419.29 + self.bad_services += [service]
419.30 +
419.31 + return self.bad_services
419.32 +
419.33 + def test_nscd_persistent(self):
419.34 + if os.path.isfile('/etc/nscd.conf'):
419.35 + if not self.check_persistent():
419.36 + return True
419.37 + else:
419.38 + return False
419.39 +
419.40 + def report(self):
419.41 + if self.bad_services:
419.42 + print '\nDisattiva in /etc/nscd.conf:'
419.43 + for service in self.bad_services:
419.44 + print "persistent %s\tyes" % service
419.45 +
419.46 + def __str__(self):
419.47 + return "test %s" % (self.name)
419.48 +
420.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
420.2 +++ b/usr/share/isi-checkup/tests/501_firefoxCfg.py Mon Apr 26 11:16:23 2010 +0200
420.3 @@ -0,0 +1,168 @@
420.4 +#!/usr/bin/python
420.5 +'''
420.6 +firefoxCfg.py
420.7 +
420.8 +Test che verifica che proxy e porta dei profili_firefox utente corrispondano
420.9 +a quelli del server impostati in /etc/isi/logon.conf
420.10 +
420.11 +Accetta in ingresso un utente.
420.12 +
420.13 +TODO
420.14 +- fixare ciclo su tutti gli utenti
420.15 +- controllare che utente richiesto Esista...
420.16 +- migliorare estetica output =)
420.17 +- Cambio nomi variabili
420.18 +'''
420.19 +
420.20 +import os
420.21 +import re
420.22 +import isi
420.23 +from isi.checkup import IsiTest
420.24 +from dry.functions import execute
420.25 +
420.26 +# MAIN
420.27 +class TestFirefox(IsiTest):
420.28 + def __init__(self, user=None):
420.29 +
420.30 + logonConfFile = "/etc/isi/logon.conf"
420.31 + self.fireConfSite = "/.profili/WinXP/Dati applicazioni/Mozilla/" + \
420.32 + "Firefox/Profiles/isi.default/prefs.js"
420.33 + self.user = user
420.34 + self.no_profile = {}
420.35 + self.wrong_profile = {}
420.36 + self.logonConf_Parsed = self.logonParser(logonConfFile)
420.37 +
420.38 + if self.user:
420.39 + ret_code, self.maingroup, err = execute('id -gn ' + self.user)
420.40 + self.maingroup
420.41 +
420.42 + def logonParser(self, logonConfFile):
420.43 + '''
420.44 + #Return a dictionary with logon.conf's ProxyServer section
420.45 + #Eg.
420.46 + ProxyServer = 192.168.1.150:8128
420.47 + ProxyServer[admins] = 192.168.1.150:3128
420.48 + ProxyServer[alunni] = 192.168.1.150:8128
420.49 +
420.50 + #return {None: '8128', 'admins': '3128', 'alunni': '8128'}
420.51 + '''
420.52 +
420.53 + fParsed = {}
420.54 + f = open(logonConfFile)
420.55 +
420.56 + PAT = re.compile(r'''
420.57 + (?:https?://)? # http://
420.58 + (?P<host>[^:/]+) # localhost o 192.168.1.254
420.59 + :(?P<port>\d+) # porta
420.60 + ''', re.VERBOSE)
420.61 +
420.62 + GROUP_RESTRICTION = re.compile(r'''
420.63 + ([^[]+) # tutto fino alla quadra [
420.64 + (?:\[ # ?: non lo vogliamo in m.groups()
420.65 + (?:(?:[A-Z]:)? # per NetFolder e ammessa sintassi: [S:admins]
420.66 + ([a-z]+) # il gruppo principale
420.67 + )
420.68 + ])?
420.69 + ''', re.VERBOSE)
420.70 +
420.71 + for line in f:
420.72 + if re.match('^\s*#', line): # comments
420.73 + continue
420.74 + #print '-%s-' % line
420.75 + m = re.match(PAT, line)
420.76 + if m:
420.77 + key, val = m.groups()
420.78 + m2 = re.search(GROUP_RESTRICTION, key)
420.79 + if m2:
420.80 + opt, maingroup = m2.groups()
420.81 + proxy_ip = key.split('=')[1].strip()
420.82 + fParsed[maingroup] = [proxy_ip, val]
420.83 + return fParsed
420.84 +
420.85 +
420.86 + def firefoxParser(self, fireConfFile):
420.87 + '''
420.88 + Return a dictionary with prefs.js options
420.89 + '''
420.90 +
420.91 + fParsed = {}
420.92 + f = open(fireConfFile)
420.93 + for line in f:
420.94 + if not 'user_pref("' in line:
420.95 + continue
420.96 + m = re.match('.*user_pref.(.*?).;', line)
420.97 + key, value = m.group(1).split(", ")
420.98 + fParsed[key.strip('\"')] = value.strip('\"')
420.99 +
420.100 + return fParsed
420.101 +
420.102 + def check_profile(self, user=None, group=None):
420.103 + '''
420.104 + Verifica che proxy e porta dei profili_firefox utente corrispondano
420.105 + a quelli del server impostati in /etc/isi/logon.conf
420.106 + '''
420.107 +
420.108 + logon_conf = self.logonConf_Parsed
420.109 +
420.110 + # Si usi la configurazione per il gruppo, se specificata in "logon.conf"
420.111 + if group in logon_conf:
420.112 + proxyServer = logon_conf[group]
420.113 + else:
420.114 + proxyServer = logon_conf[None]
420.115 +
420.116 + u = isi.Manager(isi.IsiConn())
420.117 +
420.118 + #Cerca profilo utente
420.119 + ret_code, fireConfFile, err = execute('find %s -name prefs.js' % u.get_home(user))
420.120 + fireConfFile = fireConfFile.strip()
420.121 +
420.122 + if not os.path.isfile(fireConfFile): # no firefox_profile?
420.123 + self.no_profile[user] = group
420.124 + else:
420.125 + # Leggo il profilo_firefox utente
420.126 + firefox_profile = self.firefoxParser(fireConfFile)
420.127 +
420.128 + # (profilo_firefox utente) === (configurazione proxy logon.conf) ?
420.129 + proxy_user = firefox_profile['network.proxy.http']
420.130 + proxyPort_user = firefox_profile['network.proxy.http_port']
420.131 +
420.132 + if proxy_user == proxyServer[0]:
420.133 + #self.wrong_profile[user] = [group, proxy_user]
420.134 + pass
420.135 + if proxyPort_user == proxyServer[1]:
420.136 + pass
420.137 + #self.wrong_profile[user] += [proxyPort_user]
420.138 +
420.139 +
420.140 + def test_firefoxCfg(self):
420.141 +
420.142 + # DEBUG\
420.143 + self.user = 'o_test'
420.144 + self.maingroup = 'alunni'
420.145 + # DEBUG/
420.146 +
420.147 + if self.user:
420.148 + self.check_profile(self.user, self.maingroup)
420.149 + else:
420.150 + # Se non fornito utente, ciclo su quelli presenti in ogni gruppo ISI
420.151 + groups = isi.get_main_groups()
420.152 + u = isi.Manager(isi.IsiConn())
420.153 + for group in groups:
420.154 + for user in u.get_members(group):
420.155 + self.check_profile(user, group)
420.156 +
420.157 + def report(self):
420.158 + if self.no_profile:
420.159 + print "\nUtenti senza profilo Firefox"
420.160 + print "----------------------------"
420.161 + for el in self.no_profile:
420.162 + print " ", el
420.163 +
420.164 + if self.wrong_profile:
420.165 + print "\nUtenti con profilo Firefox incoerente"
420.166 + print "-------------------------------------"
420.167 + for el in self.wrong_profile.keys():
420.168 + gruppo = self.wrong_profile[el][0]
420.169 + wrong_proxy = self.wrong_profile[el][1]
420.170 + wrong_proxy_port = self.wrong_profile[el][2]
420.171 + print " (%s)%s - %s:%s" % (gruppo, el, wrong_proxy, wrong_proxy_port)
421.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
421.2 +++ b/usr/share/isi-checkup/tests/502_check_permission_rwx.sh Mon Apr 26 11:16:23 2010 +0200
421.3 @@ -0,0 +1,235 @@
421.4 +#!/bin/bash
421.5 +
421.6 +# includo
421.7 +# source /etc/isi/checkup/tests-available/default/check_rwx.config
421.8 +
421.9 +# Directory contenute nella home da testare per i relativi permessi (R,W,X)
421.10 +homedirsR='public_html'
421.11 +homedirsW='public_html'
421.12 +homedirsX='public_html'
421.13 +
421.14 +# Aree dei gruppi
421.15 +aree_docenti='/home/shares/area_docenti'
421.16 +aree_alunni='/home/shares/area_alunni'
421.17 +aree_segreteria='/home/shares/area_segreteria'
421.18 +
421.19 +
421.20 +tmpFile=".$RANDOM.isicheckup"
421.21 +errNumber=0
421.22 +findDepth=3 # arriva fino a .profili/WinXP
421.23 +
421.24 +### Definizione Funzioni ###
421.25 +
421.26 +function checkW(){
421.27 + local utente=$1
421.28 + local gruppo=$2
421.29 + local aree=$3
421.30 + local errNumber=0
421.31 + if su $utente -c "find /home/users/$gruppo/$utente -maxdepth $findDepth -type d -exec touch {}/$tmpFile \; "; then
421.32 + find /home/users/$gruppo/$utente -maxdepth $findDepth -type d -exec rm -f {}/*.isicheckup \;
421.33 + else
421.34 + let errNumber++
421.35 + echo -e "W> !! ($gruppo)$utente non scrive in ~$utente/.profili/*"
421.36 + fi
421.37 +
421.38 + for homedirW in $homedirsW; do
421.39 + if su $utente -c "touch ~$utente/$homedirW/$tmpFile >/dev/null"; then
421.40 + eval rm -f ~$utente/$homedirW/$tmpFile
421.41 + #echo -e "W> ($gruppo)$utente scrive in $homedirW"
421.42 + else
421.43 + echo -e "W> !! ($gruppo)$utente non scrive in $homedirW"
421.44 + let errNumber++
421.45 + fi
421.46 + done
421.47 + for area in $aree;do
421.48 + if su $utente -c "touch $area/$tmpFile >/dev/null"; then
421.49 + rm -f $area/$tmpFile
421.50 + #echo -e "W> ($gruppo)$utente scrive in $area"
421.51 + else
421.52 + echo -e "W> !! ($gruppo)$utente non scrive in $area"
421.53 + let errNumber++
421.54 + fi
421.55 + done
421.56 + if [ "$errNumber" != "0" ]; then
421.57 + return 1
421.58 + else
421.59 + return 0
421.60 + fi
421.61 +}
421.62 +
421.63 +function checkR(){
421.64 + local utente=$1
421.65 + local gruppo=$2
421.66 + local aree=$3
421.67 + local errNumber=0
421.68 + if su $utente -c "find /home/users/$gruppo/$utente -maxdepth $findDepth >/dev/null"; then
421.69 + echo -n
421.70 + else
421.71 + let errNumber++
421.72 + echo -e "R> !! ($gruppo)$utente non legge in ~$utente/.profili/*"
421.73 + fi
421.74 +
421.75 + for homedirR in $homedirsR; do
421.76 + if su $utente -c "ls ~$utente/$homedirR >/dev/null"; then
421.77 + #echo -e "R> ($gruppo)$utente legge in ~$utente/$homedirR"
421.78 + echo -n
421.79 + else
421.80 + echo -e "R> !! ($gruppo)$utente non legge in ~$utente/$homedirR"
421.81 + let errNumber++
421.82 + fi
421.83 + done
421.84 + for area in $aree; do
421.85 + if su $utente -c "ls $area >/dev/null"; then
421.86 + #echo -e "R> ($gruppo)$utente legge in $area"
421.87 + echo -n
421.88 + else
421.89 + echo -e "R> !! ($gruppo)$utente non legge in $area"
421.90 + let errNumber++
421.91 + fi
421.92 + done
421.93 + if [ "$errNumber" != "0" ]; then
421.94 + return 1
421.95 + else
421.96 + return 0
421.97 + fi
421.98 +}
421.99 +
421.100 +function checkX(){
421.101 + local utente=$1
421.102 + local gruppo=$2
421.103 + local aree=$3
421.104 + local errNumber=0
421.105 +
421.106 + if su $utente -c "find /home/users/$gruppo/$utente -maxdepth $findDepth\
421.107 + -type d -exec ls {} >/dev/null \; "; then
421.108 + echo -n
421.109 + else
421.110 + echo -e "X> !! ($gruppo)$utente non attraversa ~$user/.profili/*"
421.111 + let errNumber++
421.112 + fi
421.113 +
421.114 + for homedirX in $homedirsX; do
421.115 + if su $utente -c "cd ~ && cd ~$utente/$homedirX >/dev/null" ; then
421.116 + #echo -e "X> ($gruppo)$utente attraversa ~$utente/$homedirX"
421.117 + echo -n
421.118 + else
421.119 + echo -e "X> !! ($gruppo)$utente non attraversa ~$utente/$homedirX"
421.120 + let errNumber++
421.121 + fi
421.122 + done
421.123 + for area in $aree;do
421.124 + if su $utente -c "cd $area" ; then
421.125 + #echo -e "X> ($gruppo)$utente attraversa $area"
421.126 + echo -n
421.127 + else
421.128 + echo -e "X> !! ($gruppo)$utente non attraversa $area"
421.129 + let errNumber++
421.130 + fi
421.131 + done
421.132 + if [ "$errNumber" != "0" ]; then
421.133 + return 1
421.134 + else
421.135 + return 0
421.136 + fi
421.137 +}
421.138 +
421.139 +
421.140 +function everybody(){
421.141 +
421.142 + local errNumber=0
421.143 +
421.144 + for gruppo in $(ls /home/users);do
421.145 + if isi-groupcat $gruppo 1> /dev/null 2> /dev/null; then
421.146 + for utenti in $(isi-groupcat $gruppo);do
421.147 + for utente in $utenti;do
421.148 +
421.149 + # aree = $aree_gruppo
421.150 + if [ $gruppo == 'docenti' ]; then
421.151 + aree=$aree_docenti
421.152 + elif [ $gruppo == 'alunni' ]; then
421.153 + aree=$aree_alunni
421.154 + elif [ $gruppo == 'segreteria' ]; then
421.155 + aree=$aree_segreteria
421.156 + else
421.157 + aree='/tmp'
421.158 + fi
421.159 +
421.160 + # lancio le funzioni di controllo RWX
421.161 + if ! checkW $utente $gruppo $aree; then
421.162 + let errNumber++
421.163 + fi
421.164 + if ! checkX $utente $gruppo $aree; then
421.165 + let errNumber++
421.166 + fi
421.167 + if ! checkR $utente $gruppo $aree; then
421.168 + let errNumber++
421.169 + fi
421.170 +
421.171 + done
421.172 +
421.173 + # clean tmpFile residui :-/
421.174 + find /home/users/$gruppo -iname *.isicheckup -exec rm {} \;
421.175 + done
421.176 + fi
421.177 + done
421.178 + if [ "$errNumber" != "0" ]; then
421.179 + return 1
421.180 + else
421.181 + return 0
421.182 + fi
421.183 +}
421.184 +
421.185 +### Main ###
421.186 +
421.187 +# Evito ``find: cannot get current directory: Permission denied``
421.188 +cd /tmp
421.189 +
421.190 +#se fornito argomento in ingresso (utente)
421.191 +if [[ -z "$1" ]]; then
421.192 + if ! everybody; then
421.193 + exit 1
421.194 + else
421.195 + echo "Permessi corretti"
421.196 + exit 0
421.197 + fi
421.198 +else
421.199 + utente=$1
421.200 + gruppo=$(ldapsearch -xLLL uid=$utente | grep homeD | awk -F"/" '{ print $4 }')
421.201 +
421.202 + if [ -z "$gruppo" ]; then
421.203 + echo -e "\n \"$utente\" non e' un utente del dominio"
421.204 + exit 1
421.205 + fi
421.206 +
421.207 + # aree = $aree_gruppo
421.208 + if [ $gruppo == 'docenti' ]; then
421.209 + aree=$aree_docenti
421.210 + elif [ $gruppo == 'alunni' ]; then
421.211 + aree=$aree_alunni
421.212 + elif [ $gruppo == 'segreteria' ]; then
421.213 + aree=$aree_segreteria
421.214 + else
421.215 + aree='/tmp'
421.216 + fi
421.217 +
421.218 + if ! checkW $utente $gruppo $aree; then
421.219 + let errNumber++
421.220 + fi
421.221 + if ! checkX $utente $gruppo $aree; then
421.222 + let errNumber++
421.223 + fi
421.224 + if ! checkR $utente $gruppo $aree; then
421.225 + let errNumber++
421.226 + fi
421.227 +
421.228 + # clean tmpFile residui :-/
421.229 + find /home/users/$gruppo/$utente -iname *.isicheckup -exec rm {} \;
421.230 +
421.231 +
421.232 + if [ "$errNumber" != "0" ]; then
421.233 + exit 1
421.234 + else
421.235 + echo "Permessi corretti"
421.236 + exit 0
421.237 + fi
421.238 +fi
422.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
422.2 +++ b/usr/share/isi-checkup/tests/STRUTTURA.txt Mon Apr 26 11:16:23 2010 +0200
422.3 @@ -0,0 +1,92 @@
422.4 + 0 - 100 boot
422.5 +101 - 200 servizi # servisi possibili ma non necessari
422.6 +201 - 400 reteisi # servizi necesari a reteisi
422.7 +501 - 700 user
422.8 +
422.9 +
422.10 +010 disk_space
422.11 +011 need_file_hostname
422.12 +012 need_file_hosts
422.13 +013 need_file_resolve.conf
422.14 +014 need_file_interfaces
422.15 +015 localhost
422.16 +016 need_file_runlevel.conf
422.17 +020 ip
422.18 +021 mii-tool # test che ci sia la connessione
422.19 +
422.20 +110 bind9
422.21 +111 ssh
422.22 +112 dhcp3-server
422.23 + 113 need_file_dhcpd.conf
422.24 +
422.25 +113 S_ldap_secret.py
422.26 + 115 slapd
422.27 + 116 S_sameSecrets.sh
422.28 +
422.29 +
422.30 +116 samba
422.31 +117 nmbd
422.32 + 118 need_file_smb.conf
422.33 + 119 S_netbiosIsHostname.sh
422.34 +
422.35 +120 squid
422.36 + 121 need_file_squid.conf
422.37 + 122 S_squid_parmExist.py
422.38 +
422.39 +
422.40 +123 dansguardian
422.41 + 124 need_file_dansguardian.conf
422.42 +
422.43 +125 postfix
422.44 + 126 S_postfixcheck.sh
422.45 +
422.46 +201 need_dir_home
422.47 + 201 need_dir_users
422.48 + 205 need_dir_alunni
422.49 + 206 need_dir_docenti
422.50 + 207 need_dir_admins
422.51 +
422.52 + 220 need_dir_shares
422.53 + 225 need_dir_classi
422.54 + 226 need_dir_area_alunni
422.55 + 227 need_dir_area_docenti
422.56 +
422.57 +
422.58 + 230 need_file_ldap.secret
422.59 + 231 need_file_libnss-ldap.secret
422.60 + 232 need_file_pam_ldap.secret
422.61 +
422.62 +250 need_file_logon.conf
422.63 +251 need_file_logon.bat
422.64 +252 need_file_acl.conf
422.65 +
422.66 +260 need_process_slapd
422.67 +261 need_process_sshd
422.68 +262 need_process_dhcpd3
422.69 +263 need_process_smbd
422.70 +264 need_process_nmbd
422.71 +265 need_process_squid
422.72 +266 need_process_dansguardian
422.73 +267 need_process_master
422.74 +268 need_process_named
422.75 +
422.76 +270
422.77 +271 samba_share_homes
422.78 +272 samba_share_netlogon
422.79 +273 samba_share_software
422.80 +274 samba_share_dati
422.81 +275 samba_share_classi
422.82 +276 samba_share_corsi
422.83 +277 samba_share_perl
422.84 +278 samba_share_printers
422.85 +279 samba_share_area_alunni
422.86 +280 samba_share_area_docenti
422.87 +281 samba_share_area_segreteria
422.88 +
422.89 +330 group_exist_docenti
422.90 +331 group_exist_alunni
422.91 +332 group_exist_admins
422.92 +
422.93 +501 T_firefoxCfg.py
422.94 +502 U_check_rwx2.sh
422.95 +503 U_check_rwx.sh
423.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
423.2 +++ b/web/.hgignore Mon Apr 26 11:16:23 2010 +0200
423.3 @@ -0,0 +1,7 @@
423.4 +mako_modules
423.5 +static/js/OLD
423.6 +static/img-old
423.7 +static/css/ui/themes/base
423.8 +static/css/ui/themes/ui*
423.9 +static
423.10 +local_settings.py
424.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
424.2 +++ b/web/data/boot Mon Apr 26 11:16:23 2010 +0200
424.3 @@ -0,0 +1,27 @@
424.4 +# le prossime sono quelle che servono
424.5 +# in particolare ai thin client
424.6 +# root-path (17)
424.7 +# percorso dove montare la partizione root
424.8 +dhcp-option=17,"/opt/ltsp/i386"
424.9 +
424.10 +# file di boot (percorso relativo alla root del server tftp),
424.11 +# nome tftp server, ip tftp server
424.12 +# l'indirizzo e il nome del server
424.13 +# devono essere inseriti in /etc/hosts
424.14 +dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
424.15 +
424.16 +# file di boot (percorso relativo alla root del server tftp),
424.17 +# nome tftp server, ip tftp server
424.18 +# l'indirizzo e il nome del server
424.19 +# devono essere inseriti in /etc/hosts
424.20 +#dhcp-boot=/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
424.21 +
424.22 +# PXE / Etherboot
424.23 +dhcp-vendorclass=pxe,PXEClient
424.24 +dhcp-vendorclass=eth,Etherboot
424.25 +# dhcp-option=vendor:PXEClient,1,0.0.0.0
424.26 +dhcp-boot=net:pxe,/ltsp/i386/pxelinux.0,ltsp-server,192.168.96.222
424.27 +dhcp-boot=net:eth,/ltsp/i386/pxelinux.0,ltsp-server, 192.168.96.222
424.28 +
424.29 +# other
424.30 +dhcp-boot=/ltsp/i386/nbi.img,ltsp-server,192.168.96.222
424.31 \ No newline at end of file
425.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
425.2 +++ b/web/data/dnsmasq.conf Mon Apr 26 11:16:23 2010 +0200
425.3 @@ -0,0 +1,101 @@
425.4 +# -*- mode: conf -*-
425.5 +# non inoltrare mai ai server dns esterni
425.6 +# query senza nome dominio
425.7 +domain-needed
425.8 +
425.9 +# Tutti i reverse lookup per la subnet privata
425.10 +# non presenti in /etc/hosts o nei lease dhcp
425.11 +# ottengono "host not found"
425.12 +# invece di essere inoltrati ai dns esterni
425.13 +bogus-priv
425.14 +
425.15 +# Filtra le ricorrenti richieste SOA, SRV e altre,
425.16 +# provenienti da macchine windows
425.17 +# serve in particolare a non attivare
425.18 +# per sbaglio il link quando si
425.19 +# hanno connessioni "on demand"
425.20 +filterwin2k
425.21 +
425.22 +# server dns esterni di riferimento
425.23 +# inserire i server dns uno per riga
425.24 +# usati in questo caso i server di opendns.org
425.25 +server=208.67.220.220
425.26 +server=208.67.220.220
425.27 +
425.28 +# aggiunge sempre il nome dominio al nome host
425.29 +expand-hosts
425.30 +
425.31 +# nome del mio dominio
425.32 +domain=vega.it
425.33 +
425.34 +# Se si intende passare ai client un dominio differente
425.35 +# dhcp-option=option:domain-name,isi.lan
425.36 +
425.37 +# range dei lease dhcp: indirizzo iniziale, indirizzo finale, netmask, durata del lease
425.38 +dhcp-range=192.168.96.130,192.168.96.140,255.255.255.0,8h
425.39 +
425.40 +# Range dhcp per-tag
425.41 +# ~~~~~~~~~~~~~~~~~~~
425.42 +# E` anche possibile riservare un determinato range filtrando per TAG.
425.43 +# I tag possono essere associati anche ad un'intera famiglia di indirizzi MAC
425.44 +# Ciò risulta utilissimo, ad esempio, per limitare le macchine virtuali vmware
425.45 +# ad un certo range.
425.46 +#
425.47 +# Settare il tag "macchinevmware" per le macchine con mac iniziante per
425.48 +# 00:0c:29:*:*:* (gruppo di indirizzi mac riservati a vmware)
425.49 +#
425.50 +# dhcp-mac=macchinevmware,00:0c:29:*:*:*
425.51 +#
425.52 +# Sintassi ::
425.53 +#
425.54 +# dhcp-range=[[net:]network-id,]<start-addr>,<end-addr>[[,<net‐netmask>],<broadcast>][,<lease time>]
425.55 +#
425.56 +# Esempio ::
425.57 +#
425.58 +# dhcp-range=net:macchinevmware,192.168.150,160,255.255.255.0,8h
425.59 +
425.60 +
425.61 +# Esempio di ip-reservation per client
425.62 +#
425.63 +# MAC address, indirizzo, nome host, tag(utile per associare a più server)
425.64 +#
425.65 +# dhcp-host=00:0c:29:c9:69:35,192.168.96.190,vm-ltsp01,net:ns1 # client1
425.66 +# dhcp-host=00:0c:29:5e:69:b5,192.168.96.191,vm-ltsp02,net:ns2 # client2
425.67 +#
425.68 +# le associazioni vengono definite esternamente, vedi inclusioni a fine file.
425.69 +# il file usato è /etc/isi/dns/dnsmasq/hosts.mac
425.70 +
425.71 +# dnsmasq supporta la maggior parte delle
425.72 +# opzioni dhcp e bootp specificate in
425.73 +# http://www.faqs.org/rfcs/rfc2132.html
425.74 +# la sintassi e':
425.75 +# dhcp-option=[numero relativo all'opzione],parametro
425.76 +
425.77 +# GATEWAY di default (3)
425.78 +dhcp-option=44,192.168.96.253
425.79 +
425.80 +# DNS da passare ai client (6)
425.81 +dhcp-option=6,192.168.96.254
425.82 +
425.83 +# WINS da passare ai client (44)
425.84 +dhcp-option=44,192.168.96.253
425.85 +#
425.86 +# Il server dhcp sarà AUTORITATIVO.
425.87 +dhcp-authoritative
425.88 +cache-size=1024
425.89 +### LOG
425.90 +# da usare per debug
425.91 +# log-queries
425.92 +
425.93 +# Da abilitare *solo* in caso di debug, logga tutte le transazioni che avvengono
425.94 +# tra servente DHCP e i client.
425.95 +#
425.96 +# log-dhcp
425.97 +
425.98 +# Configurazione aggiuntiva per isi.
425.99 +conf-dir=/etc/isi/dns/dnsmasq
425.100 +addn-hosts=/etc/isi/dns/hosts
425.101 +
425.102 +# Per includere ulteriori configurazioni...
425.103 +# conf-file=/etc/dnsmasq.more.conf
425.104 +# conf-dir=/etc/dnsmasq.d
425.105 \ No newline at end of file
426.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
426.2 +++ b/web/data/hosts Mon Apr 26 11:16:23 2010 +0200
426.3 @@ -0,0 +1,9 @@
426.4 +127.0.0.1 localhost
426.5 +127.0.1.1 ISI-PDC
426.6 +192.168.96.222 srv-ltsp
426.7 +192.168.96.22 www.tin.it
426.8 +192.168.96.199 vm-client-ltsp1
426.9 +192.168.96.44 srv-prova srv
426.10 +192.168.5.44 srv-test
426.11 +11.11.1.1 bluffo
426.12 +5.5.5.5 sandro
426.13 \ No newline at end of file
427.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
427.2 +++ b/web/data/hosts.mac Mon Apr 26 11:16:23 2010 +0200
427.3 @@ -0,0 +1,3 @@
427.4 +dhcp-host=00:0c:29:10:a6:45,192.168.96.199,vm-client-ltsp1
427.5 +dhcp-host=00:0c:29:c0:d7:9e,192.168.96.198,vm-client-ltsp2,net:ns1
427.6 +dhcp-host=00:0c:29:10:a6:48,192.168.5.55
427.7 \ No newline at end of file
428.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
428.2 +++ b/web/data/leases Mon Apr 26 11:16:23 2010 +0200
428.3 @@ -0,0 +1,54 @@
428.4 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.5 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.6 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.7 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.8 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.9 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.10 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.11 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.12 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.13 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.14 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.15 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.16 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.17 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.18 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.19 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.20 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.21 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.22 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.23 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.24 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.25 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.26 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.27 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.28 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.29 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.30 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.31 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.32 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.33 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.34 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.35 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.36 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.37 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.38 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.39 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.40 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.41 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.42 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.43 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.44 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.45 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.46 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.47 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.48 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.49 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.50 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.51 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
428.52 +946689575 00:00:00:00:00:05 192.168.1.155 wdt 01:00:00:00:00:00:05
428.53 +946689522 00:00:00:00:00:04 192.168.1.237 * 01:00:00:00:00:00:04
428.54 +946689351 00:0f:b0:3a:b5:0b 192.168.1.208 colinux *
428.55 +946689493 02:0f:b0:3a:b5:0b 192.168.1.199 * 01:02:0f:b0:3a:b5:0b
428.56 +1259870930 00:0c:29:f5:6f:69 192.168.96.135 * *
428.57 +1259870915 00:0c:29:10:a6:45 192.168.96.199 vm-client-ltsp1 *
429.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
429.2 +++ b/web/data/smb.conf Mon Apr 26 11:16:23 2010 +0200
429.3 @@ -0,0 +1,300 @@
429.4 +# -*- outline-regexp: "####\\|\\[..." -*-
429.5 +#
429.6 +#### preamble
429.7 +# Sample configuration file for the ISI project (www.reteisi.org)
429.8 +# derived from samba sample conf for Debian adding LDAP conf for smbdldap-tools
429.9 +#
429.10 +#
429.11 +# This is the main Samba configuration file. You should read the
429.12 +# smb.conf(5) manual page in order to understand the options listed
429.13 +# here. Samba has a huge number of configurable options most of which
429.14 +# are not shown in this example
429.15 +#
429.16 +# Any line which starts with a ; (semi-colon) or a # (hash)
429.17 +# is a comment and is ignored. In this example we will use a #
429.18 +# for commentary and a ; for parts of the config file that you
429.19 +# may wish to enable
429.20 +#
429.21 +# NOTE: Whenever you modify this file you should run the command
429.22 +# "testparm" to check that you have not many any basic syntactic
429.23 +# errors.
429.24 +#
429.25 +
429.26 +#======================= Global Settings =======================
429.27 +
429.28 +[global]
429.29 +
429.30 +## Browsing/Identification/Domain ###
429.31 +
429.32 + workgroup = FOSSATIINTERNI
429.33 + netbios name = srv-fossati
429.34 + domain master = Yes
429.35 + local master = Yes
429.36 + preferred master = Yes
429.37 + os level = 200
429.38 + domain logons = Yes
429.39 + deadtime = 15
429.40 + security = user
429.41 + enable privileges = yes
429.42 + admin users = root # , @admins
429.43 +
429.44 + logon home = \\%N\%U\.\\.profili\%a
429.45 + logon path = \\%N\%U\.profili\%a
429.46 + logon script = logon.bat
429.47 +
429.48 +# logon home = \\%N\%U\.\.profili%a
429.49 + logon drive = H:
429.50 +# logon path = \\%L\profiles
429.51 +
429.52 +
429.53 +# server string is the equivalent of the NT Description field
429.54 + server string = %h server (Samba %v)
429.55 +
429.56 +# Windows Internet Name Serving Support Section:
429.57 +# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
429.58 + wins support = Yes
429.59 +
429.60 +# WINS Server - Tells the NMBD components of Samba to be a WINS Client
429.61 +# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
429.62 +; wins server = w.x.y.z
429.63 +
429.64 +# This will prevent nmbd to search for NetBIOS names through DNS.
429.65 + dns proxy = no
429.66 +
429.67 +# What naming service and in what order should we use to resolve host names
429.68 +# to IP addresses
429.69 + name resolve order = lmhosts host wins bcast
429.70 +
429.71 +
429.72 +#### LDAP #############
429.73 + passdb backend = ldapsam:ldap://127.0.0.1
429.74 + obey pam restrictions = no
429.75 + passwd program = /usr/sbin/smbldap-passwd %u
429.76 + passwd chat = *New*password* %n\n *Retype*new*password* %n\n
429.77 + ldap ssl = no
429.78 + ldap passwd sync = yes
429.79 + ldap machine suffix = ou=Computers
429.80 + ldap idmap suffix = ou=Idmaps
429.81 + ldap group suffix = ou=Groups
429.82 + ldap user suffix = ou=People
429.83 + ldap suffix = dc=isi,dc=lan
429.84 + ldap delete dn = Yes
429.85 + ldap admin dn = cn=admin,dc=isi,dc=lan
429.86 +
429.87 + add machine script = /usr/sbin/smbldap-useradd -w "%m"
429.88 + set primary group script = /usr/sbin/smbldap-usermod -g "%g" "%u"
429.89 + delete user from group script = /usr/sbin/smbldap-groupmod -x "%u" "%g"
429.90 + add user to group script = /usr/sbin/smbldap-groupmod -m "%u" "%g"
429.91 + delete group script = /usr/sbin/smbldap-groupdel "%g"
429.92 + add group script = /usr/sbin/smbldap-groupadd -p "%g"
429.93 + delete user script = /usr/sbin/smbldap-userdel "%u"
429.94 + add user script = /usr/sbin/smbldap-useradd -m "%u"
429.95 +
429.96 +#### Debugging/Accounting ####
429.97 +
429.98 +# This tells Samba to use a separate log file for each machine
429.99 +# that connects
429.100 + log file = /var/log/samba/log.%m
429.101 + log level = 3
429.102 +
429.103 +# Put a capping on the size of the log files (in Kb).
429.104 + max log size = 1000
429.105 +
429.106 +# If you want Samba to only log through syslog then set the following
429.107 +# parameter to 'yes'.
429.108 +; syslog only = no
429.109 +
429.110 +# We want Samba to log a minimum amount of information to syslog. Everything
429.111 +# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
429.112 +# through syslog you should set the following parameter to something higher.
429.113 + syslog = 0
429.114 +
429.115 +# Do something sensible when Samba crashes: mail the admin a backtrace
429.116 + panic action = /usr/share/samba/panic-action %d
429.117 +
429.118 +
429.119 +#### Authentication #######
429.120 +
429.121 +# "security = user" is always a good idea. This will require a Unix account
429.122 +# in this server for every user accessing the server. See
429.123 +# /usr/share/doc/samba-doc/htmldocs/ServerType.html in the samba-doc
429.124 +# package for details.
429.125 +; security = user
429.126 +
429.127 +# You may wish to use password encryption. See the section on
429.128 +# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
429.129 + encrypt passwords = true
429.130 +
429.131 +# If you are using encrypted passwords, Samba will need to know what
429.132 +# password database type you are using.
429.133 +## these settings are 'overloaded' by ldap configuration
429.134 +; passdb backend = tdbsam guest
429.135 +; obey pam restrictions = yes
429.136 +; guest account = nobody
429.137 +; invalid users = root
429.138 +
429.139 +# This boolean parameter controls whether Samba attempts to sync the Unix
429.140 +# password with the SMB password when the encrypted SMB password in the
429.141 +# passdb is changed.
429.142 +; unix password sync = no
429.143 +
429.144 +# For Unix password sync to work on a Debian GNU/Linux system, the following
429.145 +# parameters must be set (thanks to Augustin Luton <[email protected]> for
429.146 +# sending the correct chat script for the passwd program in Debian Potato).
429.147 +; passwd program = /usr/bin/passwd %u
429.148 +; passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n .
429.149 +
429.150 +# This boolean controls whether PAM will be used for password changes
429.151 +# when requested by an SMB client instead of the program listed in
429.152 +# 'passwd program'. The default is 'no'.
429.153 +; pam password change = no
429.154 +
429.155 +
429.156 +#### Printing ##########
429.157 +
429.158 +# If you want to automatically load your printer list rather
429.159 +# than setting them up individually then you'll need this
429.160 +; load printers = yes
429.161 +
429.162 +# lpr(ng) printing. You may wish to override the location of the
429.163 +# printcap file
429.164 +; printing = bsd
429.165 +; printcap name = /etc/printcap
429.166 +
429.167 +# CUPS printing. See also the cupsaddsmb(8) manpage in the
429.168 +# cupsys-client package.
429.169 +; printing = cups
429.170 +; printcap name = cups
429.171 +
429.172 +# When using [print$], root is implicitly a 'printer admin', but you can
429.173 +# also give this right to other users to add drivers and set printer
429.174 +# properties
429.175 +; printer admin = @ntadmin
429.176 +
429.177 +
429.178 +#### File sharing ########
429.179 +
429.180 +# Name mangling options
429.181 +; preserve case = yes
429.182 +; short preserve case = yes
429.183 +
429.184 +
429.185 +#### Misc ############
429.186 +
429.187 +# Using the following line enables you to customise your configuration
429.188 +# of the machine that is connecting
429.189 +; include = /home/samba/etc/smb.conf.%m
429.190 +
429.191 +# Most people will find that this option gives better performance.
429.192 +# See smb.conf(5) and /usr/share/doc/samba-doc/htmldocs/speed.html
429.193 +# for details
429.194 +# You may want to add the following on a Linux system:
429.195 +# SO_RCVBUF=8192 SO_SNDBUF=8192
429.196 + socket options = TCP_NODELAY
429.197 +
429.198 +# The following parameter is useful only if you have the linpopup package
429.199 +# installed. The samba maintainer and the linpopup maintainer are
429.200 +# working to ease installation and configuration of linpopup and samba.
429.201 +; message command = /bin/sh -c '/usr/bin/linpopup "%f" "%m" %s; rm %s' &
429.202 +
429.203 +# Domain Master specifies Samba to be the Domain Master Browser. If this
429.204 +# machine will be configured as a BDC (a secondary logon server), you
429.205 +# must set this to 'no'; otherwise, the default behavior is recommended.
429.206 +; domain master = auto
429.207 +
429.208 +# Some defaults for winbind (make sure you're not using the ranges
429.209 +# for something else.)
429.210 +; idmap uid = 10000-20000
429.211 +; idmap gid = 10000-20000
429.212 +; template shell = /bin/bash
429.213 +
429.214 +#======================= Share Definitions =======================
429.215 +
429.216 +[homes]
429.217 + comment = ISI-homes (NON MODIFICARE QUESTA RIGA)
429.218 + browseable = no
429.219 + writable = yes
429.220 + guest ok = no
429.221 + #veto files = /public_html/
429.222 +
429.223 +[netlogon]
429.224 + comment = ISI-NetLogon (NON MODIFICARE QUESTA RIGA)
429.225 + path = /home/samba/netlogon
429.226 + guest ok = yes
429.227 + browseable = no
429.228 + create mask = 0644
429.229 + directory mask = 0755
429.230 + writable = yes
429.231 + root preexec=/usr/sbin/setlogonvar '%U' '%G' '%m'
429.232 + root postexec=/usr/sbin/rmlogonvar '%m'
429.233 +
429.234 +[perl]
429.235 + path = /usr/share/WinActivePerl
429.236 + comment = Per Windows Binaries
429.237 + public = yes
429.238 + writable = no
429.239 + guest ok = yes
429.240 + browseable = no
429.241 +
429.242 +[printers]
429.243 + comment = All Printers
429.244 + browseable = no
429.245 + path = /tmp
429.246 + printable = yes
429.247 + public = no
429.248 + writable = no
429.249 + create mode = 0700
429.250 +
429.251 +# Windows clients look for this share name as a source of downloadable
429.252 +# printer drivers
429.253 +
429.254 +[print$]
429.255 + comment = Printer Drivers
429.256 + path = /var/lib/samba/printers
429.257 + browseable = yes
429.258 + read only = yes
429.259 + guest ok = no
429.260 +# Uncomment to allow remote administration of Windows print drivers.
429.261 +# Replace 'ntadmin' with the name of the group your admin users are
429.262 +# members of.
429.263 +; write list = root, @ntadmin
429.264 +
429.265 +# A sample share for sharing your CD-ROM with others.
429.266 +;[cdrom]
429.267 +; comment = Samba server's CD-ROM
429.268 +; writable = no
429.269 +; locking = no
429.270 +; path = /cdrom
429.271 +; public = yes
429.272 +
429.273 +# The next two parameters show how to auto-mount a CD-ROM when the
429.274 +# cdrom share is accesed. For this to work /etc/fstab must contain
429.275 +# an entry like this:
429.276 +#
429.277 +# /dev/scd0 /cdrom iso9660 defaults,noauto,ro,user 0 0
429.278 +#
429.279 +# The CD-ROM gets unmounted automatically after the connection to the
429.280 +#
429.281 +# If you don't want to use auto-mounting/unmounting make sure the CD
429.282 +# is mounted on /cdrom
429.283 +#
429.284 +; preexec = /bin/mount /cdrom
429.285 +; postexec = /bin/umount /cdrom
429.286 +
429.287 +[gestionale]
429.288 + comment = software gestionale
429.289 + path = /home/shares/software/gestionale/lib
429.290 + browseable = yes
429.291 + writable = yes
429.292 +
429.293 +
429.294 +#### includes
429.295 +include = /etc/isi/samba/smb_servizi.conf
429.296 +include = /etc/isi/samba/smb_maingrps.conf
429.297 +include = /etc/isi/samba/smb_classi.conf
429.298 +include = /etc/isi/samba/smb_corsi.conf
429.299 +include = /etc/isi/samba/smb_aree.conf
429.300 +
429.301 +#### The End *;-)
429.302 +## DEBCONF CONFIGURED by isi-ldap3
429.303 +
430.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
430.2 +++ b/web/dnsmasq/dns_form.py Mon Apr 26 11:16:23 2010 +0200
430.3 @@ -0,0 +1,218 @@
430.4 +# -*- coding: utf-8 -*-
430.5 +
430.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
430.7 +#
430.8 +# This program is free software: you can redistribute it and/or modify
430.9 +# it under the terms of the GNU General Public License as published by
430.10 +# the Free Software Foundation, either version 3 of the License, or
430.11 +# (at your option) any later version.
430.12 +#
430.13 +# This program is distributed in the hope that it will be useful,
430.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
430.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
430.16 +# GNU General Public License for more details.
430.17 +#
430.18 +# You should have received a copy of the GNU General Public License
430.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
430.20 +
430.21 +
430.22 +"""
430.23 +# GATEWAY di default (3)
430.24 +dhcp-option=3,192.168.96.1
430.25 +
430.26 +# DNS da passare ai client (6)
430.27 +dhcp-option=6,192.168.96.254
430.28 +
430.29 +# WINS da passare ai client (44)
430.30 +dhcp-option=44,192.168.96.253
430.31 +"""
430.32 +
430.33 +from django import forms
430.34 +from django.forms import util
430.35 +from django.conf import settings
430.36 +from isi.conf import dnsmasq, tools, hosts, mac
430.37 +from django.contrib import messages
430.38 +from isiweb.logger import logger
430.39 +
430.40 +
430.41 +SIMPLE_PARAMS = ['domain-needed', 'bogus-priv', 'filterwin2k', 'expand-hosts', 'dhcp-authoritative']
430.42 +PARAMS = ['server', 'domain', 'dhcp-range', 'dhcp-host', 'dhcp-option', 'cache-size', 'conf-dir',
430.43 + 'addn-hosts', 'conf-file', 'conf-dir']
430.44 +
430.45 +auth_tip = u"""dhcp_autoritative|Deve essere 'True' per il corretto funzionamento di ReteISI.
430.46 + Indica se -in presenza di altri dhcp server- questo deve comunicare la sua priorità.
430.47 + Avere più dhcp server nella stessa rete porta normalmente a guai ed è quindi sconsigliato"""
430.48 +
430.49 +tips = {
430.50 + 'gw' : 'Gateway /Router|Il default gateway passato dal dhcp',
430.51 + 'domain' : 'Domain|il dominio internet passato dal dhcp',
430.52 + 'wins' : 'Wins Server|Il winserver usato dai client per la risoluzione delle risorse Windows',
430.53 + 'dhcp_authoritative' : auth_tip,
430.54 + 'dns' : "Dns|Il server dns per i client (deve puntare a questa versione di dnsmasq",
430.55 + 'server' : u"Server|DNS esterni cui verranno inoltrate le domande dns per le quali questo server dnsmasq non è autoritativo",
430.56 + }
430.57 +
430.58 +def get_data(filename):
430.59 +
430.60 + data = {}
430.61 + conf = dnsmasq.Conf(filename)
430.62 +
430.63 + data['server'] = " ".join([l.value for l in conf.get_param('server')])
430.64 + data['domain'] = conf.get_param('domain')[0].value
430.65 + data['dhcp_authoritative'] = bool(conf.get_param('domain'))
430.66 + data['gw'] = conf.get_option('gw')
430.67 + data['wins'] = conf.get_option('wins')
430.68 + data['dns'] = conf.get_option('dns')
430.69 + data['dhcp_range'] = conf.get_param('dhcp-range')[0].value
430.70 +
430.71 + return data
430.72 +
430.73 +class DnsForm(forms.Form):
430.74 +
430.75 +# domain_needed = forms.BooleanField()
430.76 +# bogus_priv = forms.BooleanField()
430.77 +# filterwin2k = forms.BooleanField()
430.78 +# expand_hosts = forms.BooleanField()
430.79 + dhcp_authoritative = forms.BooleanField(help_text=auth_tip, required=False)
430.80 +
430.81 + server = forms.CharField(max_length=100,help_text=tips['server'])
430.82 + domain = forms.CharField(max_length=100,)
430.83 +# chache_size = forms.CharField(max_length=10,)
430.84 +# conf_dir = forms.CharField(max_length=10,)
430.85 +
430.86 + dns = forms.IPAddressField()
430.87 + gw = forms.IPAddressField()
430.88 + wins = forms.IPAddressField()
430.89 + dhcp_range = forms.CharField(max_length=150, help_text="start_ip, end_ip, metmask, time:\n192.168.1.100,192.168.1.200,255.255.255.0,8h")
430.90 +
430.91 + def clean_server(self):
430.92 +
430.93 + servers = self.cleaned_data['server'].split()
430.94 + for srv in servers:
430.95 + if not tools.is_ip_address(srv):
430.96 + raise util.ValidationError(u"%s non è un IP valido" % srv)
430.97 + return servers
430.98 +
430.99 + def save(self):
430.100 +
430.101 + conf = dnsmasq.Conf(settings.DNSMASQ_CONF)
430.102 + for srv in self.cleaned_data['server']:
430.103 + conf.set_param('server', value=srv)
430.104 +
430.105 + conf.set_param('domain', self.cleaned_data['domain'])
430.106 + conf.set_param('dhcp-range', self.cleaned_data['dhcp_range'])
430.107 + conf.set_option('gw', self.cleaned_data['gw'])
430.108 + conf.set_option('dns', self.cleaned_data['dns'])
430.109 + conf.set_option('wins', self.cleaned_data['wins'])
430.110 + ## impongo dhcp-autoritative
430.111 + conf.set_param('dhcp-authoritative')
430.112 +
430.113 + conf.save()
430.114 +
430.115 +
430.116 +
430.117 +class HostForm(forms.Form):
430.118 +
430.119 + ip = forms.IPAddressField(help_text="Inserire l'IP della macchina di cui si vuole impostare la risoluzione")
430.120 + hostname = forms.CharField(max_length=100, help_text="Inserire il nome della macchina (possibili anche alias)")
430.121 +
430.122 + def save(self):
430.123 +
430.124 + conf = hosts.Hosts(settings.HOSTS_CONF)
430.125 + conf.set_param(self.cleaned_data['ip'], self.cleaned_data['hostname'])
430.126 + conf.save()
430.127 +
430.128 +OPTIONS = (
430.129 + ('dhcp-boot',)*2,
430.130 + ('dhcp-option',)*2,
430.131 + ('dhcp-vendorclass',)*2,
430.132 + )
430.133 +
430.134 +class BootLineForm(forms.Form):
430.135 +
430.136 + index = forms.IntegerField()
430.137 + param_name = forms.ChoiceField(help_text="Nome del parametro", choices=OPTIONS)
430.138 + value = forms.CharField(max_length=100, required=False,
430.139 + help_text="|Opzione completa di boot per sintassi dnsmasq")
430.140 + tag = forms.CharField(max_length=20, required=False,
430.141 + help_text="Tag dnsmasq|Es.: fat_ns1, thin_srv2")
430.142 + image = forms.CharField(max_length=40, required=False, initial='/ltsp/i386/pxelinux.0',
430.143 + help_text="Image|Deve esistere la corrispondente immagine/chroot. Questo parameto decide se fat/thin")
430.144 + server = forms.IPAddressField(required=False,
430.145 + help_text="Server|Inserire nome server (se correttamente risolto) o IP")
430.146 +
430.147 + def clean(self):
430.148 + value = self.cleaned_data.get('value')
430.149 + tag = self.cleaned_data.get('tag')
430.150 + image = self.cleaned_data.get('image') or '/ltsp/i386/pxelinux.0'
430.151 + server = self.cleaned_data.get('server')
430.152 +
430.153 + if not value:
430.154 + if not tag or not ip_server:
430.155 + raise util.ValidationError(u'Devi scrivere tag e ip del server')
430.156 + self.cleaned_data['value'] = "net:%s,%s,%s" % (tag, image, server)
430.157 + return self.cleaned_data
430.158 +
430.159 + def save(self):
430.160 + param_name = self.cleaned_data.get('param_name')
430.161 + value = self.cleaned_data.get('value')
430.162 + index = self.cleaned_data.get('index')
430.163 +
430.164 +
430.165 + conf = dnsmasq.Conf(settings.BOOT_CONF)
430.166 + line = dnsmasq.Line(param_name=param_name, value=value)
430.167 + conf.lines.insert(index + 1, line)
430.168 + conf.save()
430.169 +
430.170 + def update(self):
430.171 + param_name = self.cleaned_data.get('param_name')
430.172 + value = self.cleaned_data.get('value')
430.173 + index = self.cleaned_data.get('index')
430.174 +
430.175 + conf = dnsmasq.Conf(settings.BOOT_CONF)
430.176 + line = dnsmasq.Line(param_name=param_name, value=value)
430.177 + conf.lines[index] = line
430.178 + conf.save()
430.179 +
430.180 +class MacForm(forms.Form):
430.181 +
430.182 + mac = forms.CharField(help_text="MAC|Inserire il MACe della macchina di cui si vuole impostare il valore")
430.183 + ip = forms.IPAddressField(help_text="IP|Inserire l'IP della macchina di cui si vuole impostare la risoluzione",
430.184 + required=False)
430.185 + value = forms.CharField(max_length=100, required=False,
430.186 + help_text="Value|Inserire il nome della macchina (possibili anche alias)")
430.187 + tag = forms.CharField(max_length=20, required=False, help_text="Tag dnsmasq (net:)|Es. fat_ns1, thin_srv2. Deve esistere una corrispondente boot-option")
430.188 +
430.189 +
430.190 + def clean_mac(self):
430.191 +
430.192 + mac = self.cleaned_data['mac']
430.193 + if tools.is_mac_address(mac):
430.194 + return mac
430.195 + raise util.ValidationError(u"'%s' non è un mac address" % mac)
430.196 +
430.197 + def clean_tag(self):
430.198 +
430.199 + if self.cleaned_data['tag']:
430.200 + return "net:%s" % self.cleaned_data['tag']
430.201 + return None
430.202 +
430.203 + def clean(self):
430.204 + tag = self.cleaned_data.get('tag')
430.205 + mac = self.cleaned_data.get('mac')
430.206 + ip = self.cleaned_data.get('ip')
430.207 +
430.208 + if not self.cleaned_data.get('value'):
430.209 + if not ip and not tag:
430.210 + raise util.ValidationError("Occorre definire almeno o l'IP o il tag")
430.211 + self.cleaned_data['value'] = ",".join([x for x in (mac, ip, tag) if x])
430.212 +
430.213 + return self.cleaned_data
430.214 +
430.215 + def save(self):
430.216 + conf = mac.Mac(settings.MAC_CONF)
430.217 + line = conf.set_param('dhcp-host', self.cleaned_data['value'])
430.218 + conf.save()
430.219 + logger.debug("Added %s" % line)
430.220 + return line
430.221 +
431.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
431.2 +++ b/web/dnsmasq/models.py Mon Apr 26 11:16:23 2010 +0200
431.3 @@ -0,0 +1,3 @@
431.4 +from django.db import models
431.5 +
431.6 +# Create your models here.
432.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
432.2 +++ b/web/dnsmasq/templates/dnsmasq/boot_form.mako Mon Apr 26 11:16:23 2010 +0200
432.3 @@ -0,0 +1,24 @@
432.4 +<%inherit file="${jun.get_parent_template(context)}"/>
432.5 +
432.6 +<%def name="title()">Configurazione boot</%def>
432.7 +
432.8 +<%def name="layout()">
432.9 +
432.10 +param_name
432.11 +h=index=$!?index
432.12 +value
432.13 +tag
432.14 +image
432.15 +server
432.16 +--
432.17 +s=Salva
432.18 +
432.19 +</%def>
432.20 +
432.21 +${jun.show_form_errors(form)}
432.22 +${forms.mako_create_nform(context, layout, form, style='-')}
432.23 +
432.24 +
432.25 +<script type="text/javascript" >
432.26 + $('td label[title]').cluetip({splitTitle: '|'});
432.27 +</script>
433.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
433.2 +++ b/web/dnsmasq/templates/dnsmasq/dnsmasq_form.mako Mon Apr 26 11:16:23 2010 +0200
433.3 @@ -0,0 +1,26 @@
433.4 +<%inherit file="${jun.get_parent_template(context)}"/>
433.5 +
433.6 +<%def name="title()">Configurazione dhcp </%def>
433.7 +
433.8 +<%def name="layout()">
433.9 +
433.10 +server:100
433.11 +domain
433.12 +## dhcp_authoritative
433.13 +gw
433.14 +wins
433.15 +dns
433.16 +dhcp_range
433.17 +--
433.18 +s=Aggiorna
433.19 +
433.20 +</%def>
433.21 +${jun.show_form_errors(form)}
433.22 +${forms.mako_create_nform(context, layout, form, style='-')}
433.23 +
433.24 +
433.25 +<script type="text/javascript" >
433.26 +$(document).ready(function () {
433.27 + $('td label[title]').cluetip({splitTitle: '|'});
433.28 +});
433.29 +</script>
434.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
434.2 +++ b/web/dnsmasq/templates/dnsmasq/dnsmasq_list.mako Mon Apr 26 11:16:23 2010 +0200
434.3 @@ -0,0 +1,263 @@
434.4 +<%inherit file="${jun.get_parent_template(context)}"/>
434.5 +
434.6 +<%def name="dhcp()">
434.7 +
434.8 +
434.9 +<div style="margin-bottom: 40px">
434.10 +<form action="/dnsmasq/restart/">
434.11 + <input type="submit" class="submit ui-button ui-widget" value="Riavvia DnsMasq" name="Riavvia">
434.12 +</form>
434.13 +</div>
434.14 +
434.15 +<p>
434.16 +Questi parametri verranno usati per
434.17 + <table>
434.18 + <thead>
434.19 + <tr>
434.20 + <th>Parametro</th>
434.21 + <th>Valore</th>
434.22 + </tr>
434.23 + </thead>
434.24 + <tbody>
434.25 +
434.26 + % for key, value in dnsdata.iteritems():
434.27 + <tr>
434.28 + <td class="title" title="${tips.get(key, '')}"><b>${key.title()}:</b></td>
434.29 + <td>${value}</td>
434.30 + </tr>
434.31 + % endfor
434.32 +
434.33 + </tbody>
434.34 + </table>
434.35 +
434.36 + <div class="actions">
434.37 + ${jun.popup_link('/dnsmasq/set_dhcp/?'+ '&popup', txt="Modifica la configurazione", icon='edit')}
434.38 + </div> <!-- actions -->
434.39 +
434.40 +</%def>
434.41 +
434.42 +<%def name="mac()">
434.43 + <table>
434.44 + <thead>
434.45 + <tr>
434.46 + <th></th>
434.47 + <th>Parametro</th>
434.48 + <th>Valore</th>
434.49 + </tr>
434.50 + </thead>
434.51 + <tbody>
434.52 + % for mac, value in macs:
434.53 + <tr>
434.54 + <td>${jun.popup_link('/dnsmasq/mac/del/%s/?' % mac+ "&popup", icon='del')}</td>
434.55 + <td><b>${mac}</b></td>
434.56 + <td>${value}</td>
434.57 + </tr>
434.58 + % endfor
434.59 +
434.60 + </tbody>
434.61 + </table>
434.62 +
434.63 + <div class="actions">
434.64 + ${jun.popup_link('/dnsmasq/mac/add/?'+ "&popup", icon='add', txt='Aggiungi un abbinamento mac/ip')}
434.65 + </div> <!-- actions -->
434.66 +
434.67 +</%def>
434.68 +<%def name="leases_tab()">
434.69 + <table class="tbldata">
434.70 + <thead>
434.71 + <tr>
434.72 + <th>Mac</th>
434.73 + <th>IP</th>
434.74 + <th>Hostname</th>
434.75 + <th>Client ID</th>
434.76 + </tr>
434.77 + </thead>
434.78 + <tbody>
434.79 + % for lease in leases:
434.80 + <tr>
434.81 + <td>${lease.mac}</td>
434.82 + <td>${lease.ip}</td>
434.83 + <td>${lease.hostname or ''}</td>
434.84 + <td>${lease.client_id or ''}</td>
434.85 + </tr>
434.86 + % endfor
434.87 +
434.88 + </tbody>
434.89 + </table>
434.90 +</%def>
434.91 +
434.92 +<%def name="boot()">
434.93 +
434.94 + <div class="ui-state-error" style="padding: 15px;">In questa sezione è importante l'ordine dei parametri</div>
434.95 +
434.96 + Qui potete aggiungere server e corrispondenze fra server, tag e immagini
434.97 + da caricare.
434.98 +
434.99 + <table class="">
434.100 + <thead>
434.101 + <tr>
434.102 + <th>Option</th>
434.103 + <th>Value</th>
434.104 + <th>Azione</th>
434.105 + </tr>
434.106 + </thead>
434.107 + <tbody>
434.108 + % for line in [x for x in boot_conf.lines if not x.is_comment]:
434.109 + <tr>
434.110 + <td>${line.param_name}</td>
434.111 + <td>${line.value}</td>
434.112 + <td>
434.113 + ${jun.popup_link('/dnsmasq/boot/add/%s/?popup'% boot_conf.lines.index(line), icon='add')}
434.114 + ${jun.popup_link('/dnsmasq/boot/del/%s/?popup'% boot_conf.lines.index(line), icon='del')}
434.115 + ${jun.popup_link('/dnsmasq/boot/edit/%s/?popup'% boot_conf.lines.index(line), icon='edit')}
434.116 + </td>
434.117 + </tr>
434.118 + % endfor
434.119 +
434.120 + </tbody>
434.121 + </table>
434.122 +</%def>
434.123 +
434.124 +
434.125 +<%def name="sezione(sez)">
434.126 + <div id="${sez}" class="tab">
434.127 + % if sez == 'dhcp':
434.128 + ${self.dhcp()}
434.129 + % elif sez == 'dns':
434.130 + ${self.dns()}
434.131 + % elif sez == 'mac':
434.132 + ${self.mac()}
434.133 + % elif sez == 'boot':
434.134 + ${self.boot()}
434.135 + % else:
434.136 + ${self.leases_tab()}
434.137 + % endif
434.138 + </div>
434.139 +</%def>
434.140 +
434.141 +<div id="tabs">
434.142 + <ul >
434.143 + <li><a href="#dhcp">dhcp</a></li>
434.144 + <li><a href="#dns">dns</a></li>
434.145 + <li><a href="#mac">mac</a></li>
434.146 + <li><a href="#boot">boot/ltsp</a></li>
434.147 + <li><a href="#leases">leases</a></li>
434.148 + </ul>
434.149 + %for sez in ('dhcp', 'dns', 'mac', 'boot','leases'):
434.150 + ${self.sezione(sez)}
434.151 + %endfor
434.152 +
434.153 +</div> <!-- tabs -->
434.154 +
434.155 +<script type="text/javascript" >
434.156 +$(document).ready(function () {
434.157 +
434.158 + $('#tabs').tabs();
434.159 + $('#tabs li > a').click(function () {document.location.hash = this.href; });
434.160 + $('td.title').cluetip({splitTitle: '|'});
434.161 +## $('td.title').cluetip({splitTitle: '|', sticky: true, closePosition: 'title', arrows: true });
434.162 +
434.163 + $('.toggle').click(function(){
434.164 + $('.advanced').toggle();
434.165 + });
434.166 +
434.167 + $('.tbldata').dataTable( {
434.168 +## "aaSorting": [[0,'asc'],],
434.169 + "bPaginate": false,
434.170 + "bLengthChange": 25,
434.171 + "bFilter": true,
434.172 + "bSort": true,
434.173 + "bInfo": true,
434.174 + "sDom": 'ft',
434.175 +
434.176 + "bJQueryUI": false,
434.177 + "bAutoWidth": true }
434.178 + );
434.179 +
434.180 +
434.181 +});
434.182 +</script>
434.183 +
434.184 +<%def name="dns()">
434.185 + <table class="tbldata">
434.186 + <thead>
434.187 + <tr>
434.188 + <th></th>
434.189 + <th>Parametro</th>
434.190 + <th>Valore</th>
434.191 + </tr>
434.192 + </thead>
434.193 + <tbody>
434.194 + % for ip, name in hosts:
434.195 + <tr>
434.196 + <td>${jun.popup_link('/dnsmasq/host/del/%s/?&popup' % ip, icon='del')}</td>
434.197 + <td>${ip}</td>
434.198 + <td>${name}</td>
434.199 + </tr>
434.200 + % endfor
434.201 +
434.202 + </tbody>
434.203 + </table>
434.204 +
434.205 + <div class="actions">
434.206 +## <a href="/dnsmasq/host/add/?" class="dialog-form" title="Aggiungi host">Aggiungi un host con ajax</a>
434.207 + ${jun.popup_link('/dnsmasq/host/add/?'+ "&popup", icon='add', txt='Aggiungi un host')}
434.208 + </div> <!-- actions -->
434.209 +</%def>
434.210 +
434.211 +<%def name="ajax_form()">
434.212 +<script type="text/javascript" >
434.213 +$(document).ready(dialogForms);
434.214 +
434.215 +function dialogForms1() {
434.216 + $('a.dialog-form').click(function() {
434.217 + var a = $(this);
434.218 + $.get(a.attr('href'),function(resp){
434.219 + var dialog = $('<div>').attr('id','formDialog').html(resp);
434.220 + $('body').append(dialog);
434.221 + dialog.find(':submit').hide();
434.222 + dialog.dialog({
434.223 + title: a.attr('title') ? a.attr('title') : '',
434.224 + modal: true,
434.225 + autoOpen: false,
434.226 + buttons: {
434.227 + 'Save': function() {submitFormWithAjax($(this).find('form'));},
434.228 + 'Cancel': function() {$(this).dialog('close');}
434.229 + },
434.230 + close: function() {$(this).remove();},
434.231 + width: 'auto'
434.232 + });
434.233 + }, 'html');
434.234 + return false;
434.235 + });
434.236 +}
434.237 +
434.238 +function dialogForms() {
434.239 + $('a.dialog-form').click(function() {
434.240 + var a = $(this);
434.241 + $('#ajdialog').load(a.attr('href') + 'nt=1').dialog({
434.242 + title: a.attr('title') ? a.attr('title') : '',
434.243 + modal: true,
434.244 + buttons: {
434.245 + 'Save': function() {submitFormWithAjax($(this).find('form'));},
434.246 + 'Cancel': function() {$(this).dialog('close');}
434.247 + },
434.248 + close: function() {$(this).remove();},
434.249 + width: 'auto'
434.250 + });
434.251 + return false;
434.252 + });
434.253 +}
434.254 +
434.255 +function submitFormWithAjax(form) {
434.256 + form = $(form);
434.257 + $.post(form.baseURI, function (resp) {
434.258 + $('#ajdialog').html(resp)
434.259 + }).serialize();
434.260 + return false;
434.261 +}
434.262 +</script>
434.263 +</%def>
434.264 +## ${self.ajax_submit()}
434.265 +
434.266 +<div id="ajdialog"></div>
435.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
435.2 +++ b/web/dnsmasq/templates/dnsmasq/host_form.mako Mon Apr 26 11:16:23 2010 +0200
435.3 @@ -0,0 +1,21 @@
435.4 +<%inherit file="${jun.get_parent_template(context)}"/>
435.5 +
435.6 +<%def name="title()">Configurazione dhcp </%def>
435.7 +
435.8 +<%def name="layout()">
435.9 +
435.10 +hostname
435.11 +ip
435.12 +--
435.13 +s=Aggiungi
435.14 +
435.15 +</%def>
435.16 +
435.17 +<style>
435.18 +http://localhost:8000/static/css/ui/themes/isi/ui.theme.css
435.19 +</style>
435.20 +##<h2>${title()}</h2>
435.21 + ${jun.show_form_errors(form)}
435.22 + ${forms.mako_create_nform(context, layout, form, action="/dnsmasq/host/add/?nt=1", style='-')}
435.23 +
435.24 +
436.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
436.2 +++ b/web/dnsmasq/templates/dnsmasq/mac_form.mako Mon Apr 26 11:16:23 2010 +0200
436.3 @@ -0,0 +1,39 @@
436.4 +<%inherit file="${jun.get_parent_template(context)}"/>
436.5 +
436.6 +<%def name="title()">Configurazione dhcp </%def>
436.7 +
436.8 +<%def name="layout()">
436.9 +
436.10 +mac
436.11 +ip
436.12 +tag
436.13 +value
436.14 +--
436.15 +s=Aggiungi
436.16 +
436.17 +</%def>
436.18 +
436.19 +In questa pagina si possono aggiungere degli abbinamenti fra un MAC address
436.20 +ed una opzione di boot.
436.21 +
436.22 +Il MAC address ha una forma così: <tt>00:0c:29:10:a6:45</tt> ed identifica
436.23 +in modo univo una scheda di rete e quindi in generale un client.
436.24 +
436.25 +Si può aggiungere un tag, ovvero un identificatore che verrà usato dal dhcp
436.26 + per decidere quale immagine inviare al client se richiede (tramite
436.27 + PXE/gPXE) una immagine per partire come thin/fat client.
436.28 +
436.29 +Il tag è una stringa qualunque, ma deve esserci una corrispondente opzione
436.30 + di boot perché venga presa in considerazione (altrimenti il default, se
436.31 + definito viene usato). Tag sensati hanno una indicazione dell'immagine
436.32 + (fat/thin) e del server (srv1/srv2...)
436.33 +
436.34 +
436.35 +##<h2>${title()}</h2>
436.36 + ${jun.show_form_errors(form)}
436.37 + ${forms.mako_create_nform(context, layout, form, style='-')}
436.38 +
436.39 +
436.40 +<script type="text/javascript" >
436.41 + $('td label[title]').cluetip({splitTitle: '|'});
436.42 +</script>
437.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
437.2 +++ b/web/dnsmasq/tests.py Mon Apr 26 11:16:23 2010 +0200
437.3 @@ -0,0 +1,23 @@
437.4 +"""
437.5 +This file demonstrates two different styles of tests (one doctest and one
437.6 +unittest). These will both pass when you run "manage.py test".
437.7 +
437.8 +Replace these with more appropriate tests for your application.
437.9 +"""
437.10 +
437.11 +from django.test import TestCase
437.12 +
437.13 +class SimpleTest(TestCase):
437.14 + def test_basic_addition(self):
437.15 + """
437.16 + Tests that 1 + 1 always equals 2.
437.17 + """
437.18 + self.failUnlessEqual(1 + 1, 2)
437.19 +
437.20 +__test__ = {"doctest": """
437.21 +Another way to test that 1 + 1 is equal to 2.
437.22 +
437.23 +>>> 1 + 1 == 2
437.24 +True
437.25 +"""}
437.26 +
438.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
438.2 +++ b/web/dnsmasq/urls.py Mon Apr 26 11:16:23 2010 +0200
438.3 @@ -0,0 +1,17 @@
438.4 +from django.conf.urls.defaults import *
438.5 +
438.6 +urlpatterns = patterns('isiweb.dnsmasq.views',
438.7 + (r'^conf/', 'show_conf'),
438.8 + (r'^restart/', 'restart'),
438.9 + (r'^set_dhcp/', 'set_dhcp'),
438.10 + (r'^host/add/', 'add_host'),
438.11 + (r'^mac/add/', 'add_mac'),
438.12 + (r'^host/del/(?P<ip>[0-9.]+)/', 'del_host'),
438.13 + (r'^mac/del/(?P<mac_address>[0-9a-fA-F:.]+)/', 'del_mac'),
438.14 + (r'^boot/add/(?P<index>[0-9]+)/', 'add_boot_param'),
438.15 + (r'^boot/del/(?P<index>[0-9]+)/', 'del_boot_param'),
438.16 + (r'^boot/edit/(?P<index>[0-9]+)/', 'edit_boot_param'),
438.17 +
438.18 +# (r'^pc/add/', 'add_pc'),
438.19 +# (r'^pc/del/', 'del_pc'),
438.20 +)
439.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
439.2 +++ b/web/dnsmasq/views.py Mon Apr 26 11:16:23 2010 +0200
439.3 @@ -0,0 +1,218 @@
439.4 +# -*- coding: utf-8 -*-
439.5 +
439.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
439.7 +#
439.8 +# This program is free software: you can redistribute it and/or modify
439.9 +# it under the terms of the GNU General Public License as published by
439.10 +# the Free Software Foundation, either version 3 of the License, or
439.11 +# (at your option) any later version.
439.12 +#
439.13 +# This program is distributed in the hope that it will be useful,
439.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
439.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
439.16 +# GNU General Public License for more details.
439.17 +#
439.18 +# You should have received a copy of the GNU General Public License
439.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
439.20 +
439.21 +
439.22 +from django.template import RequestContext
439.23 +from django.http import HttpResponseRedirect
439.24 +from django.conf import settings
439.25 +from vov.views.decorators import login_required
439.26 +from vov.views import mgeneric
439.27 +from django.views import generic
439.28 +from vov.template import mako_loader
439.29 +from isi.conf import logon, hosts, mac, dnsmasq
439.30 +from django.contrib import messages
439.31 +import dns_form
439.32 +from django.contrib import messages
439.33 +from dry.functions import execute
439.34 +import isi
439.35 +
439.36 +logger = isi.srv.get_logger(web=True)
439.37 +
439.38 +@login_required
439.39 +def show_conf(request):
439.40 +
439.41 + data = dns_form.get_data(settings.DNSMASQ_CONF)
439.42 +
439.43 + host_conf = hosts.Hosts(settings.HOSTS_CONF)
439.44 + host_list = [(l.param_name, l.value) for l in host_conf.lines if not l.is_comment]
439.45 +
439.46 + mac_conf = mac.Mac(settings.MAC_CONF)
439.47 + mac_list = [(l.mac, l.value.replace(l.mac + ',', '')) for l in mac_conf.get_param('dhcp-host')]
439.48 +
439.49 + leases = dnsmasq.get_leases(settings.LEASES_FILE)
439.50 + boot_conf = dnsmasq.Conf(settings.BOOT_CONF)
439.51 +
439.52 + context = {
439.53 + 'dnsdata' : data,
439.54 + 'hosts' : host_list,
439.55 + 'macs' : mac_list,
439.56 + 'leases' : leases,
439.57 + 'boot_conf' : boot_conf,
439.58 + 'tips' : dns_form.tips,
439.59 + }
439.60 + return mako_loader.render_to_response('dnsmasq/dnsmasq_list.mako', context,
439.61 + context_instance=RequestContext(request),)
439.62 +
439.63 +@login_required
439.64 +def set_dhcp(request):
439.65 +
439.66 + if request.method == 'POST': # If the form has been submitted...
439.67 + form = dns_form.DnsForm(request.POST) # A form bound to the POST data
439.68 + if form.is_valid(): # All validation rules pass
439.69 + form.save()
439.70 + messages.success(request, 'Dhcp aggiornato')
439.71 + return HttpResponseRedirect('/views/close_popup/')
439.72 + else:
439.73 + data = dns_form.get_data(settings.DNSMASQ_CONF)
439.74 + form = dns_form.DnsForm(initial=data) # An unbound form
439.75 +
439.76 + context = {'form' : form,}
439.77 +
439.78 + return mako_loader.render_to_response('dnsmasq/dnsmasq_form.mako', context,
439.79 + context_instance=RequestContext(request),)
439.80 +
439.81 +@login_required
439.82 +def add_host(request):
439.83 +
439.84 + if request.method == 'POST': # If the form has been submitted...
439.85 + form = dns_form.HostForm(request.POST) # A form bound to the POST data
439.86 + if form.is_valid(): # All validation rules pass
439.87 + form.save()
439.88 + messages.success(request, 'Host aggiornato')
439.89 + return HttpResponseRedirect('/views/close_popup/')
439.90 + else:
439.91 + form = dns_form.HostForm() # An unbound form
439.92 +
439.93 + context = {'form' : form,}
439.94 +
439.95 + return mako_loader.render_to_response('dnsmasq/host_form.mako', context,
439.96 + context_instance=RequestContext(request),)
439.97 +
439.98 +@login_required
439.99 +def add_mac(request):
439.100 +
439.101 + if request.method == 'POST': # If the form has been submitted...
439.102 + form = dns_form.MacForm(request.POST) # A form bound to the POST data
439.103 + if form.is_valid(): # All validation rules pass
439.104 + line = form.save()
439.105 + messages.success(request, "Added %s" % line)
439.106 + return HttpResponseRedirect('/views/close_popup/')
439.107 + else:
439.108 + form = dns_form.MacForm() # An unbound form
439.109 +
439.110 + context = {'form' : form,}
439.111 +
439.112 + return mako_loader.render_to_response('dnsmasq/mac_form.mako', context,
439.113 + context_instance=RequestContext(request),)
439.114 +
439.115 +class IP(mgeneric.Obj):
439.116 +
439.117 + def __init__(self, request, ip):
439.118 +
439.119 + self.ip = self.value = ip
439.120 + self.conf = hosts.Hosts(settings.HOSTS_CONF)
439.121 +
439.122 + def delete(self):
439.123 + self.conf.del_param(self.ip)
439.124 + self.conf.save()
439.125 + self.message = 'Eliminato host: ' + self.ip
439.126 + logger.debug('Eliminato host %s' % self.ip)
439.127 +
439.128 +
439.129 +class Mac(mgeneric.Obj):
439.130 +
439.131 + def __init__(self, request, mac_address):
439.132 +
439.133 + self.mac = self.value = mac_address
439.134 + self.conf = mac.Mac(settings.HOSTS_CONF)
439.135 +
439.136 + def delete(self):
439.137 + self.conf.del_param(self.mac)
439.138 + self.conf.save()
439.139 + self.message = 'Eliminato mac: ' + self.mac
439.140 + logger.debug('Eliminato mac %s' % self.mac)
439.141 +
439.142 +class BootParam(mgeneric.Obj):
439.143 +
439.144 + def __init__(self, request, index):
439.145 +
439.146 + self.index = index
439.147 + self.conf = dnsmasq.Conf(settings.BOOT_CONF)
439.148 + self.value = unicode(self.conf.lines[index])
439.149 +
439.150 + def delete(self):
439.151 + line = self.conf.lines.pop(self.index)
439.152 + self.conf.save()
439.153 + self.message = 'Eliminato parametro: %s' % line
439.154 + logger.debug('Eliminato parametro: %s' % line)
439.155 +
439.156 +@login_required
439.157 +def del_host(request, ip):
439.158 +
439.159 + obj = IP(request, ip)
439.160 + return mgeneric.delete_non_model(request, obj=obj, )
439.161 +
439.162 +@login_required
439.163 +def del_mac(request, mac_address):
439.164 +
439.165 + obj = Mac(request, mac_address)
439.166 + return mgeneric.delete_non_model(request, obj=obj, )
439.167 +
439.168 +@login_required
439.169 +def del_boot_param(request, index):
439.170 +
439.171 + obj = BootParam(request, int(index))
439.172 + return mgeneric.delete_non_model(request, obj=obj, )
439.173 +
439.174 +
439.175 +######## boot #######
439.176 +@login_required
439.177 +def add_boot_param(request, index):
439.178 +
439.179 + if request.method == 'POST': # If the form has been submitted...
439.180 + form = dns_form.BootLineForm(request.POST) # A form bound to the POST data
439.181 + if form.is_valid(): # All validation rules pass
439.182 + form.save()
439.183 + messages.success(request, 'Aggiunto parametro di boot')
439.184 + return HttpResponseRedirect('/views/close_popup/')
439.185 + else:
439.186 + form = dns_form.BootLineForm() # An unbound form
439.187 +
439.188 + context = {'form' : form, 'index' : index}
439.189 +
439.190 + return mako_loader.render_to_response('dnsmasq/boot_form.mako', context,
439.191 + context_instance=RequestContext(request),)
439.192 +
439.193 +@login_required
439.194 +def edit_boot_param(request, index):
439.195 +
439.196 +
439.197 + if request.method == 'POST': # If the form has been submitted...
439.198 + form = dns_form.BootLineForm(request.POST) # A form bound to the POST data
439.199 + if form.is_valid(): # All validation rules pass
439.200 + form.update()
439.201 + messages.success(request, 'Aggiunto parametro di boot')
439.202 + return HttpResponseRedirect('/views/close_popup/')
439.203 + else:
439.204 + boot_conf = dnsmasq.Conf(settings.BOOT_CONF)
439.205 + data = vars(boot_conf.lines[int(index)])
439.206 + form = dns_form.BootLineForm(initial=data) # An unbound form
439.207 +
439.208 + context = {'form' : form, 'index': index}
439.209 +
439.210 + return mako_loader.render_to_response('dnsmasq/boot_form.mako', context,
439.211 + context_instance=RequestContext(request),)
439.212 +
439.213 +@login_required
439.214 +def restart(request):
439.215 + ret_code, out, err = execute('/etc/init.d/dnsmasq restart')
439.216 + if not ret_code:
439.217 + messages.success(request, "Dnsmasq server riavviato correttamente")
439.218 + else:
439.219 + messages.error(request, "Errore nel riavvio del server: %s" % err)
439.220 +
439.221 + return HttpResponseRedirect('/dnsmasq/conf/')
440.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
440.2 +++ b/web/ldap-auth.py Mon Apr 26 11:16:23 2010 +0200
440.3 @@ -0,0 +1,48 @@
440.4 +from django.conf import settings
440.5 +from django.contrib.auth.models import User, check_password
440.6 +import isi
440.7 +
440.8 +
440.9 +class LDAPBackend(object):
440.10 + """
440.11 + Authenticate against ldap users
440.12 + """
440.13 + def authenticate(self, username=None, password=None):
440.14 +
440.15 + l = isi.Manager()
440.16 +
440.17 + try:
440.18 + if username == 'admin':
440.19 + ## needed for the first access
440.20 + login_valid = True
440.21 + pwd_valid = password == l.srv.passwd
440.22 + else:
440.23 + login_valid = l.user_in_group(username, 'admins') or l.user_in_group(username, 'docenti')
440.24 + pwd_valid = l.test_password(username, password)
440.25 +
440.26 + if login_valid and pwd_valid:
440.27 + try:
440.28 + user = User.objects.get(username=username)
440.29 + except User.DoesNotExist:
440.30 + # Create a new user. Note that we can set password
440.31 + # to anything, because it won't be checked; the password
440.32 + # from settings.py will.
440.33 +
440.34 + user = User(username=username, password='get from ldap')
440.35 + if username == 'admin' or 'admins' in l.get_user(username).get_my_groups(as_plain_list=True):
440.36 + user.is_staff = True
440.37 + else:
440.38 + user.is_staff = False
440.39 + user.is_superuser = True
440.40 + user.save()
440.41 + return user
440.42 + except isi.exc.MissingMatch, e:
440.43 + return None
440.44 + return None
440.45 +
440.46 + def get_user(self, user_id):
440.47 + try:
440.48 + return User.objects.get(pk=user_id)
440.49 + except User.DoesNotExist:
440.50 + return None
440.51 +
441.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
441.2 +++ b/web/manage.py Mon Apr 26 11:16:23 2010 +0200
441.3 @@ -0,0 +1,11 @@
441.4 +#!/usr/bin/env python
441.5 +from django.core.management import execute_manager
441.6 +try:
441.7 + import settings # Assumed to be in the same directory.
441.8 +except ImportError:
441.9 + import sys
441.10 + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
441.11 + sys.exit(1)
441.12 +
441.13 +if __name__ == "__main__":
441.14 + execute_manager(settings)
442.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
442.2 +++ b/web/modwsgi.py Mon Apr 26 11:16:23 2010 +0200
442.3 @@ -0,0 +1,8 @@
442.4 +import os
442.5 +os.environ['DJANGO_SETTINGS_MODULE'] = 'isiweb.settings'
442.6 +
442.7 +import django.core.handlers.wsgi
442.8 +
442.9 +application = django.core.handlers.wsgi.WSGIHandler()
442.10 +
442.11 +
443.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
443.2 +++ b/web/navigazione/models.py Mon Apr 26 11:16:23 2010 +0200
443.3 @@ -0,0 +1,3 @@
443.4 +from django.db import models
443.5 +
443.6 +# Create your models here.
444.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
444.2 +++ b/web/navigazione/templates/navigazione/show_conf.mako Mon Apr 26 11:16:23 2010 +0200
444.3 @@ -0,0 +1,68 @@
444.4 +<%inherit file="${jun.get_parent_template(context)}"/>
444.5 +
444.6 +<div id="tabs">
444.7 + <ul >
444.8 + %for sez in ('classi', ):
444.9 + <li><a href="#${sez}">${sez}</a></li>
444.10 + %endfor
444.11 + </ul>
444.12 +
444.13 +
444.14 +
444.15 + <div id="classi" class="tab">
444.16 +
444.17 + <div class="azioni">
444.18 + <table>
444.19 + <theader>
444.20 + <tr>
444.21 + <th>classe</th>
444.22 + <th>bloccata?</th>
444.23 + <th></th>
444.24 + </theader>
444.25 + <tbody>
444.26 + %for c in classes:
444.27 + <tr>
444.28 + <td>${c}</td>
444.29 + % if c.get_www():
444.30 + <td>SI</td>
444.31 + <td><a href='/navigazione/allow/${c.name}'>permetti</a></td>
444.32 + % else:
444.33 + <td>NO</td>
444.34 + <td><a href='/navigazione/block/${c.name}'>inibisci</a></td>
444.35 + % endif
444.36 + </tr>
444.37 + %endfor
444.38 + </tbody>
444.39 + </table>
444.40 +
444.41 +
444.42 + </div> <!-- azioni -->
444.43 + </div> <!-- dominio -->
444.44 +
444.45 +## <div id="aule" class="tab">
444.46 +## <div class="azioni">
444.47 +## <a href="/samba/conf/save/">Inibisci un'aula <img src="/static/img/icon_changelink.gif"></>
444.48 +## </div> <!-- azioni -->
444.49 +## </div> <!-- aule -->
444.50 +##
444.51 +</div> <!-- tabs -->
444.52 +
444.53 +#### script & style
444.54 +<script>
444.55 +$(document).ready(function () {
444.56 +
444.57 + $('#tabs').tabs();
444.58 + $('td.title').cluetip({splitTitle: '|'});
444.59 +## $('td.title').cluetip({splitTitle: '|', sticky: true, closePosition: 'title', arrows: true });
444.60 +
444.61 +});
444.62 +</script>
444.63 +
444.64 +<style>
444.65 +table.data {
444.66 + margin-top: 30px
444.67 +}
444.68 +table.data th {
444.69 + text-align: left
444.70 +}
444.71 +</style>
445.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
445.2 +++ b/web/navigazione/tests.py Mon Apr 26 11:16:23 2010 +0200
445.3 @@ -0,0 +1,23 @@
445.4 +"""
445.5 +This file demonstrates two different styles of tests (one doctest and one
445.6 +unittest). These will both pass when you run "manage.py test".
445.7 +
445.8 +Replace these with more appropriate tests for your application.
445.9 +"""
445.10 +
445.11 +from django.test import TestCase
445.12 +
445.13 +class SimpleTest(TestCase):
445.14 + def test_basic_addition(self):
445.15 + """
445.16 + Tests that 1 + 1 always equals 2.
445.17 + """
445.18 + self.failUnlessEqual(1 + 1, 2)
445.19 +
445.20 +__test__ = {"doctest": """
445.21 +Another way to test that 1 + 1 is equal to 2.
445.22 +
445.23 +>>> 1 + 1 == 2
445.24 +True
445.25 +"""}
445.26 +
446.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
446.2 +++ b/web/navigazione/urls.py Mon Apr 26 11:16:23 2010 +0200
446.3 @@ -0,0 +1,7 @@
446.4 +from django.conf.urls.defaults import *
446.5 +
446.6 +urlpatterns = patterns('isiweb.navigazione.views',
446.7 + (r'^block/(?P<group_name>.*)/$', 'block'),
446.8 + (r'^allow/(?P<group_name>.*)/$', 'allow'),
446.9 + (r'^conf/$', 'show_conf'),
446.10 +)
447.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
447.2 +++ b/web/navigazione/views.py Mon Apr 26 11:16:23 2010 +0200
447.3 @@ -0,0 +1,38 @@
447.4 +from django.template import RequestContext
447.5 +from django.http import HttpResponseRedirect
447.6 +from django.conf import settings
447.7 +from vov.views.decorators import login_required
447.8 +from django.views import generic
447.9 +from vov.template import mako_loader
447.10 +from isi.conf import logon
447.11 +import isi
447.12 +from django.contrib import messages
447.13 +
447.14 +l = isi.Manager()
447.15 +
447.16 +@login_required
447.17 +def show_conf(request):
447.18 +
447.19 + context = {
447.20 + 'classes' : isi.srv.get_classes(as_groups=True)
447.21 + }
447.22 +
447.23 + return mako_loader.render_to_response('navigazione/show_conf.mako', context,
447.24 + context_instance=RequestContext(request),)
447.25 +
447.26 +@login_required
447.27 +def block(request, group_name):
447.28 +
447.29 + group = l.get_group(group_name)
447.30 + group.set_www(False)
447.31 + isi.get_logger(web=True).info("User %s has blocked class %s" % (request.user, group_name))
447.32 + return HttpResponseRedirect('/navigazione/conf/')
447.33 +
447.34 +@login_required
447.35 +def allow(request, group_name):
447.36 +
447.37 + group = l.get_group(group_name)
447.38 + group.set_www(True)
447.39 + isi.get_logger().info("User %s has permitted www to class %s" % (request.user, group_name))
447.40 + return HttpResponseRedirect('/navigazione/conf/')
447.41 +
448.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
448.2 +++ b/web/samba/models.py Mon Apr 26 11:16:23 2010 +0200
448.3 @@ -0,0 +1,3 @@
448.4 +from django.db import models
448.5 +
448.6 +# Create your models here.
449.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
449.2 +++ b/web/samba/samba_form.py Mon Apr 26 11:16:23 2010 +0200
449.3 @@ -0,0 +1,80 @@
449.4 +"""
449.5 +[global]
449.6 +
449.7 +## Browsing/Identification/Domain ###
449.8 +
449.9 + workgroup = FOSSATIINTERNI
449.10 + netbios name = srv-fossati
449.11 + domain master = Yes
449.12 + local master = Yes
449.13 + preferred master = Yes
449.14 +
449.15 +"""
449.16 +
449.17 +from django import forms
449.18 +from django.conf import settings
449.19 +from dry.functions import execute, ExecuteError
449.20 +import isi
449.21 +import re
449.22 +
449.23 +logger = isi.srv.get_logger(web=True)
449.24 +
449.25 +class SambaForm(forms.Form):
449.26 +
449.27 + domain_name = forms.CharField(label='Dominio', max_length=30, required=True)
449.28 + netbios_name = forms.CharField(label="Nome netbios", max_length=30, required=True)
449.29 + root_password = forms.CharField(widget=forms.PasswordInput(render_value=False))
449.30 + password = forms.CharField(widget=forms.PasswordInput(render_value=False))
449.31 +
449.32 + def clean_prev_password(self):
449.33 +
449.34 + password = self.cleaned_data['root_password']
449.35 + return password
449.36 +
449.37 + def save(self):
449.38 + domain = self.cleaned_data['domain_name']
449.39 + srv_name = self.cleaned_data['netbios_name']
449.40 + root_password = self.cleaned_data['root_password']
449.41 + password = self.cleaned_data['password']
449.42 + cmd = ['/usr/sbin/isi-domain', '-Qq', domain, srv_name, password]
449.43 + ret_code, out, err = execute(cmd)
449.44 + if not ret_code:
449.45 + logger.debug("/usr/sbin/isi-domain %s %s %s" % (domain, srv_name, '...'))
449.46 + self.message = "<br>".join(out.split('\n'))
449.47 + else:
449.48 + raise ExecuteError("isi-domain ha problemi: error: %s output: %s" % (err, out))
449.49 +
449.50 +
449.51 +
449.52 +class DomainInfo(object):
449.53 +
449.54 + domain_name = ''
449.55 + netbios_name = ''
449.56 + domain_pat = re.compile('\s*workgroup\s*=\s*(?P<domain>[\w_-]+)', re.I)
449.57 + netbios_name_pat = re.compile('\s*netbios name\s*=\s*(?P<name>[\w_-]+)', re.I)
449.58 +
449.59 + def __init__(self, conf=None):
449.60 +
449.61 + if conf:
449.62 + for line in conf.split('\n'):
449.63 + self.parse_line(line)
449.64 + else:
449.65 + f = open(settings.SAMBA_FILE)
449.66 + for line in f:
449.67 + self.parse_line(line)
449.68 + f.close()
449.69 +
449.70 +
449.71 + def parse_line(self, line):
449.72 + m = self.domain_pat.match(line)
449.73 + if m:
449.74 + self.domain_name = m.group('domain')
449.75 +
449.76 + m = self.netbios_name_pat.match(line)
449.77 + if m:
449.78 + self.netbios_name = m.group('name')
449.79 +
449.80 +if __name__ == '__main__':
449.81 +
449.82 + d=DomainInfo(__doc__)
449.83 + vars(d)
450.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
450.2 +++ b/web/samba/templates/samba/samba_form.mako Mon Apr 26 11:16:23 2010 +0200
450.3 @@ -0,0 +1,31 @@
450.4 +<%inherit file="${jun.get_parent_template(context)}"/>
450.5 +
450.6 +
450.7 +<h1> Configurazione Samba</h1>
450.8 +
450.9 +<%def name="layout()">
450.10 +
450.11 +domain_name
450.12 +netbios_name
450.13 +root_password
450.14 +password
450.15 +--
450.16 +s=salva
450.17 +
450.18 +</%def>
450.19 +
450.20 +${jun.show_form_errors(form)}
450.21 +${forms.mako_create_nform(context, layout, form, style='-')}
450.22 +
450.23 +
450.24 +<style>
450.25 +table.data {
450.26 + margin-top: 30px
450.27 +}
450.28 +table.data th {
450.29 + text-align: left
450.30 +}
450.31 +.data td {
450.32 + padding-right: 30px
450.33 +}
450.34 +</style>
451.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
451.2 +++ b/web/samba/templates/samba/show_conf.mako Mon Apr 26 11:16:23 2010 +0200
451.3 @@ -0,0 +1,96 @@
451.4 +<%inherit file="${jun.get_parent_template(context)}"/>
451.5 +
451.6 +<div id="tabs">
451.7 + <ul >
451.8 + %for sez in ('dominio', 'stampanti', 'shares' ):
451.9 + <li><a href="#${sez}">${sez}</a></li>
451.10 + %endfor
451.11 + </ul>
451.12 +
451.13 +
451.14 +
451.15 + <div id="dominio" class="tab">
451.16 +
451.17 + <table class="data">
451.18 + <tr>
451.19 + <th><b>Dominio:</b></th> <td>${domain.domain_name}</td>
451.20 + </tr>
451.21 + <tr>
451.22 + <th><b>Netbios Name:</b></th> <td>${domain.netbios_name}</td>
451.23 + </tr>
451.24 + <tr>
451.25 + <th><b>Password:</b></th> <td> ... ssht...</td>
451.26 + </tr>
451.27 + </table>
451.28 + <div class="azioni">
451.29 + ${jun.popup_link("/samba/conf/save/?popup", txt='Modifica la configurazione', icon='edit')}
451.30 + </div> <!-- azioni -->
451.31 + </div> <!-- dominio -->
451.32 +
451.33 + <div id="stampanti" class="tab">
451.34 +
451.35 + Si consiglia la lettura del laboratorio netkit sulla configurazione
451.36 + delle <a href="/docs/allegati/netkit/stampanti/README.html">stampanti</a>
451.37 +
451.38 + % if isinstance(printers, Exception):
451.39 + <div class="ui-state-error" style="margin: 15px; padding: 10px">
451.40 + Il seguente errore non influenza il funzionamento del sistema ma
451.41 + quello della interfaccia web!<br>
451.42 + ${printers.message}
451.43 + </div>
451.44 + % else:
451.45 + <table>
451.46 + <tr>
451.47 + <th>name</th> <th>driver</th> <th>printername</th> <th>comment</th>
451.48 + </tr>
451.49 + % for p in printers:
451.50 + <tr>
451.51 + <td>${p.sharename}</td> <td>${p.drivername}</td> <td>${p.printername}</td> <td>${p.comment}</td>
451.52 + </tr>
451.53 + % endfor
451.54 + </table>
451.55 + % endif
451.56 + </div>
451.57 +
451.58 + <div id="shares" class="tab">
451.59 + <h3>shares definite</h3>
451.60 + Le seguenti shares sono definite in /etc/samba/smb.conf o file inclusi
451.61 + (es.: /etc/isi/samba/smb_*):
451.62 +
451.63 + <table>
451.64 + <tr>
451.65 + <th>share</th> <th>path</th>
451.66 + </tr>
451.67 + % for share, path in shares:
451.68 + <tr>
451.69 + <td>${share}</td> <td>${path}</td>
451.70 + </tr>
451.71 + % endfor
451.72 + </table>
451.73 +
451.74 + </div>
451.75 +
451.76 +</div> <!-- tabs -->
451.77 +
451.78 +#### script & style
451.79 +<script type="text/javascript">
451.80 +$(document).ready(function () {
451.81 +
451.82 + $('#tabs').tabs();
451.83 + $('td.title').cluetip({splitTitle: '|'});
451.84 +## $('td.title').cluetip({splitTitle: '|', sticky: true, closePosition: 'title', arrows: true });
451.85 +
451.86 +});
451.87 +</script>
451.88 +
451.89 +<style type="text/css">
451.90 +table.data {
451.91 + margin-top: 30px
451.92 +}
451.93 +table.data th {
451.94 + text-align: left
451.95 +}
451.96 +.data td {
451.97 + padding-left: 30px
451.98 +}
451.99 +</style>
452.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
452.2 +++ b/web/samba/tests.py Mon Apr 26 11:16:23 2010 +0200
452.3 @@ -0,0 +1,23 @@
452.4 +"""
452.5 +This file demonstrates two different styles of tests (one doctest and one
452.6 +unittest). These will both pass when you run "manage.py test".
452.7 +
452.8 +Replace these with more appropriate tests for your application.
452.9 +"""
452.10 +
452.11 +from django.test import TestCase
452.12 +
452.13 +class SimpleTest(TestCase):
452.14 + def test_basic_addition(self):
452.15 + """
452.16 + Tests that 1 + 1 always equals 2.
452.17 + """
452.18 + self.failUnlessEqual(1 + 1, 2)
452.19 +
452.20 +__test__ = {"doctest": """
452.21 +Another way to test that 1 + 1 is equal to 2.
452.22 +
452.23 +>>> 1 + 1 == 2
452.24 +True
452.25 +"""}
452.26 +
453.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
453.2 +++ b/web/samba/urls.py Mon Apr 26 11:16:23 2010 +0200
453.3 @@ -0,0 +1,6 @@
453.4 +from django.conf.urls.defaults import *
453.5 +
453.6 +urlpatterns = patterns('isiweb.samba.views',
453.7 + (r'^conf/save/$', 'save_conf'),
453.8 + (r'^conf/$', 'show_conf'),
453.9 +)
454.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
454.2 +++ b/web/samba/views.py Mon Apr 26 11:16:23 2010 +0200
454.3 @@ -0,0 +1,48 @@
454.4 +from django.template import RequestContext
454.5 +from django.http import HttpResponseRedirect
454.6 +from django.conf import settings
454.7 +from vov.views.decorators import login_required
454.8 +from django.views import generic
454.9 +from vov.template import mako_loader
454.10 +from isi import exc
454.11 +from isi.conf import logon, misc
454.12 +from django.contrib import messages
454.13 +from samba_form import SambaForm, DomainInfo
454.14 +
454.15 +class Domain(object): pass
454.16 +
454.17 +@login_required
454.18 +def show_conf(request):
454.19 +
454.20 + try:
454.21 + printers = misc.get_printers_with_rpcclient()
454.22 + except (exc.ExecuteError, exc.AuthenticationError), e:
454.23 + printers = e
454.24 +
454.25 + context = {
454.26 + 'domain' : DomainInfo(),
454.27 + 'shares' : misc.get_shares(all=True, descr=False),
454.28 + 'printers': printers,
454.29 + }
454.30 + return mako_loader.render_to_response('samba/show_conf.mako', context,
454.31 + context_instance=RequestContext(request),)
454.32 +
454.33 +@login_required
454.34 +def save_conf(request):
454.35 +
454.36 + if request.method == 'POST': # If the form has been submitted...
454.37 + form = SambaForm(request.POST) # A form bound to the POST data
454.38 + if form.is_valid(): # All validation rules pass
454.39 + form.save()
454.40 + messages.success(request, 'Dominio impostato:<br>%s' % form.message)
454.41 + return HttpResponseRedirect('/views/close_popup/')
454.42 + else:
454.43 + domain = DomainInfo()
454.44 + print vars(domain)
454.45 + form = SambaForm(initial=vars(domain)) # An unbound form
454.46 +
454.47 + context = {'form' : form,
454.48 + }
454.49 +
454.50 + return mako_loader.render_to_response('samba/samba_form.mako', context,
454.51 + context_instance=RequestContext(request),)
455.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
455.2 +++ b/web/settings.py Mon Apr 26 11:16:23 2010 +0200
455.3 @@ -0,0 +1,127 @@
455.4 +import os
455.5 +import sys
455.6 +import vov
455.7 +from vov.functions.conf import *
455.8 +
455.9 +CWD = os.path.dirname(__file__)
455.10 +set_cwd(CWD)
455.11 +from vov.conf.settings import *
455.12 +from local_settings import *
455.13 +
455.14 +# Django settings for isiweb project.
455.15 +
455.16 +DEBUG = True
455.17 +TEMPLATE_DEBUG = DEBUG
455.18 +PRJ_DIR = CWD
455.19 +CWD = PRJ_DIR
455.20 +ADMINS = (
455.21 + # ('Your Name', '[email protected]'),
455.22 +)
455.23 +
455.24 +MANAGERS = ADMINS
455.25 +
455.26 +DATABASES = {
455.27 + 'default': {
455.28 + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
455.29 + 'NAME': CWD + '/isi.db', # Or path to database file if using sqlite3.
455.30 + 'USER': '', # Not used with sqlite3.
455.31 + 'PASSWORD': '', # Not used with sqlite3.
455.32 + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
455.33 + 'PORT': '', # Set to empty string for default. Not used with sqlite3.
455.34 + }
455.35 +}
455.36 +AUTHENTICATION_BACKENDS = ('isiweb.ldap-auth.LDAPBackend',)
455.37 +
455.38 +# Local time zone for this installation. Choices can be found here:
455.39 +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
455.40 +# although not all choices may be available on all operating systems.
455.41 +# If running in a Windows environment this must be set to the same as your
455.42 +# system time zone.
455.43 +TIME_ZONE = 'Europe/Rome'
455.44 +
455.45 +# Language code for this installation. All choices can be found here:
455.46 +# http://www.i18nguy.com/unicode/language-identifiers.html
455.47 +LANGUAGE_CODE = 'it_it'
455.48 +
455.49 +SITE_ID = 1
455.50 +
455.51 +# If you set this to False, Django will make some optimizations so as not
455.52 +# to load the internationalization machinery.
455.53 +USE_I18N = True
455.54 +
455.55 +# Absolute path to the directory that holds media.
455.56 +# Example: "/home/media/media.lawrence.com/"
455.57 +MEDIA_ROOT = PRJ_DIR + '/static'
455.58 +
455.59 +# URL that handles the media served from MEDIA_ROOT. Make sure to use a
455.60 +# trailing slash if there is a path component (optional in other cases).
455.61 +# Examples: "http://media.lawrence.com", "http://example.com/media/"
455.62 +MEDIA_URL = '/static'
455.63 +
455.64 +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
455.65 +# trailing slash.
455.66 +# Examples: "http://foo.com/media/", "/media/".
455.67 +ADMIN_MEDIA_PREFIX = '/media/'
455.68 +
455.69 +# Make this unique, and don't share it with anybody.
455.70 +SECRET_KEY = 'oguf-tkekbeatknmy=3m5v!w9@rr(xl5)%l09+m+=lpndx0&2w'
455.71 +
455.72 +# List of callables that know how to import templates from various sources.
455.73 +# TEMPLATE_LOADERS = (
455.74 +# 'django.template.loaders.filesystem.load_template_source',
455.75 +# 'django.template.loaders.app_directories.load_template_source',
455.76 +# 'django.template.loaders.filesystem.Loader',
455.77 +# 'django.template.loaders.app_directories.Loader',
455.78 +# # 'django.template.loaders.eggs.Loader',
455.79 +# )
455.80 +
455.81 +# MIDDLEWARE_CLASSES = (
455.82 +# 'django.middleware.common.CommonMiddleware',
455.83 +# 'django.contrib.sessions.middleware.SessionMiddleware',
455.84 +# 'django.middleware.csrf.CsrfViewMiddleware',
455.85 +# 'django.contrib.auth.middleware.AuthenticationMiddleware',
455.86 +# 'django.contrib.messages.middleware.MessageMiddleware',
455.87 +# )
455.88 +
455.89 +ROOT_URLCONF = 'isiweb.urls'
455.90 +
455.91 +
455.92 +INSTALLED_APPS = (
455.93 + 'django.contrib.auth',
455.94 + 'django.contrib.contenttypes',
455.95 + 'django.contrib.sessions',
455.96 + 'django.contrib.sites',
455.97 + 'django.contrib.admin',
455.98 + 'django.contrib.messages',
455.99 + 'vov.sys',
455.100 + 'vov.registration',
455.101 + 'isiweb.logon',
455.102 + 'isiweb.users',
455.103 + 'isiweb.samba',
455.104 + 'isiweb.dnsmasq',
455.105 + 'isiweb.navigazione',
455.106 +)
455.107 +
455.108 +TEMPLATE_CONTEXT_PROCESSORS = (
455.109 + 'django.core.context_processors.auth',
455.110 + 'django.core.context_processors.debug',
455.111 + 'django.core.context_processors.i18n',
455.112 + 'django.core.context_processors.request',
455.113 +)
455.114 +
455.115 +
455.116 +DATE_FORMAT="d/m/Y"
455.117 +TIME_FORMAT="G:i"
455.118 +DATETIME_FORMAT="d/m/Y G:i"
455.119 +
455.120 +
455.121 +
455.122 +MAKO_FILTERS = None
455.123 +
455.124 +LOGON_FILE = '/etc/isi/logon.conf'
455.125 +SAMBA_FILE = '/etc/samba/smb.conf'
455.126 +DNSMASQ_CONF = '/etc/dnsmasq.conf'
455.127 +HOSTS_CONF = '/etc/hosts'
455.128 +MAC_CONF = '/etc/isi/dnsmasq/hosts.mac'
455.129 +LEASES_FILE = '/var/lib/misc/dnsmasq.leases'
455.130 +BOOT_CONF = '/etc/isi/dnsmasq/boot'
456.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
456.2 +++ b/web/static/css/bt.css Mon Apr 26 11:16:23 2010 +0200
456.3 @@ -0,0 +1,23 @@
456.4 +.tooltip {
456.5 +color:#000000;
456.6 +font-family:Arial,sans-serif;
456.7 +font-size:11px;
456.8 +font-size-adjust:none;
456.9 +font-stretch:normal;
456.10 +font-style:normal;
456.11 +font-variant:normal;
456.12 +font-weight:lighter;
456.13 +line-height:1.3;
456.14 +text-align:center;
456.15 +text-decoration:none;
456.16 +width:200px;
456.17 +}
456.18 +.tooltip span.top {
456.19 +background:transparent url(/static/img/bt.gif) no-repeat scroll center top;
456.20 +padding:30px 8px 0pt;
456.21 +}
456.22 +.tooltip b.bottom {
456.23 +background:transparent url(/static/img/bt.gif) no-repeat scroll center bottom;
456.24 +color:#548912;
456.25 +padding:3px 8px 15px;
456.26 +}
456.27 \ No newline at end of file
457.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
457.2 +++ b/web/static/css/cluetip.css Mon Apr 26 11:16:23 2010 +0200
457.3 @@ -0,0 +1,211 @@
457.4 +/* global */
457.5 +#cluetip-close img {
457.6 + border: 0
457.7 + }
457.8 +#cluetip-title {
457.9 + overflow: hidden
457.10 + }
457.11 +#cluetip-title #cluetip-close {
457.12 + float: right;
457.13 + position: relative
457.14 + }
457.15 +#cluetip-waitimage {
457.16 + width: 43px;
457.17 + height: 11px;
457.18 + position: absolute;
457.19 + background-image: url(images/wait.gif)
457.20 + }
457.21 +.cluetip-arrows {
457.22 + display: none;
457.23 + position: absolute;
457.24 + top: 0;
457.25 + left: -11px;
457.26 + height: 22px;
457.27 + width: 11px;
457.28 + background-repeat: no-repeat;
457.29 + background-position: 0 0
457.30 + }
457.31 +#cluetip-extra {
457.32 + display: none
457.33 + }
457.34 +/***************************************
457.35 + =cluetipClass: 'default'
457.36 +-------------------------------------- */
457.37 +.cluetip-default {
457.38 + background-color: #ddf1c1
457.39 + }
457.40 +.cluetip-default #cluetip-outer {
457.41 + position: relative;
457.42 + margin: 0;
457.43 + background-color: #ddf1c1
457.44 + }
457.45 +.cluetip-default h3#cluetip-title {
457.46 + margin: 0 0 5px;
457.47 + padding: 8px 10px 4px;
457.48 + font-size: 1.1em;
457.49 + font-weight: normal;
457.50 + background-color: #437353;
457.51 + color: #fff
457.52 + }
457.53 +.cluetip-default #cluetip-title a {
457.54 + color: #ddf1c1;
457.55 + font-size: 0.95em
457.56 + }
457.57 +.cluetip-default #cluetip-inner {
457.58 + padding: 10px
457.59 + }
457.60 +.cluetip-default div#cluetip-close {
457.61 + text-align: right;
457.62 + margin: 0 5px 5px;
457.63 + color: #900
457.64 + }
457.65 +/* default arrows */
457.66 +.clue-right-default .cluetip-arrows {
457.67 + background-image: url(images/darrowleft.gif)
457.68 + }
457.69 +.clue-left-default .cluetip-arrows {
457.70 + background-image: url(images/darrowright.gif);
457.71 + left: 100%;
457.72 + margin-right: -11px
457.73 + }
457.74 +.clue-top-default .cluetip-arrows {
457.75 + background-image: url(images/darrowdown.gif);
457.76 + top: 100%;
457.77 + left: 50%;
457.78 + margin-left: -11px;
457.79 + height: 11px;
457.80 + width: 22px
457.81 + }
457.82 +.clue-bottom-default .cluetip-arrows {
457.83 + background-image: url(images/darrowup.gif);
457.84 + top: -11px;
457.85 + left: 50%;
457.86 + margin-left: -11px;
457.87 + height: 11px;
457.88 + width: 22px
457.89 + }
457.90 +/***************************************
457.91 + =cluetipClass: 'jtip'
457.92 +-------------------------------------- */
457.93 +.cluetip-jtip {
457.94 + background-color: transparent
457.95 + }
457.96 +.cluetip-jtip #cluetip-outer {
457.97 + border: 2px solid #ccc;
457.98 + position: relative;
457.99 + background-color: #fff
457.100 + }
457.101 +.cluetip-jtip h3#cluetip-title {
457.102 + margin: 0 0 5px;
457.103 + padding: 2px 5px;
457.104 + font-size: 16px;
457.105 + font-weight: normal;
457.106 + background-color: #ccc;
457.107 + color: #333
457.108 + }
457.109 +.cluetip-jtip #cluetip-inner {
457.110 + padding: 0 5px 5px;
457.111 + display: inline-block
457.112 + }
457.113 +.cluetip-jtip div#cluetip-close {
457.114 + text-align: right;
457.115 + margin: 0 5px 5px;
457.116 + color: #900
457.117 + }
457.118 +/* jtip arrows */
457.119 +.clue-right-jtip .cluetip-arrows {
457.120 + background-image: url(images/arrowleft.gif)
457.121 + }
457.122 +.clue-left-jtip .cluetip-arrows {
457.123 + background-image: url(images/arrowright.gif);
457.124 + left: 100%;
457.125 + margin-right: -11px
457.126 + }
457.127 +.clue-top-jtip .cluetip-arrows {
457.128 + background-image: url(images/arrowdown.gif);
457.129 + top: 100%;
457.130 + left: 50%;
457.131 + margin-left: -11px;
457.132 + height: 11px;
457.133 + width: 22px
457.134 + }
457.135 +.clue-bottom-jtip .cluetip-arrows {
457.136 + background-image: url(images/arrowup.gif);
457.137 + top: -11px;
457.138 + left: 50%;
457.139 + margin-left: -11px;
457.140 + height: 11px;
457.141 + width: 22px
457.142 + }
457.143 +/***************************************
457.144 + =cluetipClass: 'rounded'
457.145 +-------------------------------------- */
457.146 +.cluetip-rounded {
457.147 + background: transparent url(images/bl.gif) no-repeat 0 100%;
457.148 + margin-top: 10px;
457.149 + margin-left: 12px
457.150 + }
457.151 +.cluetip-rounded #cluetip-outer {
457.152 + background: transparent url(images/tl.gif) no-repeat 0 0;
457.153 + margin-top: -12px
457.154 + }
457.155 +.cluetip-rounded #cluetip-title {
457.156 + background-color: transparent;
457.157 + padding: 12px 12px 0;
457.158 + margin: 0 -12px 0 0;
457.159 + position: relative
457.160 + }
457.161 +.cluetip-rounded #cluetip-extra {
457.162 + position: absolute;
457.163 + display: block;
457.164 + background: transparent url(images/tr.gif) no-repeat 100% 0;
457.165 + top: 0;
457.166 + right: 0;
457.167 + width: 12px;
457.168 + height: 30px;
457.169 + margin: -12px -12px 0 0
457.170 + }
457.171 +.cluetip-rounded #cluetip-inner {
457.172 + background: url(images/br.gif) no-repeat 100% 100%;
457.173 + padding: 5px 12px 12px;
457.174 + margin: -18px -12px 0 0;
457.175 + position: relative
457.176 + }
457.177 +.cluetip-rounded div#cluetip-close {
457.178 + text-align: right;
457.179 + margin: 0 5px 5px;
457.180 + color: #009;
457.181 + background: transparent
457.182 + }
457.183 +.cluetip-rounded div#cluetip-close a {
457.184 + color: #777
457.185 + }
457.186 +/* rounded arrows */
457.187 +.clue-right-rounded .cluetip-arrows {
457.188 + background-image: url(images/rarrowleft.gif)
457.189 + }
457.190 +.clue-left-rounded .cluetip-arrows {
457.191 + background-image: url(images/rarrowright.gif);
457.192 + left: 100%;
457.193 + margin-left: 12px
457.194 + }
457.195 +.clue-top-rounded .cluetip-arrows {
457.196 + background-image: url(images/rarrowdown.gif);
457.197 + top: 100%;
457.198 + left: 50%;
457.199 + margin-left: -11px;
457.200 + height: 11px;
457.201 + width: 22px
457.202 + }
457.203 +.clue-bottom-rounded .cluetip-arrows {
457.204 + background-image: url(images/rarrowup.gif);
457.205 + top: -23px;
457.206 + left: 50%;
457.207 + margin-left: -11px;
457.208 + height: 11px;
457.209 + width: 22px
457.210 + }
457.211 +/* stupid IE6 HasLayout hack */
457.212 +.cluetip-rounded #cluetip-title, .cluetip-rounded #cluetip-inner {
457.213 + zoom: 1
457.214 + }
458.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
458.2 +++ b/web/static/css/demo_page.css Mon Apr 26 11:16:23 2010 +0200
458.3 @@ -0,0 +1,93 @@
458.4 +
458.5 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
458.6 + * General page setup
458.7 + */
458.8 +#dt_example {
458.9 + font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
458.10 + margin: 0;
458.11 + padding: 0;
458.12 + color: #333;
458.13 + background-color: #fff;
458.14 +}
458.15 +
458.16 +
458.17 +#dt_example #container {
458.18 + width: 800px;
458.19 + margin: 30px auto;
458.20 + padding: 0;
458.21 +}
458.22 +
458.23 +
458.24 +#dt_example #footer {
458.25 + margin: 50px auto 0 auto;
458.26 + padding: 0;
458.27 +}
458.28 +
458.29 +#dt_example #demo {
458.30 + margin: 30px auto 0 auto;
458.31 +}
458.32 +
458.33 +#dt_example .demo_jui {
458.34 + margin: 30px auto 0 auto;
458.35 +}
458.36 +
458.37 +#dt_example .big {
458.38 + font-size: 1.3em;
458.39 + font-weight: bold;
458.40 + line-height: 1.6em;
458.41 + color: #4E6CA3;
458.42 +}
458.43 +
458.44 +#dt_example .spacer {
458.45 + height: 20px;
458.46 + clear: both;
458.47 +}
458.48 +
458.49 +#dt_example .clear {
458.50 + clear: both;
458.51 +}
458.52 +
458.53 +#dt_example pre {
458.54 + padding: 15px;
458.55 + background-color: #F5F5F5;
458.56 + border: 1px solid #CCCCCC;
458.57 +}
458.58 +
458.59 +#dt_example h1 {
458.60 + margin-top: 2em;
458.61 + font-size: 1.3em;
458.62 + font-weight: normal;
458.63 + line-height: 1.6em;
458.64 + color: #4E6CA3;
458.65 + border-bottom: 1px solid #B0BED9;
458.66 + clear: both;
458.67 +}
458.68 +
458.69 +#dt_example h2 {
458.70 + font-size: 1.2em;
458.71 + font-weight: normal;
458.72 + line-height: 1.6em;
458.73 + color: #4E6CA3;
458.74 + clear: both;
458.75 +}
458.76 +
458.77 +#dt_example a {
458.78 + color: #0063DC;
458.79 + text-decoration: none;
458.80 +}
458.81 +
458.82 +#dt_example a:hover {
458.83 + text-decoration: underline;
458.84 +}
458.85 +
458.86 +#dt_example ul {
458.87 + color: #B0BED9;
458.88 +}
458.89 +
458.90 +.css_right {
458.91 + float: right;
458.92 +}
458.93 +
458.94 +.css_left {
458.95 + float: left;
458.96 +}
458.97 \ No newline at end of file
459.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
459.2 +++ b/web/static/css/demo_table.css Mon Apr 26 11:16:23 2010 +0200
459.3 @@ -0,0 +1,493 @@
459.4 +/*
459.5 + * File: demo_table.css
459.6 + * CVS: $Id$
459.7 + * Description: CSS descriptions for DataTables demo pages
459.8 + * Author: Allan Jardine
459.9 + * Created: Tue May 12 06:47:22 BST 2009
459.10 + * Modified: $Date$ by $Author$
459.11 + * Language: CSS
459.12 + * Project: DataTables
459.13 + *
459.14 + * Copyright 2009 Allan Jardine. All Rights Reserved.
459.15 + *
459.16 + * ***************************************************************************
459.17 + * DESCRIPTION
459.18 + *
459.19 + * The styles given here are suitable for the demos that are used with the standard DataTables
459.20 + * distribution (see www.datatables.net). You will most likely wish to modify these styles to
459.21 + * meet the layout requirements of your site.
459.22 + *
459.23 + * Common issues:
459.24 + * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
459.25 + * no conflict between the two pagination types. If you want to use full_numbers pagination
459.26 + * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
459.27 + * modify that selector.
459.28 + * Note that the path used for Images is relative. All images are by default located in
459.29 + * ../images/ - relative to this CSS file.
459.30 + */
459.31 +
459.32 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
459.33 + * DataTables features
459.34 + */
459.35 +
459.36 +.dataTables_wrapper {
459.37 + position: relative;
459.38 + min-height: 302px;
459.39 + clear: both;
459.40 + _height: 302px;
459.41 + zoom: 1; /* Feeling sorry for IE */
459.42 +}
459.43 +
459.44 +.dataTables_processing {
459.45 + position: absolute;
459.46 + top: 50%;
459.47 + left: 50%;
459.48 + width: 250px;
459.49 + height: 30px;
459.50 + margin-left: -125px;
459.51 + margin-top: -15px;
459.52 + padding: 14px 0 2px 0;
459.53 + border: 1px solid #ddd;
459.54 + text-align: center;
459.55 + color: #999;
459.56 + font-size: 14px;
459.57 + background-color: white;
459.58 +}
459.59 +
459.60 +.dataTables_length {
459.61 + width: 40%;
459.62 + float: left;
459.63 +}
459.64 +
459.65 +.dataTables_filter {
459.66 + width: 50%;
459.67 + float: right;
459.68 + text-align: right;
459.69 +}
459.70 +
459.71 +.dataTables_info {
459.72 + width: 60%;
459.73 + float: left;
459.74 +}
459.75 +
459.76 +.dataTables_paginate {
459.77 + width: 44px;
459.78 + * width: 50px;
459.79 + float: right;
459.80 + text-align: right;
459.81 +}
459.82 +
459.83 +/* Pagination nested */
459.84 +.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
459.85 + height: 19px;
459.86 + width: 19px;
459.87 + margin-left: 3px;
459.88 + float: left;
459.89 +}
459.90 +
459.91 +.paginate_disabled_previous {
459.92 + background-image: url('../images/back_disabled.jpg');
459.93 +}
459.94 +
459.95 +.paginate_enabled_previous {
459.96 + background-image: url('../images/back_enabled.jpg');
459.97 +}
459.98 +
459.99 +.paginate_disabled_next {
459.100 + background-image: url('../images/forward_disabled.jpg');
459.101 +}
459.102 +
459.103 +.paginate_enabled_next {
459.104 + background-image: url('../images/forward_enabled.jpg');
459.105 +}
459.106 +
459.107 +
459.108 +
459.109 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
459.110 + * DataTables display
459.111 + */
459.112 +table.display {
459.113 + margin: 0 auto;
459.114 + width: 100%;
459.115 + clear: both;
459.116 +}
459.117 +
459.118 +table.display thead th {
459.119 + padding: 3px 18px 3px 10px;
459.120 + border-bottom: 1px solid black;
459.121 + font-weight: bold;
459.122 + cursor: pointer;
459.123 + * cursor: hand;
459.124 +}
459.125 +
459.126 +table.display tfoot th {
459.127 + padding: 3px 10px;
459.128 + border-top: 1px solid black;
459.129 + font-weight: bold;
459.130 +}
459.131 +
459.132 +table.display tr.heading2 td {
459.133 + border-bottom: 1px solid #aaa;
459.134 +}
459.135 +
459.136 +table.display td {
459.137 + padding: 3px 10px;
459.138 +}
459.139 +
459.140 +table.display td.center {
459.141 + text-align: center;
459.142 +}
459.143 +
459.144 +
459.145 +
459.146 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
459.147 + * DataTables sorting
459.148 + */
459.149 +
459.150 +.sorting_asc {
459.151 + background: url('../images/sort_asc.png') no-repeat center right;
459.152 +}
459.153 +
459.154 +.sorting_desc {
459.155 + background: url('../images/sort_desc.png') no-repeat center right;
459.156 +}
459.157 +
459.158 +.sorting {
459.159 + background: url('../images/sort_both.png') no-repeat center right;
459.160 +}
459.161 +
459.162 +.sorting_asc_disabled {
459.163 + background: url('../images/sort_asc_disabled.png') no-repeat center right;
459.164 +}
459.165 +
459.166 +.sorting_desc_disabled {
459.167 + background: url('../images/sort_desc_disabled.png') no-repeat center right;
459.168 +}
459.169 +
459.170 +
459.171 +
459.172 +
459.173 +
459.174 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
459.175 + * DataTables row classes
459.176 + */
459.177 +table.display tr.odd.gradeA {
459.178 + background-color: #ddffdd;
459.179 +}
459.180 +
459.181 +table.display tr.even.gradeA {
459.182 + background-color: #eeffee;
459.183 +}
459.184 +
459.185 +table.display tr.odd.gradeA {
459.186 + background-color: #ddffdd;
459.187 +}
459.188 +
459.189 +table.display tr.even.gradeA {
459.190 + background-color: #eeffee;
459.191 +}
459.192 +
459.193 +table.display tr.odd.gradeC {
459.194 + background-color: #ddddff;
459.195 +}
459.196 +
459.197 +table.display tr.even.gradeC {
459.198 + background-color: #eeeeff;
459.199 +}
459.200 +
459.201 +table.display tr.odd.gradeX {
459.202 + background-color: #ffdddd;
459.203 +}
459.204 +
459.205 +table.display tr.even.gradeX {
459.206 + background-color: #ffeeee;
459.207 +}
459.208 +
459.209 +table.display tr.odd.gradeU {
459.210 + background-color: #ddd;
459.211 +}
459.212 +
459.213 +table.display tr.even.gradeU {
459.214 + background-color: #eee;
459.215 +}
459.216 +
459.217 +
459.218 +tr.odd {
459.219 + background-color: #E2E4FF;
459.220 +}
459.221 +
459.222 +tr.even {
459.223 + background-color: white;
459.224 +}
459.225 +
459.226 +
459.227 +
459.228 +
459.229 +
459.230 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
459.231 + * Misc
459.232 + */
459.233 +.top, .bottom {
459.234 + padding: 15px;
459.235 + background-color: #F5F5F5;
459.236 + border: 1px solid #CCCCCC;
459.237 +}
459.238 +
459.239 +.top .dataTables_info {
459.240 + float: none;
459.241 +}
459.242 +
459.243 +.clear {
459.244 + clear: both;
459.245 +}
459.246 +
459.247 +.dataTables_empty {
459.248 + text-align: center;
459.249 +}
459.250 +
459.251 +tfoot input {
459.252 + margin: 0.5em 0;
459.253 + width: 100%;
459.254 + color: #444;
459.255 +}
459.256 +
459.257 +tfoot input.search_init {
459.258 + color: #999;
459.259 +}
459.260 +
459.261 +td.group {
459.262 + background-color: #d1cfd0;
459.263 + border-bottom: 2px solid #A19B9E;
459.264 + border-top: 2px solid #A19B9E;
459.265 +}
459.266 +
459.267 +td.details {
459.268 + background-color: #d1cfd0;
459.269 + border: 2px solid #A19B9E;
459.270 +}
459.271 +
459.272 +
459.273 +.example_alt_pagination div.dataTables_info {
459.274 + width: 40%;
459.275 +}
459.276 +
459.277 +.paging_full_numbers {
459.278 + width: 400px;
459.279 + height: 22px;
459.280 + line-height: 22px;
459.281 +}
459.282 +
459.283 +.paging_full_numbers span.paginate_button,
459.284 + .paging_full_numbers span.paginate_active {
459.285 + border: 1px solid #aaa;
459.286 + -webkit-border-radius: 5px;
459.287 + -moz-border-radius: 5px;
459.288 + padding: 2px 5px;
459.289 + margin: 0 3px;
459.290 + cursor: pointer;
459.291 + *cursor: hand;
459.292 +}
459.293 +
459.294 +.paging_full_numbers span.paginate_button {
459.295 + background-color: #ddd;
459.296 +}
459.297 +
459.298 +.paging_full_numbers span.paginate_button:hover {
459.299 + background-color: #ccc;
459.300 +}
459.301 +
459.302 +.paging_full_numbers span.paginate_active {
459.303 + background-color: #99B3FF;
459.304 +}
459.305 +
459.306 +table.display tr.even.row_selected td {
459.307 + background-color: #B0BED9;
459.308 +}
459.309 +
459.310 +table.display tr.odd.row_selected td {
459.311 + background-color: #9FAFD1;
459.312 +}
459.313 +
459.314 +
459.315 +/*
459.316 + * Sorting classes for columns
459.317 + */
459.318 +/* For the standard odd/even */
459.319 +tr.odd td.sorting_1 {
459.320 + background-color: #D3D6FF;
459.321 +}
459.322 +
459.323 +tr.odd td.sorting_2 {
459.324 + background-color: #DADCFF;
459.325 +}
459.326 +
459.327 +tr.odd td.sorting_3 {
459.328 + background-color: #E0E2FF;
459.329 +}
459.330 +
459.331 +tr.even td.sorting_1 {
459.332 + background-color: #EAEBFF;
459.333 +}
459.334 +
459.335 +tr.even td.sorting_2 {
459.336 + background-color: #F2F3FF;
459.337 +}
459.338 +
459.339 +tr.even td.sorting_3 {
459.340 + background-color: #F9F9FF;
459.341 +}
459.342 +
459.343 +
459.344 +/* For the Conditional-CSS grading rows */
459.345 +/*
459.346 + Colour calculations (based off the main row colours)
459.347 + Level 1:
459.348 + dd > c4
459.349 + ee > d5
459.350 + Level 2:
459.351 + dd > d1
459.352 + ee > e2
459.353 + */
459.354 +tr.odd.gradeA td.sorting_1 {
459.355 + background-color: #c4ffc4;
459.356 +}
459.357 +
459.358 +tr.odd.gradeA td.sorting_2 {
459.359 + background-color: #d1ffd1;
459.360 +}
459.361 +
459.362 +tr.odd.gradeA td.sorting_3 {
459.363 + background-color: #d1ffd1;
459.364 +}
459.365 +
459.366 +tr.even.gradeA td.sorting_1 {
459.367 + background-color: #d5ffd5;
459.368 +}
459.369 +
459.370 +tr.even.gradeA td.sorting_2 {
459.371 + background-color: #e2ffe2;
459.372 +}
459.373 +
459.374 +tr.even.gradeA td.sorting_3 {
459.375 + background-color: #e2ffe2;
459.376 +}
459.377 +
459.378 +tr.odd.gradeC td.sorting_1 {
459.379 + background-color: #c4c4ff;
459.380 +}
459.381 +
459.382 +tr.odd.gradeC td.sorting_2 {
459.383 + background-color: #d1d1ff;
459.384 +}
459.385 +
459.386 +tr.odd.gradeC td.sorting_3 {
459.387 + background-color: #d1d1ff;
459.388 +}
459.389 +
459.390 +tr.even.gradeC td.sorting_1 {
459.391 + background-color: #d5d5ff;
459.392 +}
459.393 +
459.394 +tr.even.gradeC td.sorting_2 {
459.395 + background-color: #e2e2ff;
459.396 +}
459.397 +
459.398 +tr.even.gradeC td.sorting_3 {
459.399 + background-color: #e2e2ff;
459.400 +}
459.401 +
459.402 +tr.odd.gradeX td.sorting_1 {
459.403 + background-color: #ffc4c4;
459.404 +}
459.405 +
459.406 +tr.odd.gradeX td.sorting_2 {
459.407 + background-color: #ffd1d1;
459.408 +}
459.409 +
459.410 +tr.odd.gradeX td.sorting_3 {
459.411 + background-color: #ffd1d1;
459.412 +}
459.413 +
459.414 +tr.even.gradeX td.sorting_1 {
459.415 + background-color: #ffd5d5;
459.416 +}
459.417 +
459.418 +tr.even.gradeX td.sorting_2 {
459.419 + background-color: #ffe2e2;
459.420 +}
459.421 +
459.422 +tr.even.gradeX td.sorting_3 {
459.423 + background-color: #ffe2e2;
459.424 +}
459.425 +
459.426 +tr.odd.gradeU td.sorting_1 {
459.427 + background-color: #c4c4c4;
459.428 +}
459.429 +
459.430 +tr.odd.gradeU td.sorting_2 {
459.431 + background-color: #d1d1d1;
459.432 +}
459.433 +
459.434 +tr.odd.gradeU td.sorting_3 {
459.435 + background-color: #d1d1d1;
459.436 +}
459.437 +
459.438 +tr.even.gradeU td.sorting_1 {
459.439 + background-color: #d5d5d5;
459.440 +}
459.441 +
459.442 +tr.even.gradeU td.sorting_2 {
459.443 + background-color: #e2e2e2;
459.444 +}
459.445 +
459.446 +tr.even.gradeU td.sorting_3 {
459.447 + background-color: #e2e2e2;
459.448 +}
459.449 +
459.450 +
459.451 +/*
459.452 + * Row highlighting example
459.453 + */
459.454 +.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
459.455 + background-color: #ECFFB3;
459.456 +}
459.457 +
459.458 +.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
459.459 + background-color: #E6FF99;
459.460 +}
459.461 +
459.462 +
459.463 +/*
459.464 + * KeyTable
459.465 + */
459.466 +table.KeyTable td {
459.467 + border: 3px solid transparent;
459.468 +}
459.469 +
459.470 +table.KeyTable td.focus {
459.471 + border: 3px solid #3366FF;
459.472 +}
459.473 +
459.474 +table.display tr.gradeA {
459.475 + background-color: #eeffee;
459.476 +}
459.477 +
459.478 +table.display tr.gradeC {
459.479 + background-color: #ddddff;
459.480 +}
459.481 +
459.482 +table.display tr.gradeX {
459.483 + background-color: #ffdddd;
459.484 +}
459.485 +
459.486 +table.display tr.gradeU {
459.487 + background-color: #ddd;
459.488 +}
459.489 +
459.490 +div.box {
459.491 + height: 100px;
459.492 + padding: 10px;
459.493 + overflow: auto;
459.494 + border: 1px solid #8080FF;
459.495 + background-color: #E5E5FF;
459.496 +}
460.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
460.2 +++ b/web/static/css/demo_table_jui.css Mon Apr 26 11:16:23 2010 +0200
460.3 @@ -0,0 +1,476 @@
460.4 +/*
460.5 + * File: demo_table_jui.css
460.6 + * CVS: $Id$
460.7 + * Description: CSS descriptions for DataTables demo pages
460.8 + * Author: Allan Jardine
460.9 + * Created: Tue May 12 06:47:22 BST 2009
460.10 + * Modified: $Date$ by $Author$
460.11 + * Language: CSS
460.12 + * Project: DataTables
460.13 + *
460.14 + * Copyright 2009 Allan Jardine. All Rights Reserved.
460.15 + *
460.16 + * ***************************************************************************
460.17 + * DESCRIPTION
460.18 + *
460.19 + * The styles given here are suitable for the demos that are used with the standard DataTables
460.20 + * distribution (see www.datatables.net). You will most likely wish to modify these styles to
460.21 + * meet the layout requirements of your site.
460.22 + *
460.23 + * Common issues:
460.24 + * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
460.25 + * no conflict between the two pagination types. If you want to use full_numbers pagination
460.26 + * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
460.27 + * modify that selector.
460.28 + * Note that the path used for Images is relative. All images are by default located in
460.29 + * ../images/ - relative to this CSS file.
460.30 + */
460.31 +
460.32 +
460.33 +/*
460.34 + * jQuery UI specific styling
460.35 + */
460.36 +
460.37 +.paging_two_button .fg-button {
460.38 + float: left;
460.39 + cursor: pointer;
460.40 + * cursor: hand;
460.41 +}
460.42 +
460.43 +.paging_full_numbers .fg-button {
460.44 + padding: 2px 6px;
460.45 + cursor: pointer;
460.46 + * cursor: hand;
460.47 +}
460.48 +
460.49 +.paging_full_numbers {
460.50 + width: 350px !important;
460.51 +}
460.52 +
460.53 +.fg-toolbar {
460.54 + padding: 5px;
460.55 +}
460.56 +
460.57 +.dataTables_paginate {
460.58 + width: auto;
460.59 +}
460.60 +
460.61 +table.display thead th {
460.62 + padding: 3px 0px 3px 10px;
460.63 + cursor: pointer;
460.64 + * cursor: hand;
460.65 +}
460.66 +
460.67 +
460.68 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.69 + *
460.70 + * Everything below this line is the same as demo_table.css. This file is
460.71 + * required for 'cleanliness' of the markup
460.72 + *
460.73 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
460.74 +
460.75 +
460.76 +
460.77 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.78 + * DataTables features
460.79 + */
460.80 +
460.81 +.dataTables_wrapper {
460.82 + position: relative;
460.83 + min-height: 302px;
460.84 + _height: 302px;
460.85 + clear: both;
460.86 +}
460.87 +
460.88 +.dataTables_processing {
460.89 + position: absolute;
460.90 + top: 0px;
460.91 + left: 50%;
460.92 + width: 250px;
460.93 + margin-left: -125px;
460.94 + border: 1px solid #ddd;
460.95 + text-align: center;
460.96 + color: #999;
460.97 + font-size: 11px;
460.98 + padding: 2px 0;
460.99 +}
460.100 +
460.101 +.dataTables_length {
460.102 + width: 40%;
460.103 + float: left;
460.104 +}
460.105 +
460.106 +.dataTables_filter {
460.107 + width: 50%;
460.108 + float: right;
460.109 + text-align: right;
460.110 +}
460.111 +
460.112 +.dataTables_info {
460.113 + width: 50%;
460.114 + float: left;
460.115 +}
460.116 +
460.117 +.dataTables_paginate {
460.118 + float: right;
460.119 + text-align: right;
460.120 +}
460.121 +
460.122 +/* Pagination nested */
460.123 +.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
460.124 + height: 19px;
460.125 + width: 19px;
460.126 + margin-left: 3px;
460.127 + float: left;
460.128 +}
460.129 +
460.130 +.paginate_disabled_previous {
460.131 + background-image: url('../images/back_disabled.jpg');
460.132 +}
460.133 +
460.134 +.paginate_enabled_previous {
460.135 + background-image: url('../images/back_enabled.jpg');
460.136 +}
460.137 +
460.138 +.paginate_disabled_next {
460.139 + background-image: url('../images/forward_disabled.jpg');
460.140 +}
460.141 +
460.142 +.paginate_enabled_next {
460.143 + background-image: url('../images/forward_enabled.jpg');
460.144 +}
460.145 +
460.146 +
460.147 +
460.148 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.149 + * DataTables display
460.150 + */
460.151 +table.display {
460.152 + margin: 0 auto;
460.153 + width: 100%;
460.154 + clear: both;
460.155 +}
460.156 +
460.157 +table.display tfoot th {
460.158 + padding: 3px 10px;
460.159 + border-top: 1px solid black;
460.160 + font-weight: bold;
460.161 +}
460.162 +
460.163 +table.display tr.heading2 td {
460.164 + border-bottom: 1px solid #aaa;
460.165 +}
460.166 +
460.167 +table.display td {
460.168 + padding: 3px 10px;
460.169 +}
460.170 +
460.171 +table.display td.center {
460.172 + text-align: center;
460.173 +}
460.174 +
460.175 +
460.176 +
460.177 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.178 + * DataTables sorting
460.179 + */
460.180 +
460.181 +.sorting_asc {
460.182 + background: url('../images/sort_asc.jpg') no-repeat center right;
460.183 +}
460.184 +
460.185 +.sorting_desc {
460.186 + background: url('../images/sort_desc.jpg') no-repeat center right;
460.187 +}
460.188 +
460.189 +.sorting {
460.190 + background: url('../images/sort_both.jpg') no-repeat center right;
460.191 +}
460.192 +
460.193 +
460.194 +
460.195 +
460.196 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.197 + * DataTables row classes
460.198 + */
460.199 +table.display tr.odd.gradeA {
460.200 + background-color: #ddffdd;
460.201 +}
460.202 +
460.203 +table.display tr.even.gradeA {
460.204 + background-color: #eeffee;
460.205 +}
460.206 +
460.207 +
460.208 +
460.209 +
460.210 +table.display tr.odd.gradeA {
460.211 + background-color: #ddffdd;
460.212 +}
460.213 +
460.214 +table.display tr.even.gradeA {
460.215 + background-color: #eeffee;
460.216 +}
460.217 +
460.218 +table.display tr.odd.gradeC {
460.219 + background-color: #ddddff;
460.220 +}
460.221 +
460.222 +table.display tr.even.gradeC {
460.223 + background-color: #eeeeff;
460.224 +}
460.225 +
460.226 +table.display tr.odd.gradeX {
460.227 + background-color: #ffdddd;
460.228 +}
460.229 +
460.230 +table.display tr.even.gradeX {
460.231 + background-color: #ffeeee;
460.232 +}
460.233 +
460.234 +table.display tr.odd.gradeU {
460.235 + background-color: #ddd;
460.236 +}
460.237 +
460.238 +table.display tr.even.gradeU {
460.239 + background-color: #eee;
460.240 +}
460.241 +
460.242 +
460.243 +tr.odd {
460.244 + background-color: #E2E4FF;
460.245 +}
460.246 +
460.247 +tr.even {
460.248 + background-color: white;
460.249 +}
460.250 +
460.251 +
460.252 +
460.253 +
460.254 +
460.255 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
460.256 + * Misc
460.257 + */
460.258 +.top, .bottom {
460.259 + padding: 15px;
460.260 + background-color: #F5F5F5;
460.261 + border: 1px solid #CCCCCC;
460.262 +}
460.263 +
460.264 +.top .dataTables_info {
460.265 + float: none;
460.266 +}
460.267 +
460.268 +.clear {
460.269 + clear: both;
460.270 +}
460.271 +
460.272 +.dataTables_empty {
460.273 + text-align: center;
460.274 +}
460.275 +
460.276 +tfoot input {
460.277 + margin: 0.5em 0;
460.278 + width: 100%;
460.279 + color: #444;
460.280 +}
460.281 +
460.282 +tfoot input.search_init {
460.283 + color: #999;
460.284 +}
460.285 +
460.286 +td.group {
460.287 + background-color: #d1cfd0;
460.288 + border-bottom: 2px solid #A19B9E;
460.289 + border-top: 2px solid #A19B9E;
460.290 +}
460.291 +
460.292 +td.details {
460.293 + background-color: #d1cfd0;
460.294 + border: 2px solid #A19B9E;
460.295 +}
460.296 +
460.297 +
460.298 +.example_alt_pagination div.dataTables_info {
460.299 + width: 40%;
460.300 +}
460.301 +
460.302 +.paging_full_numbers span.paginate_button,
460.303 + .paging_full_numbers span.paginate_active {
460.304 + border: 1px solid #aaa;
460.305 + -webkit-border-radius: 5px;
460.306 + -moz-border-radius: 5px;
460.307 + padding: 2px 5px;
460.308 + margin: 0 3px;
460.309 + cursor: pointer;
460.310 + *cursor: hand;
460.311 +}
460.312 +
460.313 +.paging_full_numbers span.paginate_button {
460.314 + background-color: #ddd;
460.315 +}
460.316 +
460.317 +.paging_full_numbers span.paginate_button:hover {
460.318 + background-color: #ccc;
460.319 +}
460.320 +
460.321 +.paging_full_numbers span.paginate_active {
460.322 + background-color: #99B3FF;
460.323 +}
460.324 +
460.325 +table.display tr.even.row_selected td {
460.326 + background-color: #B0BED9;
460.327 +}
460.328 +
460.329 +table.display tr.odd.row_selected td {
460.330 + background-color: #9FAFD1;
460.331 +}
460.332 +
460.333 +
460.334 +/*
460.335 + * Sorting classes for columns
460.336 + */
460.337 +/* For the standard odd/even */
460.338 +tr.odd td.sorting_1 {
460.339 + background-color: #D3D6FF;
460.340 +}
460.341 +
460.342 +tr.odd td.sorting_2 {
460.343 + background-color: #DADCFF;
460.344 +}
460.345 +
460.346 +tr.odd td.sorting_3 {
460.347 + background-color: #E0E2FF;
460.348 +}
460.349 +
460.350 +tr.even td.sorting_1 {
460.351 + background-color: #EAEBFF;
460.352 +}
460.353 +
460.354 +tr.even td.sorting_2 {
460.355 + background-color: #F2F3FF;
460.356 +}
460.357 +
460.358 +tr.even td.sorting_3 {
460.359 + background-color: #F9F9FF;
460.360 +}
460.361 +
460.362 +
460.363 +/* For the Conditional-CSS grading rows */
460.364 +/*
460.365 + Colour calculations (based off the main row colours)
460.366 + Level 1:
460.367 + dd > c4
460.368 + ee > d5
460.369 + Level 2:
460.370 + dd > d1
460.371 + ee > e2
460.372 + */
460.373 +tr.odd.gradeA td.sorting_1 {
460.374 + background-color: #c4ffc4;
460.375 +}
460.376 +
460.377 +tr.odd.gradeA td.sorting_2 {
460.378 + background-color: #d1ffd1;
460.379 +}
460.380 +
460.381 +tr.odd.gradeA td.sorting_3 {
460.382 + background-color: #d1ffd1;
460.383 +}
460.384 +
460.385 +tr.even.gradeA td.sorting_1 {
460.386 + background-color: #d5ffd5;
460.387 +}
460.388 +
460.389 +tr.even.gradeA td.sorting_2 {
460.390 + background-color: #e2ffe2;
460.391 +}
460.392 +
460.393 +tr.even.gradeA td.sorting_3 {
460.394 + background-color: #e2ffe2;
460.395 +}
460.396 +
460.397 +tr.odd.gradeC td.sorting_1 {
460.398 + background-color: #c4c4ff;
460.399 +}
460.400 +
460.401 +tr.odd.gradeC td.sorting_2 {
460.402 + background-color: #d1d1ff;
460.403 +}
460.404 +
460.405 +tr.odd.gradeC td.sorting_3 {
460.406 + background-color: #d1d1ff;
460.407 +}
460.408 +
460.409 +tr.even.gradeC td.sorting_1 {
460.410 + background-color: #d5d5ff;
460.411 +}
460.412 +
460.413 +tr.even.gradeC td.sorting_2 {
460.414 + background-color: #e2e2ff;
460.415 +}
460.416 +
460.417 +tr.even.gradeC td.sorting_3 {
460.418 + background-color: #e2e2ff;
460.419 +}
460.420 +
460.421 +tr.odd.gradeX td.sorting_1 {
460.422 + background-color: #ffc4c4;
460.423 +}
460.424 +
460.425 +tr.odd.gradeX td.sorting_2 {
460.426 + background-color: #ffd1d1;
460.427 +}
460.428 +
460.429 +tr.odd.gradeX td.sorting_3 {
460.430 + background-color: #ffd1d1;
460.431 +}
460.432 +
460.433 +tr.even.gradeX td.sorting_1 {
460.434 + background-color: #ffd5d5;
460.435 +}
460.436 +
460.437 +tr.even.gradeX td.sorting_2 {
460.438 + background-color: #ffe2e2;
460.439 +}
460.440 +
460.441 +tr.even.gradeX td.sorting_3 {
460.442 + background-color: #ffe2e2;
460.443 +}
460.444 +
460.445 +tr.odd.gradeU td.sorting_1 {
460.446 + background-color: #c4c4c4;
460.447 +}
460.448 +
460.449 +tr.odd.gradeU td.sorting_2 {
460.450 + background-color: #d1d1d1;
460.451 +}
460.452 +
460.453 +tr.odd.gradeU td.sorting_3 {
460.454 + background-color: #d1d1d1;
460.455 +}
460.456 +
460.457 +tr.even.gradeU td.sorting_1 {
460.458 + background-color: #d5d5d5;
460.459 +}
460.460 +
460.461 +tr.even.gradeU td.sorting_2 {
460.462 + background-color: #e2e2e2;
460.463 +}
460.464 +
460.465 +tr.even.gradeU td.sorting_3 {
460.466 + background-color: #e2e2e2;
460.467 +}
460.468 +
460.469 +
460.470 +/*
460.471 + * Row highlighting example
460.472 + */
460.473 +.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
460.474 + background-color: #ECFFB3;
460.475 +}
460.476 +
460.477 +.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
460.478 + background-color: #E6FF99;
460.479 +}
460.480 \ No newline at end of file
461.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
461.2 +++ b/web/static/css/global.css Mon Apr 26 11:16:23 2010 +0200
461.3 @@ -0,0 +1,316 @@
461.4 +* {
461.5 + margin: 0;
461.6 + padding: 0
461.7 + }
461.8 +/* LAYOUT COLOR */
461.9 +body {
461.10 + background-color: #FFFFFF;
461.11 + }
461.12 +#container {
461.13 + background-color: #fff
461.14 + }
461.15 +#header {
461.16 + background-color:#F2F7FB;
461.17 +}
461.18 +#footer {
461.19 + background: #DDDDDD;
461.20 + border-top: 1px solid #999999
461.21 + }
461.22 +/* END LAYOUT COLOR */
461.23 +p {
461.24 + line-height: 1.2em;
461.25 +}
461.26 +h1, h2 {
461.27 + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
461.28 + font-weight: normal
461.29 + }
461.30 +h1 {
461.31 + font-size: 197%
461.32 + }
461.33 +h2 {
461.34 + font-size: 167%;
461.35 + margin: 0px
461.36 + }
461.37 +h3 {
461.38 + margin-bottom: 1em;
461.39 + text-transform: uppercase;
461.40 + font-size: 100%
461.41 + }
461.42 +ul, ol {
461.43 + /*margin-bottom: 1.5em;*/
461.44 + line-height: 1.6em;
461.45 + }
461.46 +p {}
461.47 +ol {}
461.48 +ul li {
461.49 + list-style: none
461.50 + }
461.51 +td, th {
461.52 + line-height: 10px;
461.53 + font-size: 90%;
461.54 + vertical-align: middle;
461.55 + padding: 1px 5px;
461.56 + }
461.57 +a {
461.58 + text-decoration: none;
461.59 + color: #666666
461.60 + }
461.61 +a:hover, a:active {
461.62 + /*text-decoration: none;*/
461.63 + color: #1777B1
461.64 + }
461.65 +.hide {
461.66 + display: none
461.67 + }
461.68 +/*
461.69 +a:visited {
461.70 + color: #666666;
461.71 +}*/
461.72 +img {
461.73 + border: none
461.74 + }
461.75 +img.left {
461.76 + float: left;
461.77 + margin: 0 20px 10px 0
461.78 + }
461.79 +img.right {
461.80 + float: right;
461.81 + margin: 0 0 10px 20px
461.82 + }
461.83 +input[type="text"], input[type="password"], textarea, select, .vTextField, .x-form-text, textarea.x-form-field {
461.84 + border: 1px solid #999999;
461.85 + background: #FFFFFF;
461.86 + margin-right: 0px;
461.87 + margin-left: 0px;
461.88 + padding: 2px 3px 0pt
461.89 + }
461.90 +input[type="submit"], input[type="button"], input[type="reset"], .submit-row input {
461.91 + background: white;
461.92 + border-color: #DDDDDD #aaa #aaa #ddd;
461.93 + border-style: solid;
461.94 + border-width: 1px;
461.95 + color: black;
461.96 + padding: 3px
461.97 + }
461.98 +select {
461.99 + padding: 0px
461.100 + }
461.101 +th {
461.102 + font-weight: bold;
461.103 + text-align: center
461.104 + }
461.105 +
461.106 +/* LOGIN */
461.107 +#form_login {
461.108 + margin:0px auto;
461.109 + width: 250px;
461.110 +}
461.111 +
461.112 +
461.113 +/* Finestra ancora sezioni */
461.114 +.x-hidden {
461.115 + left: -10000px;
461.116 + position: absolute;
461.117 + top: -10000px;
461.118 + visibility: hidden
461.119 + }
461.120 +.x-window-body a {
461.121 + font-size: 11px;
461.122 + font-weight: bold;
461.123 + padding: 3px;
461.124 + margin-bottom: 3px
461.125 + }
461.126 +/* Login */
461.127 +.vTextField, .vPasswordField {
461.128 + margin-bottom: 7px
461.129 + }
461.130 +#login label {
461.131 + width: 80px;
461.132 + float: left
461.133 + }
461.134 +.errors {
461.135 + background: #FFFFCC url(/static/img/icon_error.gif) no-repeat scroll 5px 10px;
461.136 + border: 1px solid red;
461.137 + color: red;
461.138 + display: block;
461.139 + font-size: 14px !important;
461.140 + margin: 0px 0px 10px;
461.141 + padding: 4px 5px 4px 5px;
461.142 + width: 100%
461.143 + }
461.144 +.errors h2 {
461.145 + margin-left: 20px
461.146 + }
461.147 +/* Logo */
461.148 +#logo {
461.149 + background: transparent url(/static/img/logo.gif) no-repeat scroll 0px 0px;
461.150 + width:150px;
461.151 + height:60px;
461.152 + float: left
461.153 + }
461.154 +
461.155 +#logo h1, #logo h2 {
461.156 + float: left
461.157 + }
461.158 +
461.159 +#logo a {
461.160 + text-decoration: none;
461.161 + color: #000000
461.162 + }
461.163 +/* Search
461.164 +#user-tools {
461.165 + float: right;
461.166 + width: 300px;
461.167 + margin-top: 70px;
461.168 + text-align: right
461.169 + }
461.170 +*/
461.171 +
461.172 +#user-tools {
461.173 + float: right;
461.174 + width: 300px;
461.175 + text-align: right
461.176 +}
461.177 +
461.178 +/* Table List */
461.179 +.list_table {
461.180 + width: 100%
461.181 + }
461.182 +.list_table td, .list_table th {
461.183 + border-bottom: 1px solid #EEEEEE;
461.184 + font-family: "Lucida Grande", Verdana, Arial, sans-serif;
461.185 + font-size: 90%;
461.186 + line-height: 10px;
461.187 + padding: 5px;
461.188 + vertical-align: middle
461.189 + }
461.190 +.title_nav {
461.191 + margin-bottom: 15px
461.192 + }
461.193 +/* table form */
461.194 +form fieldset {
461.195 + border: 1px solid #D7E5F2;
461.196 + background-color: #F9FBFD;
461.197 + margin-top: 10px;
461.198 + padding-top: 10px;
461.199 + padding-right: 10px
461.200 + }
461.201 +.form fieldset {
461.202 + padding: 20px
461.203 + }
461.204 +form legend, .form legend {
461.205 + border: 1px solid #D7E5F2;
461.206 + color: #2266AA;
461.207 + font-size: 90%;
461.208 + font-weight: bold;
461.209 + margin: 0pt 20px;
461.210 + padding: 3px
461.211 + }
461.212 +form legend a, .form legend a {
461.213 + color: #2266AA
461.214 + }
461.215 +form table {
461.216 + color: #000000;
461.217 + width: 100%;
461.218 + border: 1px solid #D7E5F2;
461.219 + border-collapse: collapse
461.220 + }
461.221 +.form table {
461.222 + border: 0px solid #EEEEEE
461.223 + }
461.224 +form td, form th {
461.225 + padding-left: 4px;
461.226 + color: #000000;
461.227 + text-align: left;
461.228 + margin-right: 0px;
461.229 + padding: 7px
461.230 + }
461.231 +.form td, .form th {
461.232 + padding-left: 4px;
461.233 + color: #000000;
461.234 + text-align: left;
461.235 + padding: 10px;
461.236 + border-bottom: 0px solid #EEEEEE
461.237 + }
461.238 +form textarea, .form textarea {
461.239 + height: 97%;
461.240 + vertical-align: top;
461.241 + width: 100%
461.242 + }
461.243 +form label, .form label {
461.244 + font-size: 11px;
461.245 + color: #666666;
461.246 + /*font-variant : small-caps;*/
461.247 + text-transform: uppercase
461.248 + }
461.249 +form label.required, .form label.required {
461.250 + font-weight: bold;
461.251 + /* font-variant : small-caps;*/
461.252 + text-transform: uppercase
461.253 + }
461.254 +.label_header {
461.255 + font-size: 13px;
461.256 + /*font-variant: small-caps;*/
461.257 + font-weight: bold;
461.258 + text-transform: uppercase
461.259 + }
461.260 +/* Footer */
461.261 +#footer p {
461.262 + margin: 5px;
461.263 + text-align: right;
461.264 + font-size: 85%
461.265 + }
461.266 +/* EXT Grid */
461.267 +.x-grid3-hd-row td, .x-grid3-row td {
461.268 + padding: 0px
461.269 + }
461.270 +.x-panel-bbar .x-toolbar table {
461.271 + width: 350px
461.272 + }
461.273 +.x-grid3-header {
461.274 + border-bottom: 1px solid #999999
461.275 + }
461.276 +.x-panel-header {
461.277 + background: #D7E5F2;
461.278 + border: 1px solid #999999
461.279 + }
461.280 +.x-panel-body {
461.281 + border-width: 0px 1px 1px 1px;
461.282 + border-style: solid;
461.283 + border-color: #999999
461.284 + }
461.285 +.x-panel-bbar .x-toolbar table td {
461.286 + padding: 0px
461.287 + }
461.288 +/* Summary Table */
461.289 +.x-grid3-summary-row {
461.290 + background: #F1F2F4 none repeat scroll 0% 50%;
461.291 + border-left: 1px solid #FFFFFF;
461.292 + border-right: 1px solid #FFFFFF;
461.293 + color: #333333
461.294 + }
461.295 +.x-grid3-summary-row .x-grid3-cell-inner {
461.296 + font-weight: bold;
461.297 + padding-bottom: 4px
461.298 + }
461.299 +.x-grid3-row td, .x-grid3-summary-row td {
461.300 + padding-left: 0px;
461.301 + padding-right: 0px
461.302 + }
461.303 +/* Icon Button */
461.304 +.icon_add {
461.305 + background-image: url(/static/img/add.gif) !important
461.306 + }
461.307 +.icon_print {
461.308 + background-image: url(/static/img/print.gif) !important
461.309 + }
461.310 +/* LEGENDA */
461.311 +.legenda {
461.312 + font-size: 10px;
461.313 + text-align: right
461.314 + }
461.315 +
461.316 +/* HELP TEXT */
461.317 +.help_text {
461.318 + border-bottom:2px dashed orange;
461.319 +}
462.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
462.2 +++ b/web/static/css/html4css1.css Mon Apr 26 11:16:23 2010 +0200
462.3 @@ -0,0 +1,338 @@
462.4 +/*
462.5 +:Author: David Goodger
462.6 +:Contact: [email protected]
462.7 +:Date: $Date: 2021-12-18 01:56:14 +0100 (Sun, 18 Dec 2021) $
462.8 +:Revision: $Revision: 4224 $
462.9 +:Copyright: This stylesheet has been placed in the public domain.
462.10 +
462.11 +Default cascading style sheet for the HTML output of Docutils.
462.12 +
462.13 +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
462.14 +customize this style sheet.
462.15 +*/
462.16 +/* used to remove borders from tables and images */
462.17 +.borderless, table.borderless td, table.borderless th {
462.18 + border: 0
462.19 + }
462.20 +table.borderless td, table.borderless th {
462.21 + /* Override padding for "table.docutils td" with "! important".
462.22 + The right padding separates the table cells. */
462.23 + padding: 0 0.5em 0 0 !important
462.24 + }
462.25 +.first {
462.26 + /* Override more specific margin styles with "! important". */
462.27 + margin-top: 0 !important
462.28 + }
462.29 +.last, .with-subtitle {
462.30 + margin-bottom: 0 !important
462.31 + }
462.32 +.hidden {
462.33 + display: none
462.34 + }
462.35 +a.toc-backref {
462.36 + text-decoration: none;
462.37 + color: #ba4a18
462.38 + }
462.39 +blockquote.epigraph {
462.40 + margin: 2em 5em
462.41 + }
462.42 +dl.docutils dd {
462.43 + margin-bottom: 0.5em
462.44 + }
462.45 +/* Uncomment (and remove this text!) to get bold-faced definition list terms
462.46 +dl.docutils dt {
462.47 + font-weight: bold ;}
462.48 +*/
462.49 +div.abstract {
462.50 + margin: 2em 5em
462.51 + }
462.52 +div.abstract p.topic-title {
462.53 + font-weight: bold;
462.54 + text-align: center
462.55 + }
462.56 +div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning {
462.57 + margin: 2em;
462.58 + border: medium outset;
462.59 + padding: 1em
462.60 + }
462.61 +div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title {
462.62 + font-weight: bold;
462.63 + font-family: sans-serif
462.64 + }
462.65 +div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title {
462.66 + color: #ff0000;
462.67 + font-weight: bold;
462.68 + font-family: sans-serif
462.69 + }
462.70 +/* Uncomment (and remove this text!) to get reduced vertical space in
462.71 + compound paragraphs.
462.72 +div.compound .compound-first, div.compound .compound-middle {
462.73 + margin-bottom: 0.5em ;}
462.74 +
462.75 +div.compound .compound-last, div.compound .compound-middle {
462.76 + margin-top: 0.5em ;}
462.77 +*/
462.78 +/* div.dedication { */
462.79 +/* margin: 2em 5em; */
462.80 +/* text-align: center; */
462.81 +/* font-style: italic */
462.82 +/* } */
462.83 +/* div.dedication p.topic-title { */
462.84 +/* font-weight: bold; */
462.85 +/* font-style: normal */
462.86 +/* } */
462.87 +/* div.figure { */
462.88 +/* margin-left: 2em; */
462.89 +/* margin-right: 2em */
462.90 +/* } */
462.91 +/* div.footer, div.header { */
462.92 +/* clear: both; */
462.93 +/* font-size: smaller */
462.94 +/* } */
462.95 +/* div.line-block { */
462.96 +/* display: block; */
462.97 +/* margin-top: 1em; */
462.98 +/* margin-bottom: 1em */
462.99 +/* } */
462.100 +/* div.line-block div.line-block { */
462.101 +/* margin-top: 0; */
462.102 +/* margin-bottom: 0; */
462.103 +/* margin-left: 1.5em */
462.104 +/* } */
462.105 +/* div.sidebar_orig { */
462.106 +/* margin-left: 1em; */
462.107 +/* border: medium outset; */
462.108 +/* padding: 1em; */
462.109 +/* background-color: #ffffee; */
462.110 +/* width: 40%; */
462.111 +/* float: right; */
462.112 +/* clear: right */
462.113 +/* } */
462.114 +div.sidebar {
462.115 + margin-left: 1em;
462.116 + margin-top: 1em;
462.117 + border: 1px solid orange;
462.118 + padding: 1em;
462.119 + background-color: #FFFFCC;
462.120 + width: 40%;
462.121 + float: right;
462.122 + clear: right;
462.123 + margin-bottom: 20px
462.124 + }
462.125 +div.sidebar p.rubric {
462.126 + font-family: sans-serif;
462.127 + font-size: medium
462.128 + }
462.129 +div.system-messages {
462.130 + margin: 5em
462.131 + }
462.132 +div.system-messages h1 {
462.133 + color: #ff0000
462.134 + }
462.135 +div.system-message {
462.136 + border: medium outset;
462.137 + padding: 1em
462.138 + }
462.139 +div.system-message p.system-message-title {
462.140 + color: #ff0000;
462.141 + font-weight: bold
462.142 + }
462.143 +div.topic {
462.144 + margin: 0em
462.145 + }
462.146 +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
462.147 + margin-top: 0.4em
462.148 + }
462.149 +h1.title {
462.150 + text-align: center
462.151 + }
462.152 +h2.subtitle {
462.153 + text-align: center
462.154 + }
462.155 +hr.docutils {
462.156 + width: 75%
462.157 + }
462.158 +img.align-left {
462.159 + clear: left
462.160 + }
462.161 +img.align-right {
462.162 + clear: right
462.163 + }
462.164 +#main_content ul {
462.165 + margin: 0pt;
462.166 + padding: 0pt 0pt 0pt 0.5em
462.167 + }
462.168 +#main_content li {
462.169 + list-style-type: square;
462.170 + margin-left: 2em;
462.171 + padding: 3px 0px 0px;
462.172 +/* font-family: arial, "Lucida Grande", verdana, sans-serif; */
462.173 +/* font-size: 12px */
462.174 + }
462.175 +ul.simple li a:hover {
462.176 + background-color: red;
462.177 + color: white
462.178 + }
462.179 +ol.arabic {
462.180 + list-style: decimal
462.181 + }
462.182 +ol.loweralpha {
462.183 + list-style: lower-alpha
462.184 + }
462.185 +ol.upperalpha {
462.186 + list-style: upper-alpha
462.187 + }
462.188 +ol.lowerroman {
462.189 + list-style: lower-roman
462.190 + }
462.191 +ol.upperroman {
462.192 + list-style: upper-roman
462.193 + }
462.194 +/* p.attribution { */
462.195 +/* text-align: right; */
462.196 +/* margin-left: 50% */
462.197 +/* } */
462.198 +/* p.caption { */
462.199 +/* font-style: italic */
462.200 +/* } */
462.201 +/* p.credits { */
462.202 +/* font-style: italic; */
462.203 +/* font-size: smaller */
462.204 +/* } */
462.205 +/* p.label { */
462.206 +/* white-space: nowrap */
462.207 +/* } */
462.208 +/* p.rubric { */
462.209 +/* font-weight: bold; */
462.210 +/* font-size: larger; */
462.211 +/* color: #b03060; */
462.212 +/* text-align: center */
462.213 +/* } */
462.214 +/* p.sidebar-title { */
462.215 +/* font-family: sans-serif; */
462.216 +/* font-weight: bold; */
462.217 +/* font-size: larger */
462.218 +/* } */
462.219 +/* p.sidebar-subtitle { */
462.220 +/* font-family: sans-serif; */
462.221 +/* font-weight: bold */
462.222 +/* } */
462.223 +/* p.topic-title { */
462.224 +/* font-size: 22px */
462.225 +/* } */
462.226 +/* p.topic-title a { */
462.227 +/* color: #AA0000 */
462.228 +/* } */
462.229 +pre.address {
462.230 + margin-bottom: 0;
462.231 + margin-top: 0;
462.232 + font-family: serif;
462.233 + font-size: 100%
462.234 + }
462.235 +pre.literal-block, pre.doctest-block {
462.236 + margin-left: 2em;
462.237 + margin-right: 2em;
462.238 + background-color: #eeeeee;
462.239 + border: 1px solid #A0A0A0;
462.240 + color: #000000;
462.241 + clear: right
462.242 + }
462.243 +span.classifier {
462.244 + font-family: sans-serif;
462.245 + font-style: oblique
462.246 + }
462.247 +span.classifier-delimiter {
462.248 + font-family: sans-serif;
462.249 + font-weight: bold
462.250 + }
462.251 +span.interpreted {
462.252 + font-family: sans-serif
462.253 + }
462.254 +span.option {
462.255 + white-space: nowrap
462.256 + }
462.257 +span.pre {
462.258 + white-space: pre;
462.259 + color: #ff00
462.260 + }
462.261 +span.problematic {
462.262 + color: #ff0000
462.263 + }
462.264 +span.section-subtitle {
462.265 + /* font-size relative to parent (h1..h6 element) */
462.266 + font-size: 80%
462.267 + }
462.268 +table.citation {
462.269 + border-left: solid 1px gray;
462.270 + margin-left: 1px
462.271 + }
462.272 +table.docinfo {
462.273 + margin: 2em 4em
462.274 + }
462.275 +table.docutils {
462.276 + margin-top: 2.5em;
462.277 + margin-bottom: 2.5em
462.278 + }
462.279 +table.footnote {
462.280 + border-left: solid 1px black;
462.281 + margin-left: 1px
462.282 + }
462.283 +table.docutils td, table.docutils th, table.docinfo td, table.docinfo th {
462.284 + padding-left: 0.5em;
462.285 + padding-right: 0.5em;
462.286 + vertical-align: top;
462.287 + line-height: 18px;
462.288 + font-size: 110%
462.289 + }
462.290 +table.docutils th {
462.291 + color: red
462.292 + }
462.293 +table.docutils th.field-name, table.docinfo th.docinfo-name {
462.294 + font-weight: bold;
462.295 + text-align: left;
462.296 + white-space: nowrap;
462.297 + padding-left: 0
462.298 + }
462.299 +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
462.300 + font-size: 100%
462.301 + }
462.302 +tt.docutils {
462.303 + /* background-color: #eeeeee ; */
462.304 + }
462.305 +ul.auto-toc {
462.306 + list-style-type: none
462.307 + }
462.308 +.section {
462.309 + margin-top: 20px
462.310 + }
462.311 +.section h1, .section h2 {
462.312 + border-style: solid;
462.313 + border-width: 0pt 0pt 1px;
462.314 + border-color: #E2DCC8
462.315 + }
462.316 +.section h1 {
462.317 + font-size: 180%;
462.318 + font-weight: bold;
462.319 + background-color: #FDFAF3
462.320 + }
462.321 +.section h2 {
462.322 + font-size: 150%
462.323 + }
462.324 +.section h1 a, .section h2 a {
462.325 + color: #AA0000
462.326 + }
462.327 +/* .section p { */
462.328 +/* margin-top: 20px; */
462.329 +/* font-family: arial, "Lucida Grande", verdana, sans-serif; */
462.330 +/* font-size: 120%; */
462.331 +/* line-height: 1.4em; */
462.332 +/* color: #333333 */
462.333 +/* } */
462.334 +/* /\* thunder *\/ */
462.335 +span.pre {
462.336 + background-color: #FFFFFF;
462.337 + color: navy;
462.338 + font-size: 110%;
462.339 + font-weight: bold;
462.340 + white-space: pre
462.341 + }
463.1 Binary file web/static/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png has changed
464.1 Binary file web/static/css/images/ui-bg_diagonals-thick_20_666666_40x40.png has changed
465.1 Binary file web/static/css/images/ui-bg_flat_10_000000_40x100.png has changed
466.1 Binary file web/static/css/images/ui-bg_glass_100_f6f6f6_1x400.png has changed
467.1 Binary file web/static/css/images/ui-bg_glass_100_fdf5ce_1x400.png has changed
468.1 Binary file web/static/css/images/ui-bg_glass_65_ffffff_1x400.png has changed
469.1 Binary file web/static/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png has changed
470.1 Binary file web/static/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png has changed
471.1 Binary file web/static/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png has changed
472.1 Binary file web/static/css/images/ui-icons_222222_256x240.png has changed
473.1 Binary file web/static/css/images/ui-icons_228ef1_256x240.png has changed
474.1 Binary file web/static/css/images/ui-icons_ef8c08_256x240.png has changed
475.1 Binary file web/static/css/images/ui-icons_ffd27a_256x240.png has changed
476.1 Binary file web/static/css/images/ui-icons_ffffff_256x240.png has changed
477.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
477.2 +++ b/web/static/css/jquery-ui-1.7.2.custom.css Mon Apr 26 11:16:23 2010 +0200
477.3 @@ -0,0 +1,406 @@
477.4 +/*
477.5 +* jQuery UI CSS Framework
477.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
477.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
477.8 +*/
477.9 +
477.10 +/* Layout helpers
477.11 +----------------------------------*/
477.12 +.ui-helper-hidden { display: none; }
477.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
477.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
477.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
477.16 +.ui-helper-clearfix { display: inline-block; }
477.17 +/* required comment for clearfix to work in Opera \*/
477.18 +* html .ui-helper-clearfix { height:1%; }
477.19 +.ui-helper-clearfix { display:block; }
477.20 +/* end clearfix */
477.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
477.22 +
477.23 +
477.24 +/* Interaction Cues
477.25 +----------------------------------*/
477.26 +.ui-state-disabled { cursor: default !important; }
477.27 +
477.28 +
477.29 +/* Icons
477.30 +----------------------------------*/
477.31 +
477.32 +/* states and images */
477.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
477.34 +
477.35 +
477.36 +/* Misc visuals
477.37 +----------------------------------*/
477.38 +
477.39 +/* Overlays */
477.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
477.41 +
477.42 +
477.43 +
477.44 +/*
477.45 +* jQuery UI CSS Framework
477.46 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
477.47 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
477.48 +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
477.49 +*/
477.50 +
477.51 +
477.52 +/* Component containers
477.53 +----------------------------------*/
477.54 +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
477.55 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
477.56 +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
477.57 +.ui-widget-content a { color: #333333; }
477.58 +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
477.59 +.ui-widget-header a { color: #ffffff; }
477.60 +
477.61 +/* Interaction states
477.62 +----------------------------------*/
477.63 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; outline: none; }
477.64 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; outline: none; }
477.65 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; outline: none; }
477.66 +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; outline: none; }
477.67 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; outline: none; }
477.68 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; outline: none; text-decoration: none; }
477.69 +
477.70 +/* Interaction Cues
477.71 +----------------------------------*/
477.72 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
477.73 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
477.74 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
477.75 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #ffffff; }
477.76 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
477.77 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
477.78 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
477.79 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
477.80 +
477.81 +/* Icons
477.82 +----------------------------------*/
477.83 +
477.84 +/* states and images */
477.85 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
477.86 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
477.87 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
477.88 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
477.89 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
477.90 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
477.91 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
477.92 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
477.93 +
477.94 +/* positioning */
477.95 +.ui-icon-carat-1-n { background-position: 0 0; }
477.96 +.ui-icon-carat-1-ne { background-position: -16px 0; }
477.97 +.ui-icon-carat-1-e { background-position: -32px 0; }
477.98 +.ui-icon-carat-1-se { background-position: -48px 0; }
477.99 +.ui-icon-carat-1-s { background-position: -64px 0; }
477.100 +.ui-icon-carat-1-sw { background-position: -80px 0; }
477.101 +.ui-icon-carat-1-w { background-position: -96px 0; }
477.102 +.ui-icon-carat-1-nw { background-position: -112px 0; }
477.103 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
477.104 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
477.105 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
477.106 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
477.107 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
477.108 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
477.109 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
477.110 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
477.111 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
477.112 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
477.113 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
477.114 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
477.115 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
477.116 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
477.117 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
477.118 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
477.119 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
477.120 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
477.121 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
477.122 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
477.123 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
477.124 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
477.125 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
477.126 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
477.127 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
477.128 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
477.129 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
477.130 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
477.131 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
477.132 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
477.133 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
477.134 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
477.135 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
477.136 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
477.137 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
477.138 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
477.139 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
477.140 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
477.141 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
477.142 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
477.143 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
477.144 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
477.145 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
477.146 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
477.147 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
477.148 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
477.149 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
477.150 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
477.151 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
477.152 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
477.153 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
477.154 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
477.155 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
477.156 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
477.157 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
477.158 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
477.159 +.ui-icon-arrow-4 { background-position: 0 -80px; }
477.160 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
477.161 +.ui-icon-extlink { background-position: -32px -80px; }
477.162 +.ui-icon-newwin { background-position: -48px -80px; }
477.163 +.ui-icon-refresh { background-position: -64px -80px; }
477.164 +.ui-icon-shuffle { background-position: -80px -80px; }
477.165 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
477.166 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
477.167 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
477.168 +.ui-icon-folder-open { background-position: -16px -96px; }
477.169 +.ui-icon-document { background-position: -32px -96px; }
477.170 +.ui-icon-document-b { background-position: -48px -96px; }
477.171 +.ui-icon-note { background-position: -64px -96px; }
477.172 +.ui-icon-mail-closed { background-position: -80px -96px; }
477.173 +.ui-icon-mail-open { background-position: -96px -96px; }
477.174 +.ui-icon-suitcase { background-position: -112px -96px; }
477.175 +.ui-icon-comment { background-position: -128px -96px; }
477.176 +.ui-icon-person { background-position: -144px -96px; }
477.177 +.ui-icon-print { background-position: -160px -96px; }
477.178 +.ui-icon-trash { background-position: -176px -96px; }
477.179 +.ui-icon-locked { background-position: -192px -96px; }
477.180 +.ui-icon-unlocked { background-position: -208px -96px; }
477.181 +.ui-icon-bookmark { background-position: -224px -96px; }
477.182 +.ui-icon-tag { background-position: -240px -96px; }
477.183 +.ui-icon-home { background-position: 0 -112px; }
477.184 +.ui-icon-flag { background-position: -16px -112px; }
477.185 +.ui-icon-calendar { background-position: -32px -112px; }
477.186 +.ui-icon-cart { background-position: -48px -112px; }
477.187 +.ui-icon-pencil { background-position: -64px -112px; }
477.188 +.ui-icon-clock { background-position: -80px -112px; }
477.189 +.ui-icon-disk { background-position: -96px -112px; }
477.190 +.ui-icon-calculator { background-position: -112px -112px; }
477.191 +.ui-icon-zoomin { background-position: -128px -112px; }
477.192 +.ui-icon-zoomout { background-position: -144px -112px; }
477.193 +.ui-icon-search { background-position: -160px -112px; }
477.194 +.ui-icon-wrench { background-position: -176px -112px; }
477.195 +.ui-icon-gear { background-position: -192px -112px; }
477.196 +.ui-icon-heart { background-position: -208px -112px; }
477.197 +.ui-icon-star { background-position: -224px -112px; }
477.198 +.ui-icon-link { background-position: -240px -112px; }
477.199 +.ui-icon-cancel { background-position: 0 -128px; }
477.200 +.ui-icon-plus { background-position: -16px -128px; }
477.201 +.ui-icon-plusthick { background-position: -32px -128px; }
477.202 +.ui-icon-minus { background-position: -48px -128px; }
477.203 +.ui-icon-minusthick { background-position: -64px -128px; }
477.204 +.ui-icon-close { background-position: -80px -128px; }
477.205 +.ui-icon-closethick { background-position: -96px -128px; }
477.206 +.ui-icon-key { background-position: -112px -128px; }
477.207 +.ui-icon-lightbulb { background-position: -128px -128px; }
477.208 +.ui-icon-scissors { background-position: -144px -128px; }
477.209 +.ui-icon-clipboard { background-position: -160px -128px; }
477.210 +.ui-icon-copy { background-position: -176px -128px; }
477.211 +.ui-icon-contact { background-position: -192px -128px; }
477.212 +.ui-icon-image { background-position: -208px -128px; }
477.213 +.ui-icon-video { background-position: -224px -128px; }
477.214 +.ui-icon-script { background-position: -240px -128px; }
477.215 +.ui-icon-alert { background-position: 0 -144px; }
477.216 +.ui-icon-info { background-position: -16px -144px; }
477.217 +.ui-icon-notice { background-position: -32px -144px; }
477.218 +.ui-icon-help { background-position: -48px -144px; }
477.219 +.ui-icon-check { background-position: -64px -144px; }
477.220 +.ui-icon-bullet { background-position: -80px -144px; }
477.221 +.ui-icon-radio-off { background-position: -96px -144px; }
477.222 +.ui-icon-radio-on { background-position: -112px -144px; }
477.223 +.ui-icon-pin-w { background-position: -128px -144px; }
477.224 +.ui-icon-pin-s { background-position: -144px -144px; }
477.225 +.ui-icon-play { background-position: 0 -160px; }
477.226 +.ui-icon-pause { background-position: -16px -160px; }
477.227 +.ui-icon-seek-next { background-position: -32px -160px; }
477.228 +.ui-icon-seek-prev { background-position: -48px -160px; }
477.229 +.ui-icon-seek-end { background-position: -64px -160px; }
477.230 +.ui-icon-seek-first { background-position: -80px -160px; }
477.231 +.ui-icon-stop { background-position: -96px -160px; }
477.232 +.ui-icon-eject { background-position: -112px -160px; }
477.233 +.ui-icon-volume-off { background-position: -128px -160px; }
477.234 +.ui-icon-volume-on { background-position: -144px -160px; }
477.235 +.ui-icon-power { background-position: 0 -176px; }
477.236 +.ui-icon-signal-diag { background-position: -16px -176px; }
477.237 +.ui-icon-signal { background-position: -32px -176px; }
477.238 +.ui-icon-battery-0 { background-position: -48px -176px; }
477.239 +.ui-icon-battery-1 { background-position: -64px -176px; }
477.240 +.ui-icon-battery-2 { background-position: -80px -176px; }
477.241 +.ui-icon-battery-3 { background-position: -96px -176px; }
477.242 +.ui-icon-circle-plus { background-position: 0 -192px; }
477.243 +.ui-icon-circle-minus { background-position: -16px -192px; }
477.244 +.ui-icon-circle-close { background-position: -32px -192px; }
477.245 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
477.246 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
477.247 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
477.248 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
477.249 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
477.250 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
477.251 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
477.252 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
477.253 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
477.254 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
477.255 +.ui-icon-circle-check { background-position: -208px -192px; }
477.256 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
477.257 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
477.258 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
477.259 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
477.260 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
477.261 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
477.262 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
477.263 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
477.264 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
477.265 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
477.266 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
477.267 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
477.268 +
477.269 +
477.270 +/* Misc visuals
477.271 +----------------------------------*/
477.272 +
477.273 +/* Corner radius */
477.274 +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
477.275 +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
477.276 +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
477.277 +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
477.278 +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
477.279 +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
477.280 +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
477.281 +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
477.282 +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
477.283 +
477.284 +/* Overlays */
477.285 +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
477.286 +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; }/* Accordion
477.287 +----------------------------------*/
477.288 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
477.289 +.ui-accordion .ui-accordion-li-fix { display: inline; }
477.290 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
477.291 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
477.292 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
477.293 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
477.294 +.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
477.295 +----------------------------------*/
477.296 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
477.297 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
477.298 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
477.299 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
477.300 +.ui-datepicker .ui-datepicker-prev { left:2px; }
477.301 +.ui-datepicker .ui-datepicker-next { right:2px; }
477.302 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
477.303 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
477.304 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
477.305 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
477.306 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
477.307 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
477.308 +.ui-datepicker select.ui-datepicker-month,
477.309 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
477.310 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
477.311 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
477.312 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
477.313 +.ui-datepicker td { border: 0; padding: 1px; }
477.314 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
477.315 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
477.316 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
477.317 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
477.318 +
477.319 +/* with multiple calendars */
477.320 +.ui-datepicker.ui-datepicker-multi { width:auto; }
477.321 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
477.322 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
477.323 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
477.324 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
477.325 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
477.326 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
477.327 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
477.328 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
477.329 +.ui-datepicker-row-break { clear:both; width:100%; }
477.330 +
477.331 +/* RTL support */
477.332 +.ui-datepicker-rtl { direction: rtl; }
477.333 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
477.334 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
477.335 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
477.336 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
477.337 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
477.338 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
477.339 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
477.340 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
477.341 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
477.342 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
477.343 +
477.344 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
477.345 +.ui-datepicker-cover {
477.346 + display: none; /*sorry for IE5*/
477.347 + display/**/: block; /*sorry for IE5*/
477.348 + position: absolute; /*must have*/
477.349 + z-index: -1; /*must have*/
477.350 + filter: mask(); /*must have*/
477.351 + top: -4px; /*must have*/
477.352 + left: -4px; /*must have*/
477.353 + width: 200px; /*must have*/
477.354 + height: 200px; /*must have*/
477.355 +}/* Dialog
477.356 +----------------------------------*/
477.357 +.ui-dialog { position: relative; padding: .2em; width: 300px; }
477.358 +.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
477.359 +.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
477.360 +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
477.361 +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
477.362 +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
477.363 +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
477.364 +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
477.365 +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
477.366 +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
477.367 +.ui-draggable .ui-dialog-titlebar { cursor: move; }
477.368 +/* Progressbar
477.369 +----------------------------------*/
477.370 +.ui-progressbar { height:2em; text-align: left; }
477.371 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
477.372 +----------------------------------*/
477.373 +.ui-resizable { position: relative;}
477.374 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
477.375 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
477.376 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
477.377 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
477.378 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
477.379 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
477.380 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
477.381 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
477.382 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
477.383 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
477.384 +----------------------------------*/
477.385 +.ui-slider { position: relative; text-align: left; }
477.386 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
477.387 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
477.388 +
477.389 +.ui-slider-horizontal { height: .8em; }
477.390 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
477.391 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
477.392 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
477.393 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
477.394 +
477.395 +.ui-slider-vertical { width: .8em; height: 100px; }
477.396 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
477.397 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
477.398 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
477.399 +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
477.400 +----------------------------------*/
477.401 +.ui-tabs { padding: .2em; zoom: 1; }
477.402 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
477.403 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
477.404 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
477.405 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
477.406 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
477.407 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
477.408 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
477.409 +.ui-tabs .ui-tabs-hide { display: none !important; }
478.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
478.2 +++ b/web/static/css/layout.css Mon Apr 26 11:16:23 2010 +0200
478.3 @@ -0,0 +1,80 @@
478.4 +html,body{margin:0; padding: 0;height: 100%}
478.5 +div#container{position: relative; height:100%}
478.6 +body>div#container{height: auto; min-height: 100%}
478.7 +div#content{padding: 0 1.5em 5em}
478.8 +div#footer{position:absolute;bottom: 0;width: 100%}
478.9 +
478.10 +
478.11 +body {
478.12 + font-family: Verdana, Arial, Helvetica, sans-serif;
478.13 + font-size: 90%;
478.14 + margin: 0em;
478.15 + padding: 0em;
478.16 +}
478.17 +
478.18 +#container {
478.19 + margin: 0em;
478.20 + padding: 0em;
478.21 + width: 100%;
478.22 +}
478.23 +
478.24 +#header {
478.25 + min-width:860px;
478.26 + padding: 5px 20px 0 30px;
478.27 +}
478.28 +
478.29 +#main_menu {
478.30 + min-width:900px;
478.31 +}
478.32 +
478.33 +#page {
478.34 + padding : 30px 20px 0 30px;
478.35 + width: 95%;
478.36 + min-width: 840px;
478.37 +}
478.38 +
478.39 +#breadcrumbs {
478.40 + margin-left: 20px;
478.41 +}
478.42 +
478.43 +#navigation_menu {
478.44 + float: left;
478.45 + width:200px;
478.46 + min-width:200px;
478.47 + margin: 0;
478.48 + padding: 0;
478.49 +}
478.50 +
478.51 +#content {
478.52 + margin-left: 20px;
478.53 + display: table;
478.54 +}
478.55 +
478.56 +.main_content {
478.57 + min-width: 600px;
478.58 + margin: 10px 50px 50px 10px
478.59 +}
478.60 +
478.61 +.ui-tabs-panel {
478.62 + padding-bottom: 20px
478.63 + }
478.64 +
478.65 +.ui-widget-content {
478.66 + min-height: 350px;
478.67 + padding: 0px 0px 0px 0px;
478.68 + margin: 0px 0px 10px 0px
478.69 + }
478.70 +
478.71 +.azioni {
478.72 + margin: 20px 0 20px 0
478.73 + }
478.74 +
478.75 +#footer {
478.76 + height: 30px;
478.77 + margin: 30px 0 20px 0;
478.78 + bottom:0px;
478.79 + left:0px;
478.80 + right:0px;
478.81 + min-width:900px;
478.82 +}
478.83 +
479.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
479.2 +++ b/web/static/css/local.css Mon Apr 26 11:16:23 2010 +0200
479.3 @@ -0,0 +1,133 @@
479.4 +@import url(local.global.css);
479.5 +@import url(local.menu.css);
479.6 +#header {
479.7 + background-color: #fefefc;
479.8 + height: 68px
479.9 + }
479.10 +#user-tools {
479.11 + margin-top: 45px
479.12 + }
479.13 +#content {
479.14 + display: table
479.15 + }
479.16 +#navigation_menu {
479.17 + min-width: 150px;
479.18 + width: 150px
479.19 + }
479.20 +td, th {
479.21 + font-size: 100%;
479.22 + line-height: 16px;
479.23 + padding: 3px;
479.24 + vertical-align: middle
479.25 + }
479.26 +.row1 {
479.27 + background-color: #f6f6f6
479.28 + }
479.29 +fieldset.form {
479.30 + background-color: #f6f6f6
479.31 + }
479.32 +#main_content a:link, a:visited {
479.33 + color: #6922c6;
479.34 + text-decoration: none
479.35 + }
479.36 +#main_content a:hover {
479.37 + color: blue
479.38 + }
479.39 +#main_content h2, #content h2 {
479.40 + color: #6922c6;
479.41 + border-style: solid;
479.42 + border-width: 0pt 0pt 1px;
479.43 + margin: 4px 0 4px 8px
479.44 + }
479.45 +.x-menu {
479.46 + border-bottom: 1px solid #645e28
479.47 + }
479.48 +ul.simple li a:hover {
479.49 + background-color: transparent;
479.50 + color: white
479.51 + }
479.52 +blockquote {
479.53 + border-left: 0px;
479.54 + margin-left: 30;
479.55 + margin-right: 30
479.56 + }
479.57 +.highlight pre {
479.58 + background-color: #efefef
479.59 + }
479.60 +.section p {
479.61 + color: #333333;
479.62 + /* font-size:110%; */
479.63 + line-height: 1.2em;
479.64 + margin-top: 10px
479.65 + }
479.66 +pre.literal-block {
479.67 + background: #EFEFEF none repeat scroll 10% 0%;
479.68 + border: 1px solid #AAAAAA;
479.69 + margin: 5pt 10px;
479.70 + padding: 6px 8px
479.71 + }
479.72 +li em {
479.73 + font-style: bold
479.74 + }
479.75 +
479.76 +div.rss_logo a {
479.77 + background-color:#FF6600;
479.78 + border-color:#FCC7A5 rgb(125, 51, 2) rgb(62, 26, 1) rgb(255, 149, 78);
479.79 + border-style:solid;
479.80 + border-width:1px;
479.81 + color:#FFFFFF;
479.82 + font-family:sans-serif;
479.83 + font-size:10px;
479.84 + font-weight:bold;
479.85 + line-height:10px;
479.86 + padding:3px 6px;
479.87 + text-align:center;
479.88 + text-decoration:none;
479.89 +}
479.90 +
479.91 +.actions {
479.92 + margin: 20px 0 20px 0
479.93 +}
479.94 +.ui-helper-reset {
479.95 + line-height:0.9
479.96 +}
479.97 +form table {
479.98 + width: 100%
479.99 +}
479.100 +form {
479.101 + width: 100%
479.102 +}
479.103 +
479.104 +table td {
479.105 + padding: 0 30px 0 30px
479.106 +}
479.107 +table.horizontal th {
479.108 + padding:0 30px;
479.109 + text-align:right;
479.110 + vertical-align:text-top;
479.111 +}
479.112 +.dataTables_length {
479.113 + ## float:left;
479.114 + width:40%;
479.115 +}
479.116 +.dataTables_filter {
479.117 + ##float:right;
479.118 + text-align:right;
479.119 + ##width:50%;
479.120 + margin: 0 0 20px;
479.121 +}
479.122 +.dataTables_info {
479.123 + ##float:left;
479.124 + width:60%;
479.125 +}
479.126 +.dataTables_paginate {
479.127 + float:right;
479.128 + text-align:right;
479.129 + width:44px;
479.130 +}
479.131 +table {
479.132 + border-bottom:1px solid #DDDDDD;
479.133 + border-top:1px solid #DDDDDD;
479.134 + margin:15px 0;
479.135 + padding:10px 0;
479.136 +}
480.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
480.2 +++ b/web/static/css/local.global.css Mon Apr 26 11:16:23 2010 +0200
480.3 @@ -0,0 +1,319 @@
480.4 +* {
480.5 + margin: 0;
480.6 + padding: 0
480.7 + }
480.8 +/* LAYOUT COLOR */
480.9 +body {
480.10 + background-color: #fcfefc;
480.11 +/* color: #666666 */
480.12 + }
480.13 +/* Logo */
480.14 +#logo {
480.15 + background: transparent url(/static/img/logo.png) no-repeat scroll 0px 0px;
480.16 + width: 250px;
480.17 + height: 90px;
480.18 + float: left
480.19 + }
480.20 +#logo h1, #logo h2 {
480.21 + float: left
480.22 + }
480.23 +#container {
480.24 + background-color: #fff
480.25 + }
480.26 +#header {
480.27 + background-color: #fdfaf3;
480.28 + /* border-bottom: 1px solid #645e28 */
480.29 + }
480.30 +#footer {
480.31 + background: #cae960;
480.32 + border-top: 1px solid #999999
480.33 + }
480.34 +li, dt, dd {
480.35 + font-size: 100%;
480.36 + line-height: none;
480.37 +}
480.38 +/* END LAYOUT COLOR */
480.39 +h1, h2, h3, h4 {
480.40 + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
480.41 + font-weight: normal
480.42 + }
480.43 +h1 {
480.44 + font-size: 197%
480.45 + }
480.46 +h2 {
480.47 + font-size: 167%;
480.48 + margin: 0px
480.49 + }
480.50 +h3 {
480.51 + margin: 1em 0 0.5em;
480.52 + text-transform: none;
480.53 + font-size: 130%;
480.54 + color: #000000;
480.55 + font-weight: bold
480.56 + }
480.57 +p, ul, ol {
480.58 + /*margin-bottom: 1.5em;*/
480.59 +/* line-height: 1.6em */
480.60 + }
480.61 +ul li {
480.62 + list-style: none
480.63 + }
480.64 +td, th {
480.65 + line-height: 10px;
480.66 + font-size: 90%;
480.67 + vertical-align: middle
480.68 + }
480.69 +a {
480.70 + text-decoration: none;
480.71 + color: #666666
480.72 + }
480.73 +a:hover, a:active {
480.74 + /*text-decoration: none;*/
480.75 + color: #6921cd
480.76 + }
480.77 +.hide {
480.78 + display: none
480.79 + }
480.80 +/*
480.81 +a:visited {
480.82 + color: #666666;
480.83 +}*/
480.84 +img {
480.85 + border: none
480.86 + }
480.87 +img.left {
480.88 + float: left;
480.89 + margin: 0 20px 10px 0
480.90 + }
480.91 +img.right {
480.92 + float: right;
480.93 + margin: 0 0 10px 20px
480.94 + }
480.95 +input[type="text"], input[type="password"], textarea, select, .vTextField, .x-form-text, textarea.x-form-field {
480.96 + border: 1px solid #999999;
480.97 + font: Verdana, Geneva, Arial, Helvetica, sans-serif;
480.98 + background: #FFFFFF;
480.99 + color: #102132;
480.100 + margin-right: 0px;
480.101 + margin-left: 0px;
480.102 + padding: 2px 3px 0pt
480.103 + }
480.104 +input[type="submit"], input[type="button"], input[type="reset"], .submit-row input {
480.105 + background: white;
480.106 + border-color: #DDDDDD #aaa #aaa #ddd;
480.107 + border-style: solid;
480.108 + border-width: 1px;
480.109 + color: black;
480.110 + padding: 3px
480.111 + }
480.112 +select {
480.113 + padding: 0px 0px 0px 4px
480.114 + }
480.115 +th {
480.116 + font-weight: bold;
480.117 + text-align: center
480.118 + }
480.119 +/* Finestra ancora sezioni */
480.120 +.x-hidden {
480.121 + left: -10000px;
480.122 + position: absolute;
480.123 + top: -10000px;
480.124 + visibility: hidden
480.125 + }
480.126 +.x-window-body a {
480.127 + font-size: 11px;
480.128 + font-weight: bold;
480.129 + padding: 3px;
480.130 + margin-bottom: 3px
480.131 + }
480.132 +/* Login */
480.133 +.vTextField, .vPasswordField {
480.134 + margin-bottom: 7px
480.135 + }
480.136 +#login label {
480.137 + width: 80px;
480.138 + float: left
480.139 + }
480.140 +.errors {
480.141 + background: #FFFFCC url(/static/img/icon_error.gif) no-repeat scroll 5px 0.3em;
480.142 + border: 1px solid red;
480.143 + color: #d9d;
480.144 + display: block;
480.145 + font-size: 14px !important;
480.146 + margin: 0px 0px 10px;
480.147 + padding: 4px 5px 4px 5px;
480.148 + width: 100%
480.149 + }
480.150 +/* Logo */
480.151 +#logo {
480.152 + float: left
480.153 + }
480.154 +#logo h1, #logo h2 {
480.155 + float: left
480.156 + }
480.157 +#logo h1 {
480.158 + padding-top: 40px;
480.159 + text-transform: lowercase;
480.160 + font-size: 34px;
480.161 + font-weight: normal
480.162 + }
480.163 +#logo h2 {
480.164 + padding: 63px 0 0 3px;
480.165 + text-transform: none;
480.166 + font-family: Verdana, Arial, Helvetica, sans-serif;
480.167 + font-size: 9px
480.168 + }
480.169 +#logo a {
480.170 + text-decoration: none;
480.171 + color: #000000
480.172 + }
480.173 +/* Search */
480.174 +#user-tools {
480.175 + float: right;
480.176 + width: 350px;
480.177 + margin-top: 70px;
480.178 + text-align: right
480.179 + }
480.180 +/* Table List */
480.181 +.list_table {
480.182 + width: 100%
480.183 + }
480.184 +.list_table td, .list_table th {
480.185 + border-bottom: 1px solid #EEEEEE;
480.186 + font-family: "Lucida Grande", Verdana, Arial, sans-serif;
480.187 + font-size: 90%;
480.188 + line-height: 10px;
480.189 + padding: 5px;
480.190 + vertical-align: middle
480.191 + }
480.192 +.title_nav {
480.193 + margin-bottom: 15px
480.194 + }
480.195 +/* table form */
480.196 +form fieldset {
480.197 + border: 1px solid #da27d8;
480.198 + background-color: #f6f6f6;
480.199 + margin-top: 10px;
480.200 + padding-top: 10px;
480.201 + padding-right: 10px
480.202 + }
480.203 +.form fieldset {
480.204 + padding: 20px
480.205 + }
480.206 +form legend, .form legend {
480.207 + border: 1px solid #da27d8;
480.208 + background-color: #f6f6f6;
480.209 + color: #253221;
480.210 + font-size: 90%;
480.211 + font-weight: bold;
480.212 + margin: 0pt 20px;
480.213 + padding: 3px
480.214 + }
480.215 +form legend a, .form legend a {
480.216 + color: #253221
480.217 + }
480.218 +form table {
480.219 + background-color: #f6f6f6;
480.220 + color: #253221;
480.221 + width: 100%;
480.222 + border: 1px solid #da27d8;
480.223 + border-collapse: collapse
480.224 + }
480.225 +.form table {
480.226 + border: 0px solid #645e28
480.227 + }
480.228 +form td {
480.229 + padding-left: 4px;
480.230 + background-color: #f6f6f6;
480.231 + color: #253221;
480.232 + text-align: left;
480.233 + margin-right: 0px;
480.234 + padding: 7px
480.235 + }
480.236 +.form td {
480.237 + padding-left: 4px;
480.238 + color: #253221;
480.239 + text-align: left;
480.240 + padding: 4px;
480.241 + border-bottom: 0px solid #f6f6f6
480.242 + }
480.243 +form textarea, .form textarea {
480.244 + height: 97%;
480.245 + vertical-align: top;
480.246 + width: 100%
480.247 + }
480.248 +form label, .form label {
480.249 + font-size: 11px;
480.250 + color: #666666;
480.251 + /*font-variant : small-caps;*/
480.252 + text-transform: none
480.253 + }
480.254 +form label.required, .form label.required {
480.255 + font-weight: bold;
480.256 + /* font-variant : small-caps;*/
480.257 + text-transform: none
480.258 + }
480.259 +.label_header {
480.260 + font-size: 13px;
480.261 + /*font-variant: small-caps;*/
480.262 + font-weight: bold;
480.263 + text-transform: none
480.264 + }
480.265 +/* Footer */
480.266 +#footer p {
480.267 + margin: 5px;
480.268 + text-align: right;
480.269 + font-size: 85%
480.270 + }
480.271 +/* EXT Grid */
480.272 +.x-grid3-hd-row td, .x-grid3-row td {
480.273 + padding: 0px
480.274 + }
480.275 +.x-panel-bbar .x-toolbar table {
480.276 + width: 350px
480.277 + }
480.278 +.x-grid3-header {
480.279 + border-bottom: 1px solid #999999
480.280 + }
480.281 +.x-panel-header {
480.282 + background: #78b1c5;
480.283 + border: 1px solid #999999
480.284 + }
480.285 +.x-panel-body {
480.286 + border-width: 0px 1px 1px 1px;
480.287 + border-style: solid;
480.288 + border-color: #999999
480.289 + }
480.290 +.x-panel-bbar .x-toolbar table td {
480.291 + padding: 0px
480.292 + }
480.293 +/* Summary Table */
480.294 +.x-grid3-summary-row {
480.295 + background: #F1F2F4 none repeat scroll 0% 50%;
480.296 + border-left: 1px solid #FFFFFF;
480.297 + border-right: 1px solid #FFFFFF;
480.298 + color: #333333
480.299 + }
480.300 +.x-grid3-summary-row .x-grid3-cell-inner {
480.301 + font-weight: bold;
480.302 + padding-bottom: 4px
480.303 + }
480.304 +.x-grid3-row td, .x-grid3-summary-row td {
480.305 + padding-left: 0px;
480.306 + padding-right: 0px
480.307 + }
480.308 +/* Icon Button */
480.309 +.icon_add {
480.310 + background-image: url(/static/img/add.gif) !important
480.311 + }
480.312 +.icon_print {
480.313 + background-image: url(/static/img/print.gif) !important
480.314 + }
480.315 +/* LEGENDA */
480.316 +.legenda {
480.317 + font-size: 10px;
480.318 + text-align: right
480.319 + }
480.320 +.errorlist 4li {
480.321 + background-color: red
480.322 + }
481.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
481.2 +++ b/web/static/css/local.menu.css Mon Apr 26 11:16:23 2010 +0200
481.3 @@ -0,0 +1,153 @@
481.4 +/* Modifico l'header in base al tipo di menu che viusalizzo */
481.5 +#bottomheader {
481.6 + background: #cae960 none repeat scroll 0% 50%;
481.7 + clear: both;
481.8 + height: 2px;
481.9 + line-height: 8px;
481.10 + padding: 0pt;
481.11 + width: 100%;
481.12 + margin-top: -8px;
481.13 + margin-left: 0px
481.14 + }
481.15 +#main_menu {
481.16 + bottom: 0px;
481.17 + margin-top: -2px;
481.18 + padding: 0pt 0pt 0pt 100px;
481.19 + position: relative
481.20 + }
481.21 +/* Menu */
481.22 +.horizontal_menu ul {
481.23 + list-style-type: none;
481.24 + margin: 0pt;
481.25 + padding: 0pt;
481.26 + z-index: 100
481.27 + }
481.28 +/* All' li principale metto un altezza piu piccola e il fon a bold */
481.29 +.horizontal_menu .mainli {
481.30 + line-height: 13px;
481.31 + font-weight: bold
481.32 + }
481.33 +/* settaggi x tt le voci di menu */
481.34 +.horizontal_menu ul li {
481.35 + display: inline;
481.36 + float: left;
481.37 + line-height: 21px;
481.38 + padding: 0px;
481.39 + position: relative;
481.40 + margin-right: 4px;
481.41 + font-weight: normal
481.42 + }
481.43 +.horizontal_menu ul li a {
481.44 + color: #ffffff;
481.45 + display: block;
481.46 + padding: 1px 8px;
481.47 + text-decoration: none
481.48 + }
481.49 +/* Colore dei sottomenu quando ci passo sopra */
481.50 +.horizontal_menu .mainli ul li a:hover {
481.51 + background-color: #e6fc1e
481.52 + }
481.53 +
481.54 +.horizontal_menu ul li a.active {
481.55 + background-color: #e6fc1e
481.56 + }
481.57 +
481.58 +/* Settaggi per menu principale, quello sempre visibile */
481.59 +.horizontal_menu .mainfoldericon {
481.60 + background: #cae960 url(/static/img/color_tabs_left.gif) no-repeat left top;
481.61 + float: left;
481.62 + color: #15428b;
481.63 + padding: 0 0 1px 3px;
481.64 + text-decoration: none;
481.65 + letter-spacing: 1px
481.66 + }
481.67 +.horizontal_menu .mainfoldericon span {
481.68 + float: left;
481.69 + display: block;
481.70 + background: transparent url(/static/img/color_tabs_right.gif) no-repeat right top;
481.71 + padding: 4px 9px 2px 6px
481.72 + }
481.73 +/* Colore del menu principale quando ci passo sopra */
481.74 +.horizontal_menu ul li a:hover {
481.75 + background-color: #e6fc1e
481.76 + }
481.77 +/* Settaggi vari per corretta visualizzazione sottomenu */
481.78 +.horizontal_menu ul li ul {
481.79 + display: block;
481.80 + left: 0pt;
481.81 + position: absolute;
481.82 + top: 1em;
481.83 + visibility: hidden;
481.84 + float: none
481.85 + }
481.86 +.horizontal_menu ul li ul li {
481.87 + display: list-item;
481.88 + float: none
481.89 + }
481.90 +.horizontal_menu ul li ul li ul {
481.91 + left: 159px;
481.92 + top: 0pt
481.93 + }
481.94 +/* settaggi dei sottomenu */
481.95 +.horizontal_menu ul li ul li a {
481.96 + background: #cae960;
481.97 + border-width: 1px 1px 0px 1px;
481.98 + border-color: #cae960;
481.99 + display: block;
481.100 + color: #333333;
481.101 + padding: 1px 5px 1px 7px;
481.102 + text-decoration: none;
481.103 + width: 160px
481.104 + }
481.105 +/* ai meu che hanno dei sottomenu aggiungo la frecceta rossa a destra */
481.106 +.horizontal_menu .subfoldericon {
481.107 + background-image: url(/static/img/arrow-right-blu.gif);
481.108 + background-position: right;
481.109 + background-repeat: no-repeat
481.110 + }
481.111 +/* .horizontal_menu .mainfoldericon {
481.112 + background:#F0F0F0 url(/static/img/arrow-down-red.gif) no-repeat scroll right center;
481.113 +}*/
481.114 +.horizontal_menu li#active a {
481.115 + background-color: #FFFFFF;
481.116 + color: #000000
481.117 + }
481.118 +* html p#iepara {
481.119 + padding-top: 1em
481.120 + }
481.121 +* html .horizontal_menu ul li {
481.122 + float: left;
481.123 + height: 1%
481.124 + }
481.125 +* html .horizontal_menu ul li a {
481.126 + height: 1%
481.127 + }
481.128 +/* Navigation Menu */
481.129 +#navigation_menu ul li {
481.130 + padding-left: 10px;
481.131 + background: url(/static/img/img16.gif) no-repeat 0px 10px;
481.132 + font-size: 11px;
481.133 + margin-bottom: 0em;
481.134 + line-height: 20px
481.135 + }
481.136 +/* Menu di sx */
481.137 +.box-blue {
481.138 + /*background: url(/static/img/img13.gif) repeat-x;*/
481.139 + border: 1px solid #999999
481.140 + }
481.141 +.box-blue .section {
481.142 + /*background: url(/static/img/img15.gif) no-repeat right top;*/
481.143 + background-color: #cae960;
481.144 + border-bottom: 1px solid #999999;
481.145 + font-size: 100%;
481.146 + color: #15428B
481.147 + }
481.148 +.box-blue .section b {
481.149 + display: block;
481.150 + height: 23px;
481.151 + padding: 7px 0 0 10px;
481.152 + /*background: url(/static/img/img14.gif) no-repeat;*/
481.153 + }
481.154 +.box-blue .content {
481.155 + padding: 7px
481.156 + }
482.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
482.2 +++ b/web/static/css/main.css Mon Apr 26 11:16:23 2010 +0200
482.3 @@ -0,0 +1,3 @@
482.4 +@import url('layout.css');
482.5 +@import url('global.css');
482.6 +@import url('menu.css');
483.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
483.2 +++ b/web/static/css/menu.css Mon Apr 26 11:16:23 2010 +0200
483.3 @@ -0,0 +1,166 @@
483.4 +/* Modifico l'header in base al tipo di menu che viusalizzo */
483.5 +#main_menu {
483.6 + bottom:0px;
483.7 + margin-top:10px;
483.8 + position:relative;
483.9 +}
483.10 +
483.11 +/* Menu */
483.12 +.horizontal_menu ul {
483.13 + list-style-type:none;
483.14 + margin:0pt;
483.15 + padding:0pt;
483.16 + z-index:100;
483.17 +}
483.18 +
483.19 +/* All' li principale metto un altezza piu piccola e il fon a bold */
483.20 +.horizontal_menu .mainli {
483.21 + line-height:13px;
483.22 + font-weight:bold;
483.23 +}
483.24 +
483.25 +/* settaggi x tt le voci di menu */
483.26 +.horizontal_menu ul li {
483.27 + display:inline;
483.28 + float:left;
483.29 + line-height:21px;
483.30 + padding:0px;
483.31 + position:relative;
483.32 + margin-right: 4px;
483.33 + font-weight:normal;
483.34 +}
483.35 +
483.36 +.horizontal_menu ul li a {
483.37 + color: #ffffff;
483.38 + display:block;
483.39 + padding:1px 8px;
483.40 + text-decoration:none;
483.41 +}
483.42 +
483.43 +/* Colore dei sottomenu quando ci passo sopra */
483.44 +.horizontal_menu .mainli ul li a:hover {
483.45 + background-color: #D7E5F2;
483.46 +}
483.47 +
483.48 +/* Settaggi per menu principale, quello sempre visibile */
483.49 +.horizontal_menu .mainfoldericon {
483.50 + background: #344682 url(/static/img/color_tabs_left.gif) no-repeat left top;
483.51 + float:left;
483.52 + color: white;
483.53 + padding:0 0 1px 3px;
483.54 + text-decoration:none;
483.55 + letter-spacing: 1px;
483.56 +}
483.57 +
483.58 +.horizontal_menu .mainfoldericon span {
483.59 + float:left;
483.60 + display:block;
483.61 + background: transparent url(/static/img/color_tabs_right.gif) no-repeat right top;
483.62 + padding:4px 9px 2px 6px;
483.63 +}
483.64 +
483.65 +/* Colore del menu principale quando ci passo sopra */
483.66 +.horizontal_menu ul li a:hover {
483.67 + background-color: #3562A6;
483.68 +}
483.69 +
483.70 +.horizontal_menu ul li a.active {
483.71 + background-color: #3562A6;
483.72 +}
483.73 +
483.74 +/* Settaggi vari per corretta visualizzazione sottomenu */
483.75 +.horizontal_menu ul li ul {
483.76 + display:block;
483.77 + left:0pt;
483.78 + position:absolute;
483.79 + top:1em;
483.80 + visibility:hidden;
483.81 + float:none;
483.82 +}
483.83 +
483.84 +.horizontal_menu ul li ul li {
483.85 + display:list-item;
483.86 + float:none;
483.87 +}
483.88 +
483.89 +.horizontal_menu ul li ul li ul {
483.90 + left:159px;
483.91 + top:0pt;
483.92 +}
483.93 +
483.94 +/* settaggi dei sottomenu */
483.95 +.horizontal_menu ul li ul li a {
483.96 + background:#F0F0F0;
483.97 + border:1px solid #CCCCCC;
483.98 + display:block;
483.99 + color: #333333;
483.100 + padding:1px 5px 1px 7px;
483.101 + text-decoration:none;
483.102 + width:160px;
483.103 +}
483.104 +
483.105 +/* ai meu che hanno dei sottomenu aggiungo la frecceta rossa a destra */
483.106 +.horizontal_menu .subfoldericon {
483.107 + background-image: url(/static/img/arrow-right-blu.gif);
483.108 + background-position: right;
483.109 + background-repeat:no-repeat;
483.110 +}
483.111 +
483.112 +/* .horizontal_menu .mainfoldericon {
483.113 + background:#F0F0F0 url(/static/img/arrow-down-red.gif) no-repeat scroll right center;
483.114 +}*/
483.115 +
483.116 +.horizontal_menu li#active a {
483.117 + background-color:#FFFFFF;
483.118 + color:#000000;
483.119 +}
483.120 +
483.121 +* html p#iepara {
483.122 + padding-top:1em;
483.123 +}
483.124 +
483.125 +* html .horizontal_menu ul li {
483.126 + float:left;
483.127 + height:1%;
483.128 +}
483.129 +
483.130 +* html .horizontal_menu ul li a {
483.131 + height:1%;
483.132 +}
483.133 +
483.134 +/* Navigation Menu */
483.135 +
483.136 +#navigation_menu ul li {
483.137 + padding-left: 10px;
483.138 + background: url(/static/img/img16.gif) no-repeat 0px 10px;
483.139 + font-size:11px;
483.140 + margin-bottom:0em;
483.141 + line-height:20px;
483.142 +}
483.143 +
483.144 +
483.145 +/* Menu di sx */
483.146 +
483.147 +.box-blue {
483.148 + /*background: url(/static/img/img13.gif) repeat-x;*/
483.149 + border: 1px solid #999999;
483.150 +}
483.151 +
483.152 +.box-blue .section {
483.153 + /*background: url(/static/img/img15.gif) no-repeat right top;*/
483.154 + background-color:#D7E5F2;
483.155 + border-bottom :1px solid #999999;
483.156 + font-size: 100%;
483.157 + color: #15428B;
483.158 +}
483.159 +
483.160 +.box-blue .section b {
483.161 + display: block;
483.162 + height: 23px;
483.163 + padding: 7px 0 0 10px;
483.164 + /*background: url(/static/img/img14.gif) no-repeat;*/
483.165 +}
483.166 +
483.167 +.box-blue .content {
483.168 + padding: 7px;
483.169 +}
484.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
484.2 +++ b/web/static/css/menu_ext.css Mon Apr 26 11:16:23 2010 +0200
484.3 @@ -0,0 +1,171 @@
484.4 +/* Modifico l'header in base al tipo di menu che viusalizzo */
484.5 +#header {
484.6 + border-bottom: 1px solid #718BB7
484.7 +}
484.8 +
484.9 +/* Menu */
484.10 +.x-menu {
484.11 + background:#F0F0F0 url(/static/img/menu.gif) repeat-y scroll 0%;
484.12 + padding:0px;
484.13 +}
484.14 +
484.15 +.x-menu a.x-menu-item {
484.16 + color:#233D6D;
484.17 +}
484.18 +
484.19 +.x-menu-item-active {
484.20 + background:#C3DAF9 none repeat scroll 0%;
484.21 + border:1px solid #8BB8F3;
484.22 + color:#233D6D;
484.23 + padding:0px;
484.24 +}
484.25 +
484.26 +.x-menubar {
484.27 + background-color:#DEECFD !important;
484.28 + padding:0px 0px 0px 40px;
484.29 +}
484.30 +
484.31 +.x-horizontal-menubar {
484.32 + border-left:0px none;
484.33 + border-right:0px none;
484.34 + border-top:0px none;
484.35 + /* width:100%!important; */
484.36 + overflow:hidden;
484.37 +}
484.38 +.x-menubar .x-menu-list {
484.39 + border:0px none;
484.40 +}
484.41 +.x-horizontal-menubar .x-menu-list {
484.42 + margin-left:0px;
484.43 + height:100%;
484.44 +}
484.45 +.x-horizontal-menubar .x-menu-list .x-menu-list-item {
484.46 + text-decoration:none;
484.47 + padding:0px 10px 0px 2px;
484.48 + display:block;
484.49 + float:left;
484.50 + background-image: none;
484.51 +}
484.52 +.x-menubar .x-menu-list .x-menu-list-item {
484.53 + border:1px solid #deecfd; /* transparent gives black border in IE? */;
484.54 +}
484.55 +.x-menubar .x-menu-list .x-menu-item-active {
484.56 + border: 1px solid #8BB8F3;
484.57 + background: #C3DAF9 none repeat scroll 0%;
484.58 +}
484.59 +.x-menubar .x-menu-activated .x-menu-item-active {
484.60 + background-color: #F0F0F0;
484.61 +}
484.62 +.x-horizontal-menubar .x-menu-list .x-menu-single-item .x-menu-item {
484.63 + background: transparent;
484.64 + padding-right:15px;
484.65 +}
484.66 +.x-horizontal-menubar .x-menu-list .x-menu-item-arrow .x-menu-item {
484.67 + background: transparent url(/static/img/menubar-parent.gif) no-repeat scroll right 0.6em;
484.68 +}
484.69 +.x-menubar .x-menu-list .x-menu-list-item .x-menu-item .x-menu-item-icon {
484.70 + display:none;
484.71 +}
484.72 +
484.73 +
484.74 +/* Navigation Menu */
484.75 +
484.76 +#navigation_menu ul li {
484.77 + padding-left: 10px;
484.78 + background: url(/static/img/img16.gif) no-repeat 0px 10px;
484.79 + font-size:11px;
484.80 + margin-bottom:0em;
484.81 + line-height:20px;
484.82 +}
484.83 +
484.84 +
484.85 +/* Menu di sx */
484.86 +
484.87 +.box-blue {
484.88 + /*background: url(/static/img/img13.gif) repeat-x;*/
484.89 + border: 1px solid #999999;
484.90 +}
484.91 +
484.92 +.box-blue .section {
484.93 + /*background: url(/static/img/img15.gif) no-repeat right top;*/
484.94 + background-color:#D7E5F2;
484.95 + border-bottom :1px solid #999999;
484.96 + font-size: 100%;
484.97 + color: #15428B;
484.98 +}
484.99 +
484.100 +.box-blue .section b {
484.101 + display: block;
484.102 + height: 23px;
484.103 + padding: 7px 0 0 10px;
484.104 + /*background: url(/static/img/img14.gif) no-repeat;*/
484.105 +}
484.106 +
484.107 +.box-blue .content {
484.108 + padding: 7px;
484.109 +}
484.110 +
484.111 +
484.112 +/* Horizontal menu NON EXT */
484.113 +#horizontal_menu {
484.114 + height: 30px;
484.115 + margin-bottom:30px;
484.116 + padding-left:40px;
484.117 +}
484.118 +
484.119 +#horizontal_menu ul {
484.120 + margin: 0;
484.121 + list-style: none;
484.122 + line-height: normal;
484.123 +}
484.124 +
484.125 +#horizontal_menu li {
484.126 + display: block;
484.127 + float: left;
484.128 + margin-right: 6px;
484.129 + padding: 0;
484.130 + /*background: #FFFFFF;*/
484.131 + background: #D7E5F2;
484.132 + border-left:1px solid #718BB7;
484.133 + border-bottom:1px solid #718BB7;
484.134 + border-right:1px solid #718BB7;
484.135 +}
484.136 +
484.137 +#horizontal_menu a {
484.138 + display: block;
484.139 + float: left;
484.140 + /*background: url(/static/images/img07.gif) no-repeat;*/
484.141 + text-decoration: none;
484.142 + color: #666666;
484.143 + height: 23px;
484.144 + padding: 7px 20px 0 20px;
484.145 + cursor: hand;
484.146 + font-weight:bold;
484.147 +}
484.148 +
484.149 +#horizontal_menu a:hover {
484.150 + color: #1777B1;
484.151 +}
484.152 +
484.153 +/*
484.154 +#menu b {
484.155 + display: block;
484.156 + float: left;
484.157 + height: 23px;
484.158 + padding: 7px 20px 0 20px;
484.159 + background: url(/static/images/img08.gif) no-repeat right top;
484.160 + cursor: hand;
484.161 +}*/
484.162 +
484.163 +#horizontal_menu li#active {
484.164 + /*background: #CFCECE url(/static/images/img04.gif) repeat-x;*/
484.165 + border-left:1px solid #718BB7;
484.166 + border-bottom:1px solid #718BB7;
484.167 + border-right:1px solid #718BB7;
484.168 +}
484.169 +
484.170 +#horizontal_menu li#active a {
484.171 + /*background: url(/static/images/img06.gif) no-repeat right top;*/
484.172 + color: #000000;
484.173 + background-color:#FFFFFF;
484.174 +}
485.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
485.2 +++ b/web/static/css/print.css Mon Apr 26 11:16:23 2010 +0200
485.3 @@ -0,0 +1,48 @@
485.4 +#navigation_menu{display: none;}
485.5 +#navigation_filter{display: none;}
485.6 +body {
485.7 + background: white;
485.8 + color: black;
485.9 + font-size: 6px;
485.10 +}
485.11 +#content{
485.12 + font-family: Verdana,Arial,sans-serif;
485.13 + font-weight: normal; border: none;
485.14 + margin: 10px; padding: 10px;
485.15 + background: transparent;
485.16 + font-size: 6px;
485.17 + }
485.18 +
485.19 +a:link,a:visited {
485.20 + font-weight: bold;
485.21 + text-decoration: underline;
485.22 +}
485.23 +
485.24 +img{display: none;}
485.25 +.title_nav{display: none;}
485.26 +#page_navigator{display: none;}
485.27 +
485.28 +
485.29 +.table_grid{
485.30 + border: 1px solid;
485.31 + width: 100%;
485.32 +}
485.33 +.tr_grid_head{
485.34 + font-weight: bold;
485.35 + text-align: center;
485.36 +}
485.37 +.td_grid_head{
485.38 +}
485.39 +.tr_grid{
485.40 +}
485.41 +.row1{
485.42 + background: #E5E5E5;
485.43 +}
485.44 +.row2{
485.45 + background: #EEEEEE;
485.46 +}
485.47 +.td_grid_label{
485.48 + font-weight: bold;
485.49 +}
485.50 +.td_grid_value{
485.51 +}
485.52 \ No newline at end of file
486.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
486.2 +++ b/web/static/css/rst.css Mon Apr 26 11:16:23 2010 +0200
486.3 @@ -0,0 +1,67 @@
486.4 +.highlight pre {
486.5 + margin:10px;
486.6 + background: #dbdfda;
486.7 + padding: 10px 10px;
486.8 + border: 1px solid #aaa;
486.9 +}
486.10 +.highlight{ background: #ffffff; margin:10px; background: #ffffff; padding: 10px 10px;}
486.11 +.highlight .c { color: #008800; font-style: italic ;} /* Comment */
486.12 +.highlight .err { border: 1px solid #FF0000 ;} /* Error */
486.13 +.highlight .k { color: #aa22ff; font-weight: 600 ;} /* Keyword */
486.14 +.highlight .o { color: #666666 ;} /* Operator */
486.15 +.highlight .cm { color: #008800; font-style: italic ;} /* Comment.Multiline */
486.16 +.highlight .cp { color: #008800 ;} /* Comment.Preproc */
486.17 +.highlight .c1 { color: #008800; font-style: italic ;} /* Comment.Single */
486.18 +.highlight .cs { color: #008800; font-weight: bold ;} /* Comment.Special */
486.19 +.highlight .gd { color: #a00000 ;} /* Generic.Deleted */
486.20 +.highlight .ge { font-style: italic ;} /* Generic.Emph */
486.21 +.highlight .gr { color: #ff0000 ;} /* Generic.Error */
486.22 +.highlight .gh { color: #000080; font-weight: bold ;} /* Generic.Heading */
486.23 +.highlight .gi { color: #00a000 ;} /* Generic.Inserted */
486.24 +.highlight .go { color: #808080 ;} /* Generic.Output */
486.25 +.highlight .gp { color: #000080; font-weight: bold ;} /* Generic.Prompt */
486.26 +.highlight .gs { font-weight: bold ;} /* Generic.Strong */
486.27 +.highlight .gu { color: #800080; font-weight: bold ;} /* Generic.Subheading */
486.28 +.highlight .gt { color: #0040d0 ;} /* Generic.Traceback */
486.29 +.highlight .kc { color: #aa22ff; font-weight: bold ;} /* Keyword.Constant */
486.30 +.highlight .kd { color: #aa22ff; font-weight: bold ;} /* Keyword.Declaration */
486.31 +.highlight .kp { color: #aa22ff ;} /* Keyword.Pseudo */
486.32 +.highlight .kr { color: #aa22ff; font-weight: bold ;} /* Keyword.Reserved */
486.33 +.highlight .kt { color: #aa22ff; font-weight: bold ;} /* Keyword.Type */
486.34 +.highlight .m { color: #666666 ;} /* Literal.Number */
486.35 +.highlight .n { color: #222 ;} /* Literal.Number */
486.36 +.highlight .s { color: #bb4444 ;} /* Literal.String */
486.37 +.highlight .na { color: #bb4444 ;} /* Name.Attribute */
486.38 +.highlight .nb { color: #aa22ff ;} /* Name.Builtin */
486.39 +.highlight .nc { color: #008000 ;} /* Name.Class */
486.40 +.highlight .no { color: #880000 ;} /* Name.Constant */
486.41 +.highlight .nd { color: #aa22ff ;} /* Name.Decorator */
486.42 +.highlight .ni { color: #999999; font-weight: bold ;} /* Name.Entity */
486.43 +.highlight .ne { color: #d2413a; font-weight: bold ;} /* Name.Exception */
486.44 +.highlight .nf { color: #0000ff ;} /* Name.Function */
486.45 +.highlight .nl { color: #a0a000 ;} /* Name.Label */
486.46 +.highlight .nn { color: #0000ff; font-weight: bold ;} /* Name.Namespace */
486.47 +.highlight .nt { color: #008000; font-weight: bold ;} /* Name.Tag */
486.48 +.highlight .nv { color: #b8860b ;} /* Name.Variable */
486.49 +.highlight .ow { color: #aa22ff; font-weight: bold ;} /* Operator.Word */
486.50 +.highlight .mf { color: #666666 ;} /* Literal.Number.Float */
486.51 +.highlight .mh { color: #666666 ;} /* Literal.Number.Hex */
486.52 +.highlight .mi { color: #666666 ;} /* Literal.Number.Integer */
486.53 +.highlight .mo { color: #666666 ;} /* Literal.Number.Oct */
486.54 +.highlight .sb { color: #bb4444 ;} /* Literal.String.Backtick */
486.55 +.highlight .sc { color: #bb4444 ;} /* Literal.String.Char */
486.56 +.highlight .sd { color: #bb4444; font-style: italic ;} /* Literal.String.Doc */
486.57 +.highlight .s2 { color: #bb4444 ;} /* Literal.String.Double */
486.58 +.highlight .se { color: #bb6622; font-weight: bold ;} /* Literal.String.Escape */
486.59 +.highlight .sh { color: #bb4444 ;} /* Literal.String.Heredoc */
486.60 +.highlight .si { color: #bb6688; font-weight: bold ;} /* Literal.String.Interpol */
486.61 +.highlight .sx { color: #008000 ;} /* Literal.String.Other */
486.62 +.highlight .sr { color: #bb6688 ;} /* Literal.String.Regex */
486.63 +.highlight .s1 { color: #bb4444 ;} /* Literal.String.Single */
486.64 +.highlight .ss { color: #b8860b ;} /* Literal.String.Symbol */
486.65 +.highlight .bp { color: #aa22ff ;} /* Name.Builtin.Pseudo */
486.66 +.highlight .vc { color: #b8860b ;} /* Name.Variable.Class */
486.67 +.highlight .vg { color: #b8860b ;} /* Name.Variable.Global */
486.68 +.highlight .vi { color: #b8860b ;} /* Name.Variable.Instance */
486.69 +.highlight .il { color: #666666 ;} /* Literal.Number.Integer.Long */
486.70 +.highlight span:hover { background: #ffff99 ;}
486.71 \ No newline at end of file
487.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
487.2 +++ b/web/static/css/tabs-no-images.css Mon Apr 26 11:16:23 2010 +0200
487.3 @@ -0,0 +1,62 @@
487.4 +
487.5 +/* root element for tabs */
487.6 +ul.css-tabs {
487.7 + margin:0 !important;
487.8 + padding:0;
487.9 + height:30px;
487.10 + border-bottom:1px solid #666;
487.11 +}
487.12 +
487.13 +/* single tab */
487.14 +ul.css-tabs li {
487.15 + float:left;
487.16 + padding:0;
487.17 + margin:0;
487.18 + list-style-type:none;
487.19 +}
487.20 +
487.21 +/* link inside the tab. uses a background image */
487.22 +ul.css-tabs a {
487.23 + float:left;
487.24 + font-size:13px;
487.25 + display:block;
487.26 + padding:5px 30px;
487.27 + text-decoration:none;
487.28 + border:1px solid #666;
487.29 + border-bottom:0px;
487.30 + height:18px;
487.31 + background-color:#efefef;
487.32 + color:#777;
487.33 + margin-right:2px;
487.34 + -moz-border-radius-topleft: 4px;
487.35 + -moz-border-radius-topright:4px;
487.36 + position:relative;
487.37 + top:1px;
487.38 +}
487.39 +
487.40 +ul.css-tabs a:hover {
487.41 + background-color:#F7F7F7;
487.42 + color:#333;
487.43 +}
487.44 +
487.45 +/* selected tab */
487.46 +ul.css-tabs a.current {
487.47 + background-color:#ddd;
487.48 + border-bottom:2px solid #ddd;
487.49 + color:#000;
487.50 + cursor:default;
487.51 +}
487.52 +
487.53 +
487.54 +/* tab pane */
487.55 +div.css-panes div {
487.56 + display:none;
487.57 + border:1px solid #666;
487.58 + border-width:0 1px 1px 1px;
487.59 + min-height:150px;
487.60 + padding:15px 20px;
487.61 + background-color:#ddd;
487.62 +}
487.63 +
487.64 +
487.65 +
488.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
488.2 +++ b/web/static/css/tabs.css Mon Apr 26 11:16:23 2010 +0200
488.3 @@ -0,0 +1,111 @@
488.4 +
488.5 +/* root element for tabs */
488.6 +ul.tabs {
488.7 + list-style:none;
488.8 + margin:0 !important;
488.9 + padding:0;
488.10 + height:30px;
488.11 + border-bottom:1px solid #666;
488.12 +}
488.13 +
488.14 +/* single tab */
488.15 +ul.tabs li {
488.16 + float:left;
488.17 + text-indent:0;
488.18 + padding:0;
488.19 + margin:0 !important;
488.20 + list-style-image:none !important;
488.21 +}
488.22 +
488.23 +/* link inside the tab. uses a background image */
488.24 +ul.tabs a {
488.25 + background: url(/static/img/tabs.png) no-repeat -420px 0;
488.26 + font-size:11px;
488.27 + display:block;
488.28 + height: 30px;
488.29 + line-height:30px;
488.30 + width: 111px;
488.31 + text-align:center;
488.32 + text-decoration:none;
488.33 + color:#000;
488.34 + padding:0px;
488.35 + margin:0px;
488.36 + position:relative;
488.37 + top:1px;
488.38 +}
488.39 +
488.40 +ul.tabs a:active {
488.41 + outline:none;
488.42 +}
488.43 +
488.44 +/* when mouse enters the tab move the background image */
488.45 +ul.tabs a:hover {
488.46 + background-position: -420px -31px;
488.47 + color:#fff;
488.48 +}
488.49 +
488.50 +/* active tab uses a class name "current". it's highlight is also done by moving the background image. */
488.51 +ul.tabs a.current, ul.tabs a.current:hover, ul.tabs li.current a {
488.52 + background-position: -420px -62px;
488.53 + cursor:default !important;
488.54 + color:#000 !important;
488.55 +}
488.56 +
488.57 +/* Different widths for tabs: use a class name: w1, w2, w3 or w2 */
488.58 +
488.59 +
488.60 +/* width 1 */
488.61 +ul.tabs a.w1 { background-position: -519px 0; width:134px; }
488.62 +ul.tabs a.w1:hover { background-position: -519px -31px; }
488.63 +ul.tabs a.w1.current { background-position: -519px -62px; }
488.64 +
488.65 +/* width 2 */
488.66 +ul.tabs a.w2 { background-position: -366px -0px; width:154px; }
488.67 +ul.tabs a.w2:hover { background-position: -366px -31px; }
488.68 +ul.tabs a.w2.current { background-position: -366px -62px; }
488.69 +
488.70 +
488.71 +/* width 3 */
488.72 +ul.tabs a.w3 { background-position: -193px -0px; width:174px; }
488.73 +ul.tabs a.w3:hover { background-position: -193px -31px; }
488.74 +ul.tabs a.w3.current { background-position: -193px -62px; }
488.75 +
488.76 +/* width 4 */
488.77 +ul.tabs a.w4 { background-position: -0px -0px; width:194px; }
488.78 +ul.tabs a.w4:hover { background-position: -0px -31px; }
488.79 +ul.tabs a.w4.current { background-position: -0px -62px; }
488.80 +
488.81 +
488.82 +/* initially all panes are hidden */
488.83 +div.panes div.pane {
488.84 + display:none;
488.85 +}
488.86 +
488.87 +
488.88 +h4.toggle {
488.89 + margin-top: 30px
488.90 +}
488.91 +dev.advanced {
488.92 + border-style: none;
488.93 +}
488.94 +
488.95 +/* tab pane styling */
488.96 +div.panes div {
488.97 + display:none;
488.98 + padding:15px 10px;
488.99 + border:0px solid #999;
488.100 + border-top:0;
488.101 + font-size:14px;
488.102 + background-color:#fff;
488.103 +}
488.104 +
488.105 +.tooltip {
488.106 + display:none;
488.107 + background:transparent url(/static/img/black_arrow.png);
488.108 + font-size:12px;
488.109 + height:165px;
488.110 + width:268px;
488.111 + color:#000;
488.112 + padding: 20px;
488.113 +}
488.114 +
489.1 Binary file web/static/css/ui/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png has changed
490.1 Binary file web/static/css/ui/themes/base/images/ui-bg_flat_75_ffffff_40x100.png has changed
491.1 Binary file web/static/css/ui/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png has changed
492.1 Binary file web/static/css/ui/themes/base/images/ui-bg_glass_65_ffffff_1x400.png has changed
493.1 Binary file web/static/css/ui/themes/base/images/ui-bg_glass_75_dadada_1x400.png has changed
494.1 Binary file web/static/css/ui/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png has changed
495.1 Binary file web/static/css/ui/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png has changed
496.1 Binary file web/static/css/ui/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png has changed
497.1 Binary file web/static/css/ui/themes/base/images/ui-icons_222222_256x240.png has changed
498.1 Binary file web/static/css/ui/themes/base/images/ui-icons_2e83ff_256x240.png has changed
499.1 Binary file web/static/css/ui/themes/base/images/ui-icons_454545_256x240.png has changed
500.1 Binary file web/static/css/ui/themes/base/images/ui-icons_888888_256x240.png has changed
501.1 Binary file web/static/css/ui/themes/base/images/ui-icons_cd0a0a_256x240.png has changed
502.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
502.2 +++ b/web/static/css/ui/themes/base/ui.accordion.css Mon Apr 26 11:16:23 2010 +0200
502.3 @@ -0,0 +1,9 @@
502.4 +/* Accordion
502.5 +----------------------------------*/
502.6 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
502.7 +.ui-accordion .ui-accordion-li-fix { display: inline; }
502.8 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
502.9 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
502.10 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
502.11 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
502.12 +.ui-accordion .ui-accordion-content-active { display: block; }
502.13 \ No newline at end of file
503.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
503.2 +++ b/web/static/css/ui/themes/base/ui.all.css Mon Apr 26 11:16:23 2010 +0200
503.3 @@ -0,0 +1,2 @@
503.4 +@import "ui.base.css";
503.5 +@import "ui.theme.css";
504.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
504.2 +++ b/web/static/css/ui/themes/base/ui.base.css Mon Apr 26 11:16:23 2010 +0200
504.3 @@ -0,0 +1,8 @@
504.4 +@import url("ui.core.css");
504.5 +@import url("ui.resizable.css");
504.6 +@import url("ui.accordion.css");
504.7 +@import url("ui.dialog.css");
504.8 +@import url("ui.slider.css");
504.9 +@import url("ui.tabs.css");
504.10 +@import url("ui.datepicker.css");
504.11 +@import url("ui.progressbar.css");
504.12 \ No newline at end of file
505.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
505.2 +++ b/web/static/css/ui/themes/base/ui.core.css Mon Apr 26 11:16:23 2010 +0200
505.3 @@ -0,0 +1,37 @@
505.4 +/*
505.5 +* jQuery UI CSS Framework
505.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
505.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
505.8 +*/
505.9 +
505.10 +/* Layout helpers
505.11 +----------------------------------*/
505.12 +.ui-helper-hidden { display: none; }
505.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
505.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
505.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
505.16 +.ui-helper-clearfix { display: inline-block; }
505.17 +/* required comment for clearfix to work in Opera \*/
505.18 +* html .ui-helper-clearfix { height:1%; }
505.19 +.ui-helper-clearfix { display:block; }
505.20 +/* end clearfix */
505.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
505.22 +
505.23 +
505.24 +/* Interaction Cues
505.25 +----------------------------------*/
505.26 +.ui-state-disabled { cursor: default !important; }
505.27 +
505.28 +
505.29 +/* Icons
505.30 +----------------------------------*/
505.31 +
505.32 +/* states and images */
505.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
505.34 +
505.35 +
505.36 +/* Misc visuals
505.37 +----------------------------------*/
505.38 +
505.39 +/* Overlays */
505.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
505.41 \ No newline at end of file
506.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
506.2 +++ b/web/static/css/ui/themes/base/ui.datepicker.css Mon Apr 26 11:16:23 2010 +0200
506.3 @@ -0,0 +1,62 @@
506.4 +/* Datepicker
506.5 +----------------------------------*/
506.6 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
506.7 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
506.8 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
506.9 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
506.10 +.ui-datepicker .ui-datepicker-prev { left:2px; }
506.11 +.ui-datepicker .ui-datepicker-next { right:2px; }
506.12 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
506.13 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
506.14 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
506.15 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
506.16 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
506.17 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
506.18 +.ui-datepicker select.ui-datepicker-month,
506.19 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
506.20 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
506.21 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
506.22 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
506.23 +.ui-datepicker td { border: 0; padding: 1px; }
506.24 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
506.25 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
506.26 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
506.27 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
506.28 +
506.29 +/* with multiple calendars */
506.30 +.ui-datepicker.ui-datepicker-multi { width:auto; }
506.31 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
506.32 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
506.33 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
506.34 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
506.35 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
506.36 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
506.37 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
506.38 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
506.39 +.ui-datepicker-row-break { clear:both; width:100%; }
506.40 +
506.41 +/* RTL support */
506.42 +.ui-datepicker-rtl { direction: rtl; }
506.43 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
506.44 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
506.45 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
506.46 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
506.47 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
506.48 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
506.49 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
506.50 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
506.51 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
506.52 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
506.53 +
506.54 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
506.55 +.ui-datepicker-cover {
506.56 + display: none; /*sorry for IE5*/
506.57 + display/**/: block; /*sorry for IE5*/
506.58 + position: absolute; /*must have*/
506.59 + z-index: -1; /*must have*/
506.60 + filter: mask(); /*must have*/
506.61 + top: -4px; /*must have*/
506.62 + left: -4px; /*must have*/
506.63 + width: 200px; /*must have*/
506.64 + height: 200px; /*must have*/
506.65 +}
506.66 \ No newline at end of file
507.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
507.2 +++ b/web/static/css/ui/themes/base/ui.progressbar.css Mon Apr 26 11:16:23 2010 +0200
507.3 @@ -0,0 +1,4 @@
507.4 +/* Progressbar
507.5 +----------------------------------*/
507.6 +.ui-progressbar { height:2em; text-align: left; }
507.7 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
507.8 \ No newline at end of file
508.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
508.2 +++ b/web/static/css/ui/themes/base/ui.resizable.css Mon Apr 26 11:16:23 2010 +0200
508.3 @@ -0,0 +1,13 @@
508.4 +/* Resizable
508.5 +----------------------------------*/
508.6 +.ui-resizable { position: relative;}
508.7 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
508.8 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
508.9 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
508.10 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
508.11 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
508.12 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
508.13 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
508.14 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
508.15 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
508.16 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
508.17 \ No newline at end of file
509.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
509.2 +++ b/web/static/css/ui/themes/base/ui.slider.css Mon Apr 26 11:16:23 2010 +0200
509.3 @@ -0,0 +1,17 @@
509.4 +/* Slider
509.5 +----------------------------------*/
509.6 +.ui-slider { position: relative; text-align: left; }
509.7 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
509.8 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
509.9 +
509.10 +.ui-slider-horizontal { height: .8em; }
509.11 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
509.12 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
509.13 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
509.14 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
509.15 +
509.16 +.ui-slider-vertical { width: .8em; height: 100px; }
509.17 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
509.18 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
509.19 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
509.20 +.ui-slider-vertical .ui-slider-range-max { top: 0; }
509.21 \ No newline at end of file
510.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
510.2 +++ b/web/static/css/ui/themes/base/ui.tabs.css Mon Apr 26 11:16:23 2010 +0200
510.3 @@ -0,0 +1,11 @@
510.4 +/* Tabs
510.5 +----------------------------------*/
510.6 +.ui-tabs { padding: .2em; zoom: 1; }
510.7 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
510.8 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
510.9 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
510.10 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
510.11 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
510.12 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
510.13 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
510.14 +.ui-tabs .ui-tabs-hide { display: none !important; }
511.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
511.2 +++ b/web/static/css/ui/themes/base/ui.theme.css Mon Apr 26 11:16:23 2010 +0200
511.3 @@ -0,0 +1,245 @@
511.4 +
511.5 +
511.6 +/*
511.7 +* jQuery UI CSS Framework
511.8 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
511.9 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
511.10 +* To view and modify this theme, visit http://jqueryui.com/themeroller/
511.11 +*/
511.12 +
511.13 +
511.14 +/* Component containers
511.15 +----------------------------------*/
511.16 +.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
511.17 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
511.18 +.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
511.19 +.ui-widget-content a { color: #222222/*{fcContent}*/; }
511.20 +.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
511.21 +.ui-widget-header a { color: #222222/*{fcHeader}*/; }
511.22 +
511.23 +/* Interaction states
511.24 +----------------------------------*/
511.25 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; outline: none; }
511.26 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; outline: none; }
511.27 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; outline: none; }
511.28 +.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; outline: none; }
511.29 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; outline: none; }
511.30 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; outline: none; text-decoration: none; }
511.31 +
511.32 +/* Interaction Cues
511.33 +----------------------------------*/
511.34 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
511.35 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
511.36 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
511.37 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
511.38 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
511.39 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
511.40 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
511.41 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
511.42 +
511.43 +/* Icons
511.44 +----------------------------------*/
511.45 +
511.46 +/* states and images */
511.47 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
511.48 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
511.49 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
511.50 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
511.51 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
511.52 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
511.53 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
511.54 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }
511.55 +
511.56 +/* positioning */
511.57 +.ui-icon-carat-1-n { background-position: 0 0; }
511.58 +.ui-icon-carat-1-ne { background-position: -16px 0; }
511.59 +.ui-icon-carat-1-e { background-position: -32px 0; }
511.60 +.ui-icon-carat-1-se { background-position: -48px 0; }
511.61 +.ui-icon-carat-1-s { background-position: -64px 0; }
511.62 +.ui-icon-carat-1-sw { background-position: -80px 0; }
511.63 +.ui-icon-carat-1-w { background-position: -96px 0; }
511.64 +.ui-icon-carat-1-nw { background-position: -112px 0; }
511.65 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
511.66 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
511.67 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
511.68 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
511.69 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
511.70 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
511.71 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
511.72 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
511.73 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
511.74 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
511.75 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
511.76 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
511.77 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
511.78 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
511.79 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
511.80 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
511.81 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
511.82 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
511.83 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
511.84 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
511.85 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
511.86 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
511.87 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
511.88 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
511.89 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
511.90 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
511.91 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
511.92 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
511.93 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
511.94 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
511.95 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
511.96 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
511.97 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
511.98 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
511.99 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
511.100 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
511.101 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
511.102 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
511.103 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
511.104 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
511.105 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
511.106 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
511.107 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
511.108 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
511.109 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
511.110 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
511.111 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
511.112 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
511.113 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
511.114 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
511.115 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
511.116 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
511.117 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
511.118 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
511.119 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
511.120 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
511.121 +.ui-icon-arrow-4 { background-position: 0 -80px; }
511.122 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
511.123 +.ui-icon-extlink { background-position: -32px -80px; }
511.124 +.ui-icon-newwin { background-position: -48px -80px; }
511.125 +.ui-icon-refresh { background-position: -64px -80px; }
511.126 +.ui-icon-shuffle { background-position: -80px -80px; }
511.127 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
511.128 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
511.129 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
511.130 +.ui-icon-folder-open { background-position: -16px -96px; }
511.131 +.ui-icon-document { background-position: -32px -96px; }
511.132 +.ui-icon-document-b { background-position: -48px -96px; }
511.133 +.ui-icon-note { background-position: -64px -96px; }
511.134 +.ui-icon-mail-closed { background-position: -80px -96px; }
511.135 +.ui-icon-mail-open { background-position: -96px -96px; }
511.136 +.ui-icon-suitcase { background-position: -112px -96px; }
511.137 +.ui-icon-comment { background-position: -128px -96px; }
511.138 +.ui-icon-person { background-position: -144px -96px; }
511.139 +.ui-icon-print { background-position: -160px -96px; }
511.140 +.ui-icon-trash { background-position: -176px -96px; }
511.141 +.ui-icon-locked { background-position: -192px -96px; }
511.142 +.ui-icon-unlocked { background-position: -208px -96px; }
511.143 +.ui-icon-bookmark { background-position: -224px -96px; }
511.144 +.ui-icon-tag { background-position: -240px -96px; }
511.145 +.ui-icon-home { background-position: 0 -112px; }
511.146 +.ui-icon-flag { background-position: -16px -112px; }
511.147 +.ui-icon-calendar { background-position: -32px -112px; }
511.148 +.ui-icon-cart { background-position: -48px -112px; }
511.149 +.ui-icon-pencil { background-position: -64px -112px; }
511.150 +.ui-icon-clock { background-position: -80px -112px; }
511.151 +.ui-icon-disk { background-position: -96px -112px; }
511.152 +.ui-icon-calculator { background-position: -112px -112px; }
511.153 +.ui-icon-zoomin { background-position: -128px -112px; }
511.154 +.ui-icon-zoomout { background-position: -144px -112px; }
511.155 +.ui-icon-search { background-position: -160px -112px; }
511.156 +.ui-icon-wrench { background-position: -176px -112px; }
511.157 +.ui-icon-gear { background-position: -192px -112px; }
511.158 +.ui-icon-heart { background-position: -208px -112px; }
511.159 +.ui-icon-star { background-position: -224px -112px; }
511.160 +.ui-icon-link { background-position: -240px -112px; }
511.161 +.ui-icon-cancel { background-position: 0 -128px; }
511.162 +.ui-icon-plus { background-position: -16px -128px; }
511.163 +.ui-icon-plusthick { background-position: -32px -128px; }
511.164 +.ui-icon-minus { background-position: -48px -128px; }
511.165 +.ui-icon-minusthick { background-position: -64px -128px; }
511.166 +.ui-icon-close { background-position: -80px -128px; }
511.167 +.ui-icon-closethick { background-position: -96px -128px; }
511.168 +.ui-icon-key { background-position: -112px -128px; }
511.169 +.ui-icon-lightbulb { background-position: -128px -128px; }
511.170 +.ui-icon-scissors { background-position: -144px -128px; }
511.171 +.ui-icon-clipboard { background-position: -160px -128px; }
511.172 +.ui-icon-copy { background-position: -176px -128px; }
511.173 +.ui-icon-contact { background-position: -192px -128px; }
511.174 +.ui-icon-image { background-position: -208px -128px; }
511.175 +.ui-icon-video { background-position: -224px -128px; }
511.176 +.ui-icon-script { background-position: -240px -128px; }
511.177 +.ui-icon-alert { background-position: 0 -144px; }
511.178 +.ui-icon-info { background-position: -16px -144px; }
511.179 +.ui-icon-notice { background-position: -32px -144px; }
511.180 +.ui-icon-help { background-position: -48px -144px; }
511.181 +.ui-icon-check { background-position: -64px -144px; }
511.182 +.ui-icon-bullet { background-position: -80px -144px; }
511.183 +.ui-icon-radio-off { background-position: -96px -144px; }
511.184 +.ui-icon-radio-on { background-position: -112px -144px; }
511.185 +.ui-icon-pin-w { background-position: -128px -144px; }
511.186 +.ui-icon-pin-s { background-position: -144px -144px; }
511.187 +.ui-icon-play { background-position: 0 -160px; }
511.188 +.ui-icon-pause { background-position: -16px -160px; }
511.189 +.ui-icon-seek-next { background-position: -32px -160px; }
511.190 +.ui-icon-seek-prev { background-position: -48px -160px; }
511.191 +.ui-icon-seek-end { background-position: -64px -160px; }
511.192 +.ui-icon-seek-first { background-position: -80px -160px; }
511.193 +.ui-icon-stop { background-position: -96px -160px; }
511.194 +.ui-icon-eject { background-position: -112px -160px; }
511.195 +.ui-icon-volume-off { background-position: -128px -160px; }
511.196 +.ui-icon-volume-on { background-position: -144px -160px; }
511.197 +.ui-icon-power { background-position: 0 -176px; }
511.198 +.ui-icon-signal-diag { background-position: -16px -176px; }
511.199 +.ui-icon-signal { background-position: -32px -176px; }
511.200 +.ui-icon-battery-0 { background-position: -48px -176px; }
511.201 +.ui-icon-battery-1 { background-position: -64px -176px; }
511.202 +.ui-icon-battery-2 { background-position: -80px -176px; }
511.203 +.ui-icon-battery-3 { background-position: -96px -176px; }
511.204 +.ui-icon-circle-plus { background-position: 0 -192px; }
511.205 +.ui-icon-circle-minus { background-position: -16px -192px; }
511.206 +.ui-icon-circle-close { background-position: -32px -192px; }
511.207 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
511.208 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
511.209 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
511.210 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
511.211 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
511.212 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
511.213 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
511.214 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
511.215 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
511.216 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
511.217 +.ui-icon-circle-check { background-position: -208px -192px; }
511.218 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
511.219 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
511.220 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
511.221 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
511.222 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
511.223 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
511.224 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
511.225 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
511.226 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
511.227 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
511.228 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
511.229 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
511.230 +
511.231 +
511.232 +/* Misc visuals
511.233 +----------------------------------*/
511.234 +
511.235 +/* Corner radius */
511.236 +.ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; }
511.237 +.ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; }
511.238 +.ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; }
511.239 +.ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
511.240 +.ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; }
511.241 +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
511.242 +.ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
511.243 +.ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; }
511.244 +.ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; }
511.245 +
511.246 +/* Overlays */
511.247 +.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
511.248 +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; }
511.249 \ No newline at end of file
512.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_flat_0_aaaaaa_40x100.png has changed
513.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_flat_100_467656_40x100.png has changed
514.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_flat_75_f0f7e9_40x100.png has changed
515.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_flat_75_ffffff_40x100.png has changed
516.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_glass_55_fef5c3_1x400.png has changed
517.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_glass_65_ffffff_1x400.png has changed
518.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_glass_75_dadada_1x400.png has changed
519.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_highlight-soft_75_cae960_1x100.png has changed
520.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_inset-soft_100_467656_1x100.png has changed
521.1 Binary file web/static/css/ui/themes/isi/images/ui-bg_inset-soft_95_ddd936_1x100.png has changed
522.1 Binary file web/static/css/ui/themes/isi/images/ui-icons_222222_256x240.png has changed
523.1 Binary file web/static/css/ui/themes/isi/images/ui-icons_2e83ff_256x240.png has changed
524.1 Binary file web/static/css/ui/themes/isi/images/ui-icons_454545_256x240.png has changed
525.1 Binary file web/static/css/ui/themes/isi/images/ui-icons_cd0a0a_256x240.png has changed
526.1 Binary file web/static/css/ui/themes/isi/images/ui-icons_f5f3ef_256x240.png has changed
527.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
527.2 +++ b/web/static/css/ui/themes/isi/jquery-ui-1.7.2.custom.css Mon Apr 26 11:16:23 2010 +0200
527.3 @@ -0,0 +1,406 @@
527.4 +/*
527.5 +* jQuery UI CSS Framework
527.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
527.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
527.8 +*/
527.9 +
527.10 +/* Layout helpers
527.11 +----------------------------------*/
527.12 +.ui-helper-hidden { display: none; }
527.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
527.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
527.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
527.16 +.ui-helper-clearfix { display: inline-block; }
527.17 +/* required comment for clearfix to work in Opera \*/
527.18 +* html .ui-helper-clearfix { height:1%; }
527.19 +.ui-helper-clearfix { display:block; }
527.20 +/* end clearfix */
527.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
527.22 +
527.23 +
527.24 +/* Interaction Cues
527.25 +----------------------------------*/
527.26 +.ui-state-disabled { cursor: default !important; }
527.27 +
527.28 +
527.29 +/* Icons
527.30 +----------------------------------*/
527.31 +
527.32 +/* states and images */
527.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
527.34 +
527.35 +
527.36 +/* Misc visuals
527.37 +----------------------------------*/
527.38 +
527.39 +/* Overlays */
527.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
527.41 +
527.42 +
527.43 +
527.44 +/*
527.45 +* jQuery UI CSS Framework
527.46 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
527.47 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
527.48 +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=cae960&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=eee&fcContent=222222&iconColorContent=222222&bgColorDefault=467656&bgTextureDefault=01_flat.png&bgImgOpacityDefault=100&borderColorDefault=d3d3d3&fcDefault=ede8e3&iconColorDefault=f5f3ef&bgColorHover=f0f7e9&bgTextureHover=01_flat.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fef5c3&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=efd748&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=ddd936&bgTextureError=05_inset_soft.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
527.49 +*/
527.50 +
527.51 +
527.52 +/* Component containers
527.53 +----------------------------------*/
527.54 +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
527.55 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
527.56 +.ui-widget-content { border: 1px solid #eee; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
527.57 +.ui-widget-content a { color: #222222; }
527.58 +.ui-widget-header { border: 1px solid #aaa; background: #cae960 url(images/ui-bg_highlight-soft_75_cae960_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
527.59 +.ui-widget-header a { color: #222222; }
527.60 +
527.61 +/* Interaction states
527.62 +----------------------------------*/
527.63 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #467656 url(images/ui-bg_flat_100_467656_40x100.png) 50% 50% repeat-x; font-weight: normal; color: #ede8e3; outline: none; }
527.64 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #ede8e3; text-decoration: none; outline: none; }
527.65 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #f0f7e9 url(images/ui-bg_flat_75_f0f7e9_40x100.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
527.66 +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; }
527.67 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
527.68 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; }
527.69 +
527.70 +/* Interaction Cues
527.71 +----------------------------------*/
527.72 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #efd748; background: #fef5c3 url(images/ui-bg_glass_55_fef5c3_1x400.png) 50% 50% repeat-x; color: #363636; }
527.73 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
527.74 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #ddd936 url(images/ui-bg_inset-soft_95_ddd936_1x100.png) 50% bottom repeat-x; color: #cd0a0a; }
527.75 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
527.76 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
527.77 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
527.78 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
527.79 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
527.80 +
527.81 +/* Icons
527.82 +----------------------------------*/
527.83 +
527.84 +/* states and images */
527.85 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
527.86 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
527.87 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
527.88 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_f5f3ef_256x240.png); }
527.89 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
527.90 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
527.91 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
527.92 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
527.93 +
527.94 +/* positioning */
527.95 +.ui-icon-carat-1-n { background-position: 0 0; }
527.96 +.ui-icon-carat-1-ne { background-position: -16px 0; }
527.97 +.ui-icon-carat-1-e { background-position: -32px 0; }
527.98 +.ui-icon-carat-1-se { background-position: -48px 0; }
527.99 +.ui-icon-carat-1-s { background-position: -64px 0; }
527.100 +.ui-icon-carat-1-sw { background-position: -80px 0; }
527.101 +.ui-icon-carat-1-w { background-position: -96px 0; }
527.102 +.ui-icon-carat-1-nw { background-position: -112px 0; }
527.103 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
527.104 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
527.105 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
527.106 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
527.107 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
527.108 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
527.109 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
527.110 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
527.111 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
527.112 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
527.113 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
527.114 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
527.115 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
527.116 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
527.117 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
527.118 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
527.119 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
527.120 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
527.121 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
527.122 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
527.123 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
527.124 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
527.125 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
527.126 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
527.127 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
527.128 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
527.129 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
527.130 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
527.131 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
527.132 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
527.133 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
527.134 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
527.135 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
527.136 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
527.137 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
527.138 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
527.139 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
527.140 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
527.141 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
527.142 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
527.143 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
527.144 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
527.145 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
527.146 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
527.147 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
527.148 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
527.149 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
527.150 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
527.151 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
527.152 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
527.153 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
527.154 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
527.155 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
527.156 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
527.157 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
527.158 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
527.159 +.ui-icon-arrow-4 { background-position: 0 -80px; }
527.160 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
527.161 +.ui-icon-extlink { background-position: -32px -80px; }
527.162 +.ui-icon-newwin { background-position: -48px -80px; }
527.163 +.ui-icon-refresh { background-position: -64px -80px; }
527.164 +.ui-icon-shuffle { background-position: -80px -80px; }
527.165 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
527.166 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
527.167 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
527.168 +.ui-icon-folder-open { background-position: -16px -96px; }
527.169 +.ui-icon-document { background-position: -32px -96px; }
527.170 +.ui-icon-document-b { background-position: -48px -96px; }
527.171 +.ui-icon-note { background-position: -64px -96px; }
527.172 +.ui-icon-mail-closed { background-position: -80px -96px; }
527.173 +.ui-icon-mail-open { background-position: -96px -96px; }
527.174 +.ui-icon-suitcase { background-position: -112px -96px; }
527.175 +.ui-icon-comment { background-position: -128px -96px; }
527.176 +.ui-icon-person { background-position: -144px -96px; }
527.177 +.ui-icon-print { background-position: -160px -96px; }
527.178 +.ui-icon-trash { background-position: -176px -96px; }
527.179 +.ui-icon-locked { background-position: -192px -96px; }
527.180 +.ui-icon-unlocked { background-position: -208px -96px; }
527.181 +.ui-icon-bookmark { background-position: -224px -96px; }
527.182 +.ui-icon-tag { background-position: -240px -96px; }
527.183 +.ui-icon-home { background-position: 0 -112px; }
527.184 +.ui-icon-flag { background-position: -16px -112px; }
527.185 +.ui-icon-calendar { background-position: -32px -112px; }
527.186 +.ui-icon-cart { background-position: -48px -112px; }
527.187 +.ui-icon-pencil { background-position: -64px -112px; }
527.188 +.ui-icon-clock { background-position: -80px -112px; }
527.189 +.ui-icon-disk { background-position: -96px -112px; }
527.190 +.ui-icon-calculator { background-position: -112px -112px; }
527.191 +.ui-icon-zoomin { background-position: -128px -112px; }
527.192 +.ui-icon-zoomout { background-position: -144px -112px; }
527.193 +.ui-icon-search { background-position: -160px -112px; }
527.194 +.ui-icon-wrench { background-position: -176px -112px; }
527.195 +.ui-icon-gear { background-position: -192px -112px; }
527.196 +.ui-icon-heart { background-position: -208px -112px; }
527.197 +.ui-icon-star { background-position: -224px -112px; }
527.198 +.ui-icon-link { background-position: -240px -112px; }
527.199 +.ui-icon-cancel { background-position: 0 -128px; }
527.200 +.ui-icon-plus { background-position: -16px -128px; }
527.201 +.ui-icon-plusthick { background-position: -32px -128px; }
527.202 +.ui-icon-minus { background-position: -48px -128px; }
527.203 +.ui-icon-minusthick { background-position: -64px -128px; }
527.204 +.ui-icon-close { background-position: -80px -128px; }
527.205 +.ui-icon-closethick { background-position: -96px -128px; }
527.206 +.ui-icon-key { background-position: -112px -128px; }
527.207 +.ui-icon-lightbulb { background-position: -128px -128px; }
527.208 +.ui-icon-scissors { background-position: -144px -128px; }
527.209 +.ui-icon-clipboard { background-position: -160px -128px; }
527.210 +.ui-icon-copy { background-position: -176px -128px; }
527.211 +.ui-icon-contact { background-position: -192px -128px; }
527.212 +.ui-icon-image { background-position: -208px -128px; }
527.213 +.ui-icon-video { background-position: -224px -128px; }
527.214 +.ui-icon-script { background-position: -240px -128px; }
527.215 +.ui-icon-alert { background-position: 0 -144px; }
527.216 +.ui-icon-info { background-position: -16px -144px; }
527.217 +.ui-icon-notice { background-position: -32px -144px; }
527.218 +.ui-icon-help { background-position: -48px -144px; }
527.219 +.ui-icon-check { background-position: -64px -144px; }
527.220 +.ui-icon-bullet { background-position: -80px -144px; }
527.221 +.ui-icon-radio-off { background-position: -96px -144px; }
527.222 +.ui-icon-radio-on { background-position: -112px -144px; }
527.223 +.ui-icon-pin-w { background-position: -128px -144px; }
527.224 +.ui-icon-pin-s { background-position: -144px -144px; }
527.225 +.ui-icon-play { background-position: 0 -160px; }
527.226 +.ui-icon-pause { background-position: -16px -160px; }
527.227 +.ui-icon-seek-next { background-position: -32px -160px; }
527.228 +.ui-icon-seek-prev { background-position: -48px -160px; }
527.229 +.ui-icon-seek-end { background-position: -64px -160px; }
527.230 +.ui-icon-seek-first { background-position: -80px -160px; }
527.231 +.ui-icon-stop { background-position: -96px -160px; }
527.232 +.ui-icon-eject { background-position: -112px -160px; }
527.233 +.ui-icon-volume-off { background-position: -128px -160px; }
527.234 +.ui-icon-volume-on { background-position: -144px -160px; }
527.235 +.ui-icon-power { background-position: 0 -176px; }
527.236 +.ui-icon-signal-diag { background-position: -16px -176px; }
527.237 +.ui-icon-signal { background-position: -32px -176px; }
527.238 +.ui-icon-battery-0 { background-position: -48px -176px; }
527.239 +.ui-icon-battery-1 { background-position: -64px -176px; }
527.240 +.ui-icon-battery-2 { background-position: -80px -176px; }
527.241 +.ui-icon-battery-3 { background-position: -96px -176px; }
527.242 +.ui-icon-circle-plus { background-position: 0 -192px; }
527.243 +.ui-icon-circle-minus { background-position: -16px -192px; }
527.244 +.ui-icon-circle-close { background-position: -32px -192px; }
527.245 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
527.246 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
527.247 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
527.248 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
527.249 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
527.250 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
527.251 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
527.252 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
527.253 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
527.254 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
527.255 +.ui-icon-circle-check { background-position: -208px -192px; }
527.256 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
527.257 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
527.258 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
527.259 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
527.260 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
527.261 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
527.262 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
527.263 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
527.264 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
527.265 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
527.266 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
527.267 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
527.268 +
527.269 +
527.270 +/* Misc visuals
527.271 +----------------------------------*/
527.272 +
527.273 +/* Corner radius */
527.274 +.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; }
527.275 +.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
527.276 +.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
527.277 +.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
527.278 +.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
527.279 +.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
527.280 +.ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
527.281 +.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
527.282 +.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; }
527.283 +
527.284 +/* Overlays */
527.285 +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
527.286 +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion
527.287 +----------------------------------*/
527.288 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
527.289 +.ui-accordion .ui-accordion-li-fix { display: inline; }
527.290 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
527.291 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
527.292 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
527.293 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
527.294 +.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
527.295 +----------------------------------*/
527.296 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
527.297 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
527.298 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
527.299 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
527.300 +.ui-datepicker .ui-datepicker-prev { left:2px; }
527.301 +.ui-datepicker .ui-datepicker-next { right:2px; }
527.302 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
527.303 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
527.304 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
527.305 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
527.306 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
527.307 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
527.308 +.ui-datepicker select.ui-datepicker-month,
527.309 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
527.310 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
527.311 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
527.312 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
527.313 +.ui-datepicker td { border: 0; padding: 1px; }
527.314 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
527.315 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
527.316 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
527.317 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
527.318 +
527.319 +/* with multiple calendars */
527.320 +.ui-datepicker.ui-datepicker-multi { width:auto; }
527.321 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
527.322 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
527.323 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
527.324 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
527.325 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
527.326 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
527.327 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
527.328 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
527.329 +.ui-datepicker-row-break { clear:both; width:100%; }
527.330 +
527.331 +/* RTL support */
527.332 +.ui-datepicker-rtl { direction: rtl; }
527.333 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
527.334 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
527.335 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
527.336 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
527.337 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
527.338 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
527.339 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
527.340 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
527.341 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
527.342 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
527.343 +
527.344 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
527.345 +.ui-datepicker-cover {
527.346 + display: none; /*sorry for IE5*/
527.347 + display/**/: block; /*sorry for IE5*/
527.348 + position: absolute; /*must have*/
527.349 + z-index: -1; /*must have*/
527.350 + filter: mask(); /*must have*/
527.351 + top: -4px; /*must have*/
527.352 + left: -4px; /*must have*/
527.353 + width: 200px; /*must have*/
527.354 + height: 200px; /*must have*/
527.355 +}/* Dialog
527.356 +----------------------------------*/
527.357 +.ui-dialog { position: relative; padding: .2em; width: 300px; }
527.358 +.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
527.359 +.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
527.360 +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
527.361 +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
527.362 +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
527.363 +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
527.364 +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
527.365 +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
527.366 +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
527.367 +.ui-draggable .ui-dialog-titlebar { cursor: move; }
527.368 +/* Progressbar
527.369 +----------------------------------*/
527.370 +.ui-progressbar { height:2em; text-align: left; }
527.371 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
527.372 +----------------------------------*/
527.373 +.ui-resizable { position: relative;}
527.374 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
527.375 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
527.376 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
527.377 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
527.378 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
527.379 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
527.380 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
527.381 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
527.382 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
527.383 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
527.384 +----------------------------------*/
527.385 +.ui-slider { position: relative; text-align: left; }
527.386 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
527.387 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
527.388 +
527.389 +.ui-slider-horizontal { height: .8em; }
527.390 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
527.391 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
527.392 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
527.393 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
527.394 +
527.395 +.ui-slider-vertical { width: .8em; height: 100px; }
527.396 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
527.397 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
527.398 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
527.399 +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
527.400 +----------------------------------*/
527.401 +.ui-tabs { padding: .2em; zoom: 1; }
527.402 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
527.403 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
527.404 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
527.405 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
527.406 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
527.407 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
527.408 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
527.409 +.ui-tabs .ui-tabs-hide { display: none !important; }
528.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
528.2 +++ b/web/static/css/ui/themes/isi/ui.accordion.css Mon Apr 26 11:16:23 2010 +0200
528.3 @@ -0,0 +1,9 @@
528.4 +/* Accordion
528.5 +----------------------------------*/
528.6 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
528.7 +.ui-accordion .ui-accordion-li-fix { display: inline; }
528.8 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
528.9 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
528.10 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
528.11 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
528.12 +.ui-accordion .ui-accordion-content-active { display: block; }
528.13 \ No newline at end of file
529.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
529.2 +++ b/web/static/css/ui/themes/isi/ui.all.css Mon Apr 26 11:16:23 2010 +0200
529.3 @@ -0,0 +1,2 @@
529.4 +@import "ui.base.css";
529.5 +@import "ui.theme.css";
530.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
530.2 +++ b/web/static/css/ui/themes/isi/ui.base.css Mon Apr 26 11:16:23 2010 +0200
530.3 @@ -0,0 +1,8 @@
530.4 +@import url("ui.core.css");
530.5 +@import url("ui.resizable.css");
530.6 +@import url("ui.accordion.css");
530.7 +@import url("ui.dialog.css");
530.8 +@import url("ui.slider.css");
530.9 +@import url("ui.tabs.css");
530.10 +@import url("ui.datepicker.css");
530.11 +@import url("ui.progressbar.css");
530.12 \ No newline at end of file
531.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
531.2 +++ b/web/static/css/ui/themes/isi/ui.core.css Mon Apr 26 11:16:23 2010 +0200
531.3 @@ -0,0 +1,37 @@
531.4 +/*
531.5 +* jQuery UI CSS Framework
531.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
531.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
531.8 +*/
531.9 +
531.10 +/* Layout helpers
531.11 +----------------------------------*/
531.12 +.ui-helper-hidden { display: none; }
531.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
531.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
531.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
531.16 +.ui-helper-clearfix { display: inline-block; }
531.17 +/* required comment for clearfix to work in Opera \*/
531.18 +* html .ui-helper-clearfix { height:1%; }
531.19 +.ui-helper-clearfix { display:block; }
531.20 +/* end clearfix */
531.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
531.22 +
531.23 +
531.24 +/* Interaction Cues
531.25 +----------------------------------*/
531.26 +.ui-state-disabled { cursor: default !important; }
531.27 +
531.28 +
531.29 +/* Icons
531.30 +----------------------------------*/
531.31 +
531.32 +/* states and images */
531.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
531.34 +
531.35 +
531.36 +/* Misc visuals
531.37 +----------------------------------*/
531.38 +
531.39 +/* Overlays */
531.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
531.41 \ No newline at end of file
532.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
532.2 +++ b/web/static/css/ui/themes/isi/ui.datepicker.css Mon Apr 26 11:16:23 2010 +0200
532.3 @@ -0,0 +1,62 @@
532.4 +/* Datepicker
532.5 +----------------------------------*/
532.6 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
532.7 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
532.8 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
532.9 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
532.10 +.ui-datepicker .ui-datepicker-prev { left:2px; }
532.11 +.ui-datepicker .ui-datepicker-next { right:2px; }
532.12 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
532.13 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
532.14 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
532.15 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
532.16 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
532.17 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
532.18 +.ui-datepicker select.ui-datepicker-month,
532.19 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
532.20 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
532.21 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
532.22 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
532.23 +.ui-datepicker td { border: 0; padding: 1px; }
532.24 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
532.25 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
532.26 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
532.27 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
532.28 +
532.29 +/* with multiple calendars */
532.30 +.ui-datepicker.ui-datepicker-multi { width:auto; }
532.31 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
532.32 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
532.33 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
532.34 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
532.35 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
532.36 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
532.37 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
532.38 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
532.39 +.ui-datepicker-row-break { clear:both; width:100%; }
532.40 +
532.41 +/* RTL support */
532.42 +.ui-datepicker-rtl { direction: rtl; }
532.43 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
532.44 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
532.45 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
532.46 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
532.47 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
532.48 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
532.49 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
532.50 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
532.51 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
532.52 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
532.53 +
532.54 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
532.55 +.ui-datepicker-cover {
532.56 + display: none; /*sorry for IE5*/
532.57 + display/**/: block; /*sorry for IE5*/
532.58 + position: absolute; /*must have*/
532.59 + z-index: -1; /*must have*/
532.60 + filter: mask(); /*must have*/
532.61 + top: -4px; /*must have*/
532.62 + left: -4px; /*must have*/
532.63 + width: 200px; /*must have*/
532.64 + height: 200px; /*must have*/
532.65 +}
532.66 \ No newline at end of file
533.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
533.2 +++ b/web/static/css/ui/themes/isi/ui.progressbar.css Mon Apr 26 11:16:23 2010 +0200
533.3 @@ -0,0 +1,4 @@
533.4 +/* Progressbar
533.5 +----------------------------------*/
533.6 +.ui-progressbar { height:2em; text-align: left; }
533.7 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
533.8 \ No newline at end of file
534.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
534.2 +++ b/web/static/css/ui/themes/isi/ui.resizable.css Mon Apr 26 11:16:23 2010 +0200
534.3 @@ -0,0 +1,13 @@
534.4 +/* Resizable
534.5 +----------------------------------*/
534.6 +.ui-resizable { position: relative;}
534.7 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
534.8 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
534.9 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
534.10 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
534.11 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
534.12 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
534.13 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
534.14 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
534.15 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
534.16 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
534.17 \ No newline at end of file
535.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
535.2 +++ b/web/static/css/ui/themes/isi/ui.slider.css Mon Apr 26 11:16:23 2010 +0200
535.3 @@ -0,0 +1,17 @@
535.4 +/* Slider
535.5 +----------------------------------*/
535.6 +.ui-slider { position: relative; text-align: left; }
535.7 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
535.8 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
535.9 +
535.10 +.ui-slider-horizontal { height: .8em; }
535.11 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
535.12 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
535.13 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
535.14 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
535.15 +
535.16 +.ui-slider-vertical { width: .8em; height: 100px; }
535.17 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
535.18 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
535.19 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
535.20 +.ui-slider-vertical .ui-slider-range-max { top: 0; }
535.21 \ No newline at end of file
536.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
536.2 +++ b/web/static/css/ui/themes/isi/ui.tabs.css Mon Apr 26 11:16:23 2010 +0200
536.3 @@ -0,0 +1,11 @@
536.4 +/* Tabs
536.5 +----------------------------------*/
536.6 +.ui-tabs { padding: .2em; zoom: 1; }
536.7 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
536.8 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
536.9 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
536.10 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
536.11 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
536.12 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
536.13 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
536.14 +.ui-tabs .ui-tabs-hide { display: none !important; }
537.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
537.2 +++ b/web/static/css/ui/themes/isi/ui.theme.css Mon Apr 26 11:16:23 2010 +0200
537.3 @@ -0,0 +1,247 @@
537.4 +
537.5 +
537.6 +
537.7 +
537.8 +/*
537.9 +* jQuery UI CSS Framework
537.10 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
537.11 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
537.12 +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=cae960&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=eee&fcContent=222222&iconColorContent=222222&bgColorDefault=467656&bgTextureDefault=01_flat.png&bgImgOpacityDefault=100&borderColorDefault=d3d3d3&fcDefault=ede8e3&iconColorDefault=f5f3ef&bgColorHover=f0f7e9&bgTextureHover=01_flat.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fef5c3&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=efd748&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=ddd936&bgTextureError=05_inset_soft.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
537.13 +*/
537.14 +
537.15 +
537.16 +/* Component containers
537.17 +----------------------------------*/
537.18 +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
537.19 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
537.20 +.ui-widget-content { border: 1px solid #eee; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
537.21 +.ui-widget-content a { color: #222222; }
537.22 +.ui-widget-header { border: 1px solid #aaa; background: #cae960 url(images/ui-bg_highlight-soft_75_cae960_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
537.23 +.ui-widget-header a { color: #222222; }
537.24 +
537.25 +/* Interaction states
537.26 +----------------------------------*/
537.27 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #467656 url(images/ui-bg_flat_100_467656_40x100.png) 50% 50% repeat-x; font-weight: normal; color: #ede8e3; outline: none; }
537.28 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #ede8e3; text-decoration: none; outline: none; }
537.29 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #f0f7e9 url(images/ui-bg_flat_75_f0f7e9_40x100.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
537.30 +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; }
537.31 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
537.32 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; }
537.33 +
537.34 +/* Interaction Cues
537.35 +----------------------------------*/
537.36 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #efd748; background: #fef5c3 url(images/ui-bg_glass_55_fef5c3_1x400.png) 50% 50% repeat-x; color: #363636; }
537.37 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
537.38 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #ddd936 url(images/ui-bg_inset-soft_95_ddd936_1x100.png) 50% bottom repeat-x; color: #cd0a0a; }
537.39 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
537.40 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
537.41 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
537.42 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
537.43 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
537.44 +
537.45 +/* Icons
537.46 +----------------------------------*/
537.47 +
537.48 +/* states and images */
537.49 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
537.50 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
537.51 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
537.52 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_f5f3ef_256x240.png); }
537.53 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
537.54 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
537.55 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
537.56 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
537.57 +
537.58 +/* positioning */
537.59 +.ui-icon-carat-1-n { background-position: 0 0; }
537.60 +.ui-icon-carat-1-ne { background-position: -16px 0; }
537.61 +.ui-icon-carat-1-e { background-position: -32px 0; }
537.62 +.ui-icon-carat-1-se { background-position: -48px 0; }
537.63 +.ui-icon-carat-1-s { background-position: -64px 0; }
537.64 +.ui-icon-carat-1-sw { background-position: -80px 0; }
537.65 +.ui-icon-carat-1-w { background-position: -96px 0; }
537.66 +.ui-icon-carat-1-nw { background-position: -112px 0; }
537.67 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
537.68 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
537.69 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
537.70 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
537.71 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
537.72 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
537.73 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
537.74 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
537.75 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
537.76 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
537.77 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
537.78 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
537.79 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
537.80 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
537.81 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
537.82 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
537.83 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
537.84 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
537.85 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
537.86 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
537.87 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
537.88 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
537.89 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
537.90 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
537.91 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
537.92 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
537.93 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
537.94 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
537.95 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
537.96 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
537.97 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
537.98 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
537.99 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
537.100 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
537.101 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
537.102 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
537.103 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
537.104 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
537.105 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
537.106 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
537.107 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
537.108 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
537.109 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
537.110 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
537.111 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
537.112 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
537.113 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
537.114 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
537.115 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
537.116 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
537.117 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
537.118 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
537.119 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
537.120 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
537.121 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
537.122 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
537.123 +.ui-icon-arrow-4 { background-position: 0 -80px; }
537.124 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
537.125 +.ui-icon-extlink { background-position: -32px -80px; }
537.126 +.ui-icon-newwin { background-position: -48px -80px; }
537.127 +.ui-icon-refresh { background-position: -64px -80px; }
537.128 +.ui-icon-shuffle { background-position: -80px -80px; }
537.129 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
537.130 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
537.131 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
537.132 +.ui-icon-folder-open { background-position: -16px -96px; }
537.133 +.ui-icon-document { background-position: -32px -96px; }
537.134 +.ui-icon-document-b { background-position: -48px -96px; }
537.135 +.ui-icon-note { background-position: -64px -96px; }
537.136 +.ui-icon-mail-closed { background-position: -80px -96px; }
537.137 +.ui-icon-mail-open { background-position: -96px -96px; }
537.138 +.ui-icon-suitcase { background-position: -112px -96px; }
537.139 +.ui-icon-comment { background-position: -128px -96px; }
537.140 +.ui-icon-person { background-position: -144px -96px; }
537.141 +.ui-icon-print { background-position: -160px -96px; }
537.142 +.ui-icon-trash { background-position: -176px -96px; }
537.143 +.ui-icon-locked { background-position: -192px -96px; }
537.144 +.ui-icon-unlocked { background-position: -208px -96px; }
537.145 +.ui-icon-bookmark { background-position: -224px -96px; }
537.146 +.ui-icon-tag { background-position: -240px -96px; }
537.147 +.ui-icon-home { background-position: 0 -112px; }
537.148 +.ui-icon-flag { background-position: -16px -112px; }
537.149 +.ui-icon-calendar { background-position: -32px -112px; }
537.150 +.ui-icon-cart { background-position: -48px -112px; }
537.151 +.ui-icon-pencil { background-position: -64px -112px; }
537.152 +.ui-icon-clock { background-position: -80px -112px; }
537.153 +.ui-icon-disk { background-position: -96px -112px; }
537.154 +.ui-icon-calculator { background-position: -112px -112px; }
537.155 +.ui-icon-zoomin { background-position: -128px -112px; }
537.156 +.ui-icon-zoomout { background-position: -144px -112px; }
537.157 +.ui-icon-search { background-position: -160px -112px; }
537.158 +.ui-icon-wrench { background-position: -176px -112px; }
537.159 +.ui-icon-gear { background-position: -192px -112px; }
537.160 +.ui-icon-heart { background-position: -208px -112px; }
537.161 +.ui-icon-star { background-position: -224px -112px; }
537.162 +.ui-icon-link { background-position: -240px -112px; }
537.163 +.ui-icon-cancel { background-position: 0 -128px; }
537.164 +.ui-icon-plus { background-position: -16px -128px; }
537.165 +.ui-icon-plusthick { background-position: -32px -128px; }
537.166 +.ui-icon-minus { background-position: -48px -128px; }
537.167 +.ui-icon-minusthick { background-position: -64px -128px; }
537.168 +.ui-icon-close { background-position: -80px -128px; }
537.169 +.ui-icon-closethick { background-position: -96px -128px; }
537.170 +.ui-icon-key { background-position: -112px -128px; }
537.171 +.ui-icon-lightbulb { background-position: -128px -128px; }
537.172 +.ui-icon-scissors { background-position: -144px -128px; }
537.173 +.ui-icon-clipboard { background-position: -160px -128px; }
537.174 +.ui-icon-copy { background-position: -176px -128px; }
537.175 +.ui-icon-contact { background-position: -192px -128px; }
537.176 +.ui-icon-image { background-position: -208px -128px; }
537.177 +.ui-icon-video { background-position: -224px -128px; }
537.178 +.ui-icon-script { background-position: -240px -128px; }
537.179 +.ui-icon-alert { background-position: 0 -144px; }
537.180 +.ui-icon-info { background-position: -16px -144px; }
537.181 +.ui-icon-notice { background-position: -32px -144px; }
537.182 +.ui-icon-help { background-position: -48px -144px; }
537.183 +.ui-icon-check { background-position: -64px -144px; }
537.184 +.ui-icon-bullet { background-position: -80px -144px; }
537.185 +.ui-icon-radio-off { background-position: -96px -144px; }
537.186 +.ui-icon-radio-on { background-position: -112px -144px; }
537.187 +.ui-icon-pin-w { background-position: -128px -144px; }
537.188 +.ui-icon-pin-s { background-position: -144px -144px; }
537.189 +.ui-icon-play { background-position: 0 -160px; }
537.190 +.ui-icon-pause { background-position: -16px -160px; }
537.191 +.ui-icon-seek-next { background-position: -32px -160px; }
537.192 +.ui-icon-seek-prev { background-position: -48px -160px; }
537.193 +.ui-icon-seek-end { background-position: -64px -160px; }
537.194 +.ui-icon-seek-first { background-position: -80px -160px; }
537.195 +.ui-icon-stop { background-position: -96px -160px; }
537.196 +.ui-icon-eject { background-position: -112px -160px; }
537.197 +.ui-icon-volume-off { background-position: -128px -160px; }
537.198 +.ui-icon-volume-on { background-position: -144px -160px; }
537.199 +.ui-icon-power { background-position: 0 -176px; }
537.200 +.ui-icon-signal-diag { background-position: -16px -176px; }
537.201 +.ui-icon-signal { background-position: -32px -176px; }
537.202 +.ui-icon-battery-0 { background-position: -48px -176px; }
537.203 +.ui-icon-battery-1 { background-position: -64px -176px; }
537.204 +.ui-icon-battery-2 { background-position: -80px -176px; }
537.205 +.ui-icon-battery-3 { background-position: -96px -176px; }
537.206 +.ui-icon-circle-plus { background-position: 0 -192px; }
537.207 +.ui-icon-circle-minus { background-position: -16px -192px; }
537.208 +.ui-icon-circle-close { background-position: -32px -192px; }
537.209 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
537.210 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
537.211 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
537.212 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
537.213 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
537.214 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
537.215 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
537.216 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
537.217 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
537.218 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
537.219 +.ui-icon-circle-check { background-position: -208px -192px; }
537.220 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
537.221 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
537.222 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
537.223 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
537.224 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
537.225 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
537.226 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
537.227 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
537.228 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
537.229 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
537.230 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
537.231 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
537.232 +
537.233 +
537.234 +/* Misc visuals
537.235 +----------------------------------*/
537.236 +
537.237 +/* Corner radius */
537.238 +.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; }
537.239 +.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
537.240 +.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
537.241 +.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
537.242 +.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
537.243 +.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
537.244 +.ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
537.245 +.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
537.246 +.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; }
537.247 +
537.248 +/* Overlays */
537.249 +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
537.250 +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }
537.251 \ No newline at end of file
538.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png has changed
539.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png has changed
540.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png has changed
541.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png has changed
542.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png has changed
543.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png has changed
544.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png has changed
545.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png has changed
546.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png has changed
547.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-icons_222222_256x240.png has changed
548.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-icons_228ef1_256x240.png has changed
549.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png has changed
550.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png has changed
551.1 Binary file web/static/css/ui/themes/ui-lightness/images/ui-icons_ffffff_256x240.png has changed
552.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
552.2 +++ b/web/static/css/ui/themes/ui-lightness/jquery-ui-1.7.2.custom.css Mon Apr 26 11:16:23 2010 +0200
552.3 @@ -0,0 +1,406 @@
552.4 +/*
552.5 +* jQuery UI CSS Framework
552.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
552.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
552.8 +*/
552.9 +
552.10 +/* Layout helpers
552.11 +----------------------------------*/
552.12 +.ui-helper-hidden { display: none; }
552.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
552.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
552.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
552.16 +.ui-helper-clearfix { display: inline-block; }
552.17 +/* required comment for clearfix to work in Opera \*/
552.18 +* html .ui-helper-clearfix { height:1%; }
552.19 +.ui-helper-clearfix { display:block; }
552.20 +/* end clearfix */
552.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
552.22 +
552.23 +
552.24 +/* Interaction Cues
552.25 +----------------------------------*/
552.26 +.ui-state-disabled { cursor: default !important; }
552.27 +
552.28 +
552.29 +/* Icons
552.30 +----------------------------------*/
552.31 +
552.32 +/* states and images */
552.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
552.34 +
552.35 +
552.36 +/* Misc visuals
552.37 +----------------------------------*/
552.38 +
552.39 +/* Overlays */
552.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
552.41 +
552.42 +
552.43 +
552.44 +/*
552.45 +* jQuery UI CSS Framework
552.46 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
552.47 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
552.48 +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
552.49 +*/
552.50 +
552.51 +
552.52 +/* Component containers
552.53 +----------------------------------*/
552.54 +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
552.55 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
552.56 +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
552.57 +.ui-widget-content a { color: #333333; }
552.58 +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
552.59 +.ui-widget-header a { color: #ffffff; }
552.60 +
552.61 +/* Interaction states
552.62 +----------------------------------*/
552.63 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; outline: none; }
552.64 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; outline: none; }
552.65 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; outline: none; }
552.66 +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; outline: none; }
552.67 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; outline: none; }
552.68 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; outline: none; text-decoration: none; }
552.69 +
552.70 +/* Interaction Cues
552.71 +----------------------------------*/
552.72 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
552.73 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
552.74 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
552.75 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #ffffff; }
552.76 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
552.77 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
552.78 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
552.79 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
552.80 +
552.81 +/* Icons
552.82 +----------------------------------*/
552.83 +
552.84 +/* states and images */
552.85 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
552.86 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
552.87 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
552.88 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
552.89 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
552.90 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
552.91 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
552.92 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
552.93 +
552.94 +/* positioning */
552.95 +.ui-icon-carat-1-n { background-position: 0 0; }
552.96 +.ui-icon-carat-1-ne { background-position: -16px 0; }
552.97 +.ui-icon-carat-1-e { background-position: -32px 0; }
552.98 +.ui-icon-carat-1-se { background-position: -48px 0; }
552.99 +.ui-icon-carat-1-s { background-position: -64px 0; }
552.100 +.ui-icon-carat-1-sw { background-position: -80px 0; }
552.101 +.ui-icon-carat-1-w { background-position: -96px 0; }
552.102 +.ui-icon-carat-1-nw { background-position: -112px 0; }
552.103 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
552.104 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
552.105 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
552.106 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
552.107 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
552.108 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
552.109 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
552.110 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
552.111 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
552.112 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
552.113 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
552.114 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
552.115 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
552.116 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
552.117 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
552.118 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
552.119 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
552.120 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
552.121 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
552.122 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
552.123 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
552.124 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
552.125 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
552.126 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
552.127 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
552.128 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
552.129 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
552.130 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
552.131 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
552.132 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
552.133 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
552.134 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
552.135 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
552.136 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
552.137 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
552.138 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
552.139 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
552.140 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
552.141 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
552.142 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
552.143 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
552.144 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
552.145 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
552.146 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
552.147 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
552.148 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
552.149 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
552.150 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
552.151 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
552.152 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
552.153 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
552.154 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
552.155 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
552.156 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
552.157 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
552.158 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
552.159 +.ui-icon-arrow-4 { background-position: 0 -80px; }
552.160 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
552.161 +.ui-icon-extlink { background-position: -32px -80px; }
552.162 +.ui-icon-newwin { background-position: -48px -80px; }
552.163 +.ui-icon-refresh { background-position: -64px -80px; }
552.164 +.ui-icon-shuffle { background-position: -80px -80px; }
552.165 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
552.166 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
552.167 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
552.168 +.ui-icon-folder-open { background-position: -16px -96px; }
552.169 +.ui-icon-document { background-position: -32px -96px; }
552.170 +.ui-icon-document-b { background-position: -48px -96px; }
552.171 +.ui-icon-note { background-position: -64px -96px; }
552.172 +.ui-icon-mail-closed { background-position: -80px -96px; }
552.173 +.ui-icon-mail-open { background-position: -96px -96px; }
552.174 +.ui-icon-suitcase { background-position: -112px -96px; }
552.175 +.ui-icon-comment { background-position: -128px -96px; }
552.176 +.ui-icon-person { background-position: -144px -96px; }
552.177 +.ui-icon-print { background-position: -160px -96px; }
552.178 +.ui-icon-trash { background-position: -176px -96px; }
552.179 +.ui-icon-locked { background-position: -192px -96px; }
552.180 +.ui-icon-unlocked { background-position: -208px -96px; }
552.181 +.ui-icon-bookmark { background-position: -224px -96px; }
552.182 +.ui-icon-tag { background-position: -240px -96px; }
552.183 +.ui-icon-home { background-position: 0 -112px; }
552.184 +.ui-icon-flag { background-position: -16px -112px; }
552.185 +.ui-icon-calendar { background-position: -32px -112px; }
552.186 +.ui-icon-cart { background-position: -48px -112px; }
552.187 +.ui-icon-pencil { background-position: -64px -112px; }
552.188 +.ui-icon-clock { background-position: -80px -112px; }
552.189 +.ui-icon-disk { background-position: -96px -112px; }
552.190 +.ui-icon-calculator { background-position: -112px -112px; }
552.191 +.ui-icon-zoomin { background-position: -128px -112px; }
552.192 +.ui-icon-zoomout { background-position: -144px -112px; }
552.193 +.ui-icon-search { background-position: -160px -112px; }
552.194 +.ui-icon-wrench { background-position: -176px -112px; }
552.195 +.ui-icon-gear { background-position: -192px -112px; }
552.196 +.ui-icon-heart { background-position: -208px -112px; }
552.197 +.ui-icon-star { background-position: -224px -112px; }
552.198 +.ui-icon-link { background-position: -240px -112px; }
552.199 +.ui-icon-cancel { background-position: 0 -128px; }
552.200 +.ui-icon-plus { background-position: -16px -128px; }
552.201 +.ui-icon-plusthick { background-position: -32px -128px; }
552.202 +.ui-icon-minus { background-position: -48px -128px; }
552.203 +.ui-icon-minusthick { background-position: -64px -128px; }
552.204 +.ui-icon-close { background-position: -80px -128px; }
552.205 +.ui-icon-closethick { background-position: -96px -128px; }
552.206 +.ui-icon-key { background-position: -112px -128px; }
552.207 +.ui-icon-lightbulb { background-position: -128px -128px; }
552.208 +.ui-icon-scissors { background-position: -144px -128px; }
552.209 +.ui-icon-clipboard { background-position: -160px -128px; }
552.210 +.ui-icon-copy { background-position: -176px -128px; }
552.211 +.ui-icon-contact { background-position: -192px -128px; }
552.212 +.ui-icon-image { background-position: -208px -128px; }
552.213 +.ui-icon-video { background-position: -224px -128px; }
552.214 +.ui-icon-script { background-position: -240px -128px; }
552.215 +.ui-icon-alert { background-position: 0 -144px; }
552.216 +.ui-icon-info { background-position: -16px -144px; }
552.217 +.ui-icon-notice { background-position: -32px -144px; }
552.218 +.ui-icon-help { background-position: -48px -144px; }
552.219 +.ui-icon-check { background-position: -64px -144px; }
552.220 +.ui-icon-bullet { background-position: -80px -144px; }
552.221 +.ui-icon-radio-off { background-position: -96px -144px; }
552.222 +.ui-icon-radio-on { background-position: -112px -144px; }
552.223 +.ui-icon-pin-w { background-position: -128px -144px; }
552.224 +.ui-icon-pin-s { background-position: -144px -144px; }
552.225 +.ui-icon-play { background-position: 0 -160px; }
552.226 +.ui-icon-pause { background-position: -16px -160px; }
552.227 +.ui-icon-seek-next { background-position: -32px -160px; }
552.228 +.ui-icon-seek-prev { background-position: -48px -160px; }
552.229 +.ui-icon-seek-end { background-position: -64px -160px; }
552.230 +.ui-icon-seek-first { background-position: -80px -160px; }
552.231 +.ui-icon-stop { background-position: -96px -160px; }
552.232 +.ui-icon-eject { background-position: -112px -160px; }
552.233 +.ui-icon-volume-off { background-position: -128px -160px; }
552.234 +.ui-icon-volume-on { background-position: -144px -160px; }
552.235 +.ui-icon-power { background-position: 0 -176px; }
552.236 +.ui-icon-signal-diag { background-position: -16px -176px; }
552.237 +.ui-icon-signal { background-position: -32px -176px; }
552.238 +.ui-icon-battery-0 { background-position: -48px -176px; }
552.239 +.ui-icon-battery-1 { background-position: -64px -176px; }
552.240 +.ui-icon-battery-2 { background-position: -80px -176px; }
552.241 +.ui-icon-battery-3 { background-position: -96px -176px; }
552.242 +.ui-icon-circle-plus { background-position: 0 -192px; }
552.243 +.ui-icon-circle-minus { background-position: -16px -192px; }
552.244 +.ui-icon-circle-close { background-position: -32px -192px; }
552.245 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
552.246 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
552.247 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
552.248 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
552.249 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
552.250 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
552.251 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
552.252 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
552.253 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
552.254 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
552.255 +.ui-icon-circle-check { background-position: -208px -192px; }
552.256 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
552.257 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
552.258 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
552.259 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
552.260 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
552.261 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
552.262 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
552.263 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
552.264 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
552.265 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
552.266 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
552.267 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
552.268 +
552.269 +
552.270 +/* Misc visuals
552.271 +----------------------------------*/
552.272 +
552.273 +/* Corner radius */
552.274 +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
552.275 +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
552.276 +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
552.277 +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
552.278 +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
552.279 +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
552.280 +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
552.281 +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
552.282 +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
552.283 +
552.284 +/* Overlays */
552.285 +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
552.286 +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; }/* Accordion
552.287 +----------------------------------*/
552.288 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
552.289 +.ui-accordion .ui-accordion-li-fix { display: inline; }
552.290 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
552.291 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
552.292 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
552.293 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
552.294 +.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
552.295 +----------------------------------*/
552.296 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
552.297 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
552.298 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
552.299 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
552.300 +.ui-datepicker .ui-datepicker-prev { left:2px; }
552.301 +.ui-datepicker .ui-datepicker-next { right:2px; }
552.302 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
552.303 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
552.304 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
552.305 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
552.306 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
552.307 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
552.308 +.ui-datepicker select.ui-datepicker-month,
552.309 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
552.310 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
552.311 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
552.312 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
552.313 +.ui-datepicker td { border: 0; padding: 1px; }
552.314 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
552.315 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
552.316 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
552.317 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
552.318 +
552.319 +/* with multiple calendars */
552.320 +.ui-datepicker.ui-datepicker-multi { width:auto; }
552.321 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
552.322 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
552.323 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
552.324 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
552.325 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
552.326 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
552.327 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
552.328 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
552.329 +.ui-datepicker-row-break { clear:both; width:100%; }
552.330 +
552.331 +/* RTL support */
552.332 +.ui-datepicker-rtl { direction: rtl; }
552.333 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
552.334 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
552.335 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
552.336 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
552.337 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
552.338 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
552.339 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
552.340 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
552.341 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
552.342 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
552.343 +
552.344 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
552.345 +.ui-datepicker-cover {
552.346 + display: none; /*sorry for IE5*/
552.347 + display/**/: block; /*sorry for IE5*/
552.348 + position: absolute; /*must have*/
552.349 + z-index: -1; /*must have*/
552.350 + filter: mask(); /*must have*/
552.351 + top: -4px; /*must have*/
552.352 + left: -4px; /*must have*/
552.353 + width: 200px; /*must have*/
552.354 + height: 200px; /*must have*/
552.355 +}/* Dialog
552.356 +----------------------------------*/
552.357 +.ui-dialog { position: relative; padding: .2em; width: 300px; }
552.358 +.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
552.359 +.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
552.360 +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
552.361 +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
552.362 +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
552.363 +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
552.364 +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
552.365 +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
552.366 +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
552.367 +.ui-draggable .ui-dialog-titlebar { cursor: move; }
552.368 +/* Progressbar
552.369 +----------------------------------*/
552.370 +.ui-progressbar { height:2em; text-align: left; }
552.371 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
552.372 +----------------------------------*/
552.373 +.ui-resizable { position: relative;}
552.374 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
552.375 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
552.376 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
552.377 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
552.378 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
552.379 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
552.380 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
552.381 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
552.382 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
552.383 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
552.384 +----------------------------------*/
552.385 +.ui-slider { position: relative; text-align: left; }
552.386 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
552.387 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
552.388 +
552.389 +.ui-slider-horizontal { height: .8em; }
552.390 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
552.391 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
552.392 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
552.393 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
552.394 +
552.395 +.ui-slider-vertical { width: .8em; height: 100px; }
552.396 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
552.397 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
552.398 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
552.399 +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
552.400 +----------------------------------*/
552.401 +.ui-tabs { padding: .2em; zoom: 1; }
552.402 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
552.403 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
552.404 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
552.405 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
552.406 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
552.407 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
552.408 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
552.409 +.ui-tabs .ui-tabs-hide { display: none !important; }
553.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
553.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.accordion.css Mon Apr 26 11:16:23 2010 +0200
553.3 @@ -0,0 +1,9 @@
553.4 +/* Accordion
553.5 +----------------------------------*/
553.6 +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
553.7 +.ui-accordion .ui-accordion-li-fix { display: inline; }
553.8 +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
553.9 +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
553.10 +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
553.11 +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
553.12 +.ui-accordion .ui-accordion-content-active { display: block; }
553.13 \ No newline at end of file
554.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
554.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.all.css Mon Apr 26 11:16:23 2010 +0200
554.3 @@ -0,0 +1,2 @@
554.4 +@import "ui.base.css";
554.5 +@import "ui.theme.css";
555.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
555.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.base.css Mon Apr 26 11:16:23 2010 +0200
555.3 @@ -0,0 +1,8 @@
555.4 +@import url("ui.core.css");
555.5 +@import url("ui.resizable.css");
555.6 +@import url("ui.accordion.css");
555.7 +@import url("ui.dialog.css");
555.8 +@import url("ui.slider.css");
555.9 +@import url("ui.tabs.css");
555.10 +@import url("ui.datepicker.css");
555.11 +@import url("ui.progressbar.css");
555.12 \ No newline at end of file
556.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
556.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.core.css Mon Apr 26 11:16:23 2010 +0200
556.3 @@ -0,0 +1,37 @@
556.4 +/*
556.5 +* jQuery UI CSS Framework
556.6 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
556.7 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
556.8 +*/
556.9 +
556.10 +/* Layout helpers
556.11 +----------------------------------*/
556.12 +.ui-helper-hidden { display: none; }
556.13 +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
556.14 +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
556.15 +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
556.16 +.ui-helper-clearfix { display: inline-block; }
556.17 +/* required comment for clearfix to work in Opera \*/
556.18 +* html .ui-helper-clearfix { height:1%; }
556.19 +.ui-helper-clearfix { display:block; }
556.20 +/* end clearfix */
556.21 +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
556.22 +
556.23 +
556.24 +/* Interaction Cues
556.25 +----------------------------------*/
556.26 +.ui-state-disabled { cursor: default !important; }
556.27 +
556.28 +
556.29 +/* Icons
556.30 +----------------------------------*/
556.31 +
556.32 +/* states and images */
556.33 +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
556.34 +
556.35 +
556.36 +/* Misc visuals
556.37 +----------------------------------*/
556.38 +
556.39 +/* Overlays */
556.40 +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
556.41 \ No newline at end of file
557.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
557.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.datepicker.css Mon Apr 26 11:16:23 2010 +0200
557.3 @@ -0,0 +1,62 @@
557.4 +/* Datepicker
557.5 +----------------------------------*/
557.6 +.ui-datepicker { width: 17em; padding: .2em .2em 0; }
557.7 +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
557.8 +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
557.9 +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
557.10 +.ui-datepicker .ui-datepicker-prev { left:2px; }
557.11 +.ui-datepicker .ui-datepicker-next { right:2px; }
557.12 +.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
557.13 +.ui-datepicker .ui-datepicker-next-hover { right:1px; }
557.14 +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
557.15 +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
557.16 +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
557.17 +.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
557.18 +.ui-datepicker select.ui-datepicker-month,
557.19 +.ui-datepicker select.ui-datepicker-year { width: 49%;}
557.20 +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
557.21 +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
557.22 +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
557.23 +.ui-datepicker td { border: 0; padding: 1px; }
557.24 +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
557.25 +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
557.26 +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
557.27 +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
557.28 +
557.29 +/* with multiple calendars */
557.30 +.ui-datepicker.ui-datepicker-multi { width:auto; }
557.31 +.ui-datepicker-multi .ui-datepicker-group { float:left; }
557.32 +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
557.33 +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
557.34 +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
557.35 +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
557.36 +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
557.37 +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
557.38 +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
557.39 +.ui-datepicker-row-break { clear:both; width:100%; }
557.40 +
557.41 +/* RTL support */
557.42 +.ui-datepicker-rtl { direction: rtl; }
557.43 +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
557.44 +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
557.45 +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
557.46 +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
557.47 +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
557.48 +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
557.49 +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
557.50 +.ui-datepicker-rtl .ui-datepicker-group { float:right; }
557.51 +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
557.52 +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
557.53 +
557.54 +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
557.55 +.ui-datepicker-cover {
557.56 + display: none; /*sorry for IE5*/
557.57 + display/**/: block; /*sorry for IE5*/
557.58 + position: absolute; /*must have*/
557.59 + z-index: -1; /*must have*/
557.60 + filter: mask(); /*must have*/
557.61 + top: -4px; /*must have*/
557.62 + left: -4px; /*must have*/
557.63 + width: 200px; /*must have*/
557.64 + height: 200px; /*must have*/
557.65 +}
557.66 \ No newline at end of file
558.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
558.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.progressbar.css Mon Apr 26 11:16:23 2010 +0200
558.3 @@ -0,0 +1,4 @@
558.4 +/* Progressbar
558.5 +----------------------------------*/
558.6 +.ui-progressbar { height:2em; text-align: left; }
558.7 +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
558.8 \ No newline at end of file
559.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
559.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.resizable.css Mon Apr 26 11:16:23 2010 +0200
559.3 @@ -0,0 +1,13 @@
559.4 +/* Resizable
559.5 +----------------------------------*/
559.6 +.ui-resizable { position: relative;}
559.7 +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
559.8 +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
559.9 +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
559.10 +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
559.11 +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
559.12 +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
559.13 +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
559.14 +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
559.15 +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
559.16 +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
559.17 \ No newline at end of file
560.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
560.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.slider.css Mon Apr 26 11:16:23 2010 +0200
560.3 @@ -0,0 +1,17 @@
560.4 +/* Slider
560.5 +----------------------------------*/
560.6 +.ui-slider { position: relative; text-align: left; }
560.7 +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
560.8 +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
560.9 +
560.10 +.ui-slider-horizontal { height: .8em; }
560.11 +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
560.12 +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
560.13 +.ui-slider-horizontal .ui-slider-range-min { left: 0; }
560.14 +.ui-slider-horizontal .ui-slider-range-max { right: 0; }
560.15 +
560.16 +.ui-slider-vertical { width: .8em; height: 100px; }
560.17 +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
560.18 +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
560.19 +.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
560.20 +.ui-slider-vertical .ui-slider-range-max { top: 0; }
560.21 \ No newline at end of file
561.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
561.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.tabs.css Mon Apr 26 11:16:23 2010 +0200
561.3 @@ -0,0 +1,11 @@
561.4 +/* Tabs
561.5 +----------------------------------*/
561.6 +.ui-tabs { padding: .2em; zoom: 1; }
561.7 +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
561.8 +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
561.9 +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
561.10 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
561.11 +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
561.12 +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
561.13 +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
561.14 +.ui-tabs .ui-tabs-hide { display: none !important; }
562.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
562.2 +++ b/web/static/css/ui/themes/ui-lightness/ui.theme.css Mon Apr 26 11:16:23 2010 +0200
562.3 @@ -0,0 +1,247 @@
562.4 +
562.5 +
562.6 +
562.7 +
562.8 +/*
562.9 +* jQuery UI CSS Framework
562.10 +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
562.11 +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
562.12 +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
562.13 +*/
562.14 +
562.15 +
562.16 +/* Component containers
562.17 +----------------------------------*/
562.18 +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
562.19 +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
562.20 +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
562.21 +.ui-widget-content a { color: #333333; }
562.22 +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
562.23 +.ui-widget-header a { color: #ffffff; }
562.24 +
562.25 +/* Interaction states
562.26 +----------------------------------*/
562.27 +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; outline: none; }
562.28 +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; outline: none; }
562.29 +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; outline: none; }
562.30 +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; outline: none; }
562.31 +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; outline: none; }
562.32 +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; outline: none; text-decoration: none; }
562.33 +
562.34 +/* Interaction Cues
562.35 +----------------------------------*/
562.36 +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
562.37 +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
562.38 +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
562.39 +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #ffffff; }
562.40 +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
562.41 +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
562.42 +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
562.43 +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
562.44 +
562.45 +/* Icons
562.46 +----------------------------------*/
562.47 +
562.48 +/* states and images */
562.49 +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
562.50 +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
562.51 +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
562.52 +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
562.53 +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
562.54 +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
562.55 +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
562.56 +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
562.57 +
562.58 +/* positioning */
562.59 +.ui-icon-carat-1-n { background-position: 0 0; }
562.60 +.ui-icon-carat-1-ne { background-position: -16px 0; }
562.61 +.ui-icon-carat-1-e { background-position: -32px 0; }
562.62 +.ui-icon-carat-1-se { background-position: -48px 0; }
562.63 +.ui-icon-carat-1-s { background-position: -64px 0; }
562.64 +.ui-icon-carat-1-sw { background-position: -80px 0; }
562.65 +.ui-icon-carat-1-w { background-position: -96px 0; }
562.66 +.ui-icon-carat-1-nw { background-position: -112px 0; }
562.67 +.ui-icon-carat-2-n-s { background-position: -128px 0; }
562.68 +.ui-icon-carat-2-e-w { background-position: -144px 0; }
562.69 +.ui-icon-triangle-1-n { background-position: 0 -16px; }
562.70 +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
562.71 +.ui-icon-triangle-1-e { background-position: -32px -16px; }
562.72 +.ui-icon-triangle-1-se { background-position: -48px -16px; }
562.73 +.ui-icon-triangle-1-s { background-position: -64px -16px; }
562.74 +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
562.75 +.ui-icon-triangle-1-w { background-position: -96px -16px; }
562.76 +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
562.77 +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
562.78 +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
562.79 +.ui-icon-arrow-1-n { background-position: 0 -32px; }
562.80 +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
562.81 +.ui-icon-arrow-1-e { background-position: -32px -32px; }
562.82 +.ui-icon-arrow-1-se { background-position: -48px -32px; }
562.83 +.ui-icon-arrow-1-s { background-position: -64px -32px; }
562.84 +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
562.85 +.ui-icon-arrow-1-w { background-position: -96px -32px; }
562.86 +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
562.87 +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
562.88 +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
562.89 +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
562.90 +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
562.91 +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
562.92 +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
562.93 +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
562.94 +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
562.95 +.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
562.96 +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
562.97 +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
562.98 +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
562.99 +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
562.100 +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
562.101 +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
562.102 +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
562.103 +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
562.104 +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
562.105 +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
562.106 +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
562.107 +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
562.108 +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
562.109 +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
562.110 +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
562.111 +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
562.112 +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
562.113 +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
562.114 +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
562.115 +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
562.116 +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
562.117 +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
562.118 +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
562.119 +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
562.120 +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
562.121 +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
562.122 +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
562.123 +.ui-icon-arrow-4 { background-position: 0 -80px; }
562.124 +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
562.125 +.ui-icon-extlink { background-position: -32px -80px; }
562.126 +.ui-icon-newwin { background-position: -48px -80px; }
562.127 +.ui-icon-refresh { background-position: -64px -80px; }
562.128 +.ui-icon-shuffle { background-position: -80px -80px; }
562.129 +.ui-icon-transfer-e-w { background-position: -96px -80px; }
562.130 +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
562.131 +.ui-icon-folder-collapsed { background-position: 0 -96px; }
562.132 +.ui-icon-folder-open { background-position: -16px -96px; }
562.133 +.ui-icon-document { background-position: -32px -96px; }
562.134 +.ui-icon-document-b { background-position: -48px -96px; }
562.135 +.ui-icon-note { background-position: -64px -96px; }
562.136 +.ui-icon-mail-closed { background-position: -80px -96px; }
562.137 +.ui-icon-mail-open { background-position: -96px -96px; }
562.138 +.ui-icon-suitcase { background-position: -112px -96px; }
562.139 +.ui-icon-comment { background-position: -128px -96px; }
562.140 +.ui-icon-person { background-position: -144px -96px; }
562.141 +.ui-icon-print { background-position: -160px -96px; }
562.142 +.ui-icon-trash { background-position: -176px -96px; }
562.143 +.ui-icon-locked { background-position: -192px -96px; }
562.144 +.ui-icon-unlocked { background-position: -208px -96px; }
562.145 +.ui-icon-bookmark { background-position: -224px -96px; }
562.146 +.ui-icon-tag { background-position: -240px -96px; }
562.147 +.ui-icon-home { background-position: 0 -112px; }
562.148 +.ui-icon-flag { background-position: -16px -112px; }
562.149 +.ui-icon-calendar { background-position: -32px -112px; }
562.150 +.ui-icon-cart { background-position: -48px -112px; }
562.151 +.ui-icon-pencil { background-position: -64px -112px; }
562.152 +.ui-icon-clock { background-position: -80px -112px; }
562.153 +.ui-icon-disk { background-position: -96px -112px; }
562.154 +.ui-icon-calculator { background-position: -112px -112px; }
562.155 +.ui-icon-zoomin { background-position: -128px -112px; }
562.156 +.ui-icon-zoomout { background-position: -144px -112px; }
562.157 +.ui-icon-search { background-position: -160px -112px; }
562.158 +.ui-icon-wrench { background-position: -176px -112px; }
562.159 +.ui-icon-gear { background-position: -192px -112px; }
562.160 +.ui-icon-heart { background-position: -208px -112px; }
562.161 +.ui-icon-star { background-position: -224px -112px; }
562.162 +.ui-icon-link { background-position: -240px -112px; }
562.163 +.ui-icon-cancel { background-position: 0 -128px; }
562.164 +.ui-icon-plus { background-position: -16px -128px; }
562.165 +.ui-icon-plusthick { background-position: -32px -128px; }
562.166 +.ui-icon-minus { background-position: -48px -128px; }
562.167 +.ui-icon-minusthick { background-position: -64px -128px; }
562.168 +.ui-icon-close { background-position: -80px -128px; }
562.169 +.ui-icon-closethick { background-position: -96px -128px; }
562.170 +.ui-icon-key { background-position: -112px -128px; }
562.171 +.ui-icon-lightbulb { background-position: -128px -128px; }
562.172 +.ui-icon-scissors { background-position: -144px -128px; }
562.173 +.ui-icon-clipboard { background-position: -160px -128px; }
562.174 +.ui-icon-copy { background-position: -176px -128px; }
562.175 +.ui-icon-contact { background-position: -192px -128px; }
562.176 +.ui-icon-image { background-position: -208px -128px; }
562.177 +.ui-icon-video { background-position: -224px -128px; }
562.178 +.ui-icon-script { background-position: -240px -128px; }
562.179 +.ui-icon-alert { background-position: 0 -144px; }
562.180 +.ui-icon-info { background-position: -16px -144px; }
562.181 +.ui-icon-notice { background-position: -32px -144px; }
562.182 +.ui-icon-help { background-position: -48px -144px; }
562.183 +.ui-icon-check { background-position: -64px -144px; }
562.184 +.ui-icon-bullet { background-position: -80px -144px; }
562.185 +.ui-icon-radio-off { background-position: -96px -144px; }
562.186 +.ui-icon-radio-on { background-position: -112px -144px; }
562.187 +.ui-icon-pin-w { background-position: -128px -144px; }
562.188 +.ui-icon-pin-s { background-position: -144px -144px; }
562.189 +.ui-icon-play { background-position: 0 -160px; }
562.190 +.ui-icon-pause { background-position: -16px -160px; }
562.191 +.ui-icon-seek-next { background-position: -32px -160px; }
562.192 +.ui-icon-seek-prev { background-position: -48px -160px; }
562.193 +.ui-icon-seek-end { background-position: -64px -160px; }
562.194 +.ui-icon-seek-first { background-position: -80px -160px; }
562.195 +.ui-icon-stop { background-position: -96px -160px; }
562.196 +.ui-icon-eject { background-position: -112px -160px; }
562.197 +.ui-icon-volume-off { background-position: -128px -160px; }
562.198 +.ui-icon-volume-on { background-position: -144px -160px; }
562.199 +.ui-icon-power { background-position: 0 -176px; }
562.200 +.ui-icon-signal-diag { background-position: -16px -176px; }
562.201 +.ui-icon-signal { background-position: -32px -176px; }
562.202 +.ui-icon-battery-0 { background-position: -48px -176px; }
562.203 +.ui-icon-battery-1 { background-position: -64px -176px; }
562.204 +.ui-icon-battery-2 { background-position: -80px -176px; }
562.205 +.ui-icon-battery-3 { background-position: -96px -176px; }
562.206 +.ui-icon-circle-plus { background-position: 0 -192px; }
562.207 +.ui-icon-circle-minus { background-position: -16px -192px; }
562.208 +.ui-icon-circle-close { background-position: -32px -192px; }
562.209 +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
562.210 +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
562.211 +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
562.212 +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
562.213 +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
562.214 +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
562.215 +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
562.216 +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
562.217 +.ui-icon-circle-zoomin { background-position: -176px -192px; }
562.218 +.ui-icon-circle-zoomout { background-position: -192px -192px; }
562.219 +.ui-icon-circle-check { background-position: -208px -192px; }
562.220 +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
562.221 +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
562.222 +.ui-icon-circlesmall-close { background-position: -32px -208px; }
562.223 +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
562.224 +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
562.225 +.ui-icon-squaresmall-close { background-position: -80px -208px; }
562.226 +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
562.227 +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
562.228 +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
562.229 +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
562.230 +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
562.231 +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
562.232 +
562.233 +
562.234 +/* Misc visuals
562.235 +----------------------------------*/
562.236 +
562.237 +/* Corner radius */
562.238 +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
562.239 +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
562.240 +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
562.241 +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
562.242 +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
562.243 +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
562.244 +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
562.245 +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
562.246 +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
562.247 +
562.248 +/* Overlays */
562.249 +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
562.250 +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; }
562.251 \ No newline at end of file
563.1 Binary file web/static/images/Sorting icons.psd has changed
564.1 Binary file web/static/images/back_disabled.jpg has changed
565.1 Binary file web/static/images/back_enabled.jpg has changed
566.1 Binary file web/static/images/forward_disabled.jpg has changed
567.1 Binary file web/static/images/forward_enabled.jpg has changed
568.1 Binary file web/static/images/sort_asc.jpg has changed
569.1 Binary file web/static/images/sort_asc.png has changed
570.1 Binary file web/static/images/sort_asc_disabled.jpg has changed
571.1 Binary file web/static/images/sort_asc_disabled.png has changed
572.1 Binary file web/static/images/sort_both.jpg has changed
573.1 Binary file web/static/images/sort_both.png has changed
574.1 Binary file web/static/images/sort_desc.jpg has changed
575.1 Binary file web/static/images/sort_desc.png has changed
576.1 Binary file web/static/images/sort_desc_disabled.jpg has changed
577.1 Binary file web/static/images/sort_desc_disabled.png has changed
578.1 Binary file web/static/img/icon_addlink.gif has changed
579.1 Binary file web/static/img/icon_changelink.gif has changed
580.1 Binary file web/static/img/icon_deletelink.gif has changed
581.1 Binary file web/static/img/python-powered-w-70x28.png has changed
582.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
582.2 +++ b/web/static/js/cluetip Mon Apr 26 11:16:23 2010 +0200
582.3 @@ -0,0 +1,1 @@
582.4 +cluetip-1.0.6/
582.5 \ No newline at end of file
583.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
583.2 +++ b/web/static/js/cluetip-1.0.6/README Mon Apr 26 11:16:23 2010 +0200
583.3 @@ -0,0 +1,56 @@
583.4 +
583.5 +/*
583.6 + * jQuery clueTip Plugin
583.7 + *
583.8 + * Dual licensed under the MIT and GPL licenses:
583.9 + * http://www.opensource.org/licenses/mit-license.php
583.10 + * http://www.gnu.org/licenses/gpl.html
583.11 + *
583.12 + * @name clueTip
583.13 + * @type jQuery
583.14 + * @cat Plugins/tooltip
583.15 + * @return jQuery
583.16 + * @author Karl Swedberg
583.17 + *
583.18 + * @requires jQuery v1.3+
583.19 + *
583.20 + * @credit Inspired by Cody Lindley's jTip (http://www.codylindley.com)
583.21 + * @credit Thanks to the following people for their many and varied contributions:
583.22 + Shelane Enos, Glen Lipka, Hector Santos, Torben Schreiter, Dan G. Switzer, Jörn Zaefferer
583.23 + * @credit Thanks to Jonathan Chaffer, as always, for help with the hard parts. :-)
583.24 + */
583.25 +
583.26 + /**
583.27 + *
583.28 + * Displays a highly customizable tooltip when the user hovers (default) or clicks (optional) the matched element.
583.29 + * By default, the clueTip plugin loads a page indicated by the "rel" attribute via ajax and displays its contents.
583.30 + * If a "title" attribute is specified, its value is used as the clueTip's heading.
583.31 + * The attribute to be used for both the body and the heading of the clueTip is user-configurable.
583.32 + * Optionally, the clueTip's body can display content from an element on the same page.
583.33 + * * Just indicate the element's id (e.g. "#some-id") in the rel attribute.
583.34 + * Optionally, the clueTip's body can display content from the title attribute, when a delimiter is indicated.
583.35 + * * The string before the first instance of the delimiter is set as the clueTip's heading.
583.36 + * * All subsequent strings are wrapped in separate DIVs and placed in the clueTip's body.
583.37 + * The clueTip plugin allows for many, many more options. Please see the examples and the option descriptions below...
583.38 + *
583.39 + *
583.40 + * @example $('#tip).cluetip();
583.41 + * @desc This is the most basic clueTip. It displays a 275px-wide clueTip on mouseover of the element with an ID of "tip." On mouseout of the element, the clueTip is hidden.
583.42 + *
583.43 + *
583.44 + * @example $('a.clue').cluetip({
583.45 + * hoverClass: 'highlight',
583.46 + * sticky: true,
583.47 + * closePosition: 'bottom',
583.48 + * closeText: '<img src="cross.png" alt="close" />',
583.49 + * truncate: 60,
583.50 + * ajaxSettings: {
583.51 + * type: 'POST'
583.52 + * }
583.53 + * });
583.54 + * @desc Displays a clueTip on mouseover of all <a> elements with class="clue". The hovered element gets a class of "highlight" added to it (so that it can be styled appropriately. This is esp. useful for non-anchor elements.). The clueTip is "sticky," which means that it will not be hidden until the user either clicks on its "close" text/graphic or displays another clueTip. The "close" text/graphic is set to diplay at the bottom of the clueTip (default is top) and display an image rather than the default "Close" text. Moreover, the body of the clueTip is truncated to the first 60 characters, which are followed by an ellipsis (...). Finally, the clueTip retrieves the content using POST rather than the $.ajax method's default "GET."
583.55 + *
583.56 + * More examples can be found at http://plugins.learningjquery.com/cluetip/demo/
583.57 + *
583.58 + * Full list of options/settings can be found at http://plugins.learningjquery.com/cluetip/
583.59 + */
584.1 Binary file web/static/js/cluetip-1.0.6/cluetip-1.0.6.zip has changed
585.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
585.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax.htm Mon Apr 26 11:16:23 2010 +0200
585.3 @@ -0,0 +1,29 @@
585.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
585.5 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
585.6 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
585.7 +<head>
585.8 + <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
585.9 + <title>Title</title>
585.10 + <style type="text/css" media="screen">
585.11 +
585.12 + .float-left {
585.13 + float: left;
585.14 + margin-right: .5em;
585.15 + display: inline;
585.16 + }
585.17 + h2 {
585.18 + font-size: 1.1em;
585.19 + }
585.20 + </style>
585.21 +
585.22 +
585.23 +
585.24 +</head>
585.25 +<body>
585.26 + <h2>A Web Page</h2>
585.27 + <img class="float-left" src="outdoor-sculpture.jpg" alt="" width="121" height="91" />
585.28 + <p>This is a full web page with all the trappings. It's just a little short</p>
585.29 + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
585.30 + </p>
585.31 +</body>
585.32 +</html>
585.33 \ No newline at end of file
586.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
586.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax2.htm Mon Apr 26 11:16:23 2010 +0200
586.3 @@ -0,0 +1,19 @@
586.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
586.5 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
586.6 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
586.7 +<head>
586.8 + <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
586.9 + <title>some page</title>
586.10 +
586.11 +</head>
586.12 +<body>
586.13 + <div id="someid1">
586.14 + <p>here is div #someid1</p>
586.15 + <p>text is text is text is text</p>
586.16 + </div>
586.17 + <div id="someid2">
586.18 + <p>here is div #someid2</p>
586.19 + <p>and more text inside the div</p>
586.20 + </div>
586.21 +</body>
586.22 +</html>
586.23 \ No newline at end of file
587.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
587.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax3.htm Mon Apr 26 11:16:23 2010 +0200
587.3 @@ -0,0 +1,4 @@
587.4 +<p>This clueTip has some <strike>nicely</strike> <strong>formatted</strong> <em>text</em>. Just kidding!
587.5 +</p>
587.6 +
587.7 +
588.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
588.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax4.htm Mon Apr 26 11:16:23 2010 +0200
588.3 @@ -0,0 +1,5 @@
588.4 +
588.5 +<p>Another clueTip? consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
588.6 +</p>
588.7 +
588.8 +
589.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
589.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax5.htm Mon Apr 26 11:16:23 2010 +0200
589.3 @@ -0,0 +1,6 @@
589.4 +<p>This is another clueTip. It is here for demonstration purposes only.</p>
589.5 +<img class="float-left" src="boy-wonder.jpg" width="65" height="65" alt="Boy Wonder" />
589.6 +<p>Did you know that jQuery has a vibrant community of web developers and designers who discuss the library and offer help to those seeking it? You can find it at groups.google.com. Just search for jQuery.
589.7 +</p>
589.8 +
589.9 +
590.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
590.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajax6.htm Mon Apr 26 11:16:23 2010 +0200
590.3 @@ -0,0 +1,21 @@
590.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
590.5 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
590.6 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
590.7 +<head>
590.8 + <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
590.9 + <title>sticky option</title>
590.10 +
590.11 +
590.12 +</head>
590.13 +<body class="page">
590.14 + <img src="kids-drop-sand.jpg" width="65" height="65" alt="Kids Drop Sand" />
590.15 + <p>The sticky option is really nice when you have a clueTip with a link to <a href="http://www.learningjquery.com">learningjquery.com</a> in it (or any other site). Now, you can click the link to go somewhere else. Not that you'd want to.</p>
590.16 + <img src="kids-drop-sand.jpg" width="65" height="65" alt="Kids Drop Sand" />
590.17 +
590.18 + <p>Notice that this is another example of a full web page. It even has a nice photograph in it. Twice!</p>
590.19 +</body>
590.20 +</html>
590.21 +
590.22 +
590.23 +
590.24 +
591.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
591.2 +++ b/web/static/js/cluetip-1.0.6/demo/ajaxclick.htm Mon Apr 26 11:16:23 2010 +0200
591.3 @@ -0,0 +1,6 @@
591.4 +<img class="float-left" src="boy-wonder.jpg" width="65" height="65" alt="Boy Wonder" />
591.5 +<p>This clueTip won't appear unless you click to activate it. And it won't go away until you click again, or until you activate another clueTip by hovering or clicking. Only one clueTip gets to show at a time.</p>
591.6 +<p>To learn more, visit <a href="http://www.learningjquery.com/">learningjquery.com</a>. ;-)
591.7 +</p>
591.8 +
591.9 +
592.1 Binary file web/static/js/cluetip-1.0.6/demo/boy-wonder.jpg has changed
593.1 Binary file web/static/js/cluetip-1.0.6/demo/cross.png has changed
594.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
594.2 +++ b/web/static/js/cluetip-1.0.6/demo/demo.css Mon Apr 26 11:16:23 2010 +0200
594.3 @@ -0,0 +1,115 @@
594.4 +body {
594.5 + font-family: Helvetica, Verdana, sans-serif;
594.6 + font-size: 95%;
594.7 + margin: 0;
594.8 +}
594.9 +
594.10 +h1 {
594.11 + height: 80px;
594.12 + font-weight: normal;
594.13 + padding: 20px 20px 0;
594.14 + margin: 0 0 .5em;
594.15 + color: #fff;
594.16 + background: #6363c1 url(headbg.jpg) repeat-x 0 0;
594.17 +}
594.18 +li {
594.19 + margin-top: .5em;
594.20 + margin-bottom: .5em;
594.21 +}
594.22 +pre, code {
594.23 + font-size: 1em;
594.24 +}
594.25 +pre {
594.26 + padding: .5em;
594.27 + background-color: #eef;
594.28 +}
594.29 +#navigation {
594.30 + float: left;
594.31 + list-style-type: none;
594.32 + margin: -60px 0 0 20px;
594.33 + padding-left: 0;
594.34 +}
594.35 +
594.36 +#navigation li {
594.37 + float: left;
594.38 + margin: 5px 0;
594.39 + padding: 5px 0;
594.40 +}
594.41 +#navigation a {
594.42 + color: #fff;
594.43 + background: #6565c1;
594.44 + padding: 5px;
594.45 + text-decoration: none;
594.46 + border: 1px solid #fff;
594.47 +}
594.48 +#navigation a.active {
594.49 + color: #009;
594.50 + background: #fff;
594.51 + border: 1px solid #009;
594.52 + border-bottom: 1px solid #fff;
594.53 +}
594.54 +#container {
594.55 + clear: left;
594.56 + padding: .5em 20px 100px 20px;
594.57 +}
594.58 +
594.59 +.highlight {
594.60 + background: #fcc;
594.61 +}
594.62 +.highlighter {
594.63 + background: #ff3;
594.64 +}
594.65 +.back-to-top {
594.66 + display: block;
594.67 + margin-top: 1em;
594.68 + width: 7em;
594.69 +}
594.70 +
594.71 +.float-left {
594.72 + float: left;
594.73 + margin-right: .5em;
594.74 + display: inline;
594.75 + position: relative;
594.76 +}
594.77 +.float-right {
594.78 + float: right;
594.79 + margin-left: .5em;
594.80 + display: inline;
594.81 + position: relative;
594.82 +}
594.83 +h2 {
594.84 + font-size: 1.1em;
594.85 +}
594.86 +h3 {
594.87 + margin-top: 0;
594.88 + padding-top: 1em;
594.89 +}
594.90 +h4 {
594.91 + margin: .5em 0;
594.92 +}
594.93 +a {
594.94 + color: #009;
594.95 +}
594.96 +.html, .jquery {
594.97 + margin-top: .5em;
594.98 + color: #900;
594.99 + cursor: pointer;
594.100 + font-size: .9em;
594.101 + width: 8.5em;
594.102 +}
594.103 +
594.104 +ul li {
594.105 + margin: .5em 0;
594.106 +}
594.107 +ins {
594.108 + text-decoration: none;
594.109 + color: #090;
594.110 +}
594.111 +#jqlogo {
594.112 + position:absolute;
594.113 + top: 10px;
594.114 + right: 10px;
594.115 +}
594.116 +#jqlogo img {
594.117 + border: 0;
594.118 +}
594.119 \ No newline at end of file
595.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
595.2 +++ b/web/static/js/cluetip-1.0.6/demo/demo.js Mon Apr 26 11:16:23 2010 +0200
595.3 @@ -0,0 +1,85 @@
595.4 +
595.5 +/* the next line is an example of how you can override default options globally (currently commented out) ... */
595.6 +
595.7 + // $.fn.cluetip.defaults.tracking = true;
595.8 + // $.fn.cluetip.defaults.width = 'auto';
595.9 +$(document).ready(function() {
595.10 +
595.11 + // $.cluetip.setup({insertionType: 'insertBefore', insertionElement: 'div:first'});
595.12 + // $.fn.cluetip.defaults.ajaxSettings.beforeSend = function(ct) {
595.13 + // console.log(this);
595.14 + // };
595.15 +
595.16 +//default theme
595.17 + $('a.title').cluetip({splitTitle: '|'});
595.18 + $('a.basic').cluetip();
595.19 + $('a.custom-width').cluetip({width: '200px', showTitle: false});
595.20 + $('h4').cluetip({attribute: 'id', hoverClass: 'highlight'});
595.21 + $('#sticky').cluetip({sticky: true, closePosition: 'title', arrows: true });
595.22 + $('#examples a:eq(5)').cluetip({
595.23 + hoverClass: 'highlight',
595.24 + sticky: true,
595.25 + closePosition: 'bottom',
595.26 + closeText: '<img src="cross.png" alt="close" width="16" height="16" />',
595.27 + truncate: 60
595.28 + });
595.29 + $('a.load-local').cluetip({local:true, hideLocal: true, sticky: true, arrows: true, cursor: 'pointer'});
595.30 + $('#clickme').cluetip({activation: 'click', sticky: true, width: 650});
595.31 + $('ol:first a:last').cluetip({tracking: true});
595.32 +
595.33 +// jTip theme
595.34 + $('a.jt:eq(0)').cluetip({
595.35 + cluetipClass: 'jtip',
595.36 + arrows: true,
595.37 + dropShadow: false,
595.38 + sticky: true,
595.39 + mouseOutClose: true,
595.40 + closePosition: 'title',
595.41 + closeText: '<img src="cross.png" alt="close" />'
595.42 + });
595.43 + $('a.jt:eq(1)').cluetip({cluetipClass: 'jtip', arrows: true, dropShadow: false, hoverIntent: false});
595.44 + $('span[title]').css({borderBottom: '1px solid #900'}).cluetip({splitTitle: '|', arrows: true, dropShadow: false, cluetipClass: 'jtip'});
595.45 +
595.46 + $('a.jt:eq(2)').cluetip({
595.47 + cluetipClass: 'jtip',
595.48 + arrows: true,
595.49 + dropShadow: false,
595.50 + height: '150px',
595.51 + sticky: true,
595.52 + positionBy: 'bottomTop'
595.53 + });
595.54 +
595.55 + $('a.jt:eq(3)').cluetip({local: true, hideLocal: false});
595.56 +
595.57 + $('a.jt:eq(4)').cluetip({
595.58 + cluetipClass: 'jtip', arrows: true,
595.59 + dropShadow: false,
595.60 + onActivate: function(e) {
595.61 + var cb = $('#cb')[0];
595.62 + return !cb || cb.checked;
595.63 + }
595.64 + });
595.65 +
595.66 +// Rounded Corner theme
595.67 + $('ol.rounded a:eq(0)').cluetip({splitTitle: '|', dropShadow: false, cluetipClass: 'rounded', showtitle: false});
595.68 + $('ol.rounded a:eq(1)').cluetip({cluetipClass: 'rounded', dropShadow: false, showtitle: false, positionBy: 'mouse'});
595.69 + $('ol.rounded a:eq(2)').cluetip({cluetipClass: 'rounded', dropShadow: false, showtitle: false, positionBy: 'bottomTop', topOffset: 70});
595.70 + $('ol.rounded a:eq(3)').cluetip({cluetipClass: 'rounded', dropShadow: false, sticky: true, ajaxCache: false, arrows: true});
595.71 + $('ol.rounded a:eq(4)').cluetip({cluetipClass: 'rounded', dropShadow: false});
595.72 +});
595.73 +
595.74 +//unrelated to clueTip -- just for the demo page...
595.75 +
595.76 +$(document).ready(function() {
595.77 + $('div.html, div.jquery').next().css('display', 'none').end().click(function() {
595.78 + $(this).next().toggle('fast');
595.79 + });
595.80 +
595.81 + $('a.false').click(function() {
595.82 + return false;
595.83 + });
595.84 +});
595.85 +
595.86 +
595.87 +
595.88 +
596.1 Binary file web/static/js/cluetip-1.0.6/demo/grate.jpg has changed
597.1 Binary file web/static/js/cluetip-1.0.6/demo/grskating.jpg has changed
598.1 Binary file web/static/js/cluetip-1.0.6/demo/handovermouth.jpg has changed
599.1 Binary file web/static/js/cluetip-1.0.6/demo/headbg.jpg has changed
600.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
600.2 +++ b/web/static/js/cluetip-1.0.6/demo/index.html Mon Apr 26 11:16:23 2010 +0200
600.3 @@ -0,0 +1,218 @@
600.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
600.5 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
600.6 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
600.7 +<head>
600.8 + <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
600.9 + <title>clueTip Plugin Demo</title>
600.10 +
600.11 + <link rel="stylesheet" href="../jquery.cluetip.css" type="text/css" />
600.12 + <link rel="stylesheet" href="demo.css" type="text/css" /></head>
600.13 +
600.14 + <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
600.15 + <script src="../lib/jquery.hoverIntent.js" type="text/javascript"></script>
600.16 + <script src="../lib/jquery.bgiframe.min.js" type="text/javascript"></script>
600.17 + <script src="../jquery.cluetip.js" type="text/javascript"></script>
600.18 + <script src="demo.js" type="text/javascript"></script>
600.19 +<body>
600.20 +
600.21 + <h1 id="top">clueTip : A jQuery Plugin</h1>
600.22 + <ul id="navigation">
600.23 + <li><a href="../#getting-started">Overview</a></li>
600.24 + <li><a class="active" href="/">Demo</a></li>
600.25 + <li><a href="../#details">Details</a></li>
600.26 + <li><a href="../#options">API / Options</a></li>
600.27 + <li><a href="../#faq">FAQ</a></li>
600.28 + <li><a href="../#credits">Credits</a></li>
600.29 + <li><a href="../#download">Download & Support</a></li>
600.30 + </ul>
600.31 + <div id="container">
600.32 +
600.33 + <div id="examplesection">
600.34 + <h3>clueTip Plugin Demo</h3>
600.35 + <p>Below are quite a few examples of how you can add a clueTip to your page, using a wide range of options. Keep in mind that there is nothing magical about the HTML markup. You can use any jQuery selector you want to attach your clueTips. For example, if you want to attach clueTips to all links with a class of "peanuts," you would simply write in your jQuery code: <code>$('a.peanuts').cluetip();</code>.</p>
600.36 + <h4>Default Style</h4>
600.37 + <div id="examples">
600.38 + <ol>
600.39 + <li><strong>basic tip from title</strong>: <a class="title" href="#" title="This is the title|The first set of body content comes after the first delimiter in the title.|In this case, the delimiter is a pipe.">This example</a> pulls the clueTip's contents from the invoking element's title attribute via the "splitTitle" option.
600.40 + <div class="html">View the HTML</div>
600.41 + <pre><code><a class="title" href="#" title="This is the title|The first set of contents comes after the first delimiter in the title.|In this case, the delimiter is a pipe"></code></pre>
600.42 + <div class="jquery">View the jQuery</div>
600.43 + <pre><code>$('a.title').cluetip({splitTitle: '|'});</code></pre>
600.44 + </li>
600.45 + <li><strong>basic ajax</strong>, with no title attribute: This one <a class="basic" href="ajax.htm" rel="ajax.htm">requires no options</a>.
600.46 + <div><select style="width: 600px"><option>no bleed-thru</option><option>in IE6</option><option>when using bgiframe plugin</option></select> </div>
600.47 + <div class="html">View the HTML</div>
600.48 + <pre><code><a class="basic" href="ajax.htm" rel="ajax.htm"></code></pre>
600.49 + <div class="jquery">View the jQuery</div>
600.50 + <pre><code>$('a.basic').cluetip();</code></pre>
600.51 + </li>
600.52 + <li><strong>custom width and hidden title bar</strong>: This tip has a custom width of 200px. The clueTip title bar (heading) is hidden. <a class="custom-width" href="ajax3.htm" rel="ajax3.htm">Try me!</a>
600.53 + <div class="html">View the HTML</div>
600.54 + <pre><code><a class="custom-width" href="ajax3.htm" rel="ajax3.htm"></code></pre>
600.55 + <div class="jquery">View the jQuery</div>
600.56 + <pre><code>$('a.custom-width').cluetip({width: '200px', showTitle: false});</code></pre>
600.57 + </li>
600.58 + <li><strong>sticky, with arrows</strong>:This sticky clueTip has its "close" text in the title bar. It won't close until you close it, or until you hover over another clue-tipped link. It also displays an arrow on one of its sides, pointing to the invoking element. <a id="sticky" href="ajax6.htm" rel="ajax6.htm">sticky clueTip with arrows</a>
600.59 + <div class="html">View the HTML</div>
600.60 + <pre><code><a id="sticky" href="ajax6.htm" rel="ajax6.htm"></code></pre>
600.61 + <div class="jquery">View the jQuery</div>
600.62 + <pre><code>$('#sticky').cluetip({sticky: true, closePosition: 'title', arrows: true});</code></pre>
600.63 + </li>
600.64 +
600.65 + <li><strong>non-link element, custom attribute, and hover class</strong>: Block-level items such as this <code>h4</code> have clueTips positioned by the mouse.
600.66 + <h4 title="Fancy Title!" id="ajax3.htm">Hover over me.</h4>
600.67 + <div class="html">View the HTML</div>
600.68 + <pre><code><h4 title="Fancy Title!" id="ajax3.htm">Hover over me</h4></code></pre>
600.69 + <div class="jquery">View the jQuery</div>
600.70 + <pre><code>$('h4').cluetip({attribute: 'id', hoverClass: 'highlight'});</code></pre>
600.71 + </li>
600.72 + <li><strong>local, with arrows</strong>: This one uses local content from a hidden <code>div</code> element and displays an arrow that points to the invoking element: <a id="load-local" class="load-local" href="#loadme" rel="#loadme">hover for local</a>
600.73 + <div class="html">View the HTML</div>
600.74 + <pre><code><a class="load-local" href="#loadme" rel="#loadme"></code></pre>
600.75 + <div class="jquery">View the jQuery</div>
600.76 + <pre><code>$('a.load-local').cluetip({local:true, cursor: 'pointer'});</code></pre>
600.77 + </li>
600.78 + <li><strong>sticky, truncated clueTip</strong> with custom hover class, close position, and close text (it also has a title). Its <code>href</code> is different from its <code>rel</code>, so if you <em>click</em> it, you'll go to the linked page <a href="http://www.learningjquery.com" title="about this link:" rel="ajax6.htm">hover for cluetip, click to visit URL</a>
600.79 + <div class="html">View the HTML</div>
600.80 + <pre><code><a href="http://www.learningjquery.com" title="about this link:" rel="ajax6.htm"></code></pre>
600.81 + <div class="jquery">View the jQuery</div>
600.82 +<pre><code>$('#examples a:eq(5)').cluetip({
600.83 + hoverClass: 'highlight',
600.84 + sticky: true,
600.85 + closePosition: 'bottom',
600.86 + closeText: '<img src="styles/cross.png" alt="" />'
600.87 + truncate: 60
600.88 +});</code></pre>
600.89 + </li>
600.90 + <li><strong>click to activate</strong>: This one won't show the clueTip unless you click it: <a id="clickme" href="ajaxclick.htm" rel="ajaxclick.htm" title="active ingredients">click me</a>. It's also really wide.
600.91 + <div class="html">View the HTML</div>
600.92 + <pre><code><a href="ajaxclick.htm" rel="ajax5.htm" title="active ingredients"></code></pre>
600.93 + <div class="jquery">View the jQuery</div>
600.94 + <pre><code>$('#clickme').cluetip({activation: 'click', width: 650});</code></pre>
600.95 + </li>
600.96 + <li><strong><ins>experimental</ins> mouse tracking</strong>: <a href="ajax5.htm" title="mouse tracks" rel="ajax5.htm">The clueTip will move</a> in the direction of your mouse movement, as long as you're still hovering over the invoking element.
600.97 + <div class="html">View the HTML</div>
600.98 + <pre><code><a href="ajax5.htm" title="mouse tracks" rel="ajax5.htm"></code></pre>
600.99 + <div class="jquery">View the jQuery</div>
600.100 +<pre><code>$('ol:first a:last').cluetip({tracking: true});</code></pre>
600.101 + </li>
600.102 + </ol>
600.103 + <h4>jTip Theme</h4>
600.104 + <ol>
600.105 + <li><a class="jt" href="ajax6.htm" rel="ajax6.htm" title="jTip Style!">jTip Style clueTip</a>, with slideDown effect and an image placed in the title for closing it, because it's sticky. <br />
600.106 + <ins>New</ins>: The clueTip will close if you mouse out of it.
600.107 + <div class="html">View the HTML</div>
600.108 + <pre><code><a class="jt" href="ajax6.htm" rel="ajax6.htm" title="jTip Style!"></code></pre>
600.109 + <div class="jquery">View the jQuery</div>
600.110 +<pre><code>$('a.jt:eq(0)').cluetip({
600.111 + cluetipClass: 'jtip',
600.112 + arrows: true,
600.113 + dropShadow: false,
600.114 + hoverIntent: false,
600.115 + sticky: true,
600.116 + mouseOutClose: true,
600.117 + closePosition: 'title',
600.118 + closeText: '<img src="cross.png" alt="close" />'
600.119 +});
600.120 +</code></pre>
600.121 + </li>
600.122 + <li>This one has hoverIntent turned off. Look for the link floated right: <span style="float:right"><a class="jt" href="ajax5.htm" rel="ajax5.htm">jTip Style clueTip</a></span>
600.123 + <div class="html">View the HTML</div>
600.124 + <pre><code><a class="jt" href="ajax5.htm" rel="ajax5.htm"></code></pre>
600.125 + <div class="jquery">View the jQuery</div>
600.126 +<pre><code>$('a.jt:eq(1)').cluetip({cluetipClass: 'jtip', arrows: true, dropShadow: false, hoverIntent: false});
600.127 +</code></pre>
600.128 + </li>
600.129 + <li>This one pulls the clueTip contents directly from the <code>title</code> attribute of a <code>span</code> tag: <span title="Split Title|This clueTip's contents were created directly from the title attribute|Nice for minimum info.">splitTitle clueTip</span>
600.130 + <div class="html">View the HTML</div>
600.131 + <code><span title="Split Title|This clueTip's contents were created directly from the title attribute|Nice for minimum info."></code>
600.132 + <div class="jquery">View the jQuery</div>
600.133 +<pre><code>$('span[title]').css({borderBottom: '1px solid #900'}).cluetip({
600.134 + splitTitle: '|',
600.135 + arrows: true,
600.136 + dropShadow: false,
600.137 + cluetipClass: 'jtip'}
600.138 +);</code></pre>
600.139 + </li>
600.140 + <li>this sticky clueTip has a <a class="jt" href="ajax5.htm" rel="ajax5.htm">fixed height</a>. It's generally a good idea to make fixed-height clueTips sticky as well, just in case the content requires a scrollbar to read it fully. It will be positioned below the clicked element unless there isn't enough room, in which case it will be positioned above.
600.141 + <div class="html">View the HTML</div>
600.142 + <pre><code><a class="jt" href="ajax5.htm" rel="ajax5.htm"></code></pre>
600.143 + <div class="jquery">View the jQuery</div>
600.144 +<pre><code>$('a.jt:eq(2)').cluetip({
600.145 + cluetipClass: 'jtip', arrows: true,
600.146 + dropShadow: false,
600.147 + height: '150px',
600.148 + sticky: true,
600.149 + positionBy: 'bottomTop'
600.150 +});</code></pre>
600.151 + </li>
600.152 + <li>For this one, we're loading <a class="jt" href="#" rel="p.localvisible">visible local content</a>
600.153 + <div class="html">View the HTML</div>
600.154 + <pre><code><a class="jt" href="#" rel="p.localvisible">visible local content</a></code></pre>
600.155 + <div class="jquery">View the jQuery</div>
600.156 + <pre><code>$('a.jt:eq(3)').cluetip({local: true, hideLocal: false});</code></pre>
600.157 + <p class="localvisible">and here is our visible local content!</p>
600.158 + </li>
600.159 + <li><a class="jt" href="ajax3.htm" rel="ajax3.htm">togglable clueTip</a> can be turned off by unchecking the checkbox<br />
600.160 + <input type="checkbox" name="cb" id="cb" checked="checked" /> <label for="cb">clueTips</label>
600.161 + <div class="html">View the HTML</div>
600.162 + <pre><code><a class="jt" href="ajax5.htm" rel="ajax5.htm"></code></pre>
600.163 + <div class="jquery">View the jQuery</div>
600.164 +<pre><code>$('a.jt:eq(3)').cluetip({
600.165 + cluetipClass: 'jtip', arrows: true,
600.166 + dropShadow: false,
600.167 + onActivate: function(e) {
600.168 + var cb = $('#cb')[0];
600.169 + return !cb || cb.checked;
600.170 + }
600.171 +});</code></pre>
600.172 + </li>
600.173 + </ol>
600.174 + <h4>Rounded Corners Theme</h4>
600.175 + <ol class="rounded">
600.176 + <li><a href="ajax4.htm" title="|first line body|second line body">content from title attribute</a>, with the clueTip heading hidden.
600.177 + <div class="html">View the HTML</div>
600.178 + <pre><code><a href="ajax4.htm" title="|first line body|second line body"></code></pre>
600.179 + <div class="jquery">View the jQuery</div>
600.180 + <pre><code>$('ol.rounded a:eq(0)').cluetip({splitTitle: '|', dropShadow: false, cluetipClass: 'rounded', showTitle: false});</code></pre>
600.181 + </li>
600.182 + <li>
600.183 + <a href="ajax4.htm" rel="ajax4.htm" title="mouse positioned">rounded corners theme and positioning by mouse</a>.
600.184 + <div class="html">View the HTML</div>
600.185 + <pre><code><a href="ajax4.htm" rel="ajax4.htm" title="mouse positioned"></code></pre>
600.186 + <div class="jquery">View the jQuery</div>
600.187 + <pre><code>$('ol.rounded a:eq(1)').cluetip({
600.188 + cluetipClass: 'rounded',
600.189 + dropShadow: false,
600.190 + positionBy: 'mouse'
600.191 +});</code></pre>
600.192 + </li>
600.193 + <li>Another one with rounded corners theme. This one has <a href="ajax4.htm" rel="ajax4.htm" title="bottom/top positioned">"bottomTop" positioning</a>: positioned under link, unless there isn't enough room (then over). It also has <strong>"topOffset" set to 70</strong>.
600.194 + <div class="html">View the HTML</div>
600.195 + <pre><code><a href="ajax4.htm" rel="ajax4.htm" title="bottom/top positioned"></code></pre>
600.196 + <div class="jquery">View the jQuery</div>
600.197 + <pre><code>$('ol.rounded a:eq(2)').cluetip({cluetipClass: 'rounded', dropShadow: false, positionBy: 'bottomTop', topOffset: 70});</code></pre>
600.198 + </li>
600.199 + <li><a href="ajax4.htm" rel="ajax4.htm" title="rounded corners">non-caching ajax clueTip with arrows enabled</a>.
600.200 + <div class="html">View the HTML</div>
600.201 + <pre><code><a href="ajax4.htm" rel="ajax4.htm" title="rounded corners"></code></pre>
600.202 + <div class="jquery">View the jQuery</div>
600.203 + <pre><code>$('ol.rounded a:eq(3)').cluetip({cluetipClass: 'rounded', dropShadow: false, sticky: true, ajaxCache: false, arrows: true});</code></pre>
600.204 + </li>
600.205 + <li><a href="ajax404.htm" rel="ajax404.htm">ajax error</a>: This one points to a file that does not exist.
600.206 + <div class="html">View the HTML</div>
600.207 + <pre><code><a href="ajax404.htm" rel="ajax404.htm"></code></pre>
600.208 + <div class="jquery">View the jQuery</div>
600.209 + <pre><code>$('ol.rounded a:eq(4)').cluetip({cluetipClass: 'rounded', dropShadow: false});</code></pre>
600.210 + </li>
600.211 + </ol>
600.212 +
600.213 + </div>
600.214 +
600.215 + <div id="loadme">this is the <a class="false" href="http://www.learningjquery.com">local content</a> to load when the 'local' parameter is set to true.</div>
600.216 + </div>
600.217 +
600.218 + </div>
600.219 + <a href="http://jquery.com" id="jqlogo"><img src="http://www.learningjquery.com/wp-content/themes/jquery/images/jq.png" alt="jQuery web site" /></a>
600.220 +</body>
600.221 +</html>
600.222 \ No newline at end of file
601.1 Binary file web/static/js/cluetip-1.0.6/demo/kids-drop-sand.jpg has changed
602.1 Binary file web/static/js/cluetip-1.0.6/demo/outdoor-sculpture.jpg has changed
603.1 Binary file web/static/js/cluetip-1.0.6/demo/pixel.gif has changed
604.1 Binary file web/static/js/cluetip-1.0.6/demo/tristan.jpg has changed
605.1 Binary file web/static/js/cluetip-1.0.6/demo/wait.gif has changed
606.1 Binary file web/static/js/cluetip-1.0.6/images/arrowdown.gif has changed
607.1 Binary file web/static/js/cluetip-1.0.6/images/arrowleft.gif has changed
608.1 Binary file web/static/js/cluetip-1.0.6/images/arrowright.gif has changed
609.1 Binary file web/static/js/cluetip-1.0.6/images/arrowup.gif has changed
610.1 Binary file web/static/js/cluetip-1.0.6/images/bl.gif has changed
611.1 Binary file web/static/js/cluetip-1.0.6/images/bl.png has changed
612.1 Binary file web/static/js/cluetip-1.0.6/images/br.gif has changed
613.1 Binary file web/static/js/cluetip-1.0.6/images/br.png has changed
614.1 Binary file web/static/js/cluetip-1.0.6/images/darrowdown.gif has changed
615.1 Binary file web/static/js/cluetip-1.0.6/images/darrowleft.gif has changed
616.1 Binary file web/static/js/cluetip-1.0.6/images/darrowright.gif has changed
617.1 Binary file web/static/js/cluetip-1.0.6/images/darrowup.gif has changed
618.1 Binary file web/static/js/cluetip-1.0.6/images/itunes.png has changed
619.1 Binary file web/static/js/cluetip-1.0.6/images/rarrowdown.gif has changed
620.1 Binary file web/static/js/cluetip-1.0.6/images/rarrowleft.gif has changed
621.1 Binary file web/static/js/cluetip-1.0.6/images/rarrowright.gif has changed
622.1 Binary file web/static/js/cluetip-1.0.6/images/rarrowup.gif has changed
623.1 Binary file web/static/js/cluetip-1.0.6/images/tl.gif has changed
624.1 Binary file web/static/js/cluetip-1.0.6/images/tl.png has changed
625.1 Binary file web/static/js/cluetip-1.0.6/images/tr.gif has changed
626.1 Binary file web/static/js/cluetip-1.0.6/images/tr.png has changed
627.1 Binary file web/static/js/cluetip-1.0.6/images/wait.gif has changed
628.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
628.2 +++ b/web/static/js/cluetip-1.0.6/index.html Mon Apr 26 11:16:23 2010 +0200
628.3 @@ -0,0 +1,329 @@
628.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
628.5 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
628.6 +<head>
628.7 +<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
628.8 +<title>clueTip: A jQuery Tooltip Plugin</title>
628.9 +<link rel="stylesheet" type="text/css" media="screen" href="../jq.css" />
628.10 +<link rel="stylesheet" type="text/css" media="screen" href="../tabs.css" />
628.11 +<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
628.12 +<script type="text/javascript" src="../jquery.tabs.min.js"></script>
628.13 +<script type="text/javascript" src="../jquery.history.pack.js"></script>
628.14 +<script type="text/javascript" src="../chili-1.8.js"></script>
628.15 +
628.16 +
628.17 +<script type="text/javascript">
628.18 +$(function() {
628.19 + // initialize the tabs
628.20 + var main = $('#main').tabs(1);
628.21 + // $('#subdetails').tabs( { selectedClass: 'sample-tab-selected', bookmarkable: false });
628.22 +});
628.23 +</script>
628.24 +
628.25 +</head>
628.26 +<body><div><a id="logo" href="http://jquery.com" title="Powered By jQuery"></a></div>
628.27 +<h1 id="banner"><a id="backnav" href="..">‹‹ home</a>clueTip: A jQuery Tooltip Plugin</h1>
628.28 +<div id="main">
628.29 + <ul id="nav" class="anchors">
628.30 + <li><a href="#getting-started">Overview</a></li>
628.31 + <li><a href="demo/">Demo</a></li>
628.32 + <li><a href="#details">Details</a></li>
628.33 + <li><a href="#options">API / Options</a></li>
628.34 + <li><a href="#faq">FAQ</a></li>
628.35 + <li><a href="#credits">Credits</a></li>
628.36 + <li><a href="#download">Download & Support</a></li>
628.37 + </ul>
628.38 + <div id="getting-started" class="tabContent">
628.39 + <h1>Overview</h1>
628.40 + <p>The clueTip plugin allows you to easily show a fancy tooltip when the user's mouse hovers over (or, optionally, clicks on) any element you designate in your script. If the element includes a <code>title</code> attribute, its text becomes the heading of the clueTip.</p>
628.41 + <p>If you like this plugin and you're feeling generous, perhaps you'd also like to visit my <a href="http://www.amazon.com/gp/registry/wishlist/1NLSYA46XTVG4/" title="Amazon.com: Wish List">amazon.com wish list</a>?</p>
628.42 + <h1>Quick Start Guide</h1>
628.43 + Showing the most basic clueTip can be achieved in two easy steps.
628.44 + <div class="step-one">Add HTML markup to your page for elements that you want to invoke a clueTip. By default, the clueTip plugin will use the <code>rel</code> attribute to load contents into the tooltip body via <acronym title="Asynchronous HTML and HTTP">AHAH</acronym>. </div>
628.45 +<pre><code class="mix">
628.46 + <!-- use ajax/ahah to pull content from fragment.html: -->
628.47 + <p><a class="tips" href="fragment.html" rel="fragment.html">show me the cluetip!</a></p>
628.48 +
628.49 + <!-- use title attribute for clueTip contents, but don't include anything in the clueTip's heading -->
628.50 + <p><a id="houdini" href="houdini.html" title="|Houdini was an escape artist.|He was also adept at prestidigitation.">Houdini</a></p>
628.51 +</code></pre>
628.52 + <div class="step-two">Include the <strong>jQuery</strong> core file and the <strong>clueTip</strong> plugin in the <code><head></code> of your document. You may optionally include the <em>hoverIntent</em> plugin as well. After these scripts are referenced, you can reference a custom script file to invoke your clueTips (preferred) or enter the script directly in the <code><head></code> (shown below). You should also include the clueTip <strong>stylesheet</strong> (jquery.cluetip.css) after the scripts. </div>
628.53 + <br />
628.54 +<pre><code class="mix"><script src="jquery.js" type="text/javascript"></script>
628.55 +<script src="jquery.hoverIntent.js" type="text/javascript"></script> <!-- optional -->
628.56 +<script src="jquery.cluetip.js" type="text/javascript"></script>
628.57 +
628.58 +<script type="text/javascript">
628.59 +$(document).ready(function() {
628.60 + $('a.tips').cluetip();
628.61 +
628.62 + $('#houdini').cluetip({
628.63 + splitTitle: '|', // use the invoking element's title attribute to populate the clueTip...
628.64 + // ...and split the contents into separate divs where there is a "|"
628.65 + showTitle: false // hide the clueTip's heading
628.66 + });
628.67 +});
628.68 +</script>
628.69 +<link rel="stylesheet" href="jquery.cluetip.css" type="text/css" />
628.70 +</code></pre>
628.71 + <p>You can change the default style and behavior in many ways. See <a href="#options">API / Options</a> for details.</p>
628.72 + </div>
628.73 + <div id="demo" class="tabContent"></div>
628.74 + <div id="details" class="tabContent">
628.75 + <h1>clueTip Plugin Details</h1>
628.76 + <div id="subdetails">
628.77 + <ul>
628.78 + <li><a href="#subdetails1">Multiple Content Sources</a></li>
628.79 + <li><a href="#subdetails2">Smart Positioning</a></li>
628.80 + <li><a href="#subdetails3">Flexible Behavior</a></li>
628.81 + <li><a href="#subdetails4">Style Variety</a></li>
628.82 + </ul>
628.83 +
628.84 + <div id="subdetails1" class="sample-tab-selected sampleTabContent">
628.85 + <h4>Multiple Content Sources</h4>
628.86 + <p>The contents of the clueTip can come from one of these sources:</p>
628.87 + <ol>
628.88 + <li>a separate file, via AHAH / AJAX</li>
628.89 + <li>an element on the same page, typically hidden</li>
628.90 + <li>the title attribute, parsed by a user-defined delimiter (if the "splitTitle" option is set). The text before the first delimiter becomes the clueTip title, and the rest of the text parts are placed in <code><div class="split-body"></div></code> elements and appended to the clueTip body </li>
628.91 + </ol>
628.92 + </div>
628.93 + <div id="subdetails2" class="sampleTabContent">
628.94 + <h4>Smart Positioning</h4>
628.95 + The clueTip Plugin has 4 positioning modes, which you can change via the "positionBy" option.
628.96 + <ol>
628.97 + <li><code>positionBy: 'auto'</code> (default)
628.98 + <ul>
628.99 + <li><strong>places the tooltip just to the right of the invoking element</strong>, but... </li>
628.100 + <li>if there is not enough room for the tooltip to be fully visible between the right edge of the invoking element and the right edge of the browser window, <strong>switches from the right side to the left side</strong>, but... </li>
628.101 + <li>if the invoking element is too close to the bottom edge of the browser window, <strong>adjusts the tooltip upwards until the whole tooltip is visible</strong>, but... </li>
628.102 + <li>if the tooltip is taller than the window (i.e. the viewable area), <strong>adjusts the tooltip back down until the tooltip's top is at the top edge of the browser window</strong>, but...</li>
628.103 + <li>position if the invoking element is so wide that the tooltip can't completely fit to the left or the right of it, <strong>places the tooltip to the right or left of the <em>mouse</em></strong>, but... </li>
628.104 + <li>if the tooltip itself can't fit to the right or left of the mouse position, <strong>places the tooltip below the mouse position (centered horizontal if enough room)</strong>, but... </li>
628.105 + <li>if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, <strong>puts the tooltip above the mouse position</strong></li>
628.106 + </ul>
628.107 + </li>
628.108 + <li><code>positionBy: 'mouse'</code>
628.109 + <ul>
628.110 + <li><strong>places the tooltip to the right of the mouse position</strong>, but...</li>
628.111 + <li>if there is not enough room to the right, <strong>places the tooltip to the left of the mouse position</strong>, but...</li>
628.112 + <li>if the tooltip itself can't fit to the right or left of the mouse position, <strong>places the tooltip below the mouse position (centered horizontally if enough room)</strong>, but... </li>
628.113 + <li>if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, <strong>puts the tooltip above the mouse position</strong></li>
628.114 + </ul>
628.115 + </li>
628.116 + <li><code>positionBy: 'bottomTop'</code>
628.117 + <ul>
628.118 + <li><strong>places the tooltip below the mouse position (centered horizontally if enough room)</strong>, but...</li>
628.119 + <li>if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, <strong>puts the tooltip above the mouse position</strong></li>
628.120 + </ul>
628.121 + </li>
628.122 + <li><code>positionBy: 'fixed'</code>
628.123 + <ul>
628.124 + <li><strong>places the tooltip in the same location relative to the invoking element</strong>, regardless of where it appears on the page.</li>
628.125 + <li>the fixed position can be adjusted by modifying the number of pixels in the <code>topOffset</code> and <code>leftOffset</code> options</li>
628.126 + </ul>
628.127 + </li>
628.128 + </ol>
628.129 + </div>
628.130 + <div id="subdetails3" class="sampleTabContent">
628.131 + <h4>Flexible Behavior</h4>
628.132 + <ol>
628.133 + <li>The clueTip takes advantage of Brian Cherne's fantastic <a href="http://cherne.net/brian/resources/jquery.hoverIntent.html" title="hoverIntent jQuery Plugin">hoverIntent plugin</a> if it's available. (Just include it in a <code><script></code> tag if you want the clueTip to use it.)</li>
628.134 + <li>It can be activated on hover or on click.</li>
628.135 + <li>It can fade in, slide down, etc.</li>
628.136 + <li>It can close when the invoking element is moused out or when the tooltip is moused out or when the user clicks a "close" link.</li>
628.137 + <li>It can cache the results of ajax requests—or not.</li>
628.138 + <li>It can be turned off</li>
628.139 + </ol>
628.140 + </div>
628.141 + <div id="subdetails4" class="sampleTabContent">
628.142 + <h4>Variety of Styles</h4>
628.143 + <p>The clueTip Plugin comes with three themes: default, jTip, and rounded corners. Additional themes can be created by following the naming patterns in the stylesheet, jquery.cluetip.css. To apply one of the alternative themes, just indicate it in the <code>cluetipClass</code> option as <code>'jtip'</code> or <code>'rounded'</code>.</p>
628.144 + <p>The "loading" image comes from this rule in the stylesheet: </p>
628.145 + <pre><code class="css">#cluetip-waitimage {
628.146 + width: 43px;
628.147 + height: 11px;
628.148 + position: absolute;
628.149 + background-image: url(wait.gif);
628.150 + }</code></pre>
628.151 + <p>It can be turned off with the following option: <code>waitImage: false</code></p>
628.152 + <p>Other options that affect the visual appearance include <code>hoverClass</code>, <code>arrows</code>, <code>dropShadow</code>, and <code>dropShadowSteps</code>. Please see <a href=#options>API / Options</a> for more information.</p>
628.153 + </div>
628.154 + </div>
628.155 + </div>
628.156 + <div id="options" class="tabContent">
628.157 + <h1>clueTip Plugin API / Options</h1>
628.158 + The clueTip Plugin API provides two methods, with many options.
628.159 + <dl>
628.160 + <dt><code class="method">$.cluetip.setup(options)</code></dt>
628.161 + <dd>Global defaults for clueTips. Will apply to all calls to the clueTip plugin.</dd>
628.162 + </dl>
628.163 + <pre><code class="mix">{
628.164 + insertionType: 'appendTo', // how the clueTip is inserted into the DOM
628.165 + // possible values: 'appendTo', 'prependTo', 'insertBefore', 'insertAfter'
628.166 + insertionElement: 'body' // where in the DOM the clueTip is to be inserted
628.167 + }</code></pre>
628.168 + <dl>
628.169 + <dt><code class="method">cluetip(options)</code></dt>
628.170 + <dd>Displays a highly customizable tooltip via ajax (default) or local content or the title attribute of the invoking element </dd>
628.171 + </dl>
628.172 +<pre><code class="mix">$.fn.cluetip.defaults = { // default options; override as needed
628.173 + width: 275, // The width of the clueTip
628.174 + height: 'auto', // The height of the clueTip. more info below [1]
628.175 + cluezIndex: 97, // Sets the z-index style property of the clueTip
628.176 + positionBy: 'auto', // Sets the type of positioning. more info below [2]
628.177 + topOffset: 15, // Number of px to offset clueTip from top of invoking element. more info below [3]
628.178 + leftOffset: 15, // Number of px to offset clueTip from left of invoking element. more info below [4]
628.179 + local: false, // Whether to use content from the same page for the clueTip's body
628.180 + // (treats the attribute used for accessing the tip as a jQuery selector,
628.181 + // but only selects the first element if the selector matches more than one). more info below [5]
628.182 + hideLocal: true, // If local option is set to true, this determines whether local content
628.183 + // to be shown in clueTip should be hidden at its original location
628.184 + attribute: 'rel', // the attribute to be used for fetching the clueTip's body content
628.185 + titleAttribute: 'title', // the attribute to be used for fetching the clueTip's title
628.186 + splitTitle: '', // A character used to split the title attribute into the clueTip title and divs
628.187 + // within the clueTip body. more info below [6]
628.188 + showTitle: true, // show title bar of the clueTip, even if title attribute not set
628.189 + cluetipClass: 'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass. more info below [7]
628.190 + hoverClass: '', // class applied to the invoking element onmouseover and removed onmouseout
628.191 + waitImage: true, // whether to show a "loading" img, which is set in jquery.cluetip.css
628.192 + arrows: false, // if true, displays arrow on appropriate side of clueTip. more info below [8]
628.193 + dropShadow: true, // set to false if you don't want the drop-shadow effect on the clueTip
628.194 + dropShadowSteps: 6, // adjusts the size of the drop shadow
628.195 + sticky: false, // keep visible until manually closed
628.196 + mouseOutClose: false, // close when clueTip is moused out
628.197 + activation: 'hover', // set to 'click' to force user to click to show clueTip
628.198 + clickThrough: false, // if true, and activation is not 'click', then clicking on a clueTipped link will take user to
628.199 + // the link's href, even if href and tipAttribute are equal
628.200 + tracking: false, // if true, clueTip will track mouse movement (experimental)
628.201 + delayedClose: 0, // close clueTip on a timed delay (experimental)
628.202 + closePosition: 'top', // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
628.203 + closeText: 'Close', // text (or HTML) to to be clicked to close sticky clueTips
628.204 + truncate: 0, // number of characters to truncate clueTip's contents. if 0, no truncation occurs
628.205 +
628.206 + // effect and speed for opening clueTips
628.207 + fx: {
628.208 + open: 'show', // can be 'show' or 'slideDown' or 'fadeIn'
628.209 + openSpeed: ''
628.210 + },
628.211 +
628.212 + // settings for when hoverIntent plugin is used
628.213 + hoverIntent: {
628.214 + sensitivity: 3,
628.215 + interval: 50,
628.216 + timeout: 0
628.217 + },
628.218 +
628.219 + // function to run just before clueTip is shown.
628.220 + onActivate: function(e) {return true;},
628.221 +
628.222 + // function to run just after clueTip is shown.
628.223 + onShow: function(ct, c){},
628.224 +
628.225 + // whether to cache results of ajax request to avoid unnecessary hits to server
628.226 + ajaxCache: true,
628.227 +
628.228 + // process data retrieved via xhr before it's displayed
628.229 + ajaxProcess: function(data) {
628.230 + data = $(data).not('style, meta, link, script, title');
628.231 + return data;
628.232 + },
628.233 +
628.234 + // can pass in standard $.ajax() parameters, not including error, complete, success, and url
628.235 + ajaxSettings: {
628.236 + dataType: 'html'
628.237 + }
628.238 + };</code></pre>
628.239 + <ol>
628.240 + <li><strong>height</strong>: Setting a specific height also sets <div id="cluetip-outer"> to "overflow:auto"</li>
628.241 + <li><strong>positionBy</strong>: Available options are 'auto', 'mouse', 'bottomTop', 'fixed'. Change to 'mouse' if you want to override positioning by element and position the clueTip based on where the mouse is instead. Change to 'bottomTop' if you want positioning to begin below the mouse when there is room or above if not -- rather than right or left of the elemnent and flush with element's top Change to 'fixed' if you want the clueTip to appear in exactly the same location relative to the linked element no matter where it appears on the page. Use 'fixed' at your own risk.</li>
628.242 + <li><strong>topOffset</strong>:For positionBy "auto", "mouse", and "bottomTop", the number will be added to the clueTip's "top" value if the clueTip appears below the invoking element and subtracted from it if the clueTip appears above. For positionBy "fixed", the number will always be added to the "top" value, offsetting the clueTip from the top of the invoking element.</li>
628.243 + <li><strong>leftOffset</strong>: For positionBy "auto", "mouse", and "bottomTop", the number will be added to clueTip's "left" value if the clueTip appears to the right of the invoking element and subtracted if the clueTip appears to the left. For positionBy "fixed", the number will always be added to the "left" value of the clueTip, offsetting it from the right side of the invoking element.</li>
628.244 + <li><strong>local</strong>: for example, using the default tip attribute, "rel", you could have a link — <a href="somewhere.htm" rel=".someClass"> — that would show the contents of the first element in the DOM that has a class of "someClass."</li>
628.245 + <li><strong>splitTitle</strong>: if used, the clueTip will be populated only by the title attribute</li>
628.246 + <li><strong>cluetipClass</strong>: this is also used for a "directional" class on the same div, depending on where the clueTip is in relation to the invoking element. The class appears in the form of 'cluetip-' + <em>direction</em> + <em>cluetipClass</em>. this allows you to create your own clueTip theme in a separate CSS file or use one of the three pre-packaged themes: default, jtip, or rounded.</li>
628.247 + <li><strong>arrows</strong>: <strong>UPDATE</strong>: this option displays a div containing an arrow background image. Arrow images are set using the background-image property in the CSS. The direction of the arrow changes depending on which side of the invoking element the clueTip appears. The arrows option sets the background-position of the cluetip div so that the arrow will accurately point to the invoking element, regardless of where it appears in relation to it.</li>
628.248 + </ol>
628.249 + </div>
628.250 +
628.251 + <div id="faq" class="tabContent">
628.252 + <h1>Frequently Asked Questions</h1>
628.253 + <dl>
628.254 + <dt>How is clueTip licensed?</dt>
628.255 + <dd>
628.256 + <p>The clueTip plugin is licensed the same way as the jQuery core file: under a dual MIT and GPL license. Users of the plugin can choose whichever license suits them. The top of the jquery.cluetip.js file has this notice:</p>
628.257 + <p>Dual licensed under the MIT and GPL licenses:<br />
628.258 + * http://www.opensource.org/licenses/mit-license.php<br />
628.259 + * http://www.gnu.org/licenses/gpl.html</p>
628.260 + </dd>
628.261 + <dt>What versions of jQuery is the clueTip Plugin compatible with?</dt>
628.262 + <dd>As of clueTip version 1.06, the plugin is compatible with version 1.3.2 or later. Prevsiou clueTip versions are compatible with jQuery 1.2.6 through 1.3.2 or later is recommended.</dd>
628.263 + <dt>Does the clueTip Plugin have any dependencies on other plugins?</dt>
628.264 + <dd><em>Optional</em> plugins that can be used in conjunction with the clueTip plugin include <a href="http://cherne.net/brian/resources/jquery.hoverIntent.html" title="hoverIntent jQuery Plug-in">hoverIntent</a> and <a href="http://brandonaaron.net/jquery/plugins/bgiframe/docs/">bgIframe</a>.</dd>
628.265 + <dt>How do I get clueTip to work with dynamic content.</dt>
628.266 + <dd>There are a number of options available for working with dynamic content. By default, the <code>ajaxCache</code> function is set to <code>true</code>. This reduces the number of http requests made to the server. However, it doesn't account for possible changes to the ajaxed data. If the contents of a particular clueTip will be updated on the server between invocations, you may want to set <code>ajaxCache: false</code>. </dd>
628.267 + <dt><em>New as of clueTip 1.0.3</em>: How do I programmatically close (hide) a clueTip?</dt>
628.268 + <dd>If you want to trigger a clueTip to close, based on some other interaction, you can use the following code: <code>$(document).trigger('hideCluetip');</code> </dd>
628.269 + <dt><em>New as of clueTip 1.0.4</em>: Why don't the styles that I've applied to my local content carry over once they're inside a clueTip?</dt>
628.270 + <dd>When using an element on the same page to populate the clueTip's content, the plugin <em>clones</em> that element. Because of potential problems caused by duplicate IDs within a page, the plugin also, by default, adds a suffix to the ID of the cloned element. If you have tied styles to the original ID, they won't be carried over. You can either give the <code>localIdSuffix</code> an empty string ( '' ) for its value or add the id to your stylesheet rule.</dd>
628.271 + <dt>How do I add a delay before showing or closing the clueTip? </dt>
628.272 + <dd>While the clueTip plugin itself doesn't have a mechanism for delaying responses, it can take advantage of the optional hoverIntent plugin. To delay the showing of a clueTip, use the <code>interval</code> property of the <code>hoverIntent</code> option; to delay its hiding, use the <code>timeout</code> property. Both properties are measured in milliseconds. For example, the following sets both the show and the hide delays to 750 milliseconds (3/4 second):
628.273 +<pre><code>$('a').cluetip({
628.274 + hoverIntent: {
628.275 + sensitivity: 1,
628.276 + interval: 750,
628.277 + timeout: 750
628.278 + }
628.279 +});
628.280 +</code></pre>
628.281 + See <a href="http://cherne.net/brian/resources/jquery.hoverIntent.html">hoverIntent plugin's documentation</a> for details.</dd>
628.282 + <dt>Why are the clueTips hidden behind my Flash elements?</dt>
628.283 + <dd><p>This is a common problem when trying to layer a DOM element over a Flash object. To avoid it, you need to set <param name="wmode" value="transparent" /> inside the <object></object> tags and/or wmode="transparent" as an attribute of the <embed /> tag. For example, your HTML might look like this:</p>
628.284 +
628.285 +<pre><code><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
628.286 + codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"
628.287 + width="500" height="300">
628.288 + <param name="movie" value="test.swf" />
628.289 + <param name="quality" value="high" />
628.290 + <strong><param name="wmode" value="transparent" /></strong>
628.291 +
628.292 + <embed src="test.swf" quality="high" <strong>wmode="transparent"</strong>
628.293 + pluginspage="http://www.macromedia.com/go/getflashplayer"
628.294 + type="application/x-shockwave-flash" width="500" height="300" />
628.295 +</object></code></pre>
628.296 + </dd>
628.297 + </dl>
628.298 + </div>
628.299 + <div id="credits" class="tabContent">
628.300 + <h1>clueTip Plugin Credits</h1>
628.301 +
628.302 + <ul>
628.303 + <li>The clueTip Plugin was inspired by <a href="http://www.codylindley.com">Cody Lindley</a>'s jTip script. </li>
628.304 + <li>Many feature ideas were provided by Shelane Enos. </li>
628.305 + <li><a href="http://commadot.com/">Glen Lipka</a> and <a href="http://bassistance.de/">Jörn Zaefferer</a> provided expert advice. </li>
628.306 + <li><a href="http://www.pengoworks.com/">Dan G. Switzer</a> and Hector Santos helped a lot and contributed code for a couple features. </li>
628.307 + <li><a href="http://blog.schreiter.info/">Torben Schreiter</a> helped squash some bugs and offered code for pre-loading images from ajaxed files</li>
628.308 + <li><a href="http://www.tweaktheviking.com">Jonathan Chaffer</a> helped a lot, but eschewed the co-author designation out of sheer modesty. </li>
628.309 + </ul>
628.310 + </div>
628.311 + <div id="download" class="tabContent">
628.312 + <h1>Download</h1>
628.313 + <p>The latest "stable" release of the clueTip Plugin is available at:
628.314 + <a class="external" href="http://plugins.jquery.com/project/cluetip/">http://plugins.jquery.com/project/cluetip/</a>.
628.315 + </p>
628.316 + <p>The plugin is also available on Github, where it is updated more frequently with incremental improvements and bug fixes: <a href="http://github.com/kswedberg/jquery-cluetip/tree/master">clueTip on Github</a></p>
628.317 + <h1>Support</h1>
628.318 + <p>Support for the clueTip Plugin is available through the
628.319 + <a class="external" href="http://groups.google.com/group/jquery-en/">jQuery Mailing List</a>.
628.320 + This is a very active list to which many jQuery developers and users subscribe.
628.321 + </p>
628.322 + <h1>Bug Reports & Feature Requests</h1>
628.323 + If you discover a bug in the clueTip plugin, please <a href="http://plugins.jquery.com/node/add/project_issue/cluetip/bug">report the bug here</a>. (Note: if you have to be registered and logged in to report a bug. If you have not already registered, <a href="http://plugins.jquery.com/user/register">you can do so here</p>.
628.324 + <p>If you would like the clueTip to do something that it doesn't already do, you may <a href="http://plugins.jquery.com/node/add/project_issue/cluetip/feature">request a feature</a>.
628.325 + </p>
628.326 + <div id="footer">
628.327 + This documentation is maintained by Karl Swedberg. Send comments or questions to karl [at] learningjquery [dot] com.
628.328 + </div>
628.329 + </div>
628.330 +</div> <!-- main -->
628.331 +
628.332 +</body></html>
629.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
629.2 +++ b/web/static/js/cluetip-1.0.6/jquery.cluetip.css Mon Apr 26 11:16:23 2010 +0200
629.3 @@ -0,0 +1,211 @@
629.4 +/* global */
629.5 +#cluetip-close img {
629.6 + border: 0
629.7 + }
629.8 +#cluetip-title {
629.9 + overflow: hidden
629.10 + }
629.11 +#cluetip-title #cluetip-close {
629.12 + float: right;
629.13 + position: relative
629.14 + }
629.15 +#cluetip-waitimage {
629.16 + width: 43px;
629.17 + height: 11px;
629.18 + position: absolute;
629.19 + background-image: url(images/wait.gif)
629.20 + }
629.21 +.cluetip-arrows {
629.22 + display: none;
629.23 + position: absolute;
629.24 + top: 0;
629.25 + left: -11px;
629.26 + height: 22px;
629.27 + width: 11px;
629.28 + background-repeat: no-repeat;
629.29 + background-position: 0 0
629.30 + }
629.31 +#cluetip-extra {
629.32 + display: none
629.33 + }
629.34 +/***************************************
629.35 + =cluetipClass: 'default'
629.36 +-------------------------------------- */
629.37 +.cluetip-default {
629.38 + background-color: #ddf1c1
629.39 + }
629.40 +.cluetip-default #cluetip-outer {
629.41 + position: relative;
629.42 + margin: 0;
629.43 + background-color: #ddf1c1
629.44 + }
629.45 +.cluetip-default h3#cluetip-title {
629.46 + margin: 0 0 5px;
629.47 + padding: 8px 10px 4px;
629.48 + font-size: 1.1em;
629.49 + font-weight: normal;
629.50 + background-color: #beeb82;
629.51 + color: #fff
629.52 + }
629.53 +.cluetip-default #cluetip-title a {
629.54 + color: #ddf1c1;
629.55 + font-size: 0.95em
629.56 + }
629.57 +.cluetip-default #cluetip-inner {
629.58 + padding: 10px
629.59 + }
629.60 +.cluetip-default div#cluetip-close {
629.61 + text-align: right;
629.62 + margin: 0 5px 5px;
629.63 + color: #900
629.64 + }
629.65 +/* default arrows */
629.66 +.clue-right-default .cluetip-arrows {
629.67 + background-image: url(images/darrowleft.gif)
629.68 + }
629.69 +.clue-left-default .cluetip-arrows {
629.70 + background-image: url(images/darrowright.gif);
629.71 + left: 100%;
629.72 + margin-right: -11px
629.73 + }
629.74 +.clue-top-default .cluetip-arrows {
629.75 + background-image: url(images/darrowdown.gif);
629.76 + top: 100%;
629.77 + left: 50%;
629.78 + margin-left: -11px;
629.79 + height: 11px;
629.80 + width: 22px
629.81 + }
629.82 +.clue-bottom-default .cluetip-arrows {
629.83 + background-image: url(images/darrowup.gif);
629.84 + top: -11px;
629.85 + left: 50%;
629.86 + margin-left: -11px;
629.87 + height: 11px;
629.88 + width: 22px
629.89 + }
629.90 +/***************************************
629.91 + =cluetipClass: 'jtip'
629.92 +-------------------------------------- */
629.93 +.cluetip-jtip {
629.94 + background-color: transparent
629.95 + }
629.96 +.cluetip-jtip #cluetip-outer {
629.97 + border: 2px solid #ccc;
629.98 + position: relative;
629.99 + background-color: #fff
629.100 + }
629.101 +.cluetip-jtip h3#cluetip-title {
629.102 + margin: 0 0 5px;
629.103 + padding: 2px 5px;
629.104 + font-size: 16px;
629.105 + font-weight: normal;
629.106 + background-color: #ccc;
629.107 + color: #333
629.108 + }
629.109 +.cluetip-jtip #cluetip-inner {
629.110 + padding: 0 5px 5px;
629.111 + display: inline-block
629.112 + }
629.113 +.cluetip-jtip div#cluetip-close {
629.114 + text-align: right;
629.115 + margin: 0 5px 5px;
629.116 + color: #900
629.117 + }
629.118 +/* jtip arrows */
629.119 +.clue-right-jtip .cluetip-arrows {
629.120 + background-image: url(images/arrowleft.gif)
629.121 + }
629.122 +.clue-left-jtip .cluetip-arrows {
629.123 + background-image: url(images/arrowright.gif);
629.124 + left: 100%;
629.125 + margin-right: -11px
629.126 + }
629.127 +.clue-top-jtip .cluetip-arrows {
629.128 + background-image: url(images/arrowdown.gif);
629.129 + top: 100%;
629.130 + left: 50%;
629.131 + margin-left: -11px;
629.132 + height: 11px;
629.133 + width: 22px
629.134 + }
629.135 +.clue-bottom-jtip .cluetip-arrows {
629.136 + background-image: url(images/arrowup.gif);
629.137 + top: -11px;
629.138 + left: 50%;
629.139 + margin-left: -11px;
629.140 + height: 11px;
629.141 + width: 22px
629.142 + }
629.143 +/***************************************
629.144 + =cluetipClass: 'rounded'
629.145 +-------------------------------------- */
629.146 +.cluetip-rounded {
629.147 + background: transparent url(images/bl.gif) no-repeat 0 100%;
629.148 + margin-top: 10px;
629.149 + margin-left: 12px
629.150 + }
629.151 +.cluetip-rounded #cluetip-outer {
629.152 + background: transparent url(images/tl.gif) no-repeat 0 0;
629.153 + margin-top: -12px
629.154 + }
629.155 +.cluetip-rounded #cluetip-title {
629.156 + background-color: transparent;
629.157 + padding: 12px 12px 0;
629.158 + margin: 0 -12px 0 0;
629.159 + position: relative
629.160 + }
629.161 +.cluetip-rounded #cluetip-extra {
629.162 + position: absolute;
629.163 + display: block;
629.164 + background: transparent url(images/tr.gif) no-repeat 100% 0;
629.165 + top: 0;
629.166 + right: 0;
629.167 + width: 12px;
629.168 + height: 30px;
629.169 + margin: -12px -12px 0 0
629.170 + }
629.171 +.cluetip-rounded #cluetip-inner {
629.172 + background: url(images/br.gif) no-repeat 100% 100%;
629.173 + padding: 5px 12px 12px;
629.174 + margin: -18px -12px 0 0;
629.175 + position: relative
629.176 + }
629.177 +.cluetip-rounded div#cluetip-close {
629.178 + text-align: right;
629.179 + margin: 0 5px 5px;
629.180 + color: #009;
629.181 + background: transparent
629.182 + }
629.183 +.cluetip-rounded div#cluetip-close a {
629.184 + color: #777
629.185 + }
629.186 +/* rounded arrows */
629.187 +.clue-right-rounded .cluetip-arrows {
629.188 + background-image: url(images/rarrowleft.gif)
629.189 + }
629.190 +.clue-left-rounded .cluetip-arrows {
629.191 + background-image: url(images/rarrowright.gif);
629.192 + left: 100%;
629.193 + margin-left: 12px
629.194 + }
629.195 +.clue-top-rounded .cluetip-arrows {
629.196 + background-image: url(images/rarrowdown.gif);
629.197 + top: 100%;
629.198 + left: 50%;
629.199 + margin-left: -11px;
629.200 + height: 11px;
629.201 + width: 22px
629.202 + }
629.203 +.clue-bottom-rounded .cluetip-arrows {
629.204 + background-image: url(images/rarrowup.gif);
629.205 + top: -23px;
629.206 + left: 50%;
629.207 + margin-left: -11px;
629.208 + height: 11px;
629.209 + width: 22px
629.210 + }
629.211 +/* stupid IE6 HasLayout hack */
629.212 +.cluetip-rounded #cluetip-title, .cluetip-rounded #cluetip-inner {
629.213 + zoom: 1
629.214 + }
630.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
630.2 +++ b/web/static/js/cluetip-1.0.6/jquery.cluetip.js Mon Apr 26 11:16:23 2010 +0200
630.3 @@ -0,0 +1,549 @@
630.4 +/*
630.5 + * jQuery clueTip plugin
630.6 + * Version 1.0.6 (January 13, 2022)
630.7 + * @requires jQuery v1.3+
630.8 + *
630.9 + * Dual licensed under the MIT and GPL licenses:
630.10 + * http://www.opensource.org/licenses/mit-license.php
630.11 + * http://www.gnu.org/licenses/gpl.html
630.12 + *
630.13 + */
630.14 +
630.15 +/*
630.16 + *
630.17 + * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
630.18 + *
630.19 + * Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
630.20 + *
630.21 +*/
630.22 +
630.23 +;(function($) {
630.24 + $.cluetip = {version: '1.0.6'};
630.25 + var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $cluetipWait, $dropShadow, imgCount;
630.26 +
630.27 + $.fn.cluetip = function(js, options) {
630.28 + if (typeof js == 'object') {
630.29 + options = js;
630.30 + js = null;
630.31 + }
630.32 + if (js == 'destroy') {
630.33 + return this.removeData('thisInfo').unbind('.cluetip');
630.34 + }
630.35 + return this.each(function(index) {
630.36 + var link = this, $this = $(this);
630.37 +
630.38 + // support metadata plugin (v1.0 and 2.0)
630.39 + var opts = $.extend(true, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});
630.40 +
630.41 + // start out with no contents (for ajax activation)
630.42 + var cluetipContents = false;
630.43 + var cluezIndex = +opts.cluezIndex;
630.44 + $this.data('thisInfo', {title: link.title, zIndex: cluezIndex});
630.45 + var isActive = false, closeOnDelay = 0;
630.46 +
630.47 + // create the cluetip divs
630.48 + if (!$('#cluetip').length) {
630.49 + $(['<div id="cluetip">',
630.50 + '<div id="cluetip-outer">',
630.51 + '<h3 id="cluetip-title"></h3>',
630.52 + '<div id="cluetip-inner"></div>',
630.53 + '</div>',
630.54 + '<div id="cluetip-extra"></div>',
630.55 + '<div id="cluetip-arrows" class="cluetip-arrows"></div>',
630.56 + '</div>'].join(''))
630.57 + [insertionType](insertionElement).hide();
630.58 +
630.59 + $cluetip = $('#cluetip').css({position: 'absolute'});
630.60 + $cluetipOuter = $('#cluetip-outer').css({position: 'relative', zIndex: cluezIndex});
630.61 + $cluetipInner = $('#cluetip-inner');
630.62 + $cluetipTitle = $('#cluetip-title');
630.63 + $cluetipArrows = $('#cluetip-arrows');
630.64 + $cluetipWait = $('<div id="cluetip-waitimage"></div>')
630.65 + .css({position: 'absolute'}).insertBefore($cluetip).hide();
630.66 + }
630.67 + var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
630.68 + if (!$dropShadow) {
630.69 + $dropShadow = $([]);
630.70 + for (var i=0; i < dropShadowSteps; i++) {
630.71 + $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-1, opacity:.1, top: 1+i, left: 1+i}));
630.72 + }
630.73 + $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
630.74 + .prependTo($cluetip);
630.75 + }
630.76 + var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
630.77 + if (!tipAttribute && !opts.splitTitle && !js) {
630.78 + return true;
630.79 + }
630.80 + // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
630.81 + if (opts.local && opts.localPrefix) {tipAttribute = opts.localPrefix + tipAttribute;}
630.82 + if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
630.83 + var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
630.84 + // vertical measurement variables
630.85 + var tipHeight, wHeight,
630.86 + defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
630.87 + var sTop, linkTop, posY, tipY, mouseY, baseline;
630.88 + // horizontal measurement variables
630.89 + var tipInnerWidth = parseInt(opts.width, 10) || 275,
630.90 + tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'),10)||0) + (parseInt($cluetip.css('paddingRight'),10)||0) + dropShadowSteps,
630.91 + linkWidth = this.offsetWidth,
630.92 + linkLeft, posX, tipX, mouseX, winWidth;
630.93 +
630.94 + // parse the title
630.95 + var tipParts;
630.96 + var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
630.97 + if (opts.splitTitle) {
630.98 + if (tipTitle == undefined) {tipTitle = '';}
630.99 + tipParts = tipTitle.split(opts.splitTitle);
630.100 + tipTitle = tipParts.shift();
630.101 + }
630.102 + if (opts.escapeTitle) {
630.103 + tipTitle = tipTitle.replace(/&/g,'&').replace(/>/g,'>').replace(/</g,'<');
630.104 + }
630.105 +
630.106 + var localContent;
630.107 + function returnFalse() { return false; }
630.108 +
630.109 +/***************************************
630.110 +* ACTIVATION
630.111 +****************************************/
630.112 +
630.113 +//activate clueTip
630.114 + var activate = function(event) {
630.115 + if (!opts.onActivate($this)) {
630.116 + return false;
630.117 + }
630.118 + isActive = true;
630.119 + $cluetip.removeClass().css({width: tipInnerWidth});
630.120 + if (tipAttribute == $this.attr('href')) {
630.121 + $this.css('cursor', opts.cursor);
630.122 + }
630.123 + if (opts.hoverClass) {
630.124 + $this.addClass(opts.hoverClass);
630.125 + }
630.126 + linkTop = posY = $this.offset().top;
630.127 + linkLeft = $this.offset().left;
630.128 + mouseX = event.pageX;
630.129 + mouseY = event.pageY;
630.130 + if (link.tagName.toLowerCase() != 'area') {
630.131 + sTop = $(document).scrollTop();
630.132 + winWidth = $(window).width();
630.133 + }
630.134 +// position clueTip horizontally
630.135 + if (opts.positionBy == 'fixed') {
630.136 + posX = linkWidth + linkLeft + lOffset;
630.137 + $cluetip.css({left: posX});
630.138 + } else {
630.139 + posX = (linkWidth > linkLeft && linkLeft > tipWidth)
630.140 + || linkLeft + linkWidth + tipWidth + lOffset > winWidth
630.141 + ? linkLeft - tipWidth - lOffset
630.142 + : linkWidth + linkLeft + lOffset;
630.143 + if (link.tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
630.144 + if (mouseX + 20 + tipWidth > winWidth) {
630.145 + $cluetip.addClass(' cluetip-' + ctClass);
630.146 + posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) : mouseX - (tipWidth/2);
630.147 + } else {
630.148 + posX = mouseX + lOffset;
630.149 + }
630.150 + }
630.151 + var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
630.152 + $cluetip.css({
630.153 + left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0),
630.154 + zIndex: $this.data('thisInfo').zIndex
630.155 + });
630.156 + $cluetipArrows.css({zIndex: $this.data('thisInfo').zIndex+1});
630.157 + }
630.158 + wHeight = $(window).height();
630.159 +
630.160 +/***************************************
630.161 +* load a string from cluetip method's first argument
630.162 +***************************************/
630.163 + if (js) {
630.164 + if (typeof js == 'function') {
630.165 + js = js.call(link);
630.166 + }
630.167 + $cluetipInner.html(js);
630.168 + cluetipShow(pY);
630.169 + }
630.170 +/***************************************
630.171 +* load the title attribute only (or user-selected attribute).
630.172 +* clueTip title is the string before the first delimiter
630.173 +* subsequent delimiters place clueTip body text on separate lines
630.174 +***************************************/
630.175 +
630.176 + else if (tipParts) {
630.177 + var tpl = tipParts.length;
630.178 + $cluetipInner.html(tpl ? tipParts[0] : '');
630.179 + if (tpl > 1) {
630.180 + for (var i=1; i < tpl; i++){
630.181 + $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
630.182 + }
630.183 + }
630.184 + cluetipShow(pY);
630.185 + }
630.186 +/***************************************
630.187 +* load external file via ajax
630.188 +***************************************/
630.189 +
630.190 + else if (!opts.local && tipAttribute.indexOf('#') !== 0) {
630.191 + if (/\.(jpe?g|tiff?|gif|png)$/i.test(tipAttribute)) {
630.192 + $cluetipInner.html('<img src="' + tipAttribute + '" alt="' + tipTitle + '" />');
630.193 + cluetipShow(pY);
630.194 + } else if (cluetipContents && opts.ajaxCache) {
630.195 + $cluetipInner.html(cluetipContents);
630.196 + cluetipShow(pY);
630.197 + } else {
630.198 + var optionBeforeSend = opts.ajaxSettings.beforeSend,
630.199 + optionError = opts.ajaxSettings.error,
630.200 + optionSuccess = opts.ajaxSettings.success,
630.201 + optionComplete = opts.ajaxSettings.complete;
630.202 + var ajaxSettings = {
630.203 + cache: false, // force requested page not to be cached by browser
630.204 + url: tipAttribute,
630.205 + beforeSend: function(xhr) {
630.206 + if (optionBeforeSend) {optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner);}
630.207 + $cluetipOuter.children().empty();
630.208 + if (opts.waitImage) {
630.209 + $cluetipWait
630.210 + .css({top: mouseY+20, left: mouseX+20, zIndex: $this.data('thisInfo').zIndex-1})
630.211 + .show();
630.212 + }
630.213 + },
630.214 + error: function(xhr, textStatus) {
630.215 + if (isActive) {
630.216 + if (optionError) {
630.217 + optionError.call(link, xhr, textStatus, $cluetip, $cluetipInner);
630.218 + } else {
630.219 + $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
630.220 + }
630.221 + }
630.222 + },
630.223 + success: function(data, textStatus) {
630.224 + cluetipContents = opts.ajaxProcess.call(link, data);
630.225 + if (isActive) {
630.226 + if (optionSuccess) {optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner);}
630.227 + $cluetipInner.html(cluetipContents);
630.228 + }
630.229 + },
630.230 + complete: function(xhr, textStatus) {
630.231 + if (optionComplete) {optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner);}
630.232 + imgCount = $('#cluetip-inner img').length;
630.233 + if (imgCount && !$.browser.opera) {
630.234 + $('#cluetip-inner img').bind('load error', function() {
630.235 + imgCount--;
630.236 + if (imgCount<1) {
630.237 + $cluetipWait.hide();
630.238 + if (isActive) { cluetipShow(pY); }
630.239 + }
630.240 + });
630.241 + } else {
630.242 + $cluetipWait.hide();
630.243 + if (isActive) { cluetipShow(pY); }
630.244 + }
630.245 + }
630.246 + };
630.247 + var ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings);
630.248 +
630.249 + $.ajax(ajaxMergedSettings);
630.250 + }
630.251 +
630.252 +/***************************************
630.253 +* load an element from the same page
630.254 +***************************************/
630.255 + } else if (opts.local) {
630.256 +
630.257 + var $localContent = $(tipAttribute + (/#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
630.258 + $cluetipInner.html($localContent);
630.259 + cluetipShow(pY);
630.260 + }
630.261 + };
630.262 +
630.263 +// get dimensions and options for cluetip and prepare it to be shown
630.264 + var cluetipShow = function(bpY) {
630.265 + $cluetip.addClass('cluetip-' + ctClass);
630.266 + if (opts.truncate) {
630.267 + var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
630.268 + $cluetipInner.html($truncloaded);
630.269 + }
630.270 + function doNothing() {}; //empty function
630.271 + tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html(' ') : $cluetipTitle.hide();
630.272 + if (opts.sticky) {
630.273 + var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
630.274 + (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
630.275 + $closeLink.bind('click.cluetip', function() {
630.276 + cluetipClose();
630.277 + return false;
630.278 + });
630.279 + if (opts.mouseOutClose) {
630.280 + $cluetip.bind('mouseleave.cluetip', function() {
630.281 + cluetipClose();
630.282 + });
630.283 + } else {
630.284 + $cluetip.unbind('mouseleave.cluetip');
630.285 + }
630.286 + }
630.287 +// now that content is loaded, finish the positioning
630.288 + var direction = '';
630.289 + $cluetipOuter.css({zIndex: $this.data('thisInfo').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
630.290 + tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);
630.291 + tipY = posY;
630.292 + baseline = sTop + wHeight;
630.293 + if (opts.positionBy == 'fixed') {
630.294 + tipY = posY - opts.dropShadowSteps + tOffset;
630.295 + } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
630.296 + if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) {
630.297 + tipY = mouseY - tipHeight - tOffset;
630.298 + direction = 'top';
630.299 + } else {
630.300 + tipY = mouseY + tOffset;
630.301 + direction = 'bottom';
630.302 + }
630.303 + } else if ( posY + tipHeight + tOffset > baseline ) {
630.304 + tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
630.305 + } else if ($this.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
630.306 + tipY = bpY - tOffset;
630.307 + } else {
630.308 + tipY = posY - opts.dropShadowSteps;
630.309 + }
630.310 + if (direction == '') {
630.311 + posX < linkLeft ? direction = 'left' : direction = 'right';
630.312 + }
630.313 + $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
630.314 + if (opts.arrows) { // set up arrow positioning to align with element
630.315 + var bgY = (posY - tipY - opts.dropShadowSteps);
630.316 + $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
630.317 + } else {
630.318 + $cluetipArrows.hide();
630.319 + }
630.320 +
630.321 +// (first hide, then) ***SHOW THE CLUETIP***
630.322 + $dropShadow.hide();
630.323 + $cluetip.hide()[opts.fx.open](opts.fx.openSpeed || 0);
630.324 + if (opts.dropShadow) { $dropShadow.css({height: tipHeight, width: tipInnerWidth, zIndex: $this.data('thisInfo').zIndex-1}).show(); }
630.325 + if ($.fn.bgiframe) { $cluetip.bgiframe(); }
630.326 + // delayed close (not fully tested)
630.327 + if (opts.delayedClose > 0) {
630.328 + closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
630.329 + }
630.330 + // trigger the optional onShow function
630.331 + opts.onShow.call(link, $cluetip, $cluetipInner);
630.332 + };
630.333 +
630.334 +/***************************************
630.335 + =INACTIVATION
630.336 +-------------------------------------- */
630.337 + var inactivate = function(event) {
630.338 + isActive = false;
630.339 + $cluetipWait.hide();
630.340 + if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
630.341 + cluetipClose();
630.342 + clearTimeout(closeOnDelay);
630.343 + }
630.344 + if (opts.hoverClass) {
630.345 + $this.removeClass(opts.hoverClass);
630.346 + }
630.347 + };
630.348 +// close cluetip and reset some things
630.349 + var cluetipClose = function() {
630.350 + $cluetipOuter
630.351 + .parent().hide().removeClass();
630.352 + opts.onHide.call(link, $cluetip, $cluetipInner);
630.353 + $this.removeClass('cluetip-clicked');
630.354 + if (tipTitle) {
630.355 + $this.attr(opts.titleAttribute, tipTitle);
630.356 + }
630.357 + $this.css('cursor','');
630.358 + if (opts.arrows) {
630.359 + $cluetipArrows.css({top: ''});
630.360 + }
630.361 + };
630.362 +
630.363 + $(document).bind('hideCluetip', function(e) {
630.364 + cluetipClose();
630.365 + });
630.366 +/***************************************
630.367 + =BIND EVENTS
630.368 +-------------------------------------- */
630.369 + // activate by click
630.370 + if ( (/click|toggle/).test(opts.activation) ) {
630.371 + $this.bind('click.cluetip', function(event) {
630.372 + if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
630.373 + activate(event);
630.374 + $('.cluetip-clicked').removeClass('cluetip-clicked');
630.375 + $this.addClass('cluetip-clicked');
630.376 + } else {
630.377 + inactivate(event);
630.378 + }
630.379 + this.blur();
630.380 + return false;
630.381 + });
630.382 + // activate by focus; inactivate by blur
630.383 + } else if (opts.activation == 'focus') {
630.384 + $this.bind('focus.cluetip', function(event) {
630.385 + activate(event);
630.386 + });
630.387 + $this.bind('blur.cluetip', function(event) {
630.388 + inactivate(event);
630.389 + });
630.390 + // activate by hover
630.391 + } else {
630.392 + // clicking is returned false if clickThrough option is set to false
630.393 + $this[opts.clickThrough ? 'unbind' : 'bind']('click', returnFalse);
630.394 + //set up mouse tracking
630.395 + var mouseTracks = function(evt) {
630.396 + if (opts.tracking == true) {
630.397 + var trackX = posX - evt.pageX;
630.398 + var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
630.399 + $this.bind('mousemove.cluetip', function(evt) {
630.400 + $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
630.401 + });
630.402 + }
630.403 + };
630.404 + if ($.fn.hoverIntent && opts.hoverIntent) {
630.405 + $this.hoverIntent({
630.406 + sensitivity: opts.hoverIntent.sensitivity,
630.407 + interval: opts.hoverIntent.interval,
630.408 + over: function(event) {
630.409 + activate(event);
630.410 + mouseTracks(event);
630.411 + },
630.412 + timeout: opts.hoverIntent.timeout,
630.413 + out: function(event) {inactivate(event); $this.unbind('mousemove.cluetip');}
630.414 + });
630.415 + } else {
630.416 + $this.bind('mouseenter.cluetip', function(event) {
630.417 + activate(event);
630.418 + mouseTracks(event);
630.419 + })
630.420 + .bind('mouseleave.cluetip', function(event) {
630.421 + inactivate(event);
630.422 + $this.unbind('mousemove.cluetip');
630.423 + });
630.424 + }
630.425 + $this.bind('mouseover.cluetip', function(event) {
630.426 + $this.attr('title','');
630.427 + }).bind('mouseleave.cluetip', function(event) {
630.428 + $this.attr('title', $this.data('thisInfo').title);
630.429 + });
630.430 + }
630.431 + });
630.432 + };
630.433 +
630.434 +/*
630.435 + * options for clueTip
630.436 + *
630.437 + * each one can be explicitly overridden by changing its value.
630.438 + * for example: $.fn.cluetip.defaults.width = 200;
630.439 + * would change the default width for all clueTips to 200.
630.440 + *
630.441 + * each one can also be overridden by passing an options map to the cluetip method.
630.442 + * for example: $('a.example').cluetip({width: 200});
630.443 + * would change the default width to 200 for clueTips invoked by a link with class of "example"
630.444 + *
630.445 + */
630.446 +
630.447 + $.fn.cluetip.defaults = { // set up default options
630.448 + width: 275, // The width of the clueTip
630.449 + height: 'auto', // The height of the clueTip
630.450 + cluezIndex: 97, // Sets the z-index style property of the clueTip
630.451 + positionBy: 'auto', // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
630.452 + topOffset: 15, // Number of px to offset clueTip from top of invoking element
630.453 + leftOffset: 15, // Number of px to offset clueTip from left of invoking element
630.454 + local: false, // Whether to use content from the same page for the clueTip's body
630.455 + localPrefix: null, // string to be prepended to the tip attribute if local is true
630.456 + hideLocal: true, // If local option is set to true, this determines whether local content
630.457 + // to be shown in clueTip should be hidden at its original location
630.458 + attribute: 'rel', // the attribute to be used for fetching the clueTip's body content
630.459 + titleAttribute: 'title', // the attribute to be used for fetching the clueTip's title
630.460 + splitTitle: '', // A character used to split the title attribute into the clueTip title and divs
630.461 + // within the clueTip body. more info below [6]
630.462 + escapeTitle: false, // whether to html escape the title attribute
630.463 + showTitle: true, // show title bar of the clueTip, even if title attribute not set
630.464 + cluetipClass: 'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
630.465 + hoverClass: '', // class applied to the invoking element onmouseover and removed onmouseout
630.466 + waitImage: true, // whether to show a "loading" img, which is set in jquery.cluetip.css
630.467 + cursor: 'help',
630.468 + arrows: false, // if true, displays arrow on appropriate side of clueTip
630.469 + dropShadow: true, // set to false if you don't want the drop-shadow effect on the clueTip
630.470 + dropShadowSteps: 6, // adjusts the size of the drop shadow
630.471 + sticky: false, // keep visible until manually closed
630.472 + mouseOutClose: false, // close when clueTip is moused out
630.473 + activation: 'hover', // set to 'click' to force user to click to show clueTip
630.474 + // set to 'focus' to show on focus of a form element and hide on blur
630.475 + clickThrough: false, // if true, and activation is not 'click', then clicking on link will take user to the link's href,
630.476 + // even if href and tipAttribute are equal
630.477 + tracking: false, // if true, clueTip will track mouse movement (experimental)
630.478 + delayedClose: 0, // close clueTip on a timed delay (experimental)
630.479 + closePosition: 'top', // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
630.480 + closeText: 'Close', // text (or HTML) to to be clicked to close sticky clueTips
630.481 + truncate: 0, // number of characters to truncate clueTip's contents. if 0, no truncation occurs
630.482 +
630.483 + // effect and speed for opening clueTips
630.484 + fx: {
630.485 + open: 'show', // can be 'show' or 'slideDown' or 'fadeIn'
630.486 + openSpeed: ''
630.487 + },
630.488 +
630.489 + // settings for when hoverIntent plugin is used
630.490 + hoverIntent: {
630.491 + sensitivity: 3,
630.492 + interval: 50,
630.493 + timeout: 0
630.494 + },
630.495 +
630.496 + // short-circuit function to run just before clueTip is shown.
630.497 + onActivate: function(e) {return true;},
630.498 +
630.499 + // function to run just after clueTip is shown.
630.500 + onShow: function(ct, ci){},
630.501 + // function to run just after clueTip is hidden.
630.502 + onHide: function(ct, ci){},
630.503 + // whether to cache results of ajax request to avoid unnecessary hits to server
630.504 + ajaxCache: true,
630.505 +
630.506 + // process data retrieved via xhr before it's displayed
630.507 + ajaxProcess: function(data) {
630.508 + data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,'');
630.509 + return data;
630.510 + },
630.511 +
630.512 + // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend,
630.513 + // will be queued first within the default callbacks.
630.514 + // The only exception is error, which overrides the default
630.515 + ajaxSettings: {
630.516 + // error: function(ct, ci) { /* override default error callback */ }
630.517 + // beforeSend: function(ct, ci) { /* called first within default beforeSend callback }
630.518 + dataType: 'html'
630.519 + },
630.520 + debug: false
630.521 + };
630.522 +
630.523 +
630.524 +/*
630.525 + * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
630.526 + *
630.527 + * @example $.cluetip.setup({
630.528 + * insertionType: 'prependTo',
630.529 + * insertionElement: '#container'
630.530 + * });
630.531 + *
630.532 + * @property
630.533 + * @name $.cluetip.setup
630.534 + * @type Map
630.535 + * @cat Plugins/tooltip
630.536 + * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
630.537 + * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
630.538 + *
630.539 + */
630.540 +
630.541 + var insertionType = 'appendTo', insertionElement = 'body';
630.542 +
630.543 + $.cluetip.setup = function(options) {
630.544 + if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
630.545 + insertionType = options.insertionType;
630.546 + }
630.547 + if (options && options.insertionElement) {
630.548 + insertionElement = options.insertionElement;
630.549 + }
630.550 + };
630.551 +
630.552 +})(jQuery);
631.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
631.2 +++ b/web/static/js/cluetip-1.0.6/jquery.cluetip.min.js Mon Apr 26 11:16:23 2010 +0200
631.3 @@ -0,0 +1,58 @@
631.4 +/*
631.5 + * jQuery clueTip plugin
631.6 + * Version 1.0.6 (January 13, 2022)
631.7 + * @requires jQuery v1.3+
631.8 + *
631.9 + * Dual licensed under the MIT and GPL licenses:
631.10 + * http://www.opensource.org/licenses/mit-license.php
631.11 + * http://www.gnu.org/licenses/gpl.html
631.12 + *
631.13 + */
631.14 +
631.15 +/*
631.16 + *
631.17 + * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
631.18 + *
631.19 + * Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
631.20 + *
631.21 +*/
631.22 +(function($){$.cluetip={version:'1.0.6'};var $cluetip,$cluetipInner,$cluetipOuter,$cluetipTitle,$cluetipArrows,$cluetipWait,$dropShadow,imgCount;$.fn.cluetip=function(js,options){if(typeof js=='object'){options=js;js=null;}
631.23 +if(js=='destroy'){return this.removeData('thisInfo').unbind('.cluetip');}
631.24 +return this.each(function(index){var link=this,$this=$(this);var opts=$.extend(true,{},$.fn.cluetip.defaults,options||{},$.metadata?$this.metadata():$.meta?$this.data():{});var cluetipContents=false;var cluezIndex=+opts.cluezIndex;$this.data('thisInfo',{title:link.title,zIndex:cluezIndex});var isActive=false,closeOnDelay=0;if(!$('#cluetip').length){$(['<div id="cluetip">','<div id="cluetip-outer">','<h3 id="cluetip-title"></h3>','<div id="cluetip-inner"></div>','</div>','<div id="cluetip-extra"></div>','<div id="cluetip-arrows" class="cluetip-arrows"></div>','</div>'].join(''))
631.25 +[insertionType](insertionElement).hide();$cluetip=$('#cluetip').css({position:'absolute'});$cluetipOuter=$('#cluetip-outer').css({position:'relative',zIndex:cluezIndex});$cluetipInner=$('#cluetip-inner');$cluetipTitle=$('#cluetip-title');$cluetipArrows=$('#cluetip-arrows');$cluetipWait=$('<div id="cluetip-waitimage"></div>').css({position:'absolute'}).insertBefore($cluetip).hide();}
631.26 +var dropShadowSteps=(opts.dropShadow)?+opts.dropShadowSteps:0;if(!$dropShadow){$dropShadow=$([]);for(var i=0;i<dropShadowSteps;i++){$dropShadow=$dropShadow.add($('<div></div>').css({zIndex:cluezIndex-1,opacity:.1,top:1+i,left:1+i}));}
631.27 +$dropShadow.css({position:'absolute',backgroundColor:'#000'}).prependTo($cluetip);}
631.28 +var tipAttribute=$this.attr(opts.attribute),ctClass=opts.cluetipClass;if(!tipAttribute&&!opts.splitTitle&&!js){return true;}
631.29 +if(opts.local&&opts.localPrefix){tipAttribute=opts.localPrefix+tipAttribute;}
631.30 +if(opts.local&&opts.hideLocal){$(tipAttribute+':first').hide();}
631.31 +var tOffset=parseInt(opts.topOffset,10),lOffset=parseInt(opts.leftOffset,10);var tipHeight,wHeight,defHeight=isNaN(parseInt(opts.height,10))?'auto':(/\D/g).test(opts.height)?opts.height:opts.height+'px';var sTop,linkTop,posY,tipY,mouseY,baseline;var tipInnerWidth=parseInt(opts.width,10)||275,tipWidth=tipInnerWidth+(parseInt($cluetip.css('paddingLeft'),10)||0)+(parseInt($cluetip.css('paddingRight'),10)||0)+dropShadowSteps,linkWidth=this.offsetWidth,linkLeft,posX,tipX,mouseX,winWidth;var tipParts;var tipTitle=(opts.attribute!='title')?$this.attr(opts.titleAttribute):'';if(opts.splitTitle){if(tipTitle==undefined){tipTitle='';}
631.32 +tipParts=tipTitle.split(opts.splitTitle);tipTitle=tipParts.shift();}
631.33 +if(opts.escapeTitle){tipTitle=tipTitle.replace(/&/g,'&').replace(/>/g,'>').replace(/</g,'<');}
631.34 +var localContent;function returnFalse(){return false;}
631.35 +var activate=function(event){if(!opts.onActivate($this)){return false;}
631.36 +isActive=true;$cluetip.removeClass().css({width:tipInnerWidth});if(tipAttribute==$this.attr('href')){$this.css('cursor',opts.cursor);}
631.37 +if(opts.hoverClass){$this.addClass(opts.hoverClass);}
631.38 +linkTop=posY=$this.offset().top;linkLeft=$this.offset().left;mouseX=event.pageX;mouseY=event.pageY;if(link.tagName.toLowerCase()!='area'){sTop=$(document).scrollTop();winWidth=$(window).width();}
631.39 +if(opts.positionBy=='fixed'){posX=linkWidth+linkLeft+lOffset;$cluetip.css({left:posX});}else{posX=(linkWidth>linkLeft&&linkLeft>tipWidth)||linkLeft+linkWidth+tipWidth+lOffset>winWidth?linkLeft-tipWidth-lOffset:linkWidth+linkLeft+lOffset;if(link.tagName.toLowerCase()=='area'||opts.positionBy=='mouse'||linkWidth+tipWidth>winWidth){if(mouseX+20+tipWidth>winWidth){$cluetip.addClass(' cluetip-'+ctClass);posX=(mouseX-tipWidth-lOffset)>=0?mouseX-tipWidth-lOffset-parseInt($cluetip.css('marginLeft'),10)+parseInt($cluetipInner.css('marginRight'),10):mouseX-(tipWidth/2);}else{posX=mouseX+lOffset;}}
631.40 +var pY=posX<0?event.pageY+tOffset:event.pageY;$cluetip.css({left:(posX>0&&opts.positionBy!='bottomTop')?posX:(mouseX+(tipWidth/2)>winWidth)?winWidth/2-tipWidth/2:Math.max(mouseX-(tipWidth/2),0),zIndex:$this.data('thisInfo').zIndex});$cluetipArrows.css({zIndex:$this.data('thisInfo').zIndex+1});}
631.41 +wHeight=$(window).height();if(js){if(typeof js=='function'){js=js.call(link);}
631.42 +$cluetipInner.html(js);cluetipShow(pY);}
631.43 +else if(tipParts){var tpl=tipParts.length;$cluetipInner.html(tpl?tipParts[0]:'');if(tpl>1){for(var i=1;i<tpl;i++){$cluetipInner.append('<div class="split-body">'+tipParts[i]+'</div>');}}
631.44 +cluetipShow(pY);}
631.45 +else if(!opts.local&&tipAttribute.indexOf('#')!==0){if(/\.(jpe?g|tiff?|gif|png)$/i.test(tipAttribute)){$cluetipInner.html('<img src="'+tipAttribute+'" alt="'+tipTitle+'" />');cluetipShow(pY);}else if(cluetipContents&&opts.ajaxCache){$cluetipInner.html(cluetipContents);cluetipShow(pY);}else{var optionBeforeSend=opts.ajaxSettings.beforeSend,optionError=opts.ajaxSettings.error,optionSuccess=opts.ajaxSettings.success,optionComplete=opts.ajaxSettings.complete;var ajaxSettings={cache:false,url:tipAttribute,beforeSend:function(xhr){if(optionBeforeSend){optionBeforeSend.call(link,xhr,$cluetip,$cluetipInner);}
631.46 +$cluetipOuter.children().empty();if(opts.waitImage){$cluetipWait.css({top:mouseY+20,left:mouseX+20,zIndex:$this.data('thisInfo').zIndex-1}).show();}},error:function(xhr,textStatus){if(isActive){if(optionError){optionError.call(link,xhr,textStatus,$cluetip,$cluetipInner);}else{$cluetipInner.html('<i>sorry, the contents could not be loaded</i>');}}},success:function(data,textStatus){cluetipContents=opts.ajaxProcess.call(link,data);if(isActive){if(optionSuccess){optionSuccess.call(link,data,textStatus,$cluetip,$cluetipInner);}
631.47 +$cluetipInner.html(cluetipContents);}},complete:function(xhr,textStatus){if(optionComplete){optionComplete.call(link,xhr,textStatus,$cluetip,$cluetipInner);}
631.48 +imgCount=$('#cluetip-inner img').length;if(imgCount&&!$.browser.opera){$('#cluetip-inner img').bind('load error',function(){imgCount--;if(imgCount<1){$cluetipWait.hide();if(isActive){cluetipShow(pY);}}});}else{$cluetipWait.hide();if(isActive){cluetipShow(pY);}}}};var ajaxMergedSettings=$.extend(true,{},opts.ajaxSettings,ajaxSettings);$.ajax(ajaxMergedSettings);}}else if(opts.local){var $localContent=$(tipAttribute+(/#\S+$/.test(tipAttribute)?'':':eq('+index+')')).clone(true).show();$cluetipInner.html($localContent);cluetipShow(pY);}};var cluetipShow=function(bpY){$cluetip.addClass('cluetip-'+ctClass);if(opts.truncate){var $truncloaded=$cluetipInner.text().slice(0,opts.truncate)+'...';$cluetipInner.html($truncloaded);}
631.49 +function doNothing(){};tipTitle?$cluetipTitle.show().html(tipTitle):(opts.showTitle)?$cluetipTitle.show().html(' '):$cluetipTitle.hide();if(opts.sticky){var $closeLink=$('<div id="cluetip-close"><a href="#">'+opts.closeText+'</a></div>');(opts.closePosition=='bottom')?$closeLink.appendTo($cluetipInner):(opts.closePosition=='title')?$closeLink.prependTo($cluetipTitle):$closeLink.prependTo($cluetipInner);$closeLink.bind('click.cluetip',function(){cluetipClose();return false;});if(opts.mouseOutClose){$cluetip.bind('mouseleave.cluetip',function(){cluetipClose();});}else{$cluetip.unbind('mouseleave.cluetip');}}
631.50 +var direction='';$cluetipOuter.css({zIndex:$this.data('thisInfo').zIndex,overflow:defHeight=='auto'?'visible':'auto',height:defHeight});tipHeight=defHeight=='auto'?Math.max($cluetip.outerHeight(),$cluetip.height()):parseInt(defHeight,10);tipY=posY;baseline=sTop+wHeight;if(opts.positionBy=='fixed'){tipY=posY-opts.dropShadowSteps+tOffset;}else if((posX<mouseX&&Math.max(posX,0)+tipWidth>mouseX)||opts.positionBy=='bottomTop'){if(posY+tipHeight+tOffset>baseline&&mouseY-sTop>tipHeight+tOffset){tipY=mouseY-tipHeight-tOffset;direction='top';}else{tipY=mouseY+tOffset;direction='bottom';}}else if(posY+tipHeight+tOffset>baseline){tipY=(tipHeight>=wHeight)?sTop:baseline-tipHeight-tOffset;}else if($this.css('display')=='block'||link.tagName.toLowerCase()=='area'||opts.positionBy=="mouse"){tipY=bpY-tOffset;}else{tipY=posY-opts.dropShadowSteps;}
631.51 +if(direction==''){posX<linkLeft?direction='left':direction='right';}
631.52 +$cluetip.css({top:tipY+'px'}).removeClass().addClass('clue-'+direction+'-'+ctClass).addClass(' cluetip-'+ctClass);if(opts.arrows){var bgY=(posY-tipY-opts.dropShadowSteps);$cluetipArrows.css({top:(/(left|right)/.test(direction)&&posX>=0&&bgY>0)?bgY+'px':/(left|right)/.test(direction)?0:''}).show();}else{$cluetipArrows.hide();}
631.53 +$dropShadow.hide();$cluetip.hide()[opts.fx.open](opts.fx.openSpeed||0);if(opts.dropShadow){$dropShadow.css({height:tipHeight,width:tipInnerWidth,zIndex:$this.data('thisInfo').zIndex-1}).show();}
631.54 +if($.fn.bgiframe){$cluetip.bgiframe();}
631.55 +if(opts.delayedClose>0){closeOnDelay=setTimeout(cluetipClose,opts.delayedClose);}
631.56 +opts.onShow.call(link,$cluetip,$cluetipInner);};var inactivate=function(event){isActive=false;$cluetipWait.hide();if(!opts.sticky||(/click|toggle/).test(opts.activation)){cluetipClose();clearTimeout(closeOnDelay);}
631.57 +if(opts.hoverClass){$this.removeClass(opts.hoverClass);}};var cluetipClose=function(){$cluetipOuter.parent().hide().removeClass();opts.onHide.call(link,$cluetip,$cluetipInner);$this.removeClass('cluetip-clicked');if(tipTitle){$this.attr(opts.titleAttribute,tipTitle);}
631.58 +$this.css('cursor','');if(opts.arrows){$cluetipArrows.css({top:''});}};$(document).bind('hideCluetip',function(e){cluetipClose();});if((/click|toggle/).test(opts.activation)){$this.bind('click.cluetip',function(event){if($cluetip.is(':hidden')||!$this.is('.cluetip-clicked')){activate(event);$('.cluetip-clicked').removeClass('cluetip-clicked');$this.addClass('cluetip-clicked');}else{inactivate(event);}
631.59 +this.blur();return false;});}else if(opts.activation=='focus'){$this.bind('focus.cluetip',function(event){activate(event);});$this.bind('blur.cluetip',function(event){inactivate(event);});}else{$this[opts.clickThrough?'unbind':'bind']('click',returnFalse);var mouseTracks=function(evt){if(opts.tracking==true){var trackX=posX-evt.pageX;var trackY=tipY?tipY-evt.pageY:posY-evt.pageY;$this.bind('mousemove.cluetip',function(evt){$cluetip.css({left:evt.pageX+trackX,top:evt.pageY+trackY});});}};if($.fn.hoverIntent&&opts.hoverIntent){$this.hoverIntent({sensitivity:opts.hoverIntent.sensitivity,interval:opts.hoverIntent.interval,over:function(event){activate(event);mouseTracks(event);},timeout:opts.hoverIntent.timeout,out:function(event){inactivate(event);$this.unbind('mousemove.cluetip');}});}else{$this.bind('mouseenter.cluetip',function(event){activate(event);mouseTracks(event);}).bind('mouseleave.cluetip',function(event){inactivate(event);$this.unbind('mousemove.cluetip');});}
631.60 +$this.bind('mouseover.cluetip',function(event){$this.attr('title','');}).bind('mouseleave.cluetip',function(event){$this.attr('title',$this.data('thisInfo').title);});}});};$.fn.cluetip.defaults={width:275,height:'auto',cluezIndex:97,positionBy:'auto',topOffset:15,leftOffset:15,local:false,localPrefix:null,hideLocal:true,attribute:'rel',titleAttribute:'title',splitTitle:'',escapeTitle:false,showTitle:true,cluetipClass:'default',hoverClass:'',waitImage:true,cursor:'help',arrows:false,dropShadow:true,dropShadowSteps:6,sticky:false,mouseOutClose:false,activation:'hover',clickThrough:false,tracking:false,delayedClose:0,closePosition:'top',closeText:'Close',truncate:0,fx:{open:'show',openSpeed:''},hoverIntent:{sensitivity:3,interval:50,timeout:0},onActivate:function(e){return true;},onShow:function(ct,ci){},onHide:function(ct,ci){},ajaxCache:true,ajaxProcess:function(data){data=data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm,'').replace(/<(link|meta)[^>]+>/g,'');return data;},ajaxSettings:{dataType:'html'},debug:false};var insertionType='appendTo',insertionElement='body';$.cluetip.setup=function(options){if(options&&options.insertionType&&(options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)){insertionType=options.insertionType;}
631.61 +if(options&&options.insertionElement){insertionElement=options.insertionElement;}};})(jQuery);
631.62 \ No newline at end of file
632.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
632.2 +++ b/web/static/js/cluetip-1.0.6/lib/jquery-1.3.2.js Mon Apr 26 11:16:23 2010 +0200
632.3 @@ -0,0 +1,4675 @@
632.4 +/*!
632.5 + * jQuery JavaScript Library v1.3.3pre
632.6 + * http://jquery.com/
632.7 + *
632.8 + * Copyright (c) 2009 John Resig
632.9 + * Dual licensed under the MIT and GPL licenses.
632.10 + * http://docs.jquery.com/License
632.11 + *
632.12 + * Date: 2021-06-04 13:36:23 -0400 (Thu, 04 Jun 2021)
632.13 + * Revision: 6372
632.14 + */
632.15 +(function(window, undefined){
632.16 +
632.17 +// Define a local copy of jQuery
632.18 +var jQuery = function( selector, context ) {
632.19 + // The jQuery object is actually just the init constructor 'enhanced'
632.20 + return arguments.length === 0 ?
632.21 + rootjQuery :
632.22 + new jQuery.fn.init( selector, context );
632.23 + },
632.24 +
632.25 + // Map over jQuery in case of overwrite
632.26 + _jQuery = window.jQuery,
632.27 +
632.28 + // Map over the $ in case of overwrite
632.29 + _$ = window.$,
632.30 +
632.31 + // A central reference to the root jQuery(document)
632.32 + rootjQuery,
632.33 +
632.34 + // A simple way to check for HTML strings or ID strings
632.35 + // (both of which we optimize for)
632.36 + quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
632.37 +
632.38 + // Is it a simple selector
632.39 + isSimple = /^.[^:#\[\.,]*$/,
632.40 +
632.41 + // Keep a UserAgent string for use with jQuery.browser
632.42 + userAgent = navigator.userAgent.toLowerCase(),
632.43 +
632.44 + // Save a reference to the core toString method
632.45 + toString = Object.prototype.toString;
632.46 +
632.47 +// Expose jQuery to the global object
632.48 +window.jQuery = window.$ = jQuery;
632.49 +
632.50 +jQuery.fn = jQuery.prototype = {
632.51 + init: function( selector, context ) {
632.52 + var match, elem, ret;
632.53 +
632.54 + // Handle $(""), $(null), or $(undefined)
632.55 + if ( !selector ) {
632.56 + this.length = 0;
632.57 + return this;
632.58 + }
632.59 +
632.60 + // Handle $(DOMElement)
632.61 + if ( selector.nodeType ) {
632.62 + this[0] = selector;
632.63 + this.length = 1;
632.64 + this.context = selector;
632.65 + return this;
632.66 + }
632.67 +
632.68 + // Handle HTML strings
632.69 + if ( typeof selector === "string" ) {
632.70 + // Are we dealing with HTML string or an ID?
632.71 + match = quickExpr.exec( selector );
632.72 +
632.73 + // Verify a match, and that no context was specified for #id
632.74 + if ( match && (match[1] || !context) ) {
632.75 +
632.76 + // HANDLE: $(html) -> $(array)
632.77 + if ( match[1] ) {
632.78 + selector = jQuery.clean( [ match[1] ], context );
632.79 +
632.80 + // HANDLE: $("#id")
632.81 + } else {
632.82 + elem = document.getElementById( match[3] );
632.83 +
632.84 + // Handle the case where IE and Opera return items
632.85 + // by name instead of ID
632.86 + if ( elem && elem.id !== match[3] ) {
632.87 + return rootjQuery.find( selector );
632.88 + }
632.89 +
632.90 + // Otherwise, we inject the element directly into the jQuery object
632.91 + ret = jQuery( elem || null );
632.92 + ret.context = document;
632.93 + ret.selector = selector;
632.94 + return ret;
632.95 + }
632.96 +
632.97 + // HANDLE: $(expr, $(...))
632.98 + } else if ( !context || context.jquery ) {
632.99 + return (context || rootjQuery).find( selector );
632.100 +
632.101 + // HANDLE: $(expr, context)
632.102 + // (which is just equivalent to: $(context).find(expr)
632.103 + } else {
632.104 + return jQuery( context ).find( selector );
632.105 + }
632.106 +
632.107 + // HANDLE: $(function)
632.108 + // Shortcut for document ready
632.109 + } else if ( jQuery.isFunction( selector ) ) {
632.110 + return rootjQuery.ready( selector );
632.111 + }
632.112 +
632.113 + // Make sure that old selector state is passed along
632.114 + if ( selector.selector && selector.context ) {
632.115 + this.selector = selector.selector;
632.116 + this.context = selector.context;
632.117 + }
632.118 +
632.119 + return this.setArray(jQuery.isArray( selector ) ?
632.120 + selector :
632.121 + jQuery.makeArray(selector));
632.122 + },
632.123 +
632.124 + // Start with an empty selector
632.125 + selector: "",
632.126 +
632.127 + // The current version of jQuery being used
632.128 + jquery: "1.3.3pre",
632.129 +
632.130 + // The number of elements contained in the matched element set
632.131 + size: function() {
632.132 + return this.length;
632.133 + },
632.134 +
632.135 + // Get the Nth element in the matched element set OR
632.136 + // Get the whole matched element set as a clean array
632.137 + get: function( num ) {
632.138 + return num == null ?
632.139 +
632.140 + // Return a 'clean' array
632.141 + Array.prototype.slice.call( this ) :
632.142 +
632.143 + // Return just the object
632.144 + this[ num ];
632.145 + },
632.146 +
632.147 + // Take an array of elements and push it onto the stack
632.148 + // (returning the new matched element set)
632.149 + pushStack: function( elems, name, selector ) {
632.150 + // Build a new jQuery matched element set
632.151 + var ret = jQuery( elems || null );
632.152 +
632.153 + // Add the old object onto the stack (as a reference)
632.154 + ret.prevObject = this;
632.155 +
632.156 + ret.context = this.context;
632.157 +
632.158 + if ( name === "find" ) {
632.159 + ret.selector = this.selector + (this.selector ? " " : "") + selector;
632.160 + } else if ( name ) {
632.161 + ret.selector = this.selector + "." + name + "(" + selector + ")";
632.162 + }
632.163 +
632.164 + // Return the newly-formed element set
632.165 + return ret;
632.166 + },
632.167 +
632.168 + // Force the current matched set of elements to become
632.169 + // the specified array of elements (destroying the stack in the process)
632.170 + // You should use pushStack() in order to do this, but maintain the stack
632.171 + setArray: function( elems ) {
632.172 + // Resetting the length to 0, then using the native Array push
632.173 + // is a super-fast way to populate an object with array-like properties
632.174 + this.length = 0;
632.175 + Array.prototype.push.apply( this, elems );
632.176 +
632.177 + return this;
632.178 + },
632.179 +
632.180 + // Execute a callback for every element in the matched set.
632.181 + // (You can seed the arguments with an array of args, but this is
632.182 + // only used internally.)
632.183 + each: function( callback, args ) {
632.184 + return jQuery.each( this, callback, args );
632.185 + },
632.186 +
632.187 + // Determine the position of an element within
632.188 + // the matched set of elements
632.189 + index: function( elem ) {
632.190 + if ( !elem || typeof elem === "string" ) {
632.191 + return jQuery.inArray( this[0],
632.192 + // If it receives a string, the selector is used
632.193 + // If it receives nothing, the siblings are used
632.194 + elem ? jQuery( elem ) : this.parent().children() );
632.195 + }
632.196 + // Locate the position of the desired element
632.197 + return jQuery.inArray(
632.198 + // If it receives a jQuery object, the first element is used
632.199 + elem.jquery ? elem[0] : elem, this );
632.200 + },
632.201 +
632.202 + is: function( selector ) {
632.203 + return !!selector && jQuery.multiFilter( selector, this ).length > 0;
632.204 + },
632.205 +
632.206 + // For internal use only.
632.207 + // Behaves like an Array's method, not like a jQuery method.
632.208 + push: [].push,
632.209 + sort: [].sort,
632.210 + splice: [].splice
632.211 +};
632.212 +
632.213 +// Give the init function the jQuery prototype for later instantiation
632.214 +jQuery.fn.init.prototype = jQuery.fn;
632.215 +
632.216 +jQuery.extend = jQuery.fn.extend = function() {
632.217 + // copy reference to target object
632.218 + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
632.219 +
632.220 + // Handle a deep copy situation
632.221 + if ( typeof target === "boolean" ) {
632.222 + deep = target;
632.223 + target = arguments[1] || {};
632.224 + // skip the boolean and the target
632.225 + i = 2;
632.226 + }
632.227 +
632.228 + // Handle case when target is a string or something (possible in deep copy)
632.229 + if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
632.230 + target = {};
632.231 + }
632.232 +
632.233 + // extend jQuery itself if only one argument is passed
632.234 + if ( length === i ) {
632.235 + target = this;
632.236 + --i;
632.237 + }
632.238 +
632.239 + for ( ; i < length; i++ ) {
632.240 + // Only deal with non-null/undefined values
632.241 + if ( (options = arguments[ i ]) != null ) {
632.242 + // Extend the base object
632.243 + for ( name in options ) {
632.244 + src = target[ name ];
632.245 + copy = options[ name ];
632.246 +
632.247 + // Prevent never-ending loop
632.248 + if ( target === copy ) {
632.249 + continue;
632.250 + }
632.251 +
632.252 + // Recurse if we're merging object values
632.253 + if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
632.254 + target[ name ] = jQuery.extend( deep,
632.255 + // Never move original objects, clone them
632.256 + src || ( copy.length != null ? [ ] : { } ), copy );
632.257 +
632.258 + // Don't bring in undefined values
632.259 + } else if ( copy !== undefined ) {
632.260 + target[ name ] = copy;
632.261 + }
632.262 + }
632.263 + }
632.264 + }
632.265 +
632.266 + // Return the modified object
632.267 + return target;
632.268 +};
632.269 +
632.270 +jQuery.extend({
632.271 + noConflict: function( deep ) {
632.272 + window.$ = _$;
632.273 +
632.274 + if ( deep ) {
632.275 + window.jQuery = _jQuery;
632.276 + }
632.277 +
632.278 + return jQuery;
632.279 + },
632.280 +
632.281 + // See test/unit/core.js for details concerning isFunction.
632.282 + // Since version 1.3, DOM methods and functions like alert
632.283 + // aren't supported. They return false on IE (#2968).
632.284 + isFunction: function( obj ) {
632.285 + return toString.call(obj) === "[object Function]";
632.286 + },
632.287 +
632.288 + isArray: function( obj ) {
632.289 + return toString.call(obj) === "[object Array]";
632.290 + },
632.291 +
632.292 + // check if an element is in a (or is an) XML document
632.293 + isXMLDoc: function( elem ) {
632.294 + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
632.295 + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
632.296 + },
632.297 +
632.298 + // Evalulates a script in a global context
632.299 + globalEval: function( data ) {
632.300 + if ( data && /\S/.test(data) ) {
632.301 + // Inspired by code by Andrea Giammarchi
632.302 + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
632.303 + var head = document.getElementsByTagName("head")[0] || document.documentElement,
632.304 + script = document.createElement("script");
632.305 +
632.306 + script.type = "text/javascript";
632.307 + if ( jQuery.support.scriptEval ) {
632.308 + script.appendChild( document.createTextNode( data ) );
632.309 + } else {
632.310 + script.text = data;
632.311 + }
632.312 +
632.313 + // Use insertBefore instead of appendChild to circumvent an IE6 bug.
632.314 + // This arises when a base node is used (#2709).
632.315 + head.insertBefore( script, head.firstChild );
632.316 + head.removeChild( script );
632.317 + }
632.318 + },
632.319 +
632.320 + nodeName: function( elem, name ) {
632.321 + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
632.322 + },
632.323 +
632.324 + // args is for internal usage only
632.325 + each: function( object, callback, args ) {
632.326 + var name, i = 0, length = object.length;
632.327 +
632.328 + if ( args ) {
632.329 + if ( length === undefined ) {
632.330 + for ( name in object ) {
632.331 + if ( callback.apply( object[ name ], args ) === false ) {
632.332 + break;
632.333 + }
632.334 + }
632.335 + } else {
632.336 + for ( ; i < length; ) {
632.337 + if ( callback.apply( object[ i++ ], args ) === false ) {
632.338 + break;
632.339 + }
632.340 + }
632.341 + }
632.342 +
632.343 + // A special, fast, case for the most common use of each
632.344 + } else {
632.345 + if ( length === undefined ) {
632.346 + for ( name in object ) {
632.347 + if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
632.348 + break;
632.349 + }
632.350 + }
632.351 + } else {
632.352 + for ( var value = object[0];
632.353 + i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
632.354 + }
632.355 + }
632.356 +
632.357 + return object;
632.358 + },
632.359 +
632.360 + trim: function( text ) {
632.361 + return (text || "").replace( /^\s+|\s+$/g, "" );
632.362 + },
632.363 +
632.364 + makeArray: function( array ) {
632.365 + var ret = [], i;
632.366 +
632.367 + if ( array != null ) {
632.368 + i = array.length;
632.369 +
632.370 + // The window, strings (and functions) also have 'length'
632.371 + if ( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval ) {
632.372 + ret[0] = array;
632.373 + } else {
632.374 + while ( i ) {
632.375 + ret[--i] = array[i];
632.376 + }
632.377 + }
632.378 + }
632.379 +
632.380 + return ret;
632.381 + },
632.382 +
632.383 + inArray: function( elem, array ) {
632.384 + for ( var i = 0, length = array.length; i < length; i++ ) {
632.385 + if ( array[ i ] === elem ) {
632.386 + return i;
632.387 + }
632.388 + }
632.389 +
632.390 + return -1;
632.391 + },
632.392 +
632.393 + merge: function( first, second ) {
632.394 + // We have to loop this way because IE & Opera overwrite the length
632.395 + // expando of getElementsByTagName
632.396 + var i = 0, elem, pos = first.length;
632.397 +
632.398 + // Also, we need to make sure that the correct elements are being returned
632.399 + // (IE returns comment nodes in a '*' query)
632.400 + if ( !jQuery.support.getAll ) {
632.401 + while ( (elem = second[ i++ ]) != null ) {
632.402 + if ( elem.nodeType !== 8 ) {
632.403 + first[ pos++ ] = elem;
632.404 + }
632.405 + }
632.406 +
632.407 + } else {
632.408 + while ( (elem = second[ i++ ]) != null ) {
632.409 + first[ pos++ ] = elem;
632.410 + }
632.411 + }
632.412 +
632.413 + return first;
632.414 + },
632.415 +
632.416 + unique: function( array ) {
632.417 + var ret = [], done = {}, id;
632.418 +
632.419 + try {
632.420 + for ( var i = 0, length = array.length; i < length; i++ ) {
632.421 + id = jQuery.data( array[ i ] );
632.422 +
632.423 + if ( !done[ id ] ) {
632.424 + done[ id ] = true;
632.425 + ret.push( array[ i ] );
632.426 + }
632.427 + }
632.428 + } catch( e ) {
632.429 + ret = array;
632.430 + }
632.431 +
632.432 + return ret;
632.433 + },
632.434 +
632.435 + grep: function( elems, callback, inv ) {
632.436 + var ret = [];
632.437 +
632.438 + // Go through the array, only saving the items
632.439 + // that pass the validator function
632.440 + for ( var i = 0, length = elems.length; i < length; i++ ) {
632.441 + if ( !inv !== !callback( elems[ i ], i ) ) {
632.442 + ret.push( elems[ i ] );
632.443 + }
632.444 + }
632.445 +
632.446 + return ret;
632.447 + },
632.448 +
632.449 + map: function( elems, callback ) {
632.450 + var ret = [], value;
632.451 +
632.452 + // Go through the array, translating each of the items to their
632.453 + // new value (or values).
632.454 + for ( var i = 0, length = elems.length; i < length; i++ ) {
632.455 + value = callback( elems[ i ], i );
632.456 +
632.457 + if ( value != null ) {
632.458 + ret[ ret.length ] = value;
632.459 + }
632.460 + }
632.461 +
632.462 + return ret.concat.apply( [], ret );
632.463 + },
632.464 +
632.465 + // Use of jQuery.browser is deprecated.
632.466 + // It's included for backwards compatibility and plugins,
632.467 + // although they should work to migrate away.
632.468 + browser: {
632.469 + version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
632.470 + safari: /webkit/.test( userAgent ),
632.471 + opera: /opera/.test( userAgent ),
632.472 + msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
632.473 + mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
632.474 + }
632.475 +});
632.476 +
632.477 +// All jQuery objects should point back to these
632.478 +rootjQuery = jQuery(document);
632.479 +
632.480 +function evalScript( i, elem ) {
632.481 + if ( elem.src ) {
632.482 + jQuery.ajax({
632.483 + url: elem.src,
632.484 + async: false,
632.485 + dataType: "script"
632.486 + });
632.487 + } else {
632.488 + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
632.489 + }
632.490 +
632.491 + if ( elem.parentNode ) {
632.492 + elem.parentNode.removeChild( elem );
632.493 + }
632.494 +}
632.495 +
632.496 +function now() {
632.497 + return (new Date).getTime();
632.498 +}
632.499 +var expando = "jQuery" + now(), uuid = 0, windowData = {};
632.500 +
632.501 +jQuery.extend({
632.502 + cache: {},
632.503 +
632.504 + data: function( elem, name, data ) {
632.505 + elem = elem == window ?
632.506 + windowData :
632.507 + elem;
632.508 +
632.509 + var id = elem[ expando ];
632.510 +
632.511 + // Compute a unique ID for the element
632.512 + if ( !id )
632.513 + id = elem[ expando ] = ++uuid;
632.514 +
632.515 + // Only generate the data cache if we're
632.516 + // trying to access or manipulate it
632.517 + if ( name && !jQuery.cache[ id ] )
632.518 + jQuery.cache[ id ] = {};
632.519 +
632.520 + // Prevent overriding the named cache with undefined values
632.521 + if ( data !== undefined )
632.522 + jQuery.cache[ id ][ name ] = data;
632.523 +
632.524 + // Return the named cache data, or the ID for the element
632.525 + return name ?
632.526 + jQuery.cache[ id ][ name ] :
632.527 + id;
632.528 + },
632.529 +
632.530 + removeData: function( elem, name ) {
632.531 + elem = elem == window ?
632.532 + windowData :
632.533 + elem;
632.534 +
632.535 + var id = elem[ expando ];
632.536 +
632.537 + // If we want to remove a specific section of the element's data
632.538 + if ( name ) {
632.539 + if ( jQuery.cache[ id ] ) {
632.540 + // Remove the section of cache data
632.541 + delete jQuery.cache[ id ][ name ];
632.542 +
632.543 + // If we've removed all the data, remove the element's cache
632.544 + name = "";
632.545 +
632.546 + for ( name in jQuery.cache[ id ] )
632.547 + break;
632.548 +
632.549 + if ( !name )
632.550 + jQuery.removeData( elem );
632.551 + }
632.552 +
632.553 + // Otherwise, we want to remove all of the element's data
632.554 + } else {
632.555 + // Clean up the element expando
632.556 + try {
632.557 + delete elem[ expando ];
632.558 + } catch(e){
632.559 + // IE has trouble directly removing the expando
632.560 + // but it's ok with using removeAttribute
632.561 + if ( elem.removeAttribute )
632.562 + elem.removeAttribute( expando );
632.563 + }
632.564 +
632.565 + // Completely remove the data cache
632.566 + delete jQuery.cache[ id ];
632.567 + }
632.568 + },
632.569 + queue: function( elem, type, data ) {
632.570 + if ( elem ){
632.571 +
632.572 + type = (type || "fx") + "queue";
632.573 +
632.574 + var q = jQuery.data( elem, type );
632.575 +
632.576 + if ( !q || jQuery.isArray(data) )
632.577 + q = jQuery.data( elem, type, jQuery.makeArray(data) );
632.578 + else if( data )
632.579 + q.push( data );
632.580 +
632.581 + }
632.582 + return q;
632.583 + },
632.584 +
632.585 + dequeue: function( elem, type ){
632.586 + var queue = jQuery.queue( elem, type ),
632.587 + fn = queue.shift();
632.588 +
632.589 + if( !type || type === "fx" )
632.590 + fn = queue[0];
632.591 +
632.592 + if( fn !== undefined )
632.593 + fn.call(elem);
632.594 + }
632.595 +});
632.596 +
632.597 +jQuery.fn.extend({
632.598 + data: function( key, value ){
632.599 + var parts = key.split(".");
632.600 + parts[1] = parts[1] ? "." + parts[1] : "";
632.601 +
632.602 + if ( value === undefined ) {
632.603 + var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
632.604 +
632.605 + if ( data === undefined && this.length )
632.606 + data = jQuery.data( this[0], key );
632.607 +
632.608 + return data === undefined && parts[1] ?
632.609 + this.data( parts[0] ) :
632.610 + data;
632.611 + } else
632.612 + return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
632.613 + jQuery.data( this, key, value );
632.614 + });
632.615 + },
632.616 +
632.617 + removeData: function( key ){
632.618 + return this.each(function(){
632.619 + jQuery.removeData( this, key );
632.620 + });
632.621 + },
632.622 + queue: function(type, data){
632.623 + if ( typeof type !== "string" ) {
632.624 + data = type;
632.625 + type = "fx";
632.626 + }
632.627 +
632.628 + if ( data === undefined )
632.629 + return jQuery.queue( this[0], type );
632.630 +
632.631 + return this.each(function(){
632.632 + var queue = jQuery.queue( this, type, data );
632.633 +
632.634 + if( type == "fx" && queue.length == 1 )
632.635 + queue[0].call(this);
632.636 + });
632.637 + },
632.638 + dequeue: function(type){
632.639 + return this.each(function(){
632.640 + jQuery.dequeue( this, type );
632.641 + });
632.642 + }
632.643 +});/*!
632.644 + * Sizzle CSS Selector Engine - v1.0
632.645 + * Copyright 2009, The Dojo Foundation
632.646 + * Released under the MIT, BSD, and GPL Licenses.
632.647 + * More information: http://sizzlejs.com/
632.648 + */
632.649 +(function(){
632.650 +
632.651 +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
632.652 + done = 0,
632.653 + toString = Object.prototype.toString,
632.654 + hasDuplicate = false;
632.655 +
632.656 +var Sizzle = function(selector, context, results, seed) {
632.657 + results = results || [];
632.658 + var origContext = context = context || document;
632.659 +
632.660 + if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
632.661 + return [];
632.662 + }
632.663 +
632.664 + if ( !selector || typeof selector !== "string" ) {
632.665 + return results;
632.666 + }
632.667 +
632.668 + var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context);
632.669 +
632.670 + // Reset the position of the chunker regexp (start from head)
632.671 + chunker.lastIndex = 0;
632.672 +
632.673 + while ( (m = chunker.exec(selector)) !== null ) {
632.674 + parts.push( m[1] );
632.675 +
632.676 + if ( m[2] ) {
632.677 + extra = RegExp.rightContext;
632.678 + break;
632.679 + }
632.680 + }
632.681 +
632.682 + if ( parts.length > 1 && origPOS.exec( selector ) ) {
632.683 + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
632.684 + set = posProcess( parts[0] + parts[1], context );
632.685 + } else {
632.686 + set = Expr.relative[ parts[0] ] ?
632.687 + [ context ] :
632.688 + Sizzle( parts.shift(), context );
632.689 +
632.690 + while ( parts.length ) {
632.691 + selector = parts.shift();
632.692 +
632.693 + if ( Expr.relative[ selector ] )
632.694 + selector += parts.shift();
632.695 +
632.696 + set = posProcess( selector, set );
632.697 + }
632.698 + }
632.699 + } else {
632.700 + // Take a shortcut and set the context if the root selector is an ID
632.701 + // (but not if it'll be faster if the inner selector is an ID)
632.702 + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
632.703 + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
632.704 + var ret = Sizzle.find( parts.shift(), context, contextXML );
632.705 + context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
632.706 + }
632.707 +
632.708 + if ( context ) {
632.709 + var ret = seed ?
632.710 + { expr: parts.pop(), set: makeArray(seed) } :
632.711 + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
632.712 + set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
632.713 +
632.714 + if ( parts.length > 0 ) {
632.715 + checkSet = makeArray(set);
632.716 + } else {
632.717 + prune = false;
632.718 + }
632.719 +
632.720 + while ( parts.length ) {
632.721 + var cur = parts.pop(), pop = cur;
632.722 +
632.723 + if ( !Expr.relative[ cur ] ) {
632.724 + cur = "";
632.725 + } else {
632.726 + pop = parts.pop();
632.727 + }
632.728 +
632.729 + if ( pop == null ) {
632.730 + pop = context;
632.731 + }
632.732 +
632.733 + Expr.relative[ cur ]( checkSet, pop, contextXML );
632.734 + }
632.735 + } else {
632.736 + checkSet = parts = [];
632.737 + }
632.738 + }
632.739 +
632.740 + if ( !checkSet ) {
632.741 + checkSet = set;
632.742 + }
632.743 +
632.744 + if ( !checkSet ) {
632.745 + throw "Syntax error, unrecognized expression: " + (cur || selector);
632.746 + }
632.747 +
632.748 + if ( toString.call(checkSet) === "[object Array]" ) {
632.749 + if ( !prune ) {
632.750 + results.push.apply( results, checkSet );
632.751 + } else if ( context && context.nodeType === 1 ) {
632.752 + for ( var i = 0; checkSet[i] != null; i++ ) {
632.753 + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
632.754 + results.push( set[i] );
632.755 + }
632.756 + }
632.757 + } else {
632.758 + for ( var i = 0; checkSet[i] != null; i++ ) {
632.759 + if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
632.760 + results.push( set[i] );
632.761 + }
632.762 + }
632.763 + }
632.764 + } else {
632.765 + makeArray( checkSet, results );
632.766 + }
632.767 +
632.768 + if ( extra ) {
632.769 + Sizzle( extra, origContext, results, seed );
632.770 + Sizzle.uniqueSort( results );
632.771 + }
632.772 +
632.773 + return results;
632.774 +};
632.775 +
632.776 +Sizzle.uniqueSort = function(results){
632.777 + if ( sortOrder ) {
632.778 + hasDuplicate = false;
632.779 + results.sort(sortOrder);
632.780 +
632.781 + if ( hasDuplicate ) {
632.782 + for ( var i = 1; i < results.length; i++ ) {
632.783 + if ( results[i] === results[i-1] ) {
632.784 + results.splice(i--, 1);
632.785 + }
632.786 + }
632.787 + }
632.788 + }
632.789 +};
632.790 +
632.791 +Sizzle.matches = function(expr, set){
632.792 + return Sizzle(expr, null, null, set);
632.793 +};
632.794 +
632.795 +Sizzle.find = function(expr, context, isXML){
632.796 + var set, match;
632.797 +
632.798 + if ( !expr ) {
632.799 + return [];
632.800 + }
632.801 +
632.802 + for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
632.803 + var type = Expr.order[i], match;
632.804 +
632.805 + if ( (match = Expr.match[ type ].exec( expr )) ) {
632.806 + var left = RegExp.leftContext;
632.807 +
632.808 + if ( left.substr( left.length - 1 ) !== "\\" ) {
632.809 + match[1] = (match[1] || "").replace(/\\/g, "");
632.810 + set = Expr.find[ type ]( match, context, isXML );
632.811 + if ( set != null ) {
632.812 + expr = expr.replace( Expr.match[ type ], "" );
632.813 + break;
632.814 + }
632.815 + }
632.816 + }
632.817 + }
632.818 +
632.819 + if ( !set ) {
632.820 + set = context.getElementsByTagName("*");
632.821 + }
632.822 +
632.823 + return {set: set, expr: expr};
632.824 +};
632.825 +
632.826 +Sizzle.filter = function(expr, set, inplace, not){
632.827 + var old = expr, result = [], curLoop = set, match, anyFound,
632.828 + isXMLFilter = set && set[0] && isXML(set[0]);
632.829 +
632.830 + while ( expr && set.length ) {
632.831 + for ( var type in Expr.filter ) {
632.832 + if ( (match = Expr.match[ type ].exec( expr )) != null ) {
632.833 + var filter = Expr.filter[ type ], found, item;
632.834 + anyFound = false;
632.835 +
632.836 + if ( curLoop == result ) {
632.837 + result = [];
632.838 + }
632.839 +
632.840 + if ( Expr.preFilter[ type ] ) {
632.841 + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
632.842 +
632.843 + if ( !match ) {
632.844 + anyFound = found = true;
632.845 + } else if ( match === true ) {
632.846 + continue;
632.847 + }
632.848 + }
632.849 +
632.850 + if ( match ) {
632.851 + for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
632.852 + if ( item ) {
632.853 + found = filter( item, match, i, curLoop );
632.854 + var pass = not ^ !!found;
632.855 +
632.856 + if ( inplace && found != null ) {
632.857 + if ( pass ) {
632.858 + anyFound = true;
632.859 + } else {
632.860 + curLoop[i] = false;
632.861 + }
632.862 + } else if ( pass ) {
632.863 + result.push( item );
632.864 + anyFound = true;
632.865 + }
632.866 + }
632.867 + }
632.868 + }
632.869 +
632.870 + if ( found !== undefined ) {
632.871 + if ( !inplace ) {
632.872 + curLoop = result;
632.873 + }
632.874 +
632.875 + expr = expr.replace( Expr.match[ type ], "" );
632.876 +
632.877 + if ( !anyFound ) {
632.878 + return [];
632.879 + }
632.880 +
632.881 + break;
632.882 + }
632.883 + }
632.884 + }
632.885 +
632.886 + // Improper expression
632.887 + if ( expr == old ) {
632.888 + if ( anyFound == null ) {
632.889 + throw "Syntax error, unrecognized expression: " + expr;
632.890 + } else {
632.891 + break;
632.892 + }
632.893 + }
632.894 +
632.895 + old = expr;
632.896 + }
632.897 +
632.898 + return curLoop;
632.899 +};
632.900 +
632.901 +var Expr = Sizzle.selectors = {
632.902 + order: [ "ID", "NAME", "TAG" ],
632.903 + match: {
632.904 + ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
632.905 + CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
632.906 + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
632.907 + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
632.908 + TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
632.909 + CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
632.910 + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
632.911 + PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
632.912 + },
632.913 + attrMap: {
632.914 + "class": "className",
632.915 + "for": "htmlFor"
632.916 + },
632.917 + attrHandle: {
632.918 + href: function(elem){
632.919 + return elem.getAttribute("href");
632.920 + }
632.921 + },
632.922 + relative: {
632.923 + "+": function(checkSet, part, isXML){
632.924 + var isPartStr = typeof part === "string",
632.925 + isTag = isPartStr && !/\W/.test(part),
632.926 + isPartStrNotTag = isPartStr && !isTag;
632.927 +
632.928 + if ( isTag && !isXML ) {
632.929 + part = part.toUpperCase();
632.930 + }
632.931 +
632.932 + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
632.933 + if ( (elem = checkSet[i]) ) {
632.934 + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
632.935 +
632.936 + checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
632.937 + elem || false :
632.938 + elem === part;
632.939 + }
632.940 + }
632.941 +
632.942 + if ( isPartStrNotTag ) {
632.943 + Sizzle.filter( part, checkSet, true );
632.944 + }
632.945 + },
632.946 + ">": function(checkSet, part, isXML){
632.947 + var isPartStr = typeof part === "string";
632.948 +
632.949 + if ( isPartStr && !/\W/.test(part) ) {
632.950 + part = isXML ? part : part.toUpperCase();
632.951 +
632.952 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
632.953 + var elem = checkSet[i];
632.954 + if ( elem ) {
632.955 + var parent = elem.parentNode;
632.956 + checkSet[i] = parent.nodeName === part ? parent : false;
632.957 + }
632.958 + }
632.959 + } else {
632.960 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
632.961 + var elem = checkSet[i];
632.962 + if ( elem ) {
632.963 + checkSet[i] = isPartStr ?
632.964 + elem.parentNode :
632.965 + elem.parentNode === part;
632.966 + }
632.967 + }
632.968 +
632.969 + if ( isPartStr ) {
632.970 + Sizzle.filter( part, checkSet, true );
632.971 + }
632.972 + }
632.973 + },
632.974 + "": function(checkSet, part, isXML){
632.975 + var doneName = done++, checkFn = dirCheck;
632.976 +
632.977 + if ( !part.match(/\W/) ) {
632.978 + var nodeCheck = part = isXML ? part : part.toUpperCase();
632.979 + checkFn = dirNodeCheck;
632.980 + }
632.981 +
632.982 + checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
632.983 + },
632.984 + "~": function(checkSet, part, isXML){
632.985 + var doneName = done++, checkFn = dirCheck;
632.986 +
632.987 + if ( typeof part === "string" && !part.match(/\W/) ) {
632.988 + var nodeCheck = part = isXML ? part : part.toUpperCase();
632.989 + checkFn = dirNodeCheck;
632.990 + }
632.991 +
632.992 + checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
632.993 + }
632.994 + },
632.995 + find: {
632.996 + ID: function(match, context, isXML){
632.997 + if ( typeof context.getElementById !== "undefined" && !isXML ) {
632.998 + var m = context.getElementById(match[1]);
632.999 + return m ? [m] : [];
632.1000 + }
632.1001 + },
632.1002 + NAME: function(match, context, isXML){
632.1003 + if ( typeof context.getElementsByName !== "undefined" ) {
632.1004 + var ret = [], results = context.getElementsByName(match[1]);
632.1005 +
632.1006 + for ( var i = 0, l = results.length; i < l; i++ ) {
632.1007 + if ( results[i].getAttribute("name") === match[1] ) {
632.1008 + ret.push( results[i] );
632.1009 + }
632.1010 + }
632.1011 +
632.1012 + return ret.length === 0 ? null : ret;
632.1013 + }
632.1014 + },
632.1015 + TAG: function(match, context){
632.1016 + return context.getElementsByTagName(match[1]);
632.1017 + }
632.1018 + },
632.1019 + preFilter: {
632.1020 + CLASS: function(match, curLoop, inplace, result, not, isXML){
632.1021 + match = " " + match[1].replace(/\\/g, "") + " ";
632.1022 +
632.1023 + if ( isXML ) {
632.1024 + return match;
632.1025 + }
632.1026 +
632.1027 + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
632.1028 + if ( elem ) {
632.1029 + if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
632.1030 + if ( !inplace )
632.1031 + result.push( elem );
632.1032 + } else if ( inplace ) {
632.1033 + curLoop[i] = false;
632.1034 + }
632.1035 + }
632.1036 + }
632.1037 +
632.1038 + return false;
632.1039 + },
632.1040 + ID: function(match){
632.1041 + return match[1].replace(/\\/g, "");
632.1042 + },
632.1043 + TAG: function(match, curLoop){
632.1044 + for ( var i = 0; curLoop[i] === false; i++ ){}
632.1045 + return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
632.1046 + },
632.1047 + CHILD: function(match){
632.1048 + if ( match[1] == "nth" ) {
632.1049 + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
632.1050 + var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
632.1051 + match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
632.1052 + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
632.1053 +
632.1054 + // calculate the numbers (first)n+(last) including if they are negative
632.1055 + match[2] = (test[1] + (test[2] || 1)) - 0;
632.1056 + match[3] = test[3] - 0;
632.1057 + }
632.1058 +
632.1059 + // TODO: Move to normal caching system
632.1060 + match[0] = done++;
632.1061 +
632.1062 + return match;
632.1063 + },
632.1064 + ATTR: function(match, curLoop, inplace, result, not, isXML){
632.1065 + var name = match[1].replace(/\\/g, "");
632.1066 +
632.1067 + if ( !isXML && Expr.attrMap[name] ) {
632.1068 + match[1] = Expr.attrMap[name];
632.1069 + }
632.1070 +
632.1071 + if ( match[2] === "~=" ) {
632.1072 + match[4] = " " + match[4] + " ";
632.1073 + }
632.1074 +
632.1075 + return match;
632.1076 + },
632.1077 + PSEUDO: function(match, curLoop, inplace, result, not){
632.1078 + if ( match[1] === "not" ) {
632.1079 + // If we're dealing with a complex expression, or a simple one
632.1080 + if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
632.1081 + match[3] = Sizzle(match[3], null, null, curLoop);
632.1082 + } else {
632.1083 + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
632.1084 + if ( !inplace ) {
632.1085 + result.push.apply( result, ret );
632.1086 + }
632.1087 + return false;
632.1088 + }
632.1089 + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
632.1090 + return true;
632.1091 + }
632.1092 +
632.1093 + return match;
632.1094 + },
632.1095 + POS: function(match){
632.1096 + match.unshift( true );
632.1097 + return match;
632.1098 + }
632.1099 + },
632.1100 + filters: {
632.1101 + enabled: function(elem){
632.1102 + return elem.disabled === false && elem.type !== "hidden";
632.1103 + },
632.1104 + disabled: function(elem){
632.1105 + return elem.disabled === true;
632.1106 + },
632.1107 + checked: function(elem){
632.1108 + return elem.checked === true;
632.1109 + },
632.1110 + selected: function(elem){
632.1111 + // Accessing this property makes selected-by-default
632.1112 + // options in Safari work properly
632.1113 + elem.parentNode.selectedIndex;
632.1114 + return elem.selected === true;
632.1115 + },
632.1116 + parent: function(elem){
632.1117 + return !!elem.firstChild;
632.1118 + },
632.1119 + empty: function(elem){
632.1120 + return !elem.firstChild;
632.1121 + },
632.1122 + has: function(elem, i, match){
632.1123 + return !!Sizzle( match[3], elem ).length;
632.1124 + },
632.1125 + header: function(elem){
632.1126 + return /h\d/i.test( elem.nodeName );
632.1127 + },
632.1128 + text: function(elem){
632.1129 + return "text" === elem.type;
632.1130 + },
632.1131 + radio: function(elem){
632.1132 + return "radio" === elem.type;
632.1133 + },
632.1134 + checkbox: function(elem){
632.1135 + return "checkbox" === elem.type;
632.1136 + },
632.1137 + file: function(elem){
632.1138 + return "file" === elem.type;
632.1139 + },
632.1140 + password: function(elem){
632.1141 + return "password" === elem.type;
632.1142 + },
632.1143 + submit: function(elem){
632.1144 + return "submit" === elem.type;
632.1145 + },
632.1146 + image: function(elem){
632.1147 + return "image" === elem.type;
632.1148 + },
632.1149 + reset: function(elem){
632.1150 + return "reset" === elem.type;
632.1151 + },
632.1152 + button: function(elem){
632.1153 + return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
632.1154 + },
632.1155 + input: function(elem){
632.1156 + return /input|select|textarea|button/i.test(elem.nodeName);
632.1157 + }
632.1158 + },
632.1159 + setFilters: {
632.1160 + first: function(elem, i){
632.1161 + return i === 0;
632.1162 + },
632.1163 + last: function(elem, i, match, array){
632.1164 + return i === array.length - 1;
632.1165 + },
632.1166 + even: function(elem, i){
632.1167 + return i % 2 === 0;
632.1168 + },
632.1169 + odd: function(elem, i){
632.1170 + return i % 2 === 1;
632.1171 + },
632.1172 + lt: function(elem, i, match){
632.1173 + return i < match[3] - 0;
632.1174 + },
632.1175 + gt: function(elem, i, match){
632.1176 + return i > match[3] - 0;
632.1177 + },
632.1178 + nth: function(elem, i, match){
632.1179 + return match[3] - 0 == i;
632.1180 + },
632.1181 + eq: function(elem, i, match){
632.1182 + return match[3] - 0 == i;
632.1183 + }
632.1184 + },
632.1185 + filter: {
632.1186 + PSEUDO: function(elem, match, i, array){
632.1187 + var name = match[1], filter = Expr.filters[ name ];
632.1188 +
632.1189 + if ( filter ) {
632.1190 + return filter( elem, i, match, array );
632.1191 + } else if ( name === "contains" ) {
632.1192 + return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
632.1193 + } else if ( name === "not" ) {
632.1194 + var not = match[3];
632.1195 +
632.1196 + for ( i = 0, l = not.length; i < l; i++ ) {
632.1197 + if ( not[i] === elem ) {
632.1198 + return false;
632.1199 + }
632.1200 + }
632.1201 +
632.1202 + return true;
632.1203 + }
632.1204 + },
632.1205 + CHILD: function(elem, match){
632.1206 + var type = match[1], node = elem;
632.1207 + switch (type) {
632.1208 + case 'only':
632.1209 + case 'first':
632.1210 + while ( (node = node.previousSibling) ) {
632.1211 + if ( node.nodeType === 1 ) return false;
632.1212 + }
632.1213 + if ( type == 'first') return true;
632.1214 + node = elem;
632.1215 + case 'last':
632.1216 + while ( (node = node.nextSibling) ) {
632.1217 + if ( node.nodeType === 1 ) return false;
632.1218 + }
632.1219 + return true;
632.1220 + case 'nth':
632.1221 + var first = match[2], last = match[3];
632.1222 +
632.1223 + if ( first == 1 && last == 0 ) {
632.1224 + return true;
632.1225 + }
632.1226 +
632.1227 + var doneName = match[0],
632.1228 + parent = elem.parentNode;
632.1229 +
632.1230 + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
632.1231 + var count = 0;
632.1232 + for ( node = parent.firstChild; node; node = node.nextSibling ) {
632.1233 + if ( node.nodeType === 1 ) {
632.1234 + node.nodeIndex = ++count;
632.1235 + }
632.1236 + }
632.1237 + parent.sizcache = doneName;
632.1238 + }
632.1239 +
632.1240 + var diff = elem.nodeIndex - last;
632.1241 + if ( first == 0 ) {
632.1242 + return diff == 0;
632.1243 + } else {
632.1244 + return ( diff % first == 0 && diff / first >= 0 );
632.1245 + }
632.1246 + }
632.1247 + },
632.1248 + ID: function(elem, match){
632.1249 + return elem.nodeType === 1 && elem.getAttribute("id") === match;
632.1250 + },
632.1251 + TAG: function(elem, match){
632.1252 + return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
632.1253 + },
632.1254 + CLASS: function(elem, match){
632.1255 + return (" " + (elem.className || elem.getAttribute("class")) + " ")
632.1256 + .indexOf( match ) > -1;
632.1257 + },
632.1258 + ATTR: function(elem, match){
632.1259 + var name = match[1],
632.1260 + result = Expr.attrHandle[ name ] ?
632.1261 + Expr.attrHandle[ name ]( elem ) :
632.1262 + elem[ name ] != null ?
632.1263 + elem[ name ] :
632.1264 + elem.getAttribute( name ),
632.1265 + value = result + "",
632.1266 + type = match[2],
632.1267 + check = match[4];
632.1268 +
632.1269 + return result == null ?
632.1270 + type === "!=" :
632.1271 + type === "=" ?
632.1272 + value === check :
632.1273 + type === "*=" ?
632.1274 + value.indexOf(check) >= 0 :
632.1275 + type === "~=" ?
632.1276 + (" " + value + " ").indexOf(check) >= 0 :
632.1277 + !check ?
632.1278 + value && result !== false :
632.1279 + type === "!=" ?
632.1280 + value != check :
632.1281 + type === "^=" ?
632.1282 + value.indexOf(check) === 0 :
632.1283 + type === "$=" ?
632.1284 + value.substr(value.length - check.length) === check :
632.1285 + type === "|=" ?
632.1286 + value === check || value.substr(0, check.length + 1) === check + "-" :
632.1287 + false;
632.1288 + },
632.1289 + POS: function(elem, match, i, array){
632.1290 + var name = match[2], filter = Expr.setFilters[ name ];
632.1291 +
632.1292 + if ( filter ) {
632.1293 + return filter( elem, i, match, array );
632.1294 + }
632.1295 + }
632.1296 + }
632.1297 +};
632.1298 +
632.1299 +var origPOS = Expr.match.POS;
632.1300 +
632.1301 +for ( var type in Expr.match ) {
632.1302 + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
632.1303 +}
632.1304 +
632.1305 +var makeArray = function(array, results) {
632.1306 + array = Array.prototype.slice.call( array );
632.1307 +
632.1308 + if ( results ) {
632.1309 + results.push.apply( results, array );
632.1310 + return results;
632.1311 + }
632.1312 +
632.1313 + return array;
632.1314 +};
632.1315 +
632.1316 +// Perform a simple check to determine if the browser is capable of
632.1317 +// converting a NodeList to an array using builtin methods.
632.1318 +try {
632.1319 + Array.prototype.slice.call( document.documentElement.childNodes );
632.1320 +
632.1321 +// Provide a fallback method if it does not work
632.1322 +} catch(e){
632.1323 + makeArray = function(array, results) {
632.1324 + var ret = results || [];
632.1325 +
632.1326 + if ( toString.call(array) === "[object Array]" ) {
632.1327 + Array.prototype.push.apply( ret, array );
632.1328 + } else {
632.1329 + if ( typeof array.length === "number" ) {
632.1330 + for ( var i = 0, l = array.length; i < l; i++ ) {
632.1331 + ret.push( array[i] );
632.1332 + }
632.1333 + } else {
632.1334 + for ( var i = 0; array[i]; i++ ) {
632.1335 + ret.push( array[i] );
632.1336 + }
632.1337 + }
632.1338 + }
632.1339 +
632.1340 + return ret;
632.1341 + };
632.1342 +}
632.1343 +
632.1344 +var sortOrder;
632.1345 +
632.1346 +if ( document.documentElement.compareDocumentPosition ) {
632.1347 + sortOrder = function( a, b ) {
632.1348 + var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
632.1349 + if ( ret === 0 ) {
632.1350 + hasDuplicate = true;
632.1351 + }
632.1352 + return ret;
632.1353 + };
632.1354 +} else if ( "sourceIndex" in document.documentElement ) {
632.1355 + sortOrder = function( a, b ) {
632.1356 + var ret = a.sourceIndex - b.sourceIndex;
632.1357 + if ( ret === 0 ) {
632.1358 + hasDuplicate = true;
632.1359 + }
632.1360 + return ret;
632.1361 + };
632.1362 +} else if ( document.createRange ) {
632.1363 + sortOrder = function( a, b ) {
632.1364 + var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
632.1365 + aRange.selectNode(a);
632.1366 + aRange.collapse(true);
632.1367 + bRange.selectNode(b);
632.1368 + bRange.collapse(true);
632.1369 + var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
632.1370 + if ( ret === 0 ) {
632.1371 + hasDuplicate = true;
632.1372 + }
632.1373 + return ret;
632.1374 + };
632.1375 +}
632.1376 +
632.1377 +// Check to see if the browser returns elements by name when
632.1378 +// querying by getElementById (and provide a workaround)
632.1379 +(function(){
632.1380 + // We're going to inject a fake input element with a specified name
632.1381 + var form = document.createElement("div"),
632.1382 + id = "script" + (new Date).getTime();
632.1383 + form.innerHTML = "<a name='" + id + "'/>";
632.1384 +
632.1385 + // Inject it into the root element, check its status, and remove it quickly
632.1386 + var root = document.documentElement;
632.1387 + root.insertBefore( form, root.firstChild );
632.1388 +
632.1389 + // The workaround has to do additional checks after a getElementById
632.1390 + // Which slows things down for other browsers (hence the branching)
632.1391 + if ( !!document.getElementById( id ) ) {
632.1392 + Expr.find.ID = function(match, context, isXML){
632.1393 + if ( typeof context.getElementById !== "undefined" && !isXML ) {
632.1394 + var m = context.getElementById(match[1]);
632.1395 + return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
632.1396 + }
632.1397 + };
632.1398 +
632.1399 + Expr.filter.ID = function(elem, match){
632.1400 + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
632.1401 + return elem.nodeType === 1 && node && node.nodeValue === match;
632.1402 + };
632.1403 + }
632.1404 +
632.1405 + root.removeChild( form );
632.1406 + root = form = null; // release memory in IE
632.1407 +})();
632.1408 +
632.1409 +(function(){
632.1410 + // Check to see if the browser returns only elements
632.1411 + // when doing getElementsByTagName("*")
632.1412 +
632.1413 + // Create a fake element
632.1414 + var div = document.createElement("div");
632.1415 + div.appendChild( document.createComment("") );
632.1416 +
632.1417 + // Make sure no comments are found
632.1418 + if ( div.getElementsByTagName("*").length > 0 ) {
632.1419 + Expr.find.TAG = function(match, context){
632.1420 + var results = context.getElementsByTagName(match[1]);
632.1421 +
632.1422 + // Filter out possible comments
632.1423 + if ( match[1] === "*" ) {
632.1424 + var tmp = [];
632.1425 +
632.1426 + for ( var i = 0; results[i]; i++ ) {
632.1427 + if ( results[i].nodeType === 1 ) {
632.1428 + tmp.push( results[i] );
632.1429 + }
632.1430 + }
632.1431 +
632.1432 + results = tmp;
632.1433 + }
632.1434 +
632.1435 + return results;
632.1436 + };
632.1437 + }
632.1438 +
632.1439 + // Check to see if an attribute returns normalized href attributes
632.1440 + div.innerHTML = "<a href='#'></a>";
632.1441 + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
632.1442 + div.firstChild.getAttribute("href") !== "#" ) {
632.1443 + Expr.attrHandle.href = function(elem){
632.1444 + return elem.getAttribute("href", 2);
632.1445 + };
632.1446 + }
632.1447 +
632.1448 + div = null; // release memory in IE
632.1449 +})();
632.1450 +
632.1451 +if ( document.querySelectorAll ) (function(){
632.1452 + var oldSizzle = Sizzle, div = document.createElement("div");
632.1453 + div.innerHTML = "<p class='TEST'></p>";
632.1454 +
632.1455 + // Safari can't handle uppercase or unicode characters when
632.1456 + // in quirks mode.
632.1457 + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
632.1458 + return;
632.1459 + }
632.1460 +
632.1461 + Sizzle = function(query, context, extra, seed){
632.1462 + context = context || document;
632.1463 +
632.1464 + // Only use querySelectorAll on non-XML documents
632.1465 + // (ID selectors don't work in non-HTML documents)
632.1466 + if ( !seed && context.nodeType === 9 && !isXML(context) ) {
632.1467 + try {
632.1468 + return makeArray( context.querySelectorAll(query), extra );
632.1469 + } catch(e){}
632.1470 + }
632.1471 +
632.1472 + return oldSizzle(query, context, extra, seed);
632.1473 + };
632.1474 +
632.1475 + for ( var prop in oldSizzle ) {
632.1476 + Sizzle[ prop ] = oldSizzle[ prop ];
632.1477 + }
632.1478 +
632.1479 + div = null; // release memory in IE
632.1480 +})();
632.1481 +
632.1482 +if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
632.1483 + var div = document.createElement("div");
632.1484 + div.innerHTML = "<div class='test e'></div><div class='test'></div>";
632.1485 +
632.1486 + // Opera can't find a second classname (in 9.6)
632.1487 + if ( div.getElementsByClassName("e").length === 0 )
632.1488 + return;
632.1489 +
632.1490 + // Safari caches class attributes, doesn't catch changes (in 3.2)
632.1491 + div.lastChild.className = "e";
632.1492 +
632.1493 + if ( div.getElementsByClassName("e").length === 1 )
632.1494 + return;
632.1495 +
632.1496 + Expr.order.splice(1, 0, "CLASS");
632.1497 + Expr.find.CLASS = function(match, context, isXML) {
632.1498 + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
632.1499 + return context.getElementsByClassName(match[1]);
632.1500 + }
632.1501 + };
632.1502 +
632.1503 + div = null; // release memory in IE
632.1504 +})();
632.1505 +
632.1506 +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
632.1507 + var sibDir = dir == "previousSibling" && !isXML;
632.1508 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
632.1509 + var elem = checkSet[i];
632.1510 + if ( elem ) {
632.1511 + if ( sibDir && elem.nodeType === 1 ){
632.1512 + elem.sizcache = doneName;
632.1513 + elem.sizset = i;
632.1514 + }
632.1515 + elem = elem[dir];
632.1516 + var match = false;
632.1517 +
632.1518 + while ( elem ) {
632.1519 + if ( elem.sizcache === doneName ) {
632.1520 + match = checkSet[elem.sizset];
632.1521 + break;
632.1522 + }
632.1523 +
632.1524 + if ( elem.nodeType === 1 && !isXML ){
632.1525 + elem.sizcache = doneName;
632.1526 + elem.sizset = i;
632.1527 + }
632.1528 +
632.1529 + if ( elem.nodeName === cur ) {
632.1530 + match = elem;
632.1531 + break;
632.1532 + }
632.1533 +
632.1534 + elem = elem[dir];
632.1535 + }
632.1536 +
632.1537 + checkSet[i] = match;
632.1538 + }
632.1539 + }
632.1540 +}
632.1541 +
632.1542 +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
632.1543 + var sibDir = dir == "previousSibling" && !isXML;
632.1544 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
632.1545 + var elem = checkSet[i];
632.1546 + if ( elem ) {
632.1547 + if ( sibDir && elem.nodeType === 1 ) {
632.1548 + elem.sizcache = doneName;
632.1549 + elem.sizset = i;
632.1550 + }
632.1551 + elem = elem[dir];
632.1552 + var match = false;
632.1553 +
632.1554 + while ( elem ) {
632.1555 + if ( elem.sizcache === doneName ) {
632.1556 + match = checkSet[elem.sizset];
632.1557 + break;
632.1558 + }
632.1559 +
632.1560 + if ( elem.nodeType === 1 ) {
632.1561 + if ( !isXML ) {
632.1562 + elem.sizcache = doneName;
632.1563 + elem.sizset = i;
632.1564 + }
632.1565 + if ( typeof cur !== "string" ) {
632.1566 + if ( elem === cur ) {
632.1567 + match = true;
632.1568 + break;
632.1569 + }
632.1570 +
632.1571 + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
632.1572 + match = elem;
632.1573 + break;
632.1574 + }
632.1575 + }
632.1576 +
632.1577 + elem = elem[dir];
632.1578 + }
632.1579 +
632.1580 + checkSet[i] = match;
632.1581 + }
632.1582 + }
632.1583 +}
632.1584 +
632.1585 +var contains = document.compareDocumentPosition ? function(a, b){
632.1586 + return a.compareDocumentPosition(b) & 16;
632.1587 +} : function(a, b){
632.1588 + return a !== b && (a.contains ? a.contains(b) : true);
632.1589 +};
632.1590 +
632.1591 +var isXML = function(elem){
632.1592 + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
632.1593 + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
632.1594 +};
632.1595 +
632.1596 +var posProcess = function(selector, context){
632.1597 + var tmpSet = [], later = "", match,
632.1598 + root = context.nodeType ? [context] : context;
632.1599 +
632.1600 + // Position selectors must be done after the filter
632.1601 + // And so must :not(positional) so we move all PSEUDOs to the end
632.1602 + while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
632.1603 + later += match[0];
632.1604 + selector = selector.replace( Expr.match.PSEUDO, "" );
632.1605 + }
632.1606 +
632.1607 + selector = Expr.relative[selector] ? selector + "*" : selector;
632.1608 +
632.1609 + for ( var i = 0, l = root.length; i < l; i++ ) {
632.1610 + Sizzle( selector, root[i], tmpSet );
632.1611 + }
632.1612 +
632.1613 + return Sizzle.filter( later, tmpSet );
632.1614 +};
632.1615 +
632.1616 +// EXPOSE
632.1617 +jQuery.find = Sizzle;
632.1618 +jQuery.expr = Sizzle.selectors;
632.1619 +jQuery.expr[":"] = jQuery.expr.filters;
632.1620 +
632.1621 +Sizzle.selectors.filters.hidden = function(elem){
632.1622 + var width = elem.offsetWidth, height = elem.offsetHeight;
632.1623 + return ( width === 0 && height === 0 ) ?
632.1624 + true :
632.1625 + ( width !== 0 && height !== 0 ) ?
632.1626 + false :
632.1627 + !!( jQuery.curCSS(elem, "display") === "none" );
632.1628 +};
632.1629 +
632.1630 +Sizzle.selectors.filters.visible = function(elem){
632.1631 + var width = elem.offsetWidth, height = elem.offsetHeight;
632.1632 + return ( width === 0 && height === 0 ) ?
632.1633 + false :
632.1634 + ( width > 0 && height > 0 ) ?
632.1635 + true :
632.1636 + !!( jQuery.curCSS(elem, "display") !== "none" );
632.1637 +};
632.1638 +
632.1639 +Sizzle.selectors.filters.animated = function(elem){
632.1640 + return jQuery.grep(jQuery.timers, function(fn){
632.1641 + return elem === fn.elem;
632.1642 + }).length;
632.1643 +};
632.1644 +
632.1645 +jQuery.filter = jQuery.multiFilter = function( expr, elems, not ) {
632.1646 + if ( not ) {
632.1647 + expr = ":not(" + expr + ")";
632.1648 + }
632.1649 +
632.1650 + return Sizzle.matches(expr, elems);
632.1651 +};
632.1652 +
632.1653 +jQuery.dir = function( elem, dir ){
632.1654 + var matched = [], cur = elem[dir];
632.1655 + while ( cur && cur != document ) {
632.1656 + if ( cur.nodeType == 1 )
632.1657 + matched.push( cur );
632.1658 + cur = cur[dir];
632.1659 + }
632.1660 + return matched;
632.1661 +};
632.1662 +
632.1663 +jQuery.nth = function(cur, result, dir, elem){
632.1664 + result = result || 1;
632.1665 + var num = 0;
632.1666 +
632.1667 + for ( ; cur; cur = cur[dir] )
632.1668 + if ( cur.nodeType == 1 && ++num == result )
632.1669 + break;
632.1670 +
632.1671 + return cur;
632.1672 +};
632.1673 +
632.1674 +jQuery.sibling = function(n, elem){
632.1675 + var r = [];
632.1676 +
632.1677 + for ( ; n; n = n.nextSibling ) {
632.1678 + if ( n.nodeType == 1 && n != elem )
632.1679 + r.push( n );
632.1680 + }
632.1681 +
632.1682 + return r;
632.1683 +};
632.1684 +
632.1685 +return;
632.1686 +
632.1687 +window.Sizzle = Sizzle;
632.1688 +
632.1689 +})();
632.1690 +jQuery.fn.extend({
632.1691 + find: function( selector ) {
632.1692 + var ret = this.pushStack( "", "find", selector ), length = 0;
632.1693 +
632.1694 + for ( var i = 0, l = this.length; i < l; i++ ) {
632.1695 + length = ret.length;
632.1696 + jQuery.find( selector, this[i], ret );
632.1697 +
632.1698 + if ( i > 0 ) {
632.1699 + // Make sure that the results are unique
632.1700 + for ( var n = length; n < ret.length; n++ ) {
632.1701 + for ( var r = 0; r < length; r++ ) {
632.1702 + if ( ret[r] === ret[n] ) {
632.1703 + ret.splice(n--, 1);
632.1704 + break;
632.1705 + }
632.1706 + }
632.1707 + }
632.1708 + }
632.1709 + }
632.1710 +
632.1711 + return ret;
632.1712 + },
632.1713 +
632.1714 + filter: function( selector ) {
632.1715 + return this.pushStack(
632.1716 + jQuery.isFunction( selector ) &&
632.1717 + jQuery.grep(this, function(elem, i){
632.1718 + return selector.call( elem, i );
632.1719 + }) ||
632.1720 +
632.1721 + jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
632.1722 + return elem.nodeType === 1;
632.1723 + }) ), "filter", selector );
632.1724 + },
632.1725 +
632.1726 + closest: function( selector ) {
632.1727 + var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
632.1728 + closer = 0;
632.1729 +
632.1730 + return this.map(function(){
632.1731 + var cur = this;
632.1732 + while ( cur && cur.ownerDocument ) {
632.1733 + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
632.1734 + jQuery.data(cur, "closest", closer);
632.1735 + return cur;
632.1736 + }
632.1737 + cur = cur.parentNode;
632.1738 + closer++;
632.1739 + }
632.1740 + });
632.1741 + },
632.1742 +
632.1743 + not: function( selector ) {
632.1744 + if ( typeof selector === "string" )
632.1745 + // test special case where just one selector is passed in
632.1746 + if ( isSimple.test( selector ) )
632.1747 + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
632.1748 + else
632.1749 + selector = jQuery.multiFilter( selector, this );
632.1750 +
632.1751 + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
632.1752 + return this.filter(function() {
632.1753 + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
632.1754 + });
632.1755 + },
632.1756 +
632.1757 + add: function( selector ) {
632.1758 + return this.pushStack( jQuery.unique( jQuery.merge(
632.1759 + this.get(),
632.1760 + typeof selector === "string" ?
632.1761 + jQuery( selector ) :
632.1762 + jQuery.makeArray( selector )
632.1763 + )));
632.1764 + },
632.1765 +
632.1766 + eq: function( i ) {
632.1767 + return this.slice( i, +i + 1 );
632.1768 + },
632.1769 +
632.1770 + slice: function() {
632.1771 + return this.pushStack( Array.prototype.slice.apply( this, arguments ),
632.1772 + "slice", Array.prototype.slice.call(arguments).join(",") );
632.1773 + },
632.1774 +
632.1775 + map: function( callback ) {
632.1776 + return this.pushStack( jQuery.map(this, function(elem, i){
632.1777 + return callback.call( elem, i, elem );
632.1778 + }));
632.1779 + },
632.1780 +
632.1781 + andSelf: function() {
632.1782 + return this.add( this.prevObject );
632.1783 + },
632.1784 +
632.1785 + end: function() {
632.1786 + return this.prevObject || jQuery(null);
632.1787 + }
632.1788 +});
632.1789 +
632.1790 +jQuery.each({
632.1791 + parent: function(elem){return elem.parentNode;},
632.1792 + parents: function(elem){return jQuery.dir(elem,"parentNode");},
632.1793 + next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
632.1794 + prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
632.1795 + nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
632.1796 + prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
632.1797 + siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
632.1798 + children: function(elem){return jQuery.sibling(elem.firstChild);},
632.1799 + contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
632.1800 +}, function(name, fn){
632.1801 + jQuery.fn[ name ] = function( selector ) {
632.1802 + var ret = jQuery.map( this, fn );
632.1803 +
632.1804 + if ( selector && typeof selector == "string" )
632.1805 + ret = jQuery.multiFilter( selector, ret );
632.1806 +
632.1807 + return this.pushStack( jQuery.unique( ret ), name, selector );
632.1808 + };
632.1809 +});jQuery.fn.extend({
632.1810 + attr: function( name, value ) {
632.1811 + var options = name, isFunction = jQuery.isFunction( value );
632.1812 +
632.1813 + if ( typeof name === "string" ) {
632.1814 + // Are we setting the attribute?
632.1815 + if ( value === undefined ) {
632.1816 + return this.length ?
632.1817 + jQuery.attr( this[0], name ) :
632.1818 + null;
632.1819 +
632.1820 + // Convert name, value params to options hash format
632.1821 + } else {
632.1822 + options = {};
632.1823 + options[ name ] = value;
632.1824 + }
632.1825 + }
632.1826 +
632.1827 + // For each element...
632.1828 + for ( var i = 0, l = this.length; i < l; i++ ) {
632.1829 + var elem = this[i];
632.1830 +
632.1831 + // Set all the attributes
632.1832 + for ( var prop in options ) {
632.1833 + value = options[prop];
632.1834 +
632.1835 + if ( isFunction ) {
632.1836 + value = value.call( elem, i );
632.1837 + }
632.1838 +
632.1839 + jQuery.attr( elem, prop, value );
632.1840 + }
632.1841 + }
632.1842 +
632.1843 + return this;
632.1844 + },
632.1845 +
632.1846 + hasClass: function( selector ) {
632.1847 + return !!selector && this.is( "." + selector );
632.1848 + },
632.1849 +
632.1850 + val: function( value ) {
632.1851 + if ( value === undefined ) {
632.1852 + var elem = this[0];
632.1853 +
632.1854 + if ( elem ) {
632.1855 + if( jQuery.nodeName( elem, 'option' ) )
632.1856 + return (elem.attributes.value || {}).specified ? elem.value : elem.text;
632.1857 +
632.1858 + // We need to handle select boxes special
632.1859 + if ( jQuery.nodeName( elem, "select" ) ) {
632.1860 + var index = elem.selectedIndex,
632.1861 + values = [],
632.1862 + options = elem.options,
632.1863 + one = elem.type == "select-one";
632.1864 +
632.1865 + // Nothing was selected
632.1866 + if ( index < 0 )
632.1867 + return null;
632.1868 +
632.1869 + // Loop through all the selected options
632.1870 + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
632.1871 + var option = options[ i ];
632.1872 +
632.1873 + if ( option.selected ) {
632.1874 + // Get the specifc value for the option
632.1875 + value = jQuery(option).val();
632.1876 +
632.1877 + // We don't need an array for one selects
632.1878 + if ( one )
632.1879 + return value;
632.1880 +
632.1881 + // Multi-Selects return an array
632.1882 + values.push( value );
632.1883 + }
632.1884 + }
632.1885 +
632.1886 + return values;
632.1887 + }
632.1888 +
632.1889 + // Everything else, we just grab the value
632.1890 + return (elem.value || "").replace(/\r/g, "");
632.1891 +
632.1892 + }
632.1893 +
632.1894 + return undefined;
632.1895 + }
632.1896 +
632.1897 + if ( typeof value === "number" )
632.1898 + value += '';
632.1899 +
632.1900 + return this.each(function(){
632.1901 + if ( this.nodeType != 1 )
632.1902 + return;
632.1903 +
632.1904 + if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
632.1905 + this.checked = (jQuery.inArray(this.value, value) >= 0 ||
632.1906 + jQuery.inArray(this.name, value) >= 0);
632.1907 +
632.1908 + else if ( jQuery.nodeName( this, "select" ) ) {
632.1909 + var values = jQuery.makeArray(value);
632.1910 +
632.1911 + jQuery( "option", this ).each(function(){
632.1912 + this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
632.1913 + jQuery.inArray( this.text, values ) >= 0);
632.1914 + });
632.1915 +
632.1916 + if ( !values.length )
632.1917 + this.selectedIndex = -1;
632.1918 +
632.1919 + } else
632.1920 + this.value = value;
632.1921 + });
632.1922 + }
632.1923 +});
632.1924 +
632.1925 +jQuery.each({
632.1926 + removeAttr: function( name ) {
632.1927 + jQuery.attr( this, name, "" );
632.1928 + if (this.nodeType == 1)
632.1929 + this.removeAttribute( name );
632.1930 + },
632.1931 +
632.1932 + addClass: function( classNames ) {
632.1933 + jQuery.className.add( this, classNames );
632.1934 + },
632.1935 +
632.1936 + removeClass: function( classNames ) {
632.1937 + jQuery.className.remove( this, classNames );
632.1938 + },
632.1939 +
632.1940 + toggleClass: function( classNames, state ) {
632.1941 + var type = typeof classNames;
632.1942 + if ( type === "string" ) {
632.1943 + // toggle individual class names
632.1944 + var isBool = typeof state === "boolean", className, i = 0,
632.1945 + classNames = classNames.split( /\s+/ );
632.1946 + while ( (className = classNames[ i++ ]) ) {
632.1947 + // check each className given, space seperated list
632.1948 + state = isBool ? state : !jQuery.className.has( this, className );
632.1949 + jQuery.className[ state ? "add" : "remove" ]( this, className );
632.1950 + }
632.1951 + } else if ( type === "undefined" || type === "boolean" ) {
632.1952 + if ( this.className ) {
632.1953 + // store className if set
632.1954 + jQuery.data( this, "__className__", this.className );
632.1955 + }
632.1956 + // toggle whole className
632.1957 + this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || "";
632.1958 + }
632.1959 + }
632.1960 +}, function(name, fn){
632.1961 + jQuery.fn[ name ] = function(){
632.1962 + return this.each( fn, arguments );
632.1963 + };
632.1964 +});
632.1965 +
632.1966 +jQuery.extend({
632.1967 + className: {
632.1968 + // internal only, use addClass("class")
632.1969 + add: function( elem, classNames ) {
632.1970 + jQuery.each((classNames || "").split(/\s+/), function(i, className){
632.1971 + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
632.1972 + elem.className += (elem.className ? " " : "") + className;
632.1973 + });
632.1974 + },
632.1975 +
632.1976 + // internal only, use removeClass("class")
632.1977 + remove: function( elem, classNames ) {
632.1978 + if (elem.nodeType == 1)
632.1979 + elem.className = classNames !== undefined ?
632.1980 + jQuery.grep(elem.className.split(/\s+/), function(className){
632.1981 + return !jQuery.className.has( classNames, className );
632.1982 + }).join(" ") :
632.1983 + "";
632.1984 + },
632.1985 +
632.1986 + // internal only, use hasClass("class")
632.1987 + has: function( elem, className ) {
632.1988 + return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
632.1989 + }
632.1990 + },
632.1991 +
632.1992 + attr: function( elem, name, value ) {
632.1993 + // don't set attributes on text and comment nodes
632.1994 + if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
632.1995 + return undefined;
632.1996 +
632.1997 + var notxml = !elem.tagName || !jQuery.isXMLDoc( elem ),
632.1998 + // Whether we are setting (or getting)
632.1999 + set = value !== undefined;
632.2000 +
632.2001 + // Try to normalize/fix the name
632.2002 + name = notxml && jQuery.props[ name ] || name;
632.2003 +
632.2004 + // Only do all the following if this is a node (faster for style)
632.2005 + if ( elem.tagName ) {
632.2006 +
632.2007 + // These attributes require special treatment
632.2008 + var special = /href|src|style/.test( name );
632.2009 +
632.2010 + // Safari mis-reports the default selected property of a hidden option
632.2011 + // Accessing the parent's selectedIndex property fixes it
632.2012 + if ( name == "selected" && elem.parentNode )
632.2013 + elem.parentNode.selectedIndex;
632.2014 +
632.2015 + // If applicable, access the attribute via the DOM 0 way
632.2016 + if ( name in elem && notxml && !special ) {
632.2017 + if ( set ){
632.2018 + // We can't allow the type property to be changed (since it causes problems in IE)
632.2019 + if ( name == "type" && elem.nodeName.match(/(button|input)/i) && elem.parentNode )
632.2020 + throw "type property can't be changed";
632.2021 +
632.2022 + elem[ name ] = value;
632.2023 + }
632.2024 +
632.2025 + // browsers index elements by id/name on forms, give priority to attributes.
632.2026 + if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
632.2027 + return elem.getAttributeNode( name ).nodeValue;
632.2028 +
632.2029 + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
632.2030 + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
632.2031 + if ( name == "tabIndex" ) {
632.2032 + var attributeNode = elem.getAttributeNode( "tabIndex" );
632.2033 + return attributeNode && attributeNode.specified
632.2034 + ? attributeNode.value
632.2035 + : elem.nodeName.match(/(button|input|object|select|textarea)/i)
632.2036 + ? 0
632.2037 + : elem.nodeName.match(/^(a|area)$/i) && elem.href
632.2038 + ? 0
632.2039 + : undefined;
632.2040 + }
632.2041 +
632.2042 + return elem[ name ];
632.2043 + }
632.2044 +
632.2045 + if ( !jQuery.support.style && notxml && name == "style" ) {
632.2046 + if ( set )
632.2047 + elem.style.cssText = "" + value;
632.2048 +
632.2049 + return elem.style.cssText;
632.2050 + }
632.2051 +
632.2052 + if ( set )
632.2053 + // convert the value to a string (all browsers do this but IE) see #1070
632.2054 + elem.setAttribute( name, "" + value );
632.2055 +
632.2056 + var attr = !jQuery.support.hrefNormalized && notxml && special
632.2057 + // Some attributes require a special call on IE
632.2058 + ? elem.getAttribute( name, 2 )
632.2059 + : elem.getAttribute( name );
632.2060 +
632.2061 + // Non-existent attributes return null, we normalize to undefined
632.2062 + return attr === null ? undefined : attr;
632.2063 + }
632.2064 +
632.2065 + // elem is actually elem.style ... set the style
632.2066 + // Using attr for specific style information is now deprecated. Use style insead.
632.2067 + return jQuery.style(elem, name, value);
632.2068 + }
632.2069 +});jQuery.fn.extend({
632.2070 + text: function( text ) {
632.2071 + if ( typeof text !== "object" && text != null )
632.2072 + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
632.2073 +
632.2074 + var ret = "";
632.2075 +
632.2076 + jQuery.each( text || this, function(){
632.2077 + jQuery.each( this.childNodes, function(){
632.2078 + if ( this.nodeType != 8 )
632.2079 + ret += this.nodeType != 1 ?
632.2080 + this.nodeValue :
632.2081 + jQuery.fn.text( [ this ] );
632.2082 + });
632.2083 + });
632.2084 +
632.2085 + return ret;
632.2086 + },
632.2087 +
632.2088 + wrapAll: function( html ) {
632.2089 + if ( this[0] ) {
632.2090 + // The elements to wrap the target around
632.2091 + var wrap = jQuery( html, this[0].ownerDocument ).clone();
632.2092 +
632.2093 + if ( this[0].parentNode )
632.2094 + wrap.insertBefore( this[0] );
632.2095 +
632.2096 + wrap.map(function(){
632.2097 + var elem = this;
632.2098 +
632.2099 + while ( elem.firstChild )
632.2100 + elem = elem.firstChild;
632.2101 +
632.2102 + return elem;
632.2103 + }).append(this);
632.2104 + }
632.2105 +
632.2106 + return this;
632.2107 + },
632.2108 +
632.2109 + wrapInner: function( html ) {
632.2110 + return this.each(function(){
632.2111 + jQuery( this ).contents().wrapAll( html );
632.2112 + });
632.2113 + },
632.2114 +
632.2115 + wrap: function( html ) {
632.2116 + return this.each(function(){
632.2117 + jQuery( this ).wrapAll( html );
632.2118 + });
632.2119 + },
632.2120 +
632.2121 + append: function() {
632.2122 + return this.domManip(arguments, true, function(elem){
632.2123 + if (this.nodeType == 1)
632.2124 + this.appendChild( elem );
632.2125 + });
632.2126 + },
632.2127 +
632.2128 + prepend: function() {
632.2129 + return this.domManip(arguments, true, function(elem){
632.2130 + if (this.nodeType == 1)
632.2131 + this.insertBefore( elem, this.firstChild );
632.2132 + });
632.2133 + },
632.2134 +
632.2135 + before: function() {
632.2136 + return this.domManip(arguments, false, function(elem){
632.2137 + this.parentNode.insertBefore( elem, this );
632.2138 + });
632.2139 + },
632.2140 +
632.2141 + after: function() {
632.2142 + return this.domManip(arguments, false, function(elem){
632.2143 + this.parentNode.insertBefore( elem, this.nextSibling );
632.2144 + });
632.2145 + },
632.2146 +
632.2147 + clone: function( events ) {
632.2148 + // Do the clone
632.2149 + var ret = this.map(function(){
632.2150 + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
632.2151 + // IE copies events bound via attachEvent when
632.2152 + // using cloneNode. Calling detachEvent on the
632.2153 + // clone will also remove the events from the orignal
632.2154 + // In order to get around this, we use innerHTML.
632.2155 + // Unfortunately, this means some modifications to
632.2156 + // attributes in IE that are actually only stored
632.2157 + // as properties will not be copied (such as the
632.2158 + // the name attribute on an input).
632.2159 + var html = this.outerHTML, ownerDocument = this.ownerDocument;
632.2160 + if ( !html ) {
632.2161 + var div = ownerDocument.createElement("div");
632.2162 + div.appendChild( this.cloneNode(true) );
632.2163 + html = div.innerHTML;
632.2164 + }
632.2165 +
632.2166 + return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")], ownerDocument)[0];
632.2167 + } else
632.2168 + return this.cloneNode(true);
632.2169 + });
632.2170 +
632.2171 + // Copy the events from the original to the clone
632.2172 + if ( events === true ) {
632.2173 + var orig = this.find("*").andSelf(), i = 0;
632.2174 +
632.2175 + ret.find("*").andSelf().each(function(){
632.2176 + if ( this.nodeName !== orig[i].nodeName )
632.2177 + return;
632.2178 +
632.2179 + var events = jQuery.data( orig[i], "events" );
632.2180 +
632.2181 + for ( var type in events ) {
632.2182 + for ( var handler in events[ type ] ) {
632.2183 + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
632.2184 + }
632.2185 + }
632.2186 +
632.2187 + i++;
632.2188 + });
632.2189 + }
632.2190 +
632.2191 + // Return the cloned set
632.2192 + return ret;
632.2193 + },
632.2194 +
632.2195 + html: function( value ) {
632.2196 + return value === undefined ?
632.2197 + (this[0] ?
632.2198 + this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
632.2199 + null) :
632.2200 + this.empty().append( value );
632.2201 + },
632.2202 +
632.2203 + replaceWith: function( value ) {
632.2204 + return this.after( value ).remove();
632.2205 + },
632.2206 +
632.2207 + domManip: function( args, table, callback ) {
632.2208 + if ( this[0] ) {
632.2209 + var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
632.2210 + scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
632.2211 + first = fragment.firstChild;
632.2212 +
632.2213 + if ( first )
632.2214 + for ( var i = 0, l = this.length; i < l; i++ )
632.2215 + callback.call( root(this[i], first), this.length > 1 || i > 0 ?
632.2216 + fragment.cloneNode(true) : fragment );
632.2217 +
632.2218 + if ( scripts )
632.2219 + jQuery.each( scripts, evalScript );
632.2220 + }
632.2221 +
632.2222 + return this;
632.2223 +
632.2224 + function root( elem, cur ) {
632.2225 + return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
632.2226 + (elem.getElementsByTagName("tbody")[0] ||
632.2227 + elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
632.2228 + elem;
632.2229 + }
632.2230 + }
632.2231 +});
632.2232 +
632.2233 +jQuery.each({
632.2234 + appendTo: "append",
632.2235 + prependTo: "prepend",
632.2236 + insertBefore: "before",
632.2237 + insertAfter: "after",
632.2238 + replaceAll: "replaceWith"
632.2239 +}, function(name, original){
632.2240 + jQuery.fn[ name ] = function( selector ) {
632.2241 + var ret = [], insert = jQuery( selector );
632.2242 +
632.2243 + for ( var i = 0, l = insert.length; i < l; i++ ) {
632.2244 + var elems = (i > 0 ? this.clone(true) : this).get();
632.2245 + jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
632.2246 + ret = ret.concat( elems );
632.2247 + }
632.2248 +
632.2249 + return this.pushStack( ret, name, selector );
632.2250 + };
632.2251 +});
632.2252 +
632.2253 +jQuery.each({
632.2254 + remove: function( selector ) {
632.2255 + if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) {
632.2256 + if ( this.nodeType === 1 ) {
632.2257 + cleanData( jQuery("*", this).add(this) );
632.2258 + }
632.2259 +
632.2260 + if ( this.parentNode ) {
632.2261 + this.parentNode.removeChild( this );
632.2262 + }
632.2263 + }
632.2264 + },
632.2265 +
632.2266 + empty: function() {
632.2267 + // Remove element nodes and prevent memory leaks
632.2268 + if ( this.nodeType === 1 ) {
632.2269 + cleanData( jQuery("*", this) );
632.2270 + }
632.2271 +
632.2272 + // Remove any remaining nodes
632.2273 + while ( this.firstChild ) {
632.2274 + this.removeChild( this.firstChild );
632.2275 + }
632.2276 + }
632.2277 +}, function(name, fn){
632.2278 + jQuery.fn[ name ] = function(){
632.2279 + return this.each( fn, arguments );
632.2280 + };
632.2281 +});
632.2282 +
632.2283 +jQuery.extend({
632.2284 + clean: function( elems, context, fragment ) {
632.2285 + context = context || document;
632.2286 +
632.2287 + // !context.createElement fails in IE with an error but returns typeof 'object'
632.2288 + if ( typeof context.createElement === "undefined" )
632.2289 + context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
632.2290 +
632.2291 + // If a single string is passed in and it's a single tag
632.2292 + // just do a createElement and skip the rest
632.2293 + if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
632.2294 + var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
632.2295 + if ( match )
632.2296 + return [ context.createElement( match[1] ) ];
632.2297 + }
632.2298 +
632.2299 + var ret = [], scripts = [], div = context.createElement("div");
632.2300 +
632.2301 + jQuery.each(elems, function(i, elem){
632.2302 + if ( typeof elem === "number" )
632.2303 + elem += '';
632.2304 +
632.2305 + if ( !elem )
632.2306 + return;
632.2307 +
632.2308 + // Convert html string into DOM nodes
632.2309 + if ( typeof elem === "string" ) {
632.2310 + // Fix "XHTML"-style tags in all browsers
632.2311 + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
632.2312 + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
632.2313 + all :
632.2314 + front + "></" + tag + ">";
632.2315 + });
632.2316 +
632.2317 + // Trim whitespace, otherwise indexOf won't work as expected
632.2318 + var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
632.2319 +
632.2320 + var wrap =
632.2321 + // option or optgroup
632.2322 + !tags.indexOf("<opt") &&
632.2323 + [ 1, "<select multiple='multiple'>", "</select>" ] ||
632.2324 +
632.2325 + !tags.indexOf("<leg") &&
632.2326 + [ 1, "<fieldset>", "</fieldset>" ] ||
632.2327 +
632.2328 + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
632.2329 + [ 1, "<table>", "</table>" ] ||
632.2330 +
632.2331 + !tags.indexOf("<tr") &&
632.2332 + [ 2, "<table><tbody>", "</tbody></table>" ] ||
632.2333 +
632.2334 + // <thead> matched above
632.2335 + (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
632.2336 + [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
632.2337 +
632.2338 + !tags.indexOf("<col") &&
632.2339 + [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
632.2340 +
632.2341 + // IE can't serialize <link> and <script> tags normally
632.2342 + !jQuery.support.htmlSerialize &&
632.2343 + [ 1, "div<div>", "</div>" ] ||
632.2344 +
632.2345 + [ 0, "", "" ];
632.2346 +
632.2347 + // Go to html and back, then peel off extra wrappers
632.2348 + div.innerHTML = wrap[1] + elem + wrap[2];
632.2349 +
632.2350 + // Move to the right depth
632.2351 + while ( wrap[0]-- )
632.2352 + div = div.lastChild;
632.2353 +
632.2354 + // Remove IE's autoinserted <tbody> from table fragments
632.2355 + if ( !jQuery.support.tbody ) {
632.2356 +
632.2357 + // String was a <table>, *may* have spurious <tbody>
632.2358 + var hasBody = /<tbody/i.test(elem),
632.2359 + tbody = !tags.indexOf("<table") && !hasBody ?
632.2360 + div.firstChild && div.firstChild.childNodes :
632.2361 +
632.2362 + // String was a bare <thead> or <tfoot>
632.2363 + wrap[1] == "<table>" && !hasBody ?
632.2364 + div.childNodes :
632.2365 + [];
632.2366 +
632.2367 + for ( var j = tbody.length - 1; j >= 0 ; --j )
632.2368 + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
632.2369 + tbody[ j ].parentNode.removeChild( tbody[ j ] );
632.2370 +
632.2371 + }
632.2372 +
632.2373 + // IE completely kills leading whitespace when innerHTML is used
632.2374 + if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
632.2375 + div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
632.2376 +
632.2377 + elem = jQuery.makeArray( div.childNodes );
632.2378 + }
632.2379 +
632.2380 + if ( elem.nodeType )
632.2381 + ret.push( elem );
632.2382 + else
632.2383 + ret = jQuery.merge( ret, elem );
632.2384 +
632.2385 + });
632.2386 +
632.2387 + if ( fragment ) {
632.2388 + for ( var i = 0; ret[i]; i++ ) {
632.2389 + if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
632.2390 + scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
632.2391 + } else {
632.2392 + if ( ret[i].nodeType === 1 )
632.2393 + ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
632.2394 + fragment.appendChild( ret[i] );
632.2395 + }
632.2396 + }
632.2397 +
632.2398 + return scripts;
632.2399 + }
632.2400 +
632.2401 + return ret;
632.2402 + }
632.2403 +});
632.2404 +
632.2405 +function cleanData( elems ) {
632.2406 + for ( var i = 0, l = elems.length; i < l; i++ ) {
632.2407 + var id = elems[i][expando];
632.2408 + if ( id ) {
632.2409 + delete jQuery.cache[ id ];
632.2410 + }
632.2411 + }
632.2412 +}
632.2413 +/*
632.2414 + * A number of helper functions used for managing events.
632.2415 + * Many of the ideas behind this code originated from
632.2416 + * Dean Edwards' addEvent library.
632.2417 + */
632.2418 +jQuery.event = {
632.2419 +
632.2420 + // Bind an event to an element
632.2421 + // Original by Dean Edwards
632.2422 + add: function( elem, types, handler, data ) {
632.2423 + if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
632.2424 + return;
632.2425 + }
632.2426 +
632.2427 + // For whatever reason, IE has trouble passing the window object
632.2428 + // around, causing it to be cloned in the process
632.2429 + if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
632.2430 + elem = window;
632.2431 + }
632.2432 +
632.2433 + // Make sure that the function being executed has a unique ID
632.2434 + if ( !handler.guid ) {
632.2435 + handler.guid = this.guid++;
632.2436 + }
632.2437 +
632.2438 + // if data is passed, bind to handler
632.2439 + if ( data !== undefined ) {
632.2440 + // Create temporary function pointer to original handler
632.2441 + var fn = handler;
632.2442 +
632.2443 + // Create unique handler function, wrapped around original handler
632.2444 + handler = this.proxy( fn );
632.2445 +
632.2446 + // Store data in unique handler
632.2447 + handler.data = data;
632.2448 + }
632.2449 +
632.2450 + // Init the element's event structure
632.2451 + var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
632.2452 + handle = jQuery.data( elem, "handle" ) || jQuery.data( elem, "handle", function() {
632.2453 + // Handle the second event of a trigger and when
632.2454 + // an event is called after a page has unloaded
632.2455 + return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
632.2456 + jQuery.event.handle.apply( arguments.callee.elem, arguments ) :
632.2457 + undefined;
632.2458 + });
632.2459 + // Add elem as a property of the handle function
632.2460 + // This is to prevent a memory leak with non-native
632.2461 + // event in IE.
632.2462 + handle.elem = elem;
632.2463 +
632.2464 + // Handle multiple events separated by a space
632.2465 + // jQuery(...).bind("mouseover mouseout", fn);
632.2466 + types = types.split( /\s+/ );
632.2467 + var type, i=0;
632.2468 + while ( (type = types[ i++ ]) ) {
632.2469 + // Namespaced event handlers
632.2470 + var namespaces = type.split(".");
632.2471 + type = namespaces.shift();
632.2472 + handler.type = namespaces.slice().sort().join(".");
632.2473 +
632.2474 + // Get the current list of functions bound to this event
632.2475 + var handlers = events[ type ],
632.2476 + special = this.special[ type ] || {};
632.2477 +
632.2478 + if ( special.add ) {
632.2479 + var modifiedHandler = special.add.call( elem, handler, data, namespaces );
632.2480 + if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
632.2481 + modifiedHandler.guid = modifiedHandler.guid || handler.guid;
632.2482 + handler = modifiedHandler;
632.2483 + }
632.2484 + }
632.2485 +
632.2486 + // Init the event handler queue
632.2487 + if ( !handlers ) {
632.2488 + handlers = events[ type ] = {};
632.2489 +
632.2490 + // Check for a special event handler
632.2491 + // Only use addEventListener/attachEvent if the special
632.2492 + // events handler returns false
632.2493 + if ( !special.setup || special.setup.call( elem, data, namespaces ) === false ) {
632.2494 + // Bind the global event handler to the element
632.2495 + if ( elem.addEventListener ) {
632.2496 + elem.addEventListener( type, handle, false );
632.2497 + } else if ( elem.attachEvent ) {
632.2498 + elem.attachEvent( "on" + type, handle );
632.2499 + }
632.2500 + }
632.2501 + }
632.2502 +
632.2503 + // Add the function to the element's handler list
632.2504 + handlers[ handler.guid ] = handler;
632.2505 +
632.2506 + // Keep track of which events have been used, for global triggering
632.2507 + this.global[ type ] = true;
632.2508 + }
632.2509 +
632.2510 + // Nullify elem to prevent memory leaks in IE
632.2511 + elem = null;
632.2512 + },
632.2513 +
632.2514 + guid: 1,
632.2515 + global: {},
632.2516 +
632.2517 + // Detach an event or set of events from an element
632.2518 + remove: function( elem, types, handler ) {
632.2519 + // don't do events on text and comment nodes
632.2520 + if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
632.2521 + return;
632.2522 + }
632.2523 +
632.2524 + var events = jQuery.data( elem, "events" ), ret, type;
632.2525 +
632.2526 + if ( events ) {
632.2527 + // Unbind all events for the element
632.2528 + if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
632.2529 + for ( type in events ) {
632.2530 + this.remove( elem, type + (types || "") );
632.2531 + }
632.2532 + } else {
632.2533 + // types is actually an event object here
632.2534 + if ( types.type ) {
632.2535 + handler = types.handler;
632.2536 + types = types.type;
632.2537 + }
632.2538 +
632.2539 + // Handle multiple events seperated by a space
632.2540 + // jQuery(...).unbind("mouseover mouseout", fn);
632.2541 + types = types.split(/\s+/);
632.2542 + var i = 0;
632.2543 + while ( (type = types[ i++ ]) ) {
632.2544 + // Namespaced event handlers
632.2545 + var namespaces = type.split(".");
632.2546 + type = namespaces.shift();
632.2547 + var all = !namespaces.length,
632.2548 + namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"),
632.2549 + special = this.special[ type ] || {};
632.2550 +
632.2551 + if ( events[ type ] ) {
632.2552 + // remove the given handler for the given type
632.2553 + if ( handler ) {
632.2554 + delete events[ type ][ handler.guid ];
632.2555 +
632.2556 + // remove all handlers for the given type
632.2557 + } else {
632.2558 + for ( var handle in events[ type ] ) {
632.2559 + // Handle the removal of namespaced events
632.2560 + if ( all || namespace.test( events[ type ][ handle ].type ) ) {
632.2561 + delete events[ type ][ handle ];
632.2562 + }
632.2563 + }
632.2564 + }
632.2565 +
632.2566 + if ( special.remove ) {
632.2567 + special.remove.call( elem, namespaces );
632.2568 + }
632.2569 +
632.2570 + // remove generic event handler if no more handlers exist
632.2571 + for ( ret in events[ type ] ) {
632.2572 + break;
632.2573 + }
632.2574 + if ( !ret ) {
632.2575 + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
632.2576 + if ( elem.removeEventListener ) {
632.2577 + elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
632.2578 + } else if ( elem.detachEvent ) {
632.2579 + elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
632.2580 + }
632.2581 + }
632.2582 + ret = null;
632.2583 + delete events[ type ];
632.2584 + }
632.2585 + }
632.2586 + }
632.2587 + }
632.2588 +
632.2589 + // Remove the expando if it's no longer used
632.2590 + for ( ret in events ) {
632.2591 + break;
632.2592 + }
632.2593 + if ( !ret ) {
632.2594 + var handle = jQuery.data( elem, "handle" );
632.2595 + if ( handle ) {
632.2596 + handle.elem = null;
632.2597 + }
632.2598 + jQuery.removeData( elem, "events" );
632.2599 + jQuery.removeData( elem, "handle" );
632.2600 + }
632.2601 + }
632.2602 + },
632.2603 +
632.2604 + // bubbling is internal
632.2605 + trigger: function( event, data, elem /*, bubbling */ ) {
632.2606 + // Event object or event type
632.2607 + var type = event.type || event,
632.2608 + bubbling = arguments[3];
632.2609 +
632.2610 + if ( !bubbling ) {
632.2611 + event = typeof event === "object" ?
632.2612 + // jQuery.Event object
632.2613 + event[expando] ? event :
632.2614 + // Object literal
632.2615 + jQuery.extend( jQuery.Event(type), event ) :
632.2616 + // Just the event type (string)
632.2617 + jQuery.Event(type);
632.2618 +
632.2619 + if ( type.indexOf("!") >= 0 ) {
632.2620 + event.type = type = type.slice(0, -1);
632.2621 + event.exclusive = true;
632.2622 + }
632.2623 +
632.2624 + // Handle a global trigger
632.2625 + if ( !elem ) {
632.2626 + // Don't bubble custom events when global (to avoid too much overhead)
632.2627 + event.stopPropagation();
632.2628 + // Only trigger if we've ever bound an event for it
632.2629 + if ( this.global[ type ] ) {
632.2630 + jQuery.each( jQuery.cache, function() {
632.2631 + if ( this.events && this.events[type] ) {
632.2632 + jQuery.event.trigger( event, data, this.handle.elem );
632.2633 + }
632.2634 + });
632.2635 + }
632.2636 + }
632.2637 +
632.2638 + // Handle triggering a single element
632.2639 +
632.2640 + // don't do events on text and comment nodes
632.2641 + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
632.2642 + return undefined;
632.2643 + }
632.2644 +
632.2645 + // Clean up in case it is reused
632.2646 + event.result = undefined;
632.2647 + event.target = elem;
632.2648 +
632.2649 + // Clone the incoming data, if any
632.2650 + data = jQuery.makeArray( data );
632.2651 + data.unshift( event );
632.2652 + }
632.2653 +
632.2654 + event.currentTarget = elem;
632.2655 +
632.2656 + // Trigger the event, it is assumed that "handle" is a function
632.2657 + var handle = jQuery.data( elem, "handle" );
632.2658 + if ( handle ) {
632.2659 + handle.apply( elem, data );
632.2660 + }
632.2661 +
632.2662 + // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
632.2663 + if ( (!elem[ type ] || (jQuery.nodeName(elem, 'a') && type === "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) {
632.2664 + event.result = false;
632.2665 + }
632.2666 +
632.2667 + // Trigger the native events (except for clicks on links)
632.2668 + if ( !bubbling && elem[ type ] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type === "click") ) {
632.2669 + this.triggered = true;
632.2670 + try {
632.2671 + elem[ type ]();
632.2672 + // prevent IE from throwing an error for some hidden elements
632.2673 + } catch (e) {}
632.2674 + }
632.2675 +
632.2676 + this.triggered = false;
632.2677 +
632.2678 + if ( !event.isPropagationStopped() ) {
632.2679 + var parent = elem.parentNode || elem.ownerDocument;
632.2680 + if ( parent ) {
632.2681 + jQuery.event.trigger( event, data, parent, true );
632.2682 + }
632.2683 + }
632.2684 + },
632.2685 +
632.2686 + handle: function( event ) {
632.2687 + // returned undefined or false
632.2688 + var all, handlers;
632.2689 +
632.2690 + event = arguments[0] = jQuery.event.fix( event || window.event );
632.2691 + event.currentTarget = this;
632.2692 +
632.2693 + // Namespaced event handlers
632.2694 + var namespaces = event.type.split(".");
632.2695 + event.type = namespaces.shift();
632.2696 +
632.2697 + // Cache this now, all = true means, any handler
632.2698 + all = !namespaces.length && !event.exclusive;
632.2699 +
632.2700 + var namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
632.2701 +
632.2702 + handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
632.2703 +
632.2704 + for ( var j in handlers ) {
632.2705 + var handler = handlers[ j ];
632.2706 +
632.2707 + // Filter the functions by class
632.2708 + if ( all || namespace.test(handler.type) ) {
632.2709 + // Pass in a reference to the handler function itself
632.2710 + // So that we can later remove it
632.2711 + event.handler = handler;
632.2712 + event.data = handler.data;
632.2713 +
632.2714 + var ret = handler.apply( this, arguments );
632.2715 +
632.2716 + if ( ret !== undefined ) {
632.2717 + event.result = ret;
632.2718 + if ( ret === false ) {
632.2719 + event.preventDefault();
632.2720 + event.stopPropagation();
632.2721 + }
632.2722 + }
632.2723 +
632.2724 + if ( event.isImmediatePropagationStopped() ) {
632.2725 + break;
632.2726 + }
632.2727 +
632.2728 + }
632.2729 + }
632.2730 + },
632.2731 +
632.2732 + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
632.2733 +
632.2734 + fix: function( event ) {
632.2735 + if ( event[ expando ] ) {
632.2736 + return event;
632.2737 + }
632.2738 +
632.2739 + // store a copy of the original event object
632.2740 + // and "clone" to set read-only properties
632.2741 + var originalEvent = event;
632.2742 + event = jQuery.Event( originalEvent );
632.2743 +
632.2744 + for ( var i = this.props.length, prop; i; ) {
632.2745 + prop = this.props[ --i ];
632.2746 + event[ prop ] = originalEvent[ prop ];
632.2747 + }
632.2748 +
632.2749 + // Fix target property, if necessary
632.2750 + if ( !event.target ) {
632.2751 + event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
632.2752 + }
632.2753 +
632.2754 + // check if target is a textnode (safari)
632.2755 + if ( event.target.nodeType === 3 ) {
632.2756 + event.target = event.target.parentNode;
632.2757 + }
632.2758 +
632.2759 + // Add relatedTarget, if necessary
632.2760 + if ( !event.relatedTarget && event.fromElement ) {
632.2761 + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
632.2762 + }
632.2763 +
632.2764 + // Calculate pageX/Y if missing and clientX/Y available
632.2765 + if ( event.pageX == null && event.clientX != null ) {
632.2766 + var doc = document.documentElement, body = document.body;
632.2767 + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
632.2768 + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
632.2769 + }
632.2770 +
632.2771 + // Add which for key events
632.2772 + if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
632.2773 + event.which = event.charCode || event.keyCode;
632.2774 + }
632.2775 +
632.2776 + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
632.2777 + if ( !event.metaKey && event.ctrlKey ) {
632.2778 + event.metaKey = event.ctrlKey;
632.2779 + }
632.2780 +
632.2781 + // Add which for click: 1 == left; 2 == middle; 3 == right
632.2782 + // Note: button is not normalized, so don't use it
632.2783 + if ( !event.which && event.button ) {
632.2784 + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
632.2785 + }
632.2786 +
632.2787 + return event;
632.2788 + },
632.2789 +
632.2790 + proxy: function( fn, proxy, thisObject ) {
632.2791 + if ( proxy !== undefined && !jQuery.isFunction( proxy ) ) {
632.2792 + thisObject = proxy;
632.2793 + proxy = undefined;
632.2794 + }
632.2795 + // FIXME: Should proxy be redefined to be applied with thisObject if defined?
632.2796 + proxy = proxy || function() { return fn.apply( thisObject !== undefined ? thisObject : this, arguments ); };
632.2797 + // Set the guid of unique handler to the same of original handler, so it can be removed
632.2798 + proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
632.2799 + // So proxy can be declared as an argument
632.2800 + return proxy;
632.2801 + },
632.2802 +
632.2803 + special: {
632.2804 + ready: {
632.2805 + // Make sure the ready event is setup
632.2806 + setup: bindReady,
632.2807 + teardown: function() {}
632.2808 + },
632.2809 +
632.2810 + live: {
632.2811 + add: function( proxy, data, namespaces ) {
632.2812 + jQuery.extend( proxy, data || {} );
632.2813 + proxy.guid += data.selector + data.live;
632.2814 + jQuery.event.add( this, data.live, liveHandler );
632.2815 + },
632.2816 +
632.2817 + remove: function( namespaces ) {
632.2818 + if ( namespaces.length ) {
632.2819 + var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
632.2820 +
632.2821 + jQuery.each( (jQuery.data(this, "events").live || {}), function() {
632.2822 + if ( name.test(this.type) ) {
632.2823 + remove++;
632.2824 + }
632.2825 + });
632.2826 +
632.2827 + if ( remove < 1 ) {
632.2828 + jQuery.event.remove( this, namespaces[0], liveHandler );
632.2829 + }
632.2830 + }
632.2831 + }
632.2832 + }
632.2833 + }
632.2834 +};
632.2835 +
632.2836 +jQuery.Event = function( src ){
632.2837 + // Allow instantiation without the 'new' keyword
632.2838 + if ( !this.preventDefault ) {
632.2839 + return new jQuery.Event( src );
632.2840 + }
632.2841 +
632.2842 + // Event object
632.2843 + if ( src && src.type ) {
632.2844 + this.originalEvent = src;
632.2845 + this.type = src.type;
632.2846 + // Event type
632.2847 + } else {
632.2848 + this.type = src;
632.2849 + }
632.2850 +
632.2851 + // timeStamp is buggy for some events on Firefox(#3843)
632.2852 + // So we won't rely on the native value
632.2853 + this.timeStamp = now();
632.2854 +
632.2855 + // Mark it as fixed
632.2856 + this[ expando ] = true;
632.2857 +};
632.2858 +
632.2859 +function returnFalse() {
632.2860 + return false;
632.2861 +}
632.2862 +function returnTrue() {
632.2863 + return true;
632.2864 +}
632.2865 +
632.2866 +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
632.2867 +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
632.2868 +jQuery.Event.prototype = {
632.2869 + preventDefault: function() {
632.2870 + this.isDefaultPrevented = returnTrue;
632.2871 +
632.2872 + var e = this.originalEvent;
632.2873 + if ( !e ) {
632.2874 + return;
632.2875 + }
632.2876 + // if preventDefault exists run it on the original event
632.2877 + if ( e.preventDefault ) {
632.2878 + e.preventDefault();
632.2879 + }
632.2880 + // otherwise set the returnValue property of the original event to false (IE)
632.2881 + e.returnValue = false;
632.2882 + },
632.2883 + stopPropagation: function() {
632.2884 + this.isPropagationStopped = returnTrue;
632.2885 +
632.2886 + var e = this.originalEvent;
632.2887 + if ( !e ) {
632.2888 + return;
632.2889 + }
632.2890 + // if stopPropagation exists run it on the original event
632.2891 + if ( e.stopPropagation ) {
632.2892 + e.stopPropagation();
632.2893 + }
632.2894 + // otherwise set the cancelBubble property of the original event to true (IE)
632.2895 + e.cancelBubble = true;
632.2896 + },
632.2897 + stopImmediatePropagation: function(){
632.2898 + this.isImmediatePropagationStopped = returnTrue;
632.2899 + this.stopPropagation();
632.2900 + },
632.2901 + isDefaultPrevented: returnFalse,
632.2902 + isPropagationStopped: returnFalse,
632.2903 + isImmediatePropagationStopped: returnFalse
632.2904 +};
632.2905 +// Checks if an event happened on an element within another element
632.2906 +// Used in jQuery.event.special.mouseenter and mouseleave handlers
632.2907 +var withinElement = function( event ) {
632.2908 + // Check if mouse(over|out) are still within the same parent element
632.2909 + var parent = event.relatedTarget;
632.2910 + // Traverse up the tree
632.2911 + while ( parent && parent != this ) {
632.2912 + // Firefox sometimes assigns relatedTarget a XUL element
632.2913 + // which we cannot access the parentNode property of
632.2914 + try { parent = parent.parentNode; }
632.2915 + // assuming we've left the element since we most likely mousedover a xul element
632.2916 + catch(e) { break; }
632.2917 + }
632.2918 +
632.2919 + if ( parent != this ) {
632.2920 + // set the correct event type
632.2921 + event.type = event.data;
632.2922 + // handle event if we actually just moused on to a non sub-element
632.2923 + jQuery.event.handle.apply( this, arguments );
632.2924 + }
632.2925 +};
632.2926 +
632.2927 +jQuery.each({
632.2928 + mouseover: 'mouseenter',
632.2929 + mouseout: 'mouseleave'
632.2930 +}, function( orig, fix ) {
632.2931 + jQuery.event.special[ fix ] = {
632.2932 + setup: function(){
632.2933 + jQuery.event.add( this, orig, withinElement, fix );
632.2934 + },
632.2935 + teardown: function(){
632.2936 + jQuery.event.remove( this, orig, withinElement );
632.2937 + }
632.2938 + };
632.2939 +});
632.2940 +
632.2941 +jQuery.fn.extend({
632.2942 + bind: function( type, data, fn, thisObject ) {
632.2943 + if ( jQuery.isFunction( data ) ) {
632.2944 + if ( fn !== undefined ) {
632.2945 + thisObject = fn;
632.2946 + }
632.2947 + fn = data;
632.2948 + data = undefined;
632.2949 + }
632.2950 + fn = thisObject === undefined ? fn : jQuery.event.proxy( fn, thisObject );
632.2951 + return type === "unload" ? this.one(type, data, fn, thisObject) : this.each(function() {
632.2952 + jQuery.event.add( this, type, fn, data );
632.2953 + });
632.2954 + },
632.2955 +
632.2956 + one: function( type, data, fn, thisObject ) {
632.2957 + if ( jQuery.isFunction( data ) ) {
632.2958 + if ( fn !== undefined ) {
632.2959 + thisObject = fn;
632.2960 + }
632.2961 + fn = data;
632.2962 + data = undefined;
632.2963 + }
632.2964 + fn = thisObject === undefined ? fn : jQuery.event.proxy( fn, thisObject );
632.2965 + var one = jQuery.event.proxy( fn, function( event ) {
632.2966 + jQuery( this ).unbind( event, one );
632.2967 + return fn.apply( this, arguments );
632.2968 + });
632.2969 + return this.each(function() {
632.2970 + jQuery.event.add( this, type, one, data );
632.2971 + });
632.2972 + },
632.2973 +
632.2974 + unbind: function( type, fn ) {
632.2975 + return this.each(function() {
632.2976 + jQuery.event.remove( this, type, fn );
632.2977 + });
632.2978 + },
632.2979 +
632.2980 + trigger: function( type, data ) {
632.2981 + return this.each(function() {
632.2982 + jQuery.event.trigger( type, data, this );
632.2983 + });
632.2984 + },
632.2985 +
632.2986 + triggerHandler: function( type, data ) {
632.2987 + if ( this[0] ) {
632.2988 + var event = jQuery.Event( type );
632.2989 + event.preventDefault();
632.2990 + event.stopPropagation();
632.2991 + jQuery.event.trigger( event, data, this[0] );
632.2992 + return event.result;
632.2993 + }
632.2994 + },
632.2995 +
632.2996 + toggle: function( fn ) {
632.2997 + // Save reference to arguments for access in closure
632.2998 + var args = arguments, i = 1;
632.2999 +
632.3000 + // link all the functions, so any of them can unbind this click handler
632.3001 + while( i < args.length ) {
632.3002 + jQuery.event.proxy( fn, args[ i++ ] );
632.3003 + }
632.3004 +
632.3005 + return this.click( jQuery.event.proxy( fn, function( event ) {
632.3006 + // Figure out which function to execute
632.3007 + this.lastToggle = ( this.lastToggle || 0 ) % i;
632.3008 +
632.3009 + // Make sure that clicks stop
632.3010 + event.preventDefault();
632.3011 +
632.3012 + // and execute the function
632.3013 + return args[ this.lastToggle++ ].apply( this, arguments ) || false;
632.3014 + }));
632.3015 + },
632.3016 +
632.3017 + hover: function( fnOver, fnOut ) {
632.3018 + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
632.3019 + },
632.3020 +
632.3021 + ready: function( fn ) {
632.3022 + // Attach the listeners
632.3023 + bindReady();
632.3024 +
632.3025 + // If the DOM is already ready
632.3026 + if ( jQuery.isReady ) {
632.3027 + // Execute the function immediately
632.3028 + fn.call( document, jQuery );
632.3029 +
632.3030 + // Otherwise, remember the function for later
632.3031 + } else {
632.3032 + // Add the function to the wait list
632.3033 + jQuery.readyList.push( fn );
632.3034 + }
632.3035 +
632.3036 + return this;
632.3037 + },
632.3038 +
632.3039 + live: function( type, data, fn, thisObject ) {
632.3040 + if ( jQuery.isFunction( data ) ) {
632.3041 + if ( fn !== undefined ) {
632.3042 + thisObject = fn;
632.3043 + }
632.3044 + fn = data;
632.3045 + data = undefined;
632.3046 + }
632.3047 + jQuery( this.context ).bind( liveConvert( type, this.selector ), {
632.3048 + data: data, selector: this.selector, live: type
632.3049 + }, fn, thisObject );
632.3050 + return this;
632.3051 + },
632.3052 +
632.3053 + die: function( type, fn ) {
632.3054 + jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
632.3055 + return this;
632.3056 + }
632.3057 +});
632.3058 +
632.3059 +function liveHandler( event ) {
632.3060 + var stop = true, elems = [], args = arguments;
632.3061 +
632.3062 + jQuery.each( jQuery.data( this, "events" ).live || [], function( i, fn ) {
632.3063 + if ( fn.live === event.type ) {
632.3064 + var elem = jQuery( event.target ).closest( fn.selector )[0];
632.3065 + if ( elem ) {
632.3066 + elems.push({ elem: elem, fn: fn });
632.3067 + }
632.3068 + }
632.3069 + });
632.3070 +
632.3071 + elems.sort(function( a, b ) {
632.3072 + return jQuery.data( a.elem, "closest" ) - jQuery.data( b.elem, "closest" );
632.3073 + });
632.3074 +
632.3075 + jQuery.each(elems, function() {
632.3076 + event.currentTarget = this.elem;
632.3077 + event.data = this.fn.data;
632.3078 + if ( this.fn.apply( this.elem, args ) === false ) {
632.3079 + return (stop = false);
632.3080 + }
632.3081 + });
632.3082 +
632.3083 + return stop;
632.3084 +}
632.3085 +
632.3086 +function liveConvert( type, selector ) {
632.3087 + return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
632.3088 +}
632.3089 +
632.3090 +jQuery.extend({
632.3091 + isReady: false,
632.3092 + readyList: [],
632.3093 + // Handle when the DOM is ready
632.3094 + ready: function() {
632.3095 + // Make sure that the DOM is not already loaded
632.3096 + if ( !jQuery.isReady ) {
632.3097 + // Remember that the DOM is ready
632.3098 + jQuery.isReady = true;
632.3099 +
632.3100 + // If there are functions bound, to execute
632.3101 + if ( jQuery.readyList ) {
632.3102 + // Execute all of them
632.3103 + var fn, i = 0;
632.3104 + while ( (fn = jQuery.readyList[ i++ ]) ) {
632.3105 + fn.call( document, jQuery );
632.3106 + }
632.3107 +
632.3108 + // Reset the list of functions
632.3109 + jQuery.readyList = null;
632.3110 + }
632.3111 +
632.3112 + // Trigger any bound ready events
632.3113 + jQuery( document ).triggerHandler( "ready" );
632.3114 + }
632.3115 + }
632.3116 +});
632.3117 +
632.3118 +var readyBound = false;
632.3119 +
632.3120 +function bindReady() {
632.3121 + if ( readyBound ) return;
632.3122 + readyBound = true;
632.3123 +
632.3124 + // Mozilla, Opera and webkit nightlies currently support this event
632.3125 + if ( document.addEventListener ) {
632.3126 + // Use the handy event callback
632.3127 + document.addEventListener( "DOMContentLoaded", function() {
632.3128 + document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
632.3129 + jQuery.ready();
632.3130 + }, false );
632.3131 +
632.3132 + // If IE event model is used
632.3133 + } else if ( document.attachEvent ) {
632.3134 + // ensure firing before onload,
632.3135 + // maybe late but safe also for iframes
632.3136 + document.attachEvent("onreadystatechange", function() {
632.3137 + if ( document.readyState === "complete" ) {
632.3138 + document.detachEvent( "onreadystatechange", arguments.callee );
632.3139 + jQuery.ready();
632.3140 + }
632.3141 + });
632.3142 +
632.3143 + // If IE and not an iframe
632.3144 + // continually check to see if the document is ready
632.3145 + if ( document.documentElement.doScroll && window === window.top ) (function() {
632.3146 + if ( jQuery.isReady ) {
632.3147 + return;
632.3148 + }
632.3149 +
632.3150 + try {
632.3151 + // If IE is used, use the trick by Diego Perini
632.3152 + // http://javascript.nwbox.com/IEContentLoaded/
632.3153 + document.documentElement.doScroll("left");
632.3154 + } catch( error ) {
632.3155 + setTimeout( arguments.callee, 0 );
632.3156 + return;
632.3157 + }
632.3158 +
632.3159 + // and execute any waiting functions
632.3160 + jQuery.ready();
632.3161 + })();
632.3162 + }
632.3163 +
632.3164 + // A fallback to window.onload, that will always work
632.3165 + jQuery.event.add( window, "load", jQuery.ready );
632.3166 +}
632.3167 +
632.3168 +jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
632.3169 + "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
632.3170 + "change,select,submit,keydown,keypress,keyup,error").split(","), function( i, name ) {
632.3171 +
632.3172 + // Handle event binding
632.3173 + jQuery.fn[ name ] = function( fn ) {
632.3174 + return fn ? this.bind( name, fn ) : this.trigger( name );
632.3175 + };
632.3176 +});
632.3177 +
632.3178 +// Prevent memory leaks in IE
632.3179 +// And prevent errors on refresh with events like mouseover in other browsers
632.3180 +// Window isn't included so as not to unbind existing unload events
632.3181 +// More info:
632.3182 +// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
632.3183 +// - https://bugzilla.mozilla.org/show_bug.cgi?id=252542
632.3184 +jQuery( window ).bind( 'unload', function() {
632.3185 + for ( var id in jQuery.cache ) {
632.3186 + // Skip the window
632.3187 + if ( id != 1 && jQuery.cache[ id ].handle ) {
632.3188 + jQuery.event.remove( jQuery.cache[ id ].handle.elem );
632.3189 + }
632.3190 + }
632.3191 +});
632.3192 +(function(){
632.3193 +
632.3194 + jQuery.support = {};
632.3195 +
632.3196 + var root = document.documentElement,
632.3197 + script = document.createElement("script"),
632.3198 + div = document.createElement("div"),
632.3199 + id = "script" + (new Date).getTime();
632.3200 +
632.3201 + div.style.display = "none";
632.3202 + div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select>';
632.3203 +
632.3204 + var all = div.getElementsByTagName("*"),
632.3205 + a = div.getElementsByTagName("a")[0];
632.3206 +
632.3207 + // Can't get basic test support
632.3208 + if ( !all || !all.length || !a ) {
632.3209 + return;
632.3210 + }
632.3211 +
632.3212 + jQuery.support = {
632.3213 + // IE strips leading whitespace when .innerHTML is used
632.3214 + leadingWhitespace: div.firstChild.nodeType == 3,
632.3215 +
632.3216 + // Make sure that tbody elements aren't automatically inserted
632.3217 + // IE will insert them into empty tables
632.3218 + tbody: !div.getElementsByTagName("tbody").length,
632.3219 +
632.3220 + // Make sure that link elements get serialized correctly by innerHTML
632.3221 + // This requires a wrapper element in IE
632.3222 + htmlSerialize: !!div.getElementsByTagName("link").length,
632.3223 +
632.3224 + // Get the style information from getAttribute
632.3225 + // (IE uses .cssText insted)
632.3226 + style: /red/.test( a.getAttribute("style") ),
632.3227 +
632.3228 + // Make sure that URLs aren't manipulated
632.3229 + // (IE normalizes it by default)
632.3230 + hrefNormalized: a.getAttribute("href") === "/a",
632.3231 +
632.3232 + // Make sure that element opacity exists
632.3233 + // (IE uses filter instead)
632.3234 + opacity: a.style.opacity === "0.5",
632.3235 +
632.3236 + // Verify style float existence
632.3237 + // (IE uses styleFloat instead of cssFloat)
632.3238 + cssFloat: !!a.style.cssFloat,
632.3239 +
632.3240 + // Will be defined later
632.3241 + scriptEval: false,
632.3242 + noCloneEvent: true,
632.3243 + boxModel: null
632.3244 + };
632.3245 +
632.3246 + script.type = "text/javascript";
632.3247 + try {
632.3248 + script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
632.3249 + } catch(e){}
632.3250 +
632.3251 + root.insertBefore( script, root.firstChild );
632.3252 +
632.3253 + // Make sure that the execution of code works by injecting a script
632.3254 + // tag with appendChild/createTextNode
632.3255 + // (IE doesn't support this, fails, and uses .text instead)
632.3256 + if ( window[ id ] ) {
632.3257 + jQuery.support.scriptEval = true;
632.3258 + delete window[ id ];
632.3259 + }
632.3260 +
632.3261 + root.removeChild( script );
632.3262 +
632.3263 + if ( div.attachEvent && div.fireEvent ) {
632.3264 + div.attachEvent("onclick", function click(){
632.3265 + // Cloning a node shouldn't copy over any
632.3266 + // bound event handlers (IE does this)
632.3267 + jQuery.support.noCloneEvent = false;
632.3268 + div.detachEvent("onclick", click);
632.3269 + });
632.3270 + div.cloneNode(true).fireEvent("onclick");
632.3271 + }
632.3272 +
632.3273 + // Figure out if the W3C box model works as expected
632.3274 + // document.body must exist before we can do this
632.3275 + jQuery(function(){
632.3276 + var div = document.createElement("div");
632.3277 + div.style.width = div.style.paddingLeft = "1px";
632.3278 +
632.3279 + document.body.appendChild( div );
632.3280 + jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
632.3281 + document.body.removeChild( div ).style.display = 'none';
632.3282 + div = null;
632.3283 + });
632.3284 +
632.3285 + // release memory in IE
632.3286 + root = script = div = all = a = null;
632.3287 +})();
632.3288 +
632.3289 +jQuery.props = {
632.3290 + "for": "htmlFor",
632.3291 + "class": "className",
632.3292 + readonly: "readOnly",
632.3293 + maxlength: "maxLength",
632.3294 + cellspacing: "cellSpacing",
632.3295 + rowspan: "rowSpan",
632.3296 + colspan: "colSpan",
632.3297 + tabindex: "tabIndex"
632.3298 +};
632.3299 +// exclude the following css properties to add px
632.3300 +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
632.3301 + // cache check for defaultView.getComputedStyle
632.3302 + getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
632.3303 + // normalize float css property
632.3304 + styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
632.3305 +
632.3306 +jQuery.fn.css = function( name, value ) {
632.3307 + var options = name, isFunction = jQuery.isFunction( value );
632.3308 +
632.3309 + if ( typeof name === "string" ) {
632.3310 + // Are we setting the style?
632.3311 + if ( value === undefined ) {
632.3312 + return this.length ?
632.3313 + jQuery.css( this[0], name ) :
632.3314 + null;
632.3315 +
632.3316 + // Convert name, value params to options hash format
632.3317 + } else {
632.3318 + options = {};
632.3319 + options[ name ] = value;
632.3320 + }
632.3321 + }
632.3322 +
632.3323 + // For each element...
632.3324 + for ( var i = 0, l = this.length; i < l; i++ ) {
632.3325 + var elem = this[i];
632.3326 +
632.3327 + // Set all the styles
632.3328 + for ( var prop in options ) {
632.3329 + value = options[prop];
632.3330 +
632.3331 + if ( isFunction ) {
632.3332 + value = value.call( elem, i );
632.3333 + }
632.3334 +
632.3335 + if ( typeof value === "number" && !exclude.test(prop) ) {
632.3336 + value = value + "px";
632.3337 + }
632.3338 +
632.3339 + jQuery.style( elem, prop, value );
632.3340 + }
632.3341 + }
632.3342 +
632.3343 + return this;
632.3344 +};
632.3345 +
632.3346 +jQuery.extend({
632.3347 + style: function( elem, name, value ) {
632.3348 + // don't set styles on text and comment nodes
632.3349 + if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
632.3350 + return undefined;
632.3351 +
632.3352 + // ignore negative width and height values #1599
632.3353 + if ( (name == 'width' || name == 'height') && parseFloat(value) < 0 )
632.3354 + value = undefined;
632.3355 +
632.3356 + var style = elem.style || elem, set = value !== undefined;
632.3357 +
632.3358 + // IE uses filters for opacity
632.3359 + if ( !jQuery.support.opacity && name == "opacity" ) {
632.3360 + if ( set ) {
632.3361 + // IE has trouble with opacity if it does not have layout
632.3362 + // Force it by setting the zoom level
632.3363 + style.zoom = 1;
632.3364 +
632.3365 + // Set the alpha filter to set the opacity
632.3366 + style.filter = (style.filter || "").replace( /alpha\([^)]*\)/, "" ) +
632.3367 + (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
632.3368 + }
632.3369 +
632.3370 + return style.filter && style.filter.indexOf("opacity=") >= 0 ?
632.3371 + (parseFloat( style.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
632.3372 + "";
632.3373 + }
632.3374 +
632.3375 + // Make sure we're using the right name for getting the float value
632.3376 + if ( /float/i.test( name ) )
632.3377 + name = styleFloat;
632.3378 +
632.3379 + name = name.replace(/-([a-z])/ig, function(all, letter){
632.3380 + return letter.toUpperCase();
632.3381 + });
632.3382 +
632.3383 + if ( set )
632.3384 + style[ name ] = value;
632.3385 +
632.3386 + return style[ name ];
632.3387 + },
632.3388 +
632.3389 + css: function( elem, name, force, extra ) {
632.3390 + if ( name == "width" || name == "height" ) {
632.3391 + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
632.3392 +
632.3393 + function getWH() {
632.3394 + val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
632.3395 +
632.3396 + if ( extra === "border" )
632.3397 + return;
632.3398 +
632.3399 + jQuery.each( which, function() {
632.3400 + if ( !extra )
632.3401 + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
632.3402 + if ( extra === "margin" )
632.3403 + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
632.3404 + else
632.3405 + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
632.3406 + });
632.3407 + }
632.3408 +
632.3409 + if ( elem.offsetWidth !== 0 )
632.3410 + getWH();
632.3411 + else
632.3412 + jQuery.swap( elem, props, getWH );
632.3413 +
632.3414 + return Math.max(0, Math.round(val));
632.3415 + }
632.3416 +
632.3417 + return jQuery.curCSS( elem, name, force );
632.3418 + },
632.3419 +
632.3420 + curCSS: function( elem, name, force ) {
632.3421 + var ret, style = elem.style, filter;
632.3422 +
632.3423 + // IE uses filters for opacity
632.3424 + if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
632.3425 + ret = (elem.currentStyle.filter || "").match(/opacity=([^)]*)/) ?
632.3426 + (parseFloat(RegExp.$1) / 100) + "" :
632.3427 + "";
632.3428 +
632.3429 + return ret === "" ?
632.3430 + "1" :
632.3431 + ret;
632.3432 + }
632.3433 +
632.3434 + // Make sure we're using the right name for getting the float value
632.3435 + if ( /float/i.test( name ) )
632.3436 + name = styleFloat;
632.3437 +
632.3438 + if ( !force && style && style[ name ] ) {
632.3439 + ret = style[ name ];
632.3440 +
632.3441 + } else if ( getComputedStyle ) {
632.3442 +
632.3443 + // Only "float" is needed here
632.3444 + if ( /float/i.test( name ) )
632.3445 + name = "float";
632.3446 +
632.3447 + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
632.3448 +
632.3449 + var computedStyle = elem.ownerDocument.defaultView.getComputedStyle( elem, null );
632.3450 +
632.3451 + if ( computedStyle )
632.3452 + ret = computedStyle.getPropertyValue( name );
632.3453 +
632.3454 + // We should always get a number back from opacity
632.3455 + if ( name == "opacity" && ret == "" )
632.3456 + ret = "1";
632.3457 +
632.3458 + } else if ( elem.currentStyle ) {
632.3459 + var camelCase = name.replace(/\-(\w)/g, function(all, letter){
632.3460 + return letter.toUpperCase();
632.3461 + });
632.3462 +
632.3463 + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
632.3464 +
632.3465 + // From the awesome hack by Dean Edwards
632.3466 + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
632.3467 +
632.3468 + // If we're not dealing with a regular pixel number
632.3469 + // but a number that has a weird ending, we need to convert it to pixels
632.3470 + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
632.3471 + // Remember the original values
632.3472 + var left = style.left, rsLeft = elem.runtimeStyle.left;
632.3473 +
632.3474 + // Put in the new values to get a computed value out
632.3475 + elem.runtimeStyle.left = elem.currentStyle.left;
632.3476 + style.left = ret || 0;
632.3477 + ret = style.pixelLeft + "px";
632.3478 +
632.3479 + // Revert the changed values
632.3480 + style.left = left;
632.3481 + elem.runtimeStyle.left = rsLeft;
632.3482 + }
632.3483 + }
632.3484 +
632.3485 + return ret;
632.3486 + },
632.3487 +
632.3488 + // A method for quickly swapping in/out CSS properties to get correct calculations
632.3489 + swap: function( elem, options, callback ) {
632.3490 + var old = {};
632.3491 + // Remember the old values, and insert the new ones
632.3492 + for ( var name in options ) {
632.3493 + old[ name ] = elem.style[ name ];
632.3494 + elem.style[ name ] = options[ name ];
632.3495 + }
632.3496 +
632.3497 + callback.call( elem );
632.3498 +
632.3499 + // Revert the old values
632.3500 + for ( var name in options )
632.3501 + elem.style[ name ] = old[ name ];
632.3502 + }
632.3503 +});jQuery.fn.extend({
632.3504 + // Keep a copy of the old load
632.3505 + _load: jQuery.fn.load,
632.3506 +
632.3507 + load: function( url, params, callback ) {
632.3508 + if ( typeof url !== "string" )
632.3509 + return this._load( url );
632.3510 +
632.3511 + var off = url.indexOf(" ");
632.3512 + if ( off >= 0 ) {
632.3513 + var selector = url.slice(off, url.length);
632.3514 + url = url.slice(0, off);
632.3515 + }
632.3516 +
632.3517 + // Default to a GET request
632.3518 + var type = "GET";
632.3519 +
632.3520 + // If the second parameter was provided
632.3521 + if ( params )
632.3522 + // If it's a function
632.3523 + if ( jQuery.isFunction( params ) ) {
632.3524 + // We assume that it's the callback
632.3525 + callback = params;
632.3526 + params = null;
632.3527 +
632.3528 + // Otherwise, build a param string
632.3529 + } else if( typeof params === "object" ) {
632.3530 + params = jQuery.param( params );
632.3531 + type = "POST";
632.3532 + }
632.3533 +
632.3534 + var self = this;
632.3535 +
632.3536 + // Request the remote document
632.3537 + jQuery.ajax({
632.3538 + url: url,
632.3539 + type: type,
632.3540 + dataType: "html",
632.3541 + data: params,
632.3542 + complete: function(res, status){
632.3543 + // If successful, inject the HTML into all the matched elements
632.3544 + if ( status == "success" || status == "notmodified" )
632.3545 + // See if a selector was specified
632.3546 + self.html( selector ?
632.3547 + // Create a dummy div to hold the results
632.3548 + jQuery("<div/>")
632.3549 + // inject the contents of the document in, removing the scripts
632.3550 + // to avoid any 'Permission Denied' errors in IE
632.3551 + .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
632.3552 +
632.3553 + // Locate the specified elements
632.3554 + .find(selector) :
632.3555 +
632.3556 + // If not, just inject the full result
632.3557 + res.responseText );
632.3558 +
632.3559 + if( callback )
632.3560 + self.each( callback, [res.responseText, status, res] );
632.3561 + }
632.3562 + });
632.3563 + return this;
632.3564 + },
632.3565 +
632.3566 + serialize: function() {
632.3567 + return jQuery.param(this.serializeArray());
632.3568 + },
632.3569 + serializeArray: function() {
632.3570 + return this.map(function(){
632.3571 + return this.elements ? jQuery.makeArray(this.elements) : this;
632.3572 + })
632.3573 + .filter(function(){
632.3574 + return this.name && !this.disabled &&
632.3575 + (this.checked || /select|textarea/i.test(this.nodeName) ||
632.3576 + /text|hidden|password|search/i.test(this.type));
632.3577 + })
632.3578 + .map(function(i, elem){
632.3579 + var val = jQuery(this).val();
632.3580 + return val == null ? null :
632.3581 + jQuery.isArray(val) ?
632.3582 + jQuery.map( val, function(val, i){
632.3583 + return {name: elem.name, value: val};
632.3584 + }) :
632.3585 + {name: elem.name, value: val};
632.3586 + }).get();
632.3587 + }
632.3588 +});
632.3589 +
632.3590 +// Attach a bunch of functions for handling common AJAX events
632.3591 +jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
632.3592 + jQuery.fn[o] = function(f){
632.3593 + return this.bind(o, f);
632.3594 + };
632.3595 +});
632.3596 +
632.3597 +var jsc = now();
632.3598 +
632.3599 +jQuery.extend({
632.3600 +
632.3601 + get: function( url, data, callback, type ) {
632.3602 + // shift arguments if data argument was ommited
632.3603 + if ( jQuery.isFunction( data ) ) {
632.3604 + callback = data;
632.3605 + data = null;
632.3606 + }
632.3607 +
632.3608 + return jQuery.ajax({
632.3609 + type: "GET",
632.3610 + url: url,
632.3611 + data: data,
632.3612 + success: callback,
632.3613 + dataType: type
632.3614 + });
632.3615 + },
632.3616 +
632.3617 + getScript: function( url, callback ) {
632.3618 + return jQuery.get(url, null, callback, "script");
632.3619 + },
632.3620 +
632.3621 + getJSON: function( url, data, callback ) {
632.3622 + return jQuery.get(url, data, callback, "json");
632.3623 + },
632.3624 +
632.3625 + post: function( url, data, callback, type ) {
632.3626 + if ( jQuery.isFunction( data ) ) {
632.3627 + callback = data;
632.3628 + data = {};
632.3629 + }
632.3630 +
632.3631 + return jQuery.ajax({
632.3632 + type: "POST",
632.3633 + url: url,
632.3634 + data: data,
632.3635 + success: callback,
632.3636 + dataType: type
632.3637 + });
632.3638 + },
632.3639 +
632.3640 + ajaxSetup: function( settings ) {
632.3641 + jQuery.extend( jQuery.ajaxSettings, settings );
632.3642 + },
632.3643 +
632.3644 + ajaxSettings: {
632.3645 + url: location.href,
632.3646 + global: true,
632.3647 + type: "GET",
632.3648 + contentType: "application/x-www-form-urlencoded",
632.3649 + processData: true,
632.3650 + async: true,
632.3651 + /*
632.3652 + timeout: 0,
632.3653 + data: null,
632.3654 + username: null,
632.3655 + password: null,
632.3656 + */
632.3657 + // Create the request object; Microsoft failed to properly
632.3658 + // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
632.3659 + // This function can be overriden by calling jQuery.ajaxSetup
632.3660 + xhr:function(){
632.3661 + return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
632.3662 + },
632.3663 + accepts: {
632.3664 + xml: "application/xml, text/xml",
632.3665 + html: "text/html",
632.3666 + script: "text/javascript, application/javascript",
632.3667 + json: "application/json, text/javascript",
632.3668 + text: "text/plain",
632.3669 + _default: "*/*"
632.3670 + }
632.3671 + },
632.3672 +
632.3673 + // Last-Modified header cache for next request
632.3674 + lastModified: {},
632.3675 +
632.3676 + ajax: function( s ) {
632.3677 + // Extend the settings, but re-extend 's' so that it can be
632.3678 + // checked again later (in the test suite, specifically)
632.3679 + s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
632.3680 +
632.3681 + var jsonp, jsre = /=\?(&|$)/g, status, data,
632.3682 + type = s.type.toUpperCase();
632.3683 +
632.3684 + // convert data if not already a string
632.3685 + if ( s.data && s.processData && typeof s.data !== "string" )
632.3686 + s.data = jQuery.param(s.data);
632.3687 +
632.3688 + // Handle JSONP Parameter Callbacks
632.3689 + if ( s.dataType == "jsonp" ) {
632.3690 + if ( type == "GET" ) {
632.3691 + if ( !s.url.match(jsre) )
632.3692 + s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
632.3693 + } else if ( !s.data || !s.data.match(jsre) )
632.3694 + s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
632.3695 + s.dataType = "json";
632.3696 + }
632.3697 +
632.3698 + // Build temporary JSONP function
632.3699 + if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
632.3700 + jsonp = "jsonp" + jsc++;
632.3701 +
632.3702 + // Replace the =? sequence both in the query string and the data
632.3703 + if ( s.data )
632.3704 + s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
632.3705 + s.url = s.url.replace(jsre, "=" + jsonp + "$1");
632.3706 +
632.3707 + // We need to make sure
632.3708 + // that a JSONP style response is executed properly
632.3709 + s.dataType = "script";
632.3710 +
632.3711 + // Handle JSONP-style loading
632.3712 + window[ jsonp ] = function(tmp){
632.3713 + data = tmp;
632.3714 + success();
632.3715 + complete();
632.3716 + // Garbage collect
632.3717 + window[ jsonp ] = undefined;
632.3718 + try{ delete window[ jsonp ]; } catch(e){}
632.3719 + if ( head )
632.3720 + head.removeChild( script );
632.3721 + };
632.3722 + }
632.3723 +
632.3724 + if ( s.dataType == "script" && s.cache == null )
632.3725 + s.cache = false;
632.3726 +
632.3727 + if ( s.cache === false && type == "GET" ) {
632.3728 + var ts = now();
632.3729 + // try replacing _= if it is there
632.3730 + var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
632.3731 + // if nothing was replaced, add timestamp to the end
632.3732 + s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
632.3733 + }
632.3734 +
632.3735 + // If data is available, append data to url for get requests
632.3736 + if ( s.data && type == "GET" ) {
632.3737 + s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
632.3738 + }
632.3739 +
632.3740 + // Watch for a new set of requests
632.3741 + if ( s.global && ! jQuery.active++ )
632.3742 + jQuery.event.trigger( "ajaxStart" );
632.3743 +
632.3744 + // Matches an absolute URL, and saves the domain
632.3745 + var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
632.3746 +
632.3747 + // If we're requesting a remote document
632.3748 + // and trying to load JSON or Script with a GET
632.3749 + if ( s.dataType == "script" && type == "GET" && parts
632.3750 + && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
632.3751 +
632.3752 + var head = document.getElementsByTagName("head")[0];
632.3753 + var script = document.createElement("script");
632.3754 + script.src = s.url;
632.3755 + if (s.scriptCharset)
632.3756 + script.charset = s.scriptCharset;
632.3757 +
632.3758 + // Handle Script loading
632.3759 + if ( !jsonp ) {
632.3760 + var done = false;
632.3761 +
632.3762 + // Attach handlers for all browsers
632.3763 + script.onload = script.onreadystatechange = function(){
632.3764 + if ( !done && (!this.readyState ||
632.3765 + this.readyState == "loaded" || this.readyState == "complete") ) {
632.3766 + done = true;
632.3767 + success();
632.3768 + complete();
632.3769 +
632.3770 + // Handle memory leak in IE
632.3771 + script.onload = script.onreadystatechange = null;
632.3772 + head.removeChild( script );
632.3773 + }
632.3774 + };
632.3775 + }
632.3776 +
632.3777 + // Use insertBefore instead of appendChild to circumvent an IE6 bug.
632.3778 + // This arises when a base node is used (#2709 and #4378).
632.3779 + head.insertBefore( script, head.firstChild );
632.3780 +
632.3781 + // We handle everything using the script element injection
632.3782 + return undefined;
632.3783 + }
632.3784 +
632.3785 + var requestDone = false;
632.3786 +
632.3787 + // Create the request object
632.3788 + var xhr = s.xhr();
632.3789 +
632.3790 + // Open the socket
632.3791 + // Passing null username, generates a login popup on Opera (#2865)
632.3792 + if( s.username )
632.3793 + xhr.open(type, s.url, s.async, s.username, s.password);
632.3794 + else
632.3795 + xhr.open(type, s.url, s.async);
632.3796 +
632.3797 + // Need an extra try/catch for cross domain requests in Firefox 3
632.3798 + try {
632.3799 + // Set the correct header, if data is being sent
632.3800 + if ( s.data )
632.3801 + xhr.setRequestHeader("Content-Type", s.contentType);
632.3802 +
632.3803 + // Set the If-Modified-Since header, if ifModified mode.
632.3804 + if ( s.ifModified )
632.3805 + xhr.setRequestHeader("If-Modified-Since",
632.3806 + jQuery.lastModified[s.url] || "Thu, 01 Jan 2022 00:00:00 GMT" );
632.3807 +
632.3808 + // Set header so the called script knows that it's an XMLHttpRequest
632.3809 + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
632.3810 +
632.3811 + // Set the Accepts header for the server, depending on the dataType
632.3812 + xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
632.3813 + s.accepts[ s.dataType ] + ", */*" :
632.3814 + s.accepts._default );
632.3815 + } catch(e){}
632.3816 +
632.3817 + // Allow custom headers/mimetypes and early abort
632.3818 + if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
632.3819 + // Handle the global AJAX counter
632.3820 + if ( s.global && ! --jQuery.active )
632.3821 + jQuery.event.trigger( "ajaxStop" );
632.3822 + // close opended socket
632.3823 + xhr.abort();
632.3824 + return false;
632.3825 + }
632.3826 +
632.3827 + if ( s.global )
632.3828 + jQuery.event.trigger("ajaxSend", [xhr, s]);
632.3829 +
632.3830 + // Wait for a response to come back
632.3831 + var onreadystatechange = function(isTimeout){
632.3832 + // The request was aborted, clear the interval and decrement jQuery.active
632.3833 + if (xhr.readyState == 0) {
632.3834 + if (ival) {
632.3835 + // clear poll interval
632.3836 + clearInterval(ival);
632.3837 + ival = null;
632.3838 + // Handle the global AJAX counter
632.3839 + if ( s.global && ! --jQuery.active )
632.3840 + jQuery.event.trigger( "ajaxStop" );
632.3841 + }
632.3842 + // The transfer is complete and the data is available, or the request timed out
632.3843 + } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
632.3844 + requestDone = true;
632.3845 +
632.3846 + // clear poll interval
632.3847 + if (ival) {
632.3848 + clearInterval(ival);
632.3849 + ival = null;
632.3850 + }
632.3851 +
632.3852 + status = isTimeout == "timeout" ? "timeout" :
632.3853 + !jQuery.httpSuccess( xhr ) ? "error" :
632.3854 + s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
632.3855 + "success";
632.3856 +
632.3857 + if ( status == "success" ) {
632.3858 + // Watch for, and catch, XML document parse errors
632.3859 + try {
632.3860 + // process the data (runs the xml through httpData regardless of callback)
632.3861 + data = jQuery.httpData( xhr, s.dataType, s );
632.3862 + } catch(e) {
632.3863 + status = "parsererror";
632.3864 + }
632.3865 + }
632.3866 +
632.3867 + // Make sure that the request was successful or notmodified
632.3868 + if ( status == "success" ) {
632.3869 + // Cache Last-Modified header, if ifModified mode.
632.3870 + var modRes;
632.3871 + try {
632.3872 + modRes = xhr.getResponseHeader("Last-Modified");
632.3873 + } catch(e) {} // swallow exception thrown by FF if header is not available
632.3874 +
632.3875 + if ( s.ifModified && modRes )
632.3876 + jQuery.lastModified[s.url] = modRes;
632.3877 +
632.3878 + // JSONP handles its own success callback
632.3879 + if ( !jsonp )
632.3880 + success();
632.3881 + } else
632.3882 + jQuery.handleError(s, xhr, status);
632.3883 +
632.3884 + // Fire the complete handlers
632.3885 + complete();
632.3886 +
632.3887 + if ( isTimeout )
632.3888 + xhr.abort();
632.3889 +
632.3890 + // Stop memory leaks
632.3891 + if ( s.async )
632.3892 + xhr = null;
632.3893 + }
632.3894 + };
632.3895 +
632.3896 + if ( s.async ) {
632.3897 + // don't attach the handler to the request, just poll it instead
632.3898 + var ival = setInterval(onreadystatechange, 13);
632.3899 +
632.3900 + // Timeout checker
632.3901 + if ( s.timeout > 0 )
632.3902 + setTimeout(function(){
632.3903 + // Check to see if the request is still happening
632.3904 + if ( xhr && !requestDone )
632.3905 + onreadystatechange( "timeout" );
632.3906 + }, s.timeout);
632.3907 + }
632.3908 +
632.3909 + // Send the data
632.3910 + try {
632.3911 + xhr.send( type === "POST" ? s.data : null );
632.3912 + } catch(e) {
632.3913 + jQuery.handleError(s, xhr, null, e);
632.3914 + }
632.3915 +
632.3916 + // firefox 1.5 doesn't fire statechange for sync requests
632.3917 + if ( !s.async )
632.3918 + onreadystatechange();
632.3919 +
632.3920 + function success(){
632.3921 + // If a local callback was specified, fire it and pass it the data
632.3922 + if ( s.success )
632.3923 + s.success( data, status );
632.3924 +
632.3925 + // Fire the global callback
632.3926 + if ( s.global )
632.3927 + jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
632.3928 + }
632.3929 +
632.3930 + function complete(){
632.3931 + // Process result
632.3932 + if ( s.complete )
632.3933 + s.complete(xhr, status);
632.3934 +
632.3935 + // The request was completed
632.3936 + if ( s.global )
632.3937 + jQuery.event.trigger( "ajaxComplete", [xhr, s] );
632.3938 +
632.3939 + // Handle the global AJAX counter
632.3940 + if ( s.global && ! --jQuery.active )
632.3941 + jQuery.event.trigger( "ajaxStop" );
632.3942 + }
632.3943 +
632.3944 + // return XMLHttpRequest to allow aborting the request etc.
632.3945 + return xhr;
632.3946 + },
632.3947 +
632.3948 + handleError: function( s, xhr, status, e ) {
632.3949 + // If a local callback was specified, fire it
632.3950 + if ( s.error ) s.error( xhr, status, e );
632.3951 +
632.3952 + // Fire the global callback
632.3953 + if ( s.global )
632.3954 + jQuery.event.trigger( "ajaxError", [xhr, s, e] );
632.3955 + },
632.3956 +
632.3957 + // Counter for holding the number of active queries
632.3958 + active: 0,
632.3959 +
632.3960 + // Determines if an XMLHttpRequest was successful or not
632.3961 + httpSuccess: function( xhr ) {
632.3962 + try {
632.3963 + // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
632.3964 + return !xhr.status && location.protocol == "file:" ||
632.3965 + ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
632.3966 + } catch(e){}
632.3967 + return false;
632.3968 + },
632.3969 +
632.3970 + // Determines if an XMLHttpRequest returns NotModified
632.3971 + httpNotModified: function( xhr, url ) {
632.3972 + try {
632.3973 + var xhrRes = xhr.getResponseHeader("Last-Modified");
632.3974 +
632.3975 + // Firefox always returns 200. check Last-Modified date
632.3976 + return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
632.3977 + } catch(e){}
632.3978 + return false;
632.3979 + },
632.3980 +
632.3981 + httpData: function( xhr, type, s ) {
632.3982 + var ct = xhr.getResponseHeader("content-type"),
632.3983 + xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
632.3984 + data = xml ? xhr.responseXML : xhr.responseText;
632.3985 +
632.3986 + if ( xml && data.documentElement.tagName == "parsererror" ) {
632.3987 + throw "parsererror";
632.3988 + }
632.3989 +
632.3990 + // Allow a pre-filtering function to sanitize the response
632.3991 + // s != null is checked to keep backwards compatibility
632.3992 + if ( s && s.dataFilter ) {
632.3993 + data = s.dataFilter( data, type );
632.3994 + }
632.3995 +
632.3996 + // The filter can actually parse the response
632.3997 + if ( typeof data === "string" ) {
632.3998 +
632.3999 + // If the type is "script", eval it in global context
632.4000 + if ( type === "script" ) {
632.4001 + jQuery.globalEval( data );
632.4002 + }
632.4003 +
632.4004 + // Get the JavaScript object, if JSON is used.
632.4005 + if ( type == "json" ) {
632.4006 + if ( typeof JSON === "object" && JSON.parse ) {
632.4007 + data = JSON.parse( data );
632.4008 + } else {
632.4009 + data = (new Function("return " + data))();
632.4010 + }
632.4011 + }
632.4012 + }
632.4013 +
632.4014 + return data;
632.4015 + },
632.4016 +
632.4017 + // Serialize an array of form elements or a set of
632.4018 + // key/values into a query string
632.4019 + param: function( a ) {
632.4020 + var s = [ ];
632.4021 +
632.4022 + function add( key, value ){
632.4023 + s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
632.4024 + };
632.4025 +
632.4026 + // If an array was passed in, assume that it is an array
632.4027 + // of form elements
632.4028 + if ( jQuery.isArray(a) || a.jquery )
632.4029 + // Serialize the form elements
632.4030 + jQuery.each( a, function(){
632.4031 + add( this.name, this.value );
632.4032 + });
632.4033 +
632.4034 + // Otherwise, assume that it's an object of key/value pairs
632.4035 + else
632.4036 + // Serialize the key/values
632.4037 + for ( var j in a )
632.4038 + // If the value is an array then the key names need to be repeated
632.4039 + if ( jQuery.isArray(a[j]) )
632.4040 + jQuery.each( a[j], function(){
632.4041 + add( j, this );
632.4042 + });
632.4043 + else
632.4044 + add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
632.4045 +
632.4046 + // Return the resulting serialization
632.4047 + return s.join("&").replace(/%20/g, "+");
632.4048 + }
632.4049 +
632.4050 +});
632.4051 +var elemdisplay = {},
632.4052 + timerId,
632.4053 + fxAttrs = [
632.4054 + // height animations
632.4055 + [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
632.4056 + // width animations
632.4057 + [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
632.4058 + // opacity animations
632.4059 + [ "opacity" ]
632.4060 + ];
632.4061 +
632.4062 +function genFx( type, num ){
632.4063 + var obj = {};
632.4064 + jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
632.4065 + obj[ this ] = type;
632.4066 + });
632.4067 + return obj;
632.4068 +}
632.4069 +
632.4070 +jQuery.fn.extend({
632.4071 + show: function(speed,callback){
632.4072 + if ( speed ) {
632.4073 + return this.animate( genFx("show", 3), speed, callback);
632.4074 + } else {
632.4075 + for ( var i = 0, l = this.length; i < l; i++ ){
632.4076 + var old = jQuery.data(this[i], "olddisplay");
632.4077 +
632.4078 + this[i].style.display = old || "";
632.4079 +
632.4080 + if ( jQuery.css(this[i], "display") === "none" ) {
632.4081 + var tagName = this[i].tagName, display;
632.4082 +
632.4083 + if ( elemdisplay[ tagName ] ) {
632.4084 + display = elemdisplay[ tagName ];
632.4085 + } else {
632.4086 + var elem = jQuery("<" + tagName + " />").appendTo("body");
632.4087 +
632.4088 + display = elem.css("display");
632.4089 + if ( display === "none" )
632.4090 + display = "block";
632.4091 +
632.4092 + elem.remove();
632.4093 +
632.4094 + elemdisplay[ tagName ] = display;
632.4095 + }
632.4096 +
632.4097 + jQuery.data(this[i], "olddisplay", display);
632.4098 + }
632.4099 + }
632.4100 +
632.4101 + // Set the display of the elements in a second loop
632.4102 + // to avoid the constant reflow
632.4103 + for ( var i = 0, l = this.length; i < l; i++ ){
632.4104 + this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
632.4105 + }
632.4106 +
632.4107 + return this;
632.4108 + }
632.4109 + },
632.4110 +
632.4111 + hide: function(speed,callback){
632.4112 + if ( speed ) {
632.4113 + return this.animate( genFx("hide", 3), speed, callback);
632.4114 + } else {
632.4115 + for ( var i = 0, l = this.length; i < l; i++ ){
632.4116 + var old = jQuery.data(this[i], "olddisplay");
632.4117 + if ( !old && old !== "none" )
632.4118 + jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
632.4119 + }
632.4120 +
632.4121 + // Set the display of the elements in a second loop
632.4122 + // to avoid the constant reflow
632.4123 + for ( var i = 0, l = this.length; i < l; i++ ){
632.4124 + this[i].style.display = "none";
632.4125 + }
632.4126 +
632.4127 + return this;
632.4128 + }
632.4129 + },
632.4130 +
632.4131 + // Save the old toggle function
632.4132 + _toggle: jQuery.fn.toggle,
632.4133 +
632.4134 + toggle: function( fn, fn2 ){
632.4135 + var bool = typeof fn === "boolean";
632.4136 +
632.4137 + return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
632.4138 + this._toggle.apply( this, arguments ) :
632.4139 + fn == null || bool ?
632.4140 + this.each(function(){
632.4141 + var state = bool ? fn : jQuery(this).is(":hidden");
632.4142 + jQuery(this)[ state ? "show" : "hide" ]();
632.4143 + }) :
632.4144 + this.animate(genFx("toggle", 3), fn, fn2);
632.4145 + },
632.4146 +
632.4147 + fadeTo: function(speed,to,callback){
632.4148 + return this.filter(":hidden").css('opacity', 0).show().end()
632.4149 + .animate({opacity: to}, speed, callback);
632.4150 + },
632.4151 +
632.4152 + animate: function( prop, speed, easing, callback ) {
632.4153 + var optall = jQuery.speed(speed, easing, callback);
632.4154 +
632.4155 + return this[ optall.queue === false ? "each" : "queue" ](function(){
632.4156 +
632.4157 + var opt = jQuery.extend({}, optall), p,
632.4158 + hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
632.4159 + self = this;
632.4160 +
632.4161 + for ( p in prop ) {
632.4162 + if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
632.4163 + return opt.complete.call(this);
632.4164 +
632.4165 + if ( ( p == "height" || p == "width" ) && this.style ) {
632.4166 + // Store display property
632.4167 + opt.display = jQuery.css(this, "display");
632.4168 +
632.4169 + // Make sure that nothing sneaks out
632.4170 + opt.overflow = this.style.overflow;
632.4171 + }
632.4172 + }
632.4173 +
632.4174 + if ( opt.overflow != null )
632.4175 + this.style.overflow = "hidden";
632.4176 +
632.4177 + opt.curAnim = jQuery.extend({}, prop);
632.4178 +
632.4179 + jQuery.each( prop, function(name, val){
632.4180 + var e = new jQuery.fx( self, opt, name );
632.4181 +
632.4182 + if ( /toggle|show|hide/.test(val) )
632.4183 + e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
632.4184 + else {
632.4185 + var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
632.4186 + start = e.cur(true) || 0;
632.4187 +
632.4188 + if ( parts ) {
632.4189 + var end = parseFloat(parts[2]),
632.4190 + unit = parts[3] || "px";
632.4191 +
632.4192 + // We need to compute starting value
632.4193 + if ( unit != "px" ) {
632.4194 + self.style[ name ] = (end || 1) + unit;
632.4195 + start = ((end || 1) / e.cur(true)) * start;
632.4196 + self.style[ name ] = start + unit;
632.4197 + }
632.4198 +
632.4199 + // If a +=/-= token was provided, we're doing a relative animation
632.4200 + if ( parts[1] )
632.4201 + end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
632.4202 +
632.4203 + e.custom( start, end, unit );
632.4204 + } else
632.4205 + e.custom( start, val, "" );
632.4206 + }
632.4207 + });
632.4208 +
632.4209 + // For JS strict compliance
632.4210 + return true;
632.4211 + });
632.4212 + },
632.4213 +
632.4214 + stop: function(clearQueue, gotoEnd){
632.4215 + var timers = jQuery.timers;
632.4216 +
632.4217 + if (clearQueue)
632.4218 + this.queue([]);
632.4219 +
632.4220 + this.each(function(){
632.4221 + // go in reverse order so anything added to the queue during the loop is ignored
632.4222 + for ( var i = timers.length - 1; i >= 0; i-- )
632.4223 + if ( timers[i].elem == this ) {
632.4224 + if (gotoEnd)
632.4225 + // force the next step to be the last
632.4226 + timers[i](true);
632.4227 + timers.splice(i, 1);
632.4228 + }
632.4229 + });
632.4230 +
632.4231 + // start the next in the queue if the last step wasn't forced
632.4232 + if (!gotoEnd)
632.4233 + this.dequeue();
632.4234 +
632.4235 + return this;
632.4236 + }
632.4237 +
632.4238 +});
632.4239 +
632.4240 +// Generate shortcuts for custom animations
632.4241 +jQuery.each({
632.4242 + slideDown: genFx("show", 1),
632.4243 + slideUp: genFx("hide", 1),
632.4244 + slideToggle: genFx("toggle", 1),
632.4245 + fadeIn: { opacity: "show" },
632.4246 + fadeOut: { opacity: "hide" }
632.4247 +}, function( name, props ){
632.4248 + jQuery.fn[ name ] = function( speed, callback ){
632.4249 + return this.animate( props, speed, callback );
632.4250 + };
632.4251 +});
632.4252 +
632.4253 +jQuery.extend({
632.4254 +
632.4255 + speed: function(speed, easing, fn) {
632.4256 + var opt = typeof speed === "object" ? speed : {
632.4257 + complete: fn || !fn && easing ||
632.4258 + jQuery.isFunction( speed ) && speed,
632.4259 + duration: speed,
632.4260 + easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
632.4261 + };
632.4262 +
632.4263 + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
632.4264 + jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
632.4265 +
632.4266 + // Queueing
632.4267 + opt.old = opt.complete;
632.4268 + opt.complete = function(){
632.4269 + if ( opt.queue !== false )
632.4270 + jQuery(this).dequeue();
632.4271 + if ( jQuery.isFunction( opt.old ) )
632.4272 + opt.old.call( this );
632.4273 + };
632.4274 +
632.4275 + return opt;
632.4276 + },
632.4277 +
632.4278 + easing: {
632.4279 + linear: function( p, n, firstNum, diff ) {
632.4280 + return firstNum + diff * p;
632.4281 + },
632.4282 + swing: function( p, n, firstNum, diff ) {
632.4283 + return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
632.4284 + }
632.4285 + },
632.4286 +
632.4287 + timers: [],
632.4288 +
632.4289 + fx: function( elem, options, prop ){
632.4290 + this.options = options;
632.4291 + this.elem = elem;
632.4292 + this.prop = prop;
632.4293 +
632.4294 + if ( !options.orig )
632.4295 + options.orig = {};
632.4296 + }
632.4297 +
632.4298 +});
632.4299 +
632.4300 +jQuery.fx.prototype = {
632.4301 +
632.4302 + // Simple function for setting a style value
632.4303 + update: function(){
632.4304 + if ( this.options.step )
632.4305 + this.options.step.call( this.elem, this.now, this );
632.4306 +
632.4307 + (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
632.4308 +
632.4309 + // Set display property to block for height/width animations
632.4310 + if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
632.4311 + this.elem.style.display = "block";
632.4312 + },
632.4313 +
632.4314 + // Get the current size
632.4315 + cur: function(force){
632.4316 + if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
632.4317 + return this.elem[ this.prop ];
632.4318 +
632.4319 + var r = parseFloat(jQuery.css(this.elem, this.prop, force));
632.4320 + return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
632.4321 + },
632.4322 +
632.4323 + // Start an animation from one number to another
632.4324 + custom: function(from, to, unit){
632.4325 + this.startTime = now();
632.4326 + this.start = from;
632.4327 + this.end = to;
632.4328 + this.unit = unit || this.unit || "px";
632.4329 + this.now = this.start;
632.4330 + this.pos = this.state = 0;
632.4331 +
632.4332 + var self = this;
632.4333 + function t(gotoEnd){
632.4334 + return self.step(gotoEnd);
632.4335 + }
632.4336 +
632.4337 + t.elem = this.elem;
632.4338 +
632.4339 + if ( t() && jQuery.timers.push(t) && !timerId )
632.4340 + timerId = setInterval(jQuery.fx.tick, 13);
632.4341 + },
632.4342 +
632.4343 + // Simple 'show' function
632.4344 + show: function(){
632.4345 + // Remember where we started, so that we can go back to it later
632.4346 + this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
632.4347 + this.options.show = true;
632.4348 +
632.4349 + // Begin the animation
632.4350 + // Make sure that we start at a small width/height to avoid any
632.4351 + // flash of content
632.4352 + this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
632.4353 +
632.4354 + // Start by showing the element
632.4355 + jQuery(this.elem).show();
632.4356 + },
632.4357 +
632.4358 + // Simple 'hide' function
632.4359 + hide: function(){
632.4360 + // Remember where we started, so that we can go back to it later
632.4361 + this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
632.4362 + this.options.hide = true;
632.4363 +
632.4364 + // Begin the animation
632.4365 + this.custom(this.cur(), 0);
632.4366 + },
632.4367 +
632.4368 + // Each step of an animation
632.4369 + step: function(gotoEnd){
632.4370 + var t = now();
632.4371 +
632.4372 + if ( gotoEnd || t >= this.options.duration + this.startTime ) {
632.4373 + this.now = this.end;
632.4374 + this.pos = this.state = 1;
632.4375 + this.update();
632.4376 +
632.4377 + this.options.curAnim[ this.prop ] = true;
632.4378 +
632.4379 + var done = true;
632.4380 + for ( var i in this.options.curAnim )
632.4381 + if ( this.options.curAnim[i] !== true )
632.4382 + done = false;
632.4383 +
632.4384 + if ( done ) {
632.4385 + if ( this.options.display != null ) {
632.4386 + // Reset the overflow
632.4387 + this.elem.style.overflow = this.options.overflow;
632.4388 +
632.4389 + // Reset the display
632.4390 + this.elem.style.display = this.options.display;
632.4391 + if ( jQuery.css(this.elem, "display") == "none" )
632.4392 + this.elem.style.display = "block";
632.4393 + }
632.4394 +
632.4395 + // Hide the element if the "hide" operation was done
632.4396 + if ( this.options.hide )
632.4397 + jQuery(this.elem).hide();
632.4398 +
632.4399 + // Reset the properties, if the item has been hidden or shown
632.4400 + if ( this.options.hide || this.options.show )
632.4401 + for ( var p in this.options.curAnim )
632.4402 + jQuery.style(this.elem, p, this.options.orig[p]);
632.4403 +
632.4404 + // Execute the complete function
632.4405 + this.options.complete.call( this.elem );
632.4406 + }
632.4407 +
632.4408 + return false;
632.4409 + } else {
632.4410 + var n = t - this.startTime;
632.4411 + this.state = n / this.options.duration;
632.4412 +
632.4413 + // Perform the easing function, defaults to swing
632.4414 + this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
632.4415 + this.now = this.start + ((this.end - this.start) * this.pos);
632.4416 +
632.4417 + // Perform the next step of the animation
632.4418 + this.update();
632.4419 + }
632.4420 +
632.4421 + return true;
632.4422 + }
632.4423 +
632.4424 +};
632.4425 +
632.4426 +jQuery.extend( jQuery.fx, {
632.4427 +
632.4428 + tick:function(){
632.4429 + var timers = jQuery.timers;
632.4430 +
632.4431 + for ( var i = 0; i < timers.length; i++ )
632.4432 + if ( !timers[i]() )
632.4433 + timers.splice(i--, 1);
632.4434 +
632.4435 + if ( !timers.length )
632.4436 + jQuery.fx.stop();
632.4437 + },
632.4438 +
632.4439 + stop:function(){
632.4440 + clearInterval( timerId );
632.4441 + timerId = null;
632.4442 + },
632.4443 +
632.4444 + speeds:{
632.4445 + slow: 600,
632.4446 + fast: 200,
632.4447 + // Default speed
632.4448 + _default: 400
632.4449 + },
632.4450 +
632.4451 + step: {
632.4452 +
632.4453 + opacity: function(fx){
632.4454 + jQuery.style(fx.elem, "opacity", fx.now);
632.4455 + },
632.4456 +
632.4457 + _default: function(fx){
632.4458 + if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
632.4459 + fx.elem.style[ fx.prop ] = fx.now + fx.unit;
632.4460 + else
632.4461 + fx.elem[ fx.prop ] = fx.now;
632.4462 + }
632.4463 + }
632.4464 +});
632.4465 +if ( "getBoundingClientRect" in document.documentElement )
632.4466 + jQuery.fn.offset = function() {
632.4467 + var elem = this[0];
632.4468 + if ( !elem || !elem.ownerDocument ) return null;
632.4469 + if ( elem === elem.ownerDocument.body ) return jQuery.offset.bodyOffset( elem );
632.4470 + var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
632.4471 + clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
632.4472 + top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
632.4473 + left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
632.4474 + return { top: top, left: left };
632.4475 + };
632.4476 +else
632.4477 + jQuery.fn.offset = function() {
632.4478 + var elem = this[0];
632.4479 + if ( !elem || !elem.ownerDocument ) return null;
632.4480 + if ( elem === elem.ownerDocument.body ) return jQuery.offset.bodyOffset( elem );
632.4481 + jQuery.offset.initialize();
632.4482 +
632.4483 + var offsetParent = elem.offsetParent, prevOffsetParent = elem,
632.4484 + doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
632.4485 + body = doc.body, defaultView = doc.defaultView,
632.4486 + prevComputedStyle = defaultView.getComputedStyle(elem, null),
632.4487 + top = elem.offsetTop, left = elem.offsetLeft;
632.4488 +
632.4489 + while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
632.4490 + if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) break;
632.4491 + computedStyle = defaultView.getComputedStyle(elem, null);
632.4492 + top -= elem.scrollTop, left -= elem.scrollLeft;
632.4493 + if ( elem === offsetParent ) {
632.4494 + top += elem.offsetTop, left += elem.offsetLeft;
632.4495 + if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
632.4496 + top += parseFloat( computedStyle.borderTopWidth ) || 0,
632.4497 + left += parseFloat( computedStyle.borderLeftWidth ) || 0;
632.4498 + prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
632.4499 + }
632.4500 + if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
632.4501 + top += parseFloat( computedStyle.borderTopWidth ) || 0,
632.4502 + left += parseFloat( computedStyle.borderLeftWidth ) || 0;
632.4503 + prevComputedStyle = computedStyle;
632.4504 + }
632.4505 +
632.4506 + if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
632.4507 + top += body.offsetTop,
632.4508 + left += body.offsetLeft;
632.4509 +
632.4510 + if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" )
632.4511 + top += Math.max( docElem.scrollTop, body.scrollTop ),
632.4512 + left += Math.max( docElem.scrollLeft, body.scrollLeft );
632.4513 +
632.4514 + return { top: top, left: left };
632.4515 + };
632.4516 +
632.4517 +jQuery.offset = {
632.4518 + initialize: function() {
632.4519 + var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, 'marginTop', true) ) || 0,
632.4520 + html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
632.4521 +
632.4522 + jQuery.extend( container.style, { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' } );
632.4523 +
632.4524 + container.innerHTML = html;
632.4525 + body.insertBefore( container, body.firstChild );
632.4526 + innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
632.4527 +
632.4528 + this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
632.4529 + this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
632.4530 +
632.4531 + checkDiv.style.position = 'fixed', checkDiv.style.top = '20px';
632.4532 + this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); // safari subtracts parent border width here which is 5px
632.4533 + checkDiv.style.position = '', checkDiv.style.top = '';
632.4534 +
632.4535 + innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
632.4536 + this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
632.4537 +
632.4538 + this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
632.4539 +
632.4540 + body.removeChild( container );
632.4541 + jQuery.offset.initialize = function(){};
632.4542 +
632.4543 + body = container = innerDiv = checkDiv = table = td = null;
632.4544 + },
632.4545 +
632.4546 + bodyOffset: function(body) {
632.4547 + jQuery.offset.initialize();
632.4548 + var top = body.offsetTop, left = body.offsetLeft;
632.4549 + if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
632.4550 + top += parseFloat( jQuery.curCSS(body, 'marginTop', true) ) || 0,
632.4551 + left += parseFloat( jQuery.curCSS(body, 'marginLeft', true) ) || 0;
632.4552 + return { top: top, left: left };
632.4553 + }
632.4554 +};
632.4555 +
632.4556 +
632.4557 +jQuery.fn.extend({
632.4558 + position: function() {
632.4559 + if ( !this[0] ) return null;
632.4560 +
632.4561 + var elem = this[0],
632.4562 +
632.4563 + // Get *real* offsetParent
632.4564 + offsetParent = this.offsetParent(),
632.4565 +
632.4566 + // Get correct offsets
632.4567 + offset = this.offset(),
632.4568 + parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
632.4569 +
632.4570 + // Subtract element margins
632.4571 + // note: when an element has margin: auto the offsetLeft and marginLeft
632.4572 + // are the same in Safari causing offset.left to incorrectly be 0
632.4573 + offset.top -= parseFloat( jQuery.curCSS(elem, 'marginTop', true) ) || 0;
632.4574 + offset.left -= parseFloat( jQuery.curCSS(elem, 'marginLeft', true) ) || 0;
632.4575 +
632.4576 + // Add offsetParent borders
632.4577 + parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], 'borderTopWidth', true) ) || 0;
632.4578 + parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], 'borderLeftWidth', true) ) || 0;
632.4579 +
632.4580 + // Subtract the two offsets
632.4581 + return {
632.4582 + top: offset.top - parentOffset.top,
632.4583 + left: offset.left - parentOffset.left
632.4584 + };
632.4585 + },
632.4586 +
632.4587 + offsetParent: function() {
632.4588 + var offsetParent = this[0].offsetParent || document.body;
632.4589 + while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') === 'static') )
632.4590 + offsetParent = offsetParent.offsetParent;
632.4591 + return jQuery( offsetParent );
632.4592 + }
632.4593 +});
632.4594 +
632.4595 +
632.4596 +// Create scrollLeft and scrollTop methods
632.4597 +jQuery.each( ['Left', 'Top'], function(i, name) {
632.4598 + var method = 'scroll' + name;
632.4599 +
632.4600 + jQuery.fn[ method ] = function(val) {
632.4601 + if ( !this[0] ) return null;
632.4602 +
632.4603 + var elem = this[0], win = ("scrollTo" in elem && elem.document) ? elem :
632.4604 + (elem.nodeName === "#document") ? elem.defaultView || elem.parentWindow :
632.4605 + false;
632.4606 +
632.4607 + return val !== undefined ?
632.4608 +
632.4609 + // Set the scroll offset
632.4610 + this.each(function() {
632.4611 + win = ("scrollTo" in this && this.document) ? this :
632.4612 + (this.nodeName === "#document") ? this.defaultView || this.parentWindow :
632.4613 + false;
632.4614 +
632.4615 + win ?
632.4616 + win.scrollTo(
632.4617 + !i ? val : jQuery(win).scrollLeft(),
632.4618 + i ? val : jQuery(win).scrollTop()
632.4619 + ) :
632.4620 + this[ method ] = val;
632.4621 + }) :
632.4622 +
632.4623 + // Return the scroll offset
632.4624 + win ?
632.4625 + win[ i ? 'pageYOffset' : 'pageXOffset' ] ||
632.4626 + jQuery.support.boxModel && win.document.documentElement[ method ] ||
632.4627 + win.document.body[ method ] :
632.4628 + elem[ method ];
632.4629 + };
632.4630 +});
632.4631 +// Create innerHeight, innerWidth, outerHeight and outerWidth methods
632.4632 +jQuery.each([ "Height", "Width" ], function(i, name){
632.4633 +
632.4634 + var type = name.toLowerCase();
632.4635 +
632.4636 + // innerHeight and innerWidth
632.4637 + jQuery.fn["inner" + name] = function(){
632.4638 + return this[0] ?
632.4639 + jQuery.css( this[0], type, false, "padding" ) :
632.4640 + null;
632.4641 + };
632.4642 +
632.4643 + // outerHeight and outerWidth
632.4644 + jQuery.fn["outer" + name] = function(margin) {
632.4645 + return this[0] ?
632.4646 + jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
632.4647 + null;
632.4648 + };
632.4649 +
632.4650 + jQuery.fn[ type ] = function( size ) {
632.4651 + // Get window width or height
632.4652 + var elem = this[0];
632.4653 + if ( !elem ) return null;
632.4654 + return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
632.4655 + // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
632.4656 + elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
632.4657 + elem.document.body[ "client" + name ] :
632.4658 +
632.4659 + // Get document width or height
632.4660 + (elem.nodeName === "#document") ? // is it a document
632.4661 + // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
632.4662 + Math.max(
632.4663 + elem.documentElement["client" + name],
632.4664 + elem.body["scroll" + name], elem.documentElement["scroll" + name],
632.4665 + elem.body["offset" + name], elem.documentElement["offset" + name]
632.4666 + ) :
632.4667 +
632.4668 + // Get or set width or height on the element
632.4669 + size === undefined ?
632.4670 + // Get width or height on the element
632.4671 + jQuery.css( elem, type ) :
632.4672 +
632.4673 + // Set the width or height on the element (default to pixels if value is unitless)
632.4674 + this.css( type, typeof size === "string" ? size : size + "px" );
632.4675 + };
632.4676 +
632.4677 +});
632.4678 +})(window);
633.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
633.2 +++ b/web/static/js/cluetip-1.0.6/lib/jquery-1.4.js Mon Apr 26 11:16:23 2010 +0200
633.3 @@ -0,0 +1,5999 @@
633.4 +/*!
633.5 + * jQuery JavaScript Library v1.4
633.6 + * http://jquery.com/
633.7 + *
633.8 + * Copyright 2010, John Resig
633.9 + * Dual licensed under the MIT or GPL Version 2 licenses.
633.10 + * http://docs.jquery.com/License
633.11 + *
633.12 + * Includes Sizzle.js
633.13 + * http://sizzlejs.com/
633.14 + * Copyright 2010, The Dojo Foundation
633.15 + * Released under the MIT, BSD, and GPL Licenses.
633.16 + *
633.17 + * Date: Wed Jan 13 11:24:54 2010 -0500
633.18 + */
633.19 +(function( window, undefined ) {
633.20 +
633.21 +// Define a local copy of jQuery
633.22 +var jQuery = function( selector, context ) {
633.23 + // The jQuery object is actually just the init constructor 'enhanced'
633.24 + return new jQuery.fn.init( selector, context );
633.25 + },
633.26 +
633.27 + // Map over jQuery in case of overwrite
633.28 + _jQuery = window.jQuery,
633.29 +
633.30 + // Map over the $ in case of overwrite
633.31 + _$ = window.$,
633.32 +
633.33 + // Use the correct document accordingly with window argument (sandbox)
633.34 + document = window.document,
633.35 +
633.36 + // A central reference to the root jQuery(document)
633.37 + rootjQuery,
633.38 +
633.39 + // A simple way to check for HTML strings or ID strings
633.40 + // (both of which we optimize for)
633.41 + quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
633.42 +
633.43 + // Is it a simple selector
633.44 + isSimple = /^.[^:#\[\.,]*$/,
633.45 +
633.46 + // Check if a string has a non-whitespace character in it
633.47 + rnotwhite = /\S/,
633.48 +
633.49 + // Used for trimming whitespace
633.50 + rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
633.51 +
633.52 + // Match a standalone tag
633.53 + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
633.54 +
633.55 + // Keep a UserAgent string for use with jQuery.browser
633.56 + userAgent = navigator.userAgent,
633.57 +
633.58 + // For matching the engine and version of the browser
633.59 + browserMatch,
633.60 +
633.61 + // Has the ready events already been bound?
633.62 + readyBound = false,
633.63 +
633.64 + // The functions to execute on DOM ready
633.65 + readyList = [],
633.66 +
633.67 + // The ready event handler
633.68 + DOMContentLoaded,
633.69 +
633.70 + // Save a reference to some core methods
633.71 + toString = Object.prototype.toString,
633.72 + hasOwnProperty = Object.prototype.hasOwnProperty,
633.73 + push = Array.prototype.push,
633.74 + slice = Array.prototype.slice,
633.75 + indexOf = Array.prototype.indexOf;
633.76 +
633.77 +jQuery.fn = jQuery.prototype = {
633.78 + init: function( selector, context ) {
633.79 + var match, elem, ret, doc;
633.80 +
633.81 + // Handle $(""), $(null), or $(undefined)
633.82 + if ( !selector ) {
633.83 + return this;
633.84 + }
633.85 +
633.86 + // Handle $(DOMElement)
633.87 + if ( selector.nodeType ) {
633.88 + this.context = this[0] = selector;
633.89 + this.length = 1;
633.90 + return this;
633.91 + }
633.92 +
633.93 + // Handle HTML strings
633.94 + if ( typeof selector === "string" ) {
633.95 + // Are we dealing with HTML string or an ID?
633.96 + match = quickExpr.exec( selector );
633.97 +
633.98 + // Verify a match, and that no context was specified for #id
633.99 + if ( match && (match[1] || !context) ) {
633.100 +
633.101 + // HANDLE: $(html) -> $(array)
633.102 + if ( match[1] ) {
633.103 + doc = (context ? context.ownerDocument || context : document);
633.104 +
633.105 + // If a single string is passed in and it's a single tag
633.106 + // just do a createElement and skip the rest
633.107 + ret = rsingleTag.exec( selector );
633.108 +
633.109 + if ( ret ) {
633.110 + if ( jQuery.isPlainObject( context ) ) {
633.111 + selector = [ document.createElement( ret[1] ) ];
633.112 + jQuery.fn.attr.call( selector, context, true );
633.113 +
633.114 + } else {
633.115 + selector = [ doc.createElement( ret[1] ) ];
633.116 + }
633.117 +
633.118 + } else {
633.119 + ret = buildFragment( [ match[1] ], [ doc ] );
633.120 + selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
633.121 + }
633.122 +
633.123 + // HANDLE: $("#id")
633.124 + } else {
633.125 + elem = document.getElementById( match[2] );
633.126 +
633.127 + if ( elem ) {
633.128 + // Handle the case where IE and Opera return items
633.129 + // by name instead of ID
633.130 + if ( elem.id !== match[2] ) {
633.131 + return rootjQuery.find( selector );
633.132 + }
633.133 +
633.134 + // Otherwise, we inject the element directly into the jQuery object
633.135 + this.length = 1;
633.136 + this[0] = elem;
633.137 + }
633.138 +
633.139 + this.context = document;
633.140 + this.selector = selector;
633.141 + return this;
633.142 + }
633.143 +
633.144 + // HANDLE: $("TAG")
633.145 + } else if ( !context && /^\w+$/.test( selector ) ) {
633.146 + this.selector = selector;
633.147 + this.context = document;
633.148 + selector = document.getElementsByTagName( selector );
633.149 +
633.150 + // HANDLE: $(expr, $(...))
633.151 + } else if ( !context || context.jquery ) {
633.152 + return (context || rootjQuery).find( selector );
633.153 +
633.154 + // HANDLE: $(expr, context)
633.155 + // (which is just equivalent to: $(context).find(expr)
633.156 + } else {
633.157 + return jQuery( context ).find( selector );
633.158 + }
633.159 +
633.160 + // HANDLE: $(function)
633.161 + // Shortcut for document ready
633.162 + } else if ( jQuery.isFunction( selector ) ) {
633.163 + return rootjQuery.ready( selector );
633.164 + }
633.165 +
633.166 + if (selector.selector !== undefined) {
633.167 + this.selector = selector.selector;
633.168 + this.context = selector.context;
633.169 + }
633.170 +
633.171 + return jQuery.isArray( selector ) ?
633.172 + this.setArray( selector ) :
633.173 + jQuery.makeArray( selector, this );
633.174 + },
633.175 +
633.176 + // Start with an empty selector
633.177 + selector: "",
633.178 +
633.179 + // The current version of jQuery being used
633.180 + jquery: "1.4",
633.181 +
633.182 + // The default length of a jQuery object is 0
633.183 + length: 0,
633.184 +
633.185 + // The number of elements contained in the matched element set
633.186 + size: function() {
633.187 + return this.length;
633.188 + },
633.189 +
633.190 + toArray: function() {
633.191 + return slice.call( this, 0 );
633.192 + },
633.193 +
633.194 + // Get the Nth element in the matched element set OR
633.195 + // Get the whole matched element set as a clean array
633.196 + get: function( num ) {
633.197 + return num == null ?
633.198 +
633.199 + // Return a 'clean' array
633.200 + this.toArray() :
633.201 +
633.202 + // Return just the object
633.203 + ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
633.204 + },
633.205 +
633.206 + // Take an array of elements and push it onto the stack
633.207 + // (returning the new matched element set)
633.208 + pushStack: function( elems, name, selector ) {
633.209 + // Build a new jQuery matched element set
633.210 + var ret = jQuery( elems || null );
633.211 +
633.212 + // Add the old object onto the stack (as a reference)
633.213 + ret.prevObject = this;
633.214 +
633.215 + ret.context = this.context;
633.216 +
633.217 + if ( name === "find" ) {
633.218 + ret.selector = this.selector + (this.selector ? " " : "") + selector;
633.219 + } else if ( name ) {
633.220 + ret.selector = this.selector + "." + name + "(" + selector + ")";
633.221 + }
633.222 +
633.223 + // Return the newly-formed element set
633.224 + return ret;
633.225 + },
633.226 +
633.227 + // Force the current matched set of elements to become
633.228 + // the specified array of elements (destroying the stack in the process)
633.229 + // You should use pushStack() in order to do this, but maintain the stack
633.230 + setArray: function( elems ) {
633.231 + // Resetting the length to 0, then using the native Array push
633.232 + // is a super-fast way to populate an object with array-like properties
633.233 + this.length = 0;
633.234 + push.apply( this, elems );
633.235 +
633.236 + return this;
633.237 + },
633.238 +
633.239 + // Execute a callback for every element in the matched set.
633.240 + // (You can seed the arguments with an array of args, but this is
633.241 + // only used internally.)
633.242 + each: function( callback, args ) {
633.243 + return jQuery.each( this, callback, args );
633.244 + },
633.245 +
633.246 + ready: function( fn ) {
633.247 + // Attach the listeners
633.248 + jQuery.bindReady();
633.249 +
633.250 + // If the DOM is already ready
633.251 + if ( jQuery.isReady ) {
633.252 + // Execute the function immediately
633.253 + fn.call( document, jQuery );
633.254 +
633.255 + // Otherwise, remember the function for later
633.256 + } else if ( readyList ) {
633.257 + // Add the function to the wait list
633.258 + readyList.push( fn );
633.259 + }
633.260 +
633.261 + return this;
633.262 + },
633.263 +
633.264 + eq: function( i ) {
633.265 + return i === -1 ?
633.266 + this.slice( i ) :
633.267 + this.slice( i, +i + 1 );
633.268 + },
633.269 +
633.270 + first: function() {
633.271 + return this.eq( 0 );
633.272 + },
633.273 +
633.274 + last: function() {
633.275 + return this.eq( -1 );
633.276 + },
633.277 +
633.278 + slice: function() {
633.279 + return this.pushStack( slice.apply( this, arguments ),
633.280 + "slice", slice.call(arguments).join(",") );
633.281 + },
633.282 +
633.283 + map: function( callback ) {
633.284 + return this.pushStack( jQuery.map(this, function( elem, i ) {
633.285 + return callback.call( elem, i, elem );
633.286 + }));
633.287 + },
633.288 +
633.289 + end: function() {
633.290 + return this.prevObject || jQuery(null);
633.291 + },
633.292 +
633.293 + // For internal use only.
633.294 + // Behaves like an Array's method, not like a jQuery method.
633.295 + push: push,
633.296 + sort: [].sort,
633.297 + splice: [].splice
633.298 +};
633.299 +
633.300 +// Give the init function the jQuery prototype for later instantiation
633.301 +jQuery.fn.init.prototype = jQuery.fn;
633.302 +
633.303 +jQuery.extend = jQuery.fn.extend = function() {
633.304 + // copy reference to target object
633.305 + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
633.306 +
633.307 + // Handle a deep copy situation
633.308 + if ( typeof target === "boolean" ) {
633.309 + deep = target;
633.310 + target = arguments[1] || {};
633.311 + // skip the boolean and the target
633.312 + i = 2;
633.313 + }
633.314 +
633.315 + // Handle case when target is a string or something (possible in deep copy)
633.316 + if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
633.317 + target = {};
633.318 + }
633.319 +
633.320 + // extend jQuery itself if only one argument is passed
633.321 + if ( length === i ) {
633.322 + target = this;
633.323 + --i;
633.324 + }
633.325 +
633.326 + for ( ; i < length; i++ ) {
633.327 + // Only deal with non-null/undefined values
633.328 + if ( (options = arguments[ i ]) != null ) {
633.329 + // Extend the base object
633.330 + for ( name in options ) {
633.331 + src = target[ name ];
633.332 + copy = options[ name ];
633.333 +
633.334 + // Prevent never-ending loop
633.335 + if ( target === copy ) {
633.336 + continue;
633.337 + }
633.338 +
633.339 + // Recurse if we're merging object literal values or arrays
633.340 + if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
633.341 + var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
633.342 + : jQuery.isArray(copy) ? [] : {};
633.343 +
633.344 + // Never move original objects, clone them
633.345 + target[ name ] = jQuery.extend( deep, clone, copy );
633.346 +
633.347 + // Don't bring in undefined values
633.348 + } else if ( copy !== undefined ) {
633.349 + target[ name ] = copy;
633.350 + }
633.351 + }
633.352 + }
633.353 + }
633.354 +
633.355 + // Return the modified object
633.356 + return target;
633.357 +};
633.358 +
633.359 +jQuery.extend({
633.360 + noConflict: function( deep ) {
633.361 + window.$ = _$;
633.362 +
633.363 + if ( deep ) {
633.364 + window.jQuery = _jQuery;
633.365 + }
633.366 +
633.367 + return jQuery;
633.368 + },
633.369 +
633.370 + // Is the DOM ready to be used? Set to true once it occurs.
633.371 + isReady: false,
633.372 +
633.373 + // Handle when the DOM is ready
633.374 + ready: function() {
633.375 + // Make sure that the DOM is not already loaded
633.376 + if ( !jQuery.isReady ) {
633.377 + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
633.378 + if ( !document.body ) {
633.379 + return setTimeout( jQuery.ready, 13 );
633.380 + }
633.381 +
633.382 + // Remember that the DOM is ready
633.383 + jQuery.isReady = true;
633.384 +
633.385 + // If there are functions bound, to execute
633.386 + if ( readyList ) {
633.387 + // Execute all of them
633.388 + var fn, i = 0;
633.389 + while ( (fn = readyList[ i++ ]) ) {
633.390 + fn.call( document, jQuery );
633.391 + }
633.392 +
633.393 + // Reset the list of functions
633.394 + readyList = null;
633.395 + }
633.396 +
633.397 + // Trigger any bound ready events
633.398 + if ( jQuery.fn.triggerHandler ) {
633.399 + jQuery( document ).triggerHandler( "ready" );
633.400 + }
633.401 + }
633.402 + },
633.403 +
633.404 + bindReady: function() {
633.405 + if ( readyBound ) {
633.406 + return;
633.407 + }
633.408 +
633.409 + readyBound = true;
633.410 +
633.411 + // Catch cases where $(document).ready() is called after the
633.412 + // browser event has already occurred.
633.413 + if ( document.readyState === "complete" ) {
633.414 + return jQuery.ready();
633.415 + }
633.416 +
633.417 + // Mozilla, Opera and webkit nightlies currently support this event
633.418 + if ( document.addEventListener ) {
633.419 + // Use the handy event callback
633.420 + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
633.421 +
633.422 + // A fallback to window.onload, that will always work
633.423 + window.addEventListener( "load", jQuery.ready, false );
633.424 +
633.425 + // If IE event model is used
633.426 + } else if ( document.attachEvent ) {
633.427 + // ensure firing before onload,
633.428 + // maybe late but safe also for iframes
633.429 + document.attachEvent("onreadystatechange", DOMContentLoaded);
633.430 +
633.431 + // A fallback to window.onload, that will always work
633.432 + window.attachEvent( "onload", jQuery.ready );
633.433 +
633.434 + // If IE and not a frame
633.435 + // continually check to see if the document is ready
633.436 + var toplevel = false;
633.437 +
633.438 + try {
633.439 + toplevel = window.frameElement == null;
633.440 + } catch(e) {}
633.441 +
633.442 + if ( document.documentElement.doScroll && toplevel ) {
633.443 + doScrollCheck();
633.444 + }
633.445 + }
633.446 + },
633.447 +
633.448 + // See test/unit/core.js for details concerning isFunction.
633.449 + // Since version 1.3, DOM methods and functions like alert
633.450 + // aren't supported. They return false on IE (#2968).
633.451 + isFunction: function( obj ) {
633.452 + return toString.call(obj) === "[object Function]";
633.453 + },
633.454 +
633.455 + isArray: function( obj ) {
633.456 + return toString.call(obj) === "[object Array]";
633.457 + },
633.458 +
633.459 + isPlainObject: function( obj ) {
633.460 + // Must be an Object.
633.461 + // Because of IE, we also have to check the presence of the constructor property.
633.462 + // Make sure that DOM nodes and window objects don't pass through, as well
633.463 + if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
633.464 + return false;
633.465 + }
633.466 +
633.467 + // Not own constructor property must be Object
633.468 + if ( obj.constructor
633.469 + && !hasOwnProperty.call(obj, "constructor")
633.470 + && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
633.471 + return false;
633.472 + }
633.473 +
633.474 + // Own properties are enumerated firstly, so to speed up,
633.475 + // if last one is own, then all properties are own.
633.476 +
633.477 + var key;
633.478 + for ( key in obj ) {}
633.479 +
633.480 + return key === undefined || hasOwnProperty.call( obj, key );
633.481 + },
633.482 +
633.483 + isEmptyObject: function( obj ) {
633.484 + for ( var name in obj ) {
633.485 + return false;
633.486 + }
633.487 + return true;
633.488 + },
633.489 +
633.490 + noop: function() {},
633.491 +
633.492 + // Evalulates a script in a global context
633.493 + globalEval: function( data ) {
633.494 + if ( data && rnotwhite.test(data) ) {
633.495 + // Inspired by code by Andrea Giammarchi
633.496 + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
633.497 + var head = document.getElementsByTagName("head")[0] || document.documentElement,
633.498 + script = document.createElement("script");
633.499 +
633.500 + script.type = "text/javascript";
633.501 +
633.502 + if ( jQuery.support.scriptEval ) {
633.503 + script.appendChild( document.createTextNode( data ) );
633.504 + } else {
633.505 + script.text = data;
633.506 + }
633.507 +
633.508 + // Use insertBefore instead of appendChild to circumvent an IE6 bug.
633.509 + // This arises when a base node is used (#2709).
633.510 + head.insertBefore( script, head.firstChild );
633.511 + head.removeChild( script );
633.512 + }
633.513 + },
633.514 +
633.515 + nodeName: function( elem, name ) {
633.516 + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
633.517 + },
633.518 +
633.519 + // args is for internal usage only
633.520 + each: function( object, callback, args ) {
633.521 + var name, i = 0,
633.522 + length = object.length,
633.523 + isObj = length === undefined || jQuery.isFunction(object);
633.524 +
633.525 + if ( args ) {
633.526 + if ( isObj ) {
633.527 + for ( name in object ) {
633.528 + if ( callback.apply( object[ name ], args ) === false ) {
633.529 + break;
633.530 + }
633.531 + }
633.532 + } else {
633.533 + for ( ; i < length; ) {
633.534 + if ( callback.apply( object[ i++ ], args ) === false ) {
633.535 + break;
633.536 + }
633.537 + }
633.538 + }
633.539 +
633.540 + // A special, fast, case for the most common use of each
633.541 + } else {
633.542 + if ( isObj ) {
633.543 + for ( name in object ) {
633.544 + if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
633.545 + break;
633.546 + }
633.547 + }
633.548 + } else {
633.549 + for ( var value = object[0];
633.550 + i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
633.551 + }
633.552 + }
633.553 +
633.554 + return object;
633.555 + },
633.556 +
633.557 + trim: function( text ) {
633.558 + return (text || "").replace( rtrim, "" );
633.559 + },
633.560 +
633.561 + // results is for internal usage only
633.562 + makeArray: function( array, results ) {
633.563 + var ret = results || [];
633.564 +
633.565 + if ( array != null ) {
633.566 + // The window, strings (and functions) also have 'length'
633.567 + // The extra typeof function check is to prevent crashes
633.568 + // in Safari 2 (See: #3039)
633.569 + if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
633.570 + push.call( ret, array );
633.571 + } else {
633.572 + jQuery.merge( ret, array );
633.573 + }
633.574 + }
633.575 +
633.576 + return ret;
633.577 + },
633.578 +
633.579 + inArray: function( elem, array ) {
633.580 + if ( array.indexOf ) {
633.581 + return array.indexOf( elem );
633.582 + }
633.583 +
633.584 + for ( var i = 0, length = array.length; i < length; i++ ) {
633.585 + if ( array[ i ] === elem ) {
633.586 + return i;
633.587 + }
633.588 + }
633.589 +
633.590 + return -1;
633.591 + },
633.592 +
633.593 + merge: function( first, second ) {
633.594 + var i = first.length, j = 0;
633.595 +
633.596 + if ( typeof second.length === "number" ) {
633.597 + for ( var l = second.length; j < l; j++ ) {
633.598 + first[ i++ ] = second[ j ];
633.599 + }
633.600 + } else {
633.601 + while ( second[j] !== undefined ) {
633.602 + first[ i++ ] = second[ j++ ];
633.603 + }
633.604 + }
633.605 +
633.606 + first.length = i;
633.607 +
633.608 + return first;
633.609 + },
633.610 +
633.611 + grep: function( elems, callback, inv ) {
633.612 + var ret = [];
633.613 +
633.614 + // Go through the array, only saving the items
633.615 + // that pass the validator function
633.616 + for ( var i = 0, length = elems.length; i < length; i++ ) {
633.617 + if ( !inv !== !callback( elems[ i ], i ) ) {
633.618 + ret.push( elems[ i ] );
633.619 + }
633.620 + }
633.621 +
633.622 + return ret;
633.623 + },
633.624 +
633.625 + // arg is for internal usage only
633.626 + map: function( elems, callback, arg ) {
633.627 + var ret = [], value;
633.628 +
633.629 + // Go through the array, translating each of the items to their
633.630 + // new value (or values).
633.631 + for ( var i = 0, length = elems.length; i < length; i++ ) {
633.632 + value = callback( elems[ i ], i, arg );
633.633 +
633.634 + if ( value != null ) {
633.635 + ret[ ret.length ] = value;
633.636 + }
633.637 + }
633.638 +
633.639 + return ret.concat.apply( [], ret );
633.640 + },
633.641 +
633.642 + // A global GUID counter for objects
633.643 + guid: 1,
633.644 +
633.645 + proxy: function( fn, proxy, thisObject ) {
633.646 + if ( arguments.length === 2 ) {
633.647 + if ( typeof proxy === "string" ) {
633.648 + thisObject = fn;
633.649 + fn = thisObject[ proxy ];
633.650 + proxy = undefined;
633.651 +
633.652 + } else if ( proxy && !jQuery.isFunction( proxy ) ) {
633.653 + thisObject = proxy;
633.654 + proxy = undefined;
633.655 + }
633.656 + }
633.657 +
633.658 + if ( !proxy && fn ) {
633.659 + proxy = function() {
633.660 + return fn.apply( thisObject || this, arguments );
633.661 + };
633.662 + }
633.663 +
633.664 + // Set the guid of unique handler to the same of original handler, so it can be removed
633.665 + if ( fn ) {
633.666 + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
633.667 + }
633.668 +
633.669 + // So proxy can be declared as an argument
633.670 + return proxy;
633.671 + },
633.672 +
633.673 + // Use of jQuery.browser is frowned upon.
633.674 + // More details: http://docs.jquery.com/Utilities/jQuery.browser
633.675 + uaMatch: function( ua ) {
633.676 + var ret = { browser: "" };
633.677 +
633.678 + ua = ua.toLowerCase();
633.679 +
633.680 + if ( /webkit/.test( ua ) ) {
633.681 + ret = { browser: "webkit", version: /webkit[\/ ]([\w.]+)/ };
633.682 +
633.683 + } else if ( /opera/.test( ua ) ) {
633.684 + ret = { browser: "opera", version: /version/.test( ua ) ? /version[\/ ]([\w.]+)/ : /opera[\/ ]([\w.]+)/ };
633.685 +
633.686 + } else if ( /msie/.test( ua ) ) {
633.687 + ret = { browser: "msie", version: /msie ([\w.]+)/ };
633.688 +
633.689 + } else if ( /mozilla/.test( ua ) && !/compatible/.test( ua ) ) {
633.690 + ret = { browser: "mozilla", version: /rv:([\w.]+)/ };
633.691 + }
633.692 +
633.693 + ret.version = (ret.version && ret.version.exec( ua ) || [0, "0"])[1];
633.694 +
633.695 + return ret;
633.696 + },
633.697 +
633.698 + browser: {}
633.699 +});
633.700 +
633.701 +browserMatch = jQuery.uaMatch( userAgent );
633.702 +if ( browserMatch.browser ) {
633.703 + jQuery.browser[ browserMatch.browser ] = true;
633.704 + jQuery.browser.version = browserMatch.version;
633.705 +}
633.706 +
633.707 +// Deprecated, use jQuery.browser.webkit instead
633.708 +if ( jQuery.browser.webkit ) {
633.709 + jQuery.browser.safari = true;
633.710 +}
633.711 +
633.712 +if ( indexOf ) {
633.713 + jQuery.inArray = function( elem, array ) {
633.714 + return indexOf.call( array, elem );
633.715 + };
633.716 +}
633.717 +
633.718 +// All jQuery objects should point back to these
633.719 +rootjQuery = jQuery(document);
633.720 +
633.721 +// Cleanup functions for the document ready method
633.722 +if ( document.addEventListener ) {
633.723 + DOMContentLoaded = function() {
633.724 + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
633.725 + jQuery.ready();
633.726 + };
633.727 +
633.728 +} else if ( document.attachEvent ) {
633.729 + DOMContentLoaded = function() {
633.730 + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
633.731 + if ( document.readyState === "complete" ) {
633.732 + document.detachEvent( "onreadystatechange", DOMContentLoaded );
633.733 + jQuery.ready();
633.734 + }
633.735 + };
633.736 +}
633.737 +
633.738 +// The DOM ready check for Internet Explorer
633.739 +function doScrollCheck() {
633.740 + if ( jQuery.isReady ) {
633.741 + return;
633.742 + }
633.743 +
633.744 + try {
633.745 + // If IE is used, use the trick by Diego Perini
633.746 + // http://javascript.nwbox.com/IEContentLoaded/
633.747 + document.documentElement.doScroll("left");
633.748 + } catch( error ) {
633.749 + setTimeout( doScrollCheck, 1 );
633.750 + return;
633.751 + }
633.752 +
633.753 + // and execute any waiting functions
633.754 + jQuery.ready();
633.755 +}
633.756 +
633.757 +if ( indexOf ) {
633.758 + jQuery.inArray = function( elem, array ) {
633.759 + return indexOf.call( array, elem );
633.760 + };
633.761 +}
633.762 +
633.763 +function evalScript( i, elem ) {
633.764 + if ( elem.src ) {
633.765 + jQuery.ajax({
633.766 + url: elem.src,
633.767 + async: false,
633.768 + dataType: "script"
633.769 + });
633.770 + } else {
633.771 + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
633.772 + }
633.773 +
633.774 + if ( elem.parentNode ) {
633.775 + elem.parentNode.removeChild( elem );
633.776 + }
633.777 +}
633.778 +
633.779 +// Mutifunctional method to get and set values to a collection
633.780 +// The value/s can be optionally by executed if its a function
633.781 +function access( elems, key, value, exec, fn, pass ) {
633.782 + var length = elems.length;
633.783 +
633.784 + // Setting many attributes
633.785 + if ( typeof key === "object" ) {
633.786 + for ( var k in key ) {
633.787 + access( elems, k, key[k], exec, fn, value );
633.788 + }
633.789 + return elems;
633.790 + }
633.791 +
633.792 + // Setting one attribute
633.793 + if ( value !== undefined ) {
633.794 + // Optionally, function values get executed if exec is true
633.795 + exec = !pass && exec && jQuery.isFunction(value);
633.796 +
633.797 + for ( var i = 0; i < length; i++ ) {
633.798 + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
633.799 + }
633.800 +
633.801 + return elems;
633.802 + }
633.803 +
633.804 + // Getting an attribute
633.805 + return length ? fn( elems[0], key ) : null;
633.806 +}
633.807 +
633.808 +function now() {
633.809 + return (new Date).getTime();
633.810 +}
633.811 +(function() {
633.812 +
633.813 + jQuery.support = {};
633.814 +
633.815 + var root = document.documentElement,
633.816 + script = document.createElement("script"),
633.817 + div = document.createElement("div"),
633.818 + id = "script" + now();
633.819 +
633.820 + div.style.display = "none";
633.821 + div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
633.822 +
633.823 + var all = div.getElementsByTagName("*"),
633.824 + a = div.getElementsByTagName("a")[0];
633.825 +
633.826 + // Can't get basic test support
633.827 + if ( !all || !all.length || !a ) {
633.828 + return;
633.829 + }
633.830 +
633.831 + jQuery.support = {
633.832 + // IE strips leading whitespace when .innerHTML is used
633.833 + leadingWhitespace: div.firstChild.nodeType === 3,
633.834 +
633.835 + // Make sure that tbody elements aren't automatically inserted
633.836 + // IE will insert them into empty tables
633.837 + tbody: !div.getElementsByTagName("tbody").length,
633.838 +
633.839 + // Make sure that link elements get serialized correctly by innerHTML
633.840 + // This requires a wrapper element in IE
633.841 + htmlSerialize: !!div.getElementsByTagName("link").length,
633.842 +
633.843 + // Get the style information from getAttribute
633.844 + // (IE uses .cssText insted)
633.845 + style: /red/.test( a.getAttribute("style") ),
633.846 +
633.847 + // Make sure that URLs aren't manipulated
633.848 + // (IE normalizes it by default)
633.849 + hrefNormalized: a.getAttribute("href") === "/a",
633.850 +
633.851 + // Make sure that element opacity exists
633.852 + // (IE uses filter instead)
633.853 + // Use a regex to work around a WebKit issue. See #5145
633.854 + opacity: /^0.55$/.test( a.style.opacity ),
633.855 +
633.856 + // Verify style float existence
633.857 + // (IE uses styleFloat instead of cssFloat)
633.858 + cssFloat: !!a.style.cssFloat,
633.859 +
633.860 + // Make sure that if no value is specified for a checkbox
633.861 + // that it defaults to "on".
633.862 + // (WebKit defaults to "" instead)
633.863 + checkOn: div.getElementsByTagName("input")[0].value === "on",
633.864 +
633.865 + // Make sure that a selected-by-default option has a working selected property.
633.866 + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
633.867 + optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
633.868 +
633.869 + // Will be defined later
633.870 + scriptEval: false,
633.871 + noCloneEvent: true,
633.872 + boxModel: null
633.873 + };
633.874 +
633.875 + script.type = "text/javascript";
633.876 + try {
633.877 + script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
633.878 + } catch(e) {}
633.879 +
633.880 + root.insertBefore( script, root.firstChild );
633.881 +
633.882 + // Make sure that the execution of code works by injecting a script
633.883 + // tag with appendChild/createTextNode
633.884 + // (IE doesn't support this, fails, and uses .text instead)
633.885 + if ( window[ id ] ) {
633.886 + jQuery.support.scriptEval = true;
633.887 + delete window[ id ];
633.888 + }
633.889 +
633.890 + root.removeChild( script );
633.891 +
633.892 + if ( div.attachEvent && div.fireEvent ) {
633.893 + div.attachEvent("onclick", function click() {
633.894 + // Cloning a node shouldn't copy over any
633.895 + // bound event handlers (IE does this)
633.896 + jQuery.support.noCloneEvent = false;
633.897 + div.detachEvent("onclick", click);
633.898 + });
633.899 + div.cloneNode(true).fireEvent("onclick");
633.900 + }
633.901 +
633.902 + // Figure out if the W3C box model works as expected
633.903 + // document.body must exist before we can do this
633.904 + // TODO: This timeout is temporary until I move ready into core.js.
633.905 + jQuery(function() {
633.906 + var div = document.createElement("div");
633.907 + div.style.width = div.style.paddingLeft = "1px";
633.908 +
633.909 + document.body.appendChild( div );
633.910 + jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
633.911 + document.body.removeChild( div ).style.display = 'none';
633.912 + div = null;
633.913 + });
633.914 +
633.915 + // Technique from Juriy Zaytsev
633.916 + // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
633.917 + var eventSupported = function( eventName ) {
633.918 + var el = document.createElement("div");
633.919 + eventName = "on" + eventName;
633.920 +
633.921 + var isSupported = (eventName in el);
633.922 + if ( !isSupported ) {
633.923 + el.setAttribute(eventName, "return;");
633.924 + isSupported = typeof el[eventName] === "function";
633.925 + }
633.926 + el = null;
633.927 +
633.928 + return isSupported;
633.929 + };
633.930 +
633.931 + jQuery.support.submitBubbles = eventSupported("submit");
633.932 + jQuery.support.changeBubbles = eventSupported("change");
633.933 +
633.934 + // release memory in IE
633.935 + root = script = div = all = a = null;
633.936 +})();
633.937 +
633.938 +jQuery.props = {
633.939 + "for": "htmlFor",
633.940 + "class": "className",
633.941 + readonly: "readOnly",
633.942 + maxlength: "maxLength",
633.943 + cellspacing: "cellSpacing",
633.944 + rowspan: "rowSpan",
633.945 + colspan: "colSpan",
633.946 + tabindex: "tabIndex",
633.947 + usemap: "useMap",
633.948 + frameborder: "frameBorder"
633.949 +};
633.950 +var expando = "jQuery" + now(), uuid = 0, windowData = {};
633.951 +var emptyObject = {};
633.952 +
633.953 +jQuery.extend({
633.954 + cache: {},
633.955 +
633.956 + expando:expando,
633.957 +
633.958 + // The following elements throw uncatchable exceptions if you
633.959 + // attempt to add expando properties to them.
633.960 + noData: {
633.961 + "embed": true,
633.962 + "object": true,
633.963 + "applet": true
633.964 + },
633.965 +
633.966 + data: function( elem, name, data ) {
633.967 + if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
633.968 + return;
633.969 + }
633.970 +
633.971 + elem = elem == window ?
633.972 + windowData :
633.973 + elem;
633.974 +
633.975 + var id = elem[ expando ], cache = jQuery.cache, thisCache;
633.976 +
633.977 + // Handle the case where there's no name immediately
633.978 + if ( !name && !id ) {
633.979 + return null;
633.980 + }
633.981 +
633.982 + // Compute a unique ID for the element
633.983 + if ( !id ) {
633.984 + id = ++uuid;
633.985 + }
633.986 +
633.987 + // Avoid generating a new cache unless none exists and we
633.988 + // want to manipulate it.
633.989 + if ( typeof name === "object" ) {
633.990 + elem[ expando ] = id;
633.991 + thisCache = cache[ id ] = jQuery.extend(true, {}, name);
633.992 + } else if ( cache[ id ] ) {
633.993 + thisCache = cache[ id ];
633.994 + } else if ( typeof data === "undefined" ) {
633.995 + thisCache = emptyObject;
633.996 + } else {
633.997 + thisCache = cache[ id ] = {};
633.998 + }
633.999 +
633.1000 + // Prevent overriding the named cache with undefined values
633.1001 + if ( data !== undefined ) {
633.1002 + elem[ expando ] = id;
633.1003 + thisCache[ name ] = data;
633.1004 + }
633.1005 +
633.1006 + return typeof name === "string" ? thisCache[ name ] : thisCache;
633.1007 + },
633.1008 +
633.1009 + removeData: function( elem, name ) {
633.1010 + if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
633.1011 + return;
633.1012 + }
633.1013 +
633.1014 + elem = elem == window ?
633.1015 + windowData :
633.1016 + elem;
633.1017 +
633.1018 + var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
633.1019 +
633.1020 + // If we want to remove a specific section of the element's data
633.1021 + if ( name ) {
633.1022 + if ( thisCache ) {
633.1023 + // Remove the section of cache data
633.1024 + delete thisCache[ name ];
633.1025 +
633.1026 + // If we've removed all the data, remove the element's cache
633.1027 + if ( jQuery.isEmptyObject(thisCache) ) {
633.1028 + jQuery.removeData( elem );
633.1029 + }
633.1030 + }
633.1031 +
633.1032 + // Otherwise, we want to remove all of the element's data
633.1033 + } else {
633.1034 + // Clean up the element expando
633.1035 + try {
633.1036 + delete elem[ expando ];
633.1037 + } catch( e ) {
633.1038 + // IE has trouble directly removing the expando
633.1039 + // but it's ok with using removeAttribute
633.1040 + if ( elem.removeAttribute ) {
633.1041 + elem.removeAttribute( expando );
633.1042 + }
633.1043 + }
633.1044 +
633.1045 + // Completely remove the data cache
633.1046 + delete cache[ id ];
633.1047 + }
633.1048 + }
633.1049 +});
633.1050 +
633.1051 +jQuery.fn.extend({
633.1052 + data: function( key, value ) {
633.1053 + if ( typeof key === "undefined" && this.length ) {
633.1054 + return jQuery.data( this[0] );
633.1055 +
633.1056 + } else if ( typeof key === "object" ) {
633.1057 + return this.each(function() {
633.1058 + jQuery.data( this, key );
633.1059 + });
633.1060 + }
633.1061 +
633.1062 + var parts = key.split(".");
633.1063 + parts[1] = parts[1] ? "." + parts[1] : "";
633.1064 +
633.1065 + if ( value === undefined ) {
633.1066 + var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
633.1067 +
633.1068 + if ( data === undefined && this.length ) {
633.1069 + data = jQuery.data( this[0], key );
633.1070 + }
633.1071 + return data === undefined && parts[1] ?
633.1072 + this.data( parts[0] ) :
633.1073 + data;
633.1074 + } else {
633.1075 + return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
633.1076 + jQuery.data( this, key, value );
633.1077 + });
633.1078 + }
633.1079 + },
633.1080 +
633.1081 + removeData: function( key ) {
633.1082 + return this.each(function() {
633.1083 + jQuery.removeData( this, key );
633.1084 + });
633.1085 + }
633.1086 +});
633.1087 +jQuery.extend({
633.1088 + queue: function( elem, type, data ) {
633.1089 + if ( !elem ) {
633.1090 + return;
633.1091 + }
633.1092 +
633.1093 + type = (type || "fx") + "queue";
633.1094 + var q = jQuery.data( elem, type );
633.1095 +
633.1096 + // Speed up dequeue by getting out quickly if this is just a lookup
633.1097 + if ( !data ) {
633.1098 + return q || [];
633.1099 + }
633.1100 +
633.1101 + if ( !q || jQuery.isArray(data) ) {
633.1102 + q = jQuery.data( elem, type, jQuery.makeArray(data) );
633.1103 +
633.1104 + } else {
633.1105 + q.push( data );
633.1106 + }
633.1107 +
633.1108 + return q;
633.1109 + },
633.1110 +
633.1111 + dequeue: function( elem, type ) {
633.1112 + type = type || "fx";
633.1113 +
633.1114 + var queue = jQuery.queue( elem, type ), fn = queue.shift();
633.1115 +
633.1116 + // If the fx queue is dequeued, always remove the progress sentinel
633.1117 + if ( fn === "inprogress" ) {
633.1118 + fn = queue.shift();
633.1119 + }
633.1120 +
633.1121 + if ( fn ) {
633.1122 + // Add a progress sentinel to prevent the fx queue from being
633.1123 + // automatically dequeued
633.1124 + if ( type === "fx" ) {
633.1125 + queue.unshift("inprogress");
633.1126 + }
633.1127 +
633.1128 + fn.call(elem, function() {
633.1129 + jQuery.dequeue(elem, type);
633.1130 + });
633.1131 + }
633.1132 + }
633.1133 +});
633.1134 +
633.1135 +jQuery.fn.extend({
633.1136 + queue: function( type, data ) {
633.1137 + if ( typeof type !== "string" ) {
633.1138 + data = type;
633.1139 + type = "fx";
633.1140 + }
633.1141 +
633.1142 + if ( data === undefined ) {
633.1143 + return jQuery.queue( this[0], type );
633.1144 + }
633.1145 + return this.each(function( i, elem ) {
633.1146 + var queue = jQuery.queue( this, type, data );
633.1147 +
633.1148 + if ( type === "fx" && queue[0] !== "inprogress" ) {
633.1149 + jQuery.dequeue( this, type );
633.1150 + }
633.1151 + });
633.1152 + },
633.1153 + dequeue: function( type ) {
633.1154 + return this.each(function() {
633.1155 + jQuery.dequeue( this, type );
633.1156 + });
633.1157 + },
633.1158 +
633.1159 + // Based off of the plugin by Clint Helfers, with permission.
633.1160 + // http://blindsignals.com/index.php/2009/07/jquery-delay/
633.1161 + delay: function( time, type ) {
633.1162 + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
633.1163 + type = type || "fx";
633.1164 +
633.1165 + return this.queue( type, function() {
633.1166 + var elem = this;
633.1167 + setTimeout(function() {
633.1168 + jQuery.dequeue( elem, type );
633.1169 + }, time );
633.1170 + });
633.1171 + },
633.1172 +
633.1173 + clearQueue: function( type ) {
633.1174 + return this.queue( type || "fx", [] );
633.1175 + }
633.1176 +});
633.1177 +var rclass = /[\n\t]/g,
633.1178 + rspace = /\s+/,
633.1179 + rreturn = /\r/g,
633.1180 + rspecialurl = /href|src|style/,
633.1181 + rtype = /(button|input)/i,
633.1182 + rfocusable = /(button|input|object|select|textarea)/i,
633.1183 + rclickable = /^(a|area)$/i,
633.1184 + rradiocheck = /radio|checkbox/;
633.1185 +
633.1186 +jQuery.fn.extend({
633.1187 + attr: function( name, value ) {
633.1188 + return access( this, name, value, true, jQuery.attr );
633.1189 + },
633.1190 +
633.1191 + removeAttr: function( name, fn ) {
633.1192 + return this.each(function(){
633.1193 + jQuery.attr( this, name, "" );
633.1194 + if ( this.nodeType === 1 ) {
633.1195 + this.removeAttribute( name );
633.1196 + }
633.1197 + });
633.1198 + },
633.1199 +
633.1200 + addClass: function( value ) {
633.1201 + if ( jQuery.isFunction(value) ) {
633.1202 + return this.each(function(i) {
633.1203 + var self = jQuery(this);
633.1204 + self.addClass( value.call(this, i, self.attr("class")) );
633.1205 + });
633.1206 + }
633.1207 +
633.1208 + if ( value && typeof value === "string" ) {
633.1209 + var classNames = (value || "").split( rspace );
633.1210 +
633.1211 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.1212 + var elem = this[i];
633.1213 +
633.1214 + if ( elem.nodeType === 1 ) {
633.1215 + if ( !elem.className ) {
633.1216 + elem.className = value;
633.1217 +
633.1218 + } else {
633.1219 + var className = " " + elem.className + " ";
633.1220 + for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
633.1221 + if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
633.1222 + elem.className += " " + classNames[c];
633.1223 + }
633.1224 + }
633.1225 + }
633.1226 + }
633.1227 + }
633.1228 + }
633.1229 +
633.1230 + return this;
633.1231 + },
633.1232 +
633.1233 + removeClass: function( value ) {
633.1234 + if ( jQuery.isFunction(value) ) {
633.1235 + return this.each(function(i) {
633.1236 + var self = jQuery(this);
633.1237 + self.removeClass( value.call(this, i, self.attr("class")) );
633.1238 + });
633.1239 + }
633.1240 +
633.1241 + if ( (value && typeof value === "string") || value === undefined ) {
633.1242 + var classNames = (value || "").split(rspace);
633.1243 +
633.1244 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.1245 + var elem = this[i];
633.1246 +
633.1247 + if ( elem.nodeType === 1 && elem.className ) {
633.1248 + if ( value ) {
633.1249 + var className = (" " + elem.className + " ").replace(rclass, " ");
633.1250 + for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
633.1251 + className = className.replace(" " + classNames[c] + " ", " ");
633.1252 + }
633.1253 + elem.className = className.substring(1, className.length - 1);
633.1254 +
633.1255 + } else {
633.1256 + elem.className = "";
633.1257 + }
633.1258 + }
633.1259 + }
633.1260 + }
633.1261 +
633.1262 + return this;
633.1263 + },
633.1264 +
633.1265 + toggleClass: function( value, stateVal ) {
633.1266 + var type = typeof value, isBool = typeof stateVal === "boolean";
633.1267 +
633.1268 + if ( jQuery.isFunction( value ) ) {
633.1269 + return this.each(function(i) {
633.1270 + var self = jQuery(this);
633.1271 + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
633.1272 + });
633.1273 + }
633.1274 +
633.1275 + return this.each(function() {
633.1276 + if ( type === "string" ) {
633.1277 + // toggle individual class names
633.1278 + var className, i = 0, self = jQuery(this),
633.1279 + state = stateVal,
633.1280 + classNames = value.split( rspace );
633.1281 +
633.1282 + while ( (className = classNames[ i++ ]) ) {
633.1283 + // check each className given, space seperated list
633.1284 + state = isBool ? state : !self.hasClass( className );
633.1285 + self[ state ? "addClass" : "removeClass" ]( className );
633.1286 + }
633.1287 +
633.1288 + } else if ( type === "undefined" || type === "boolean" ) {
633.1289 + if ( this.className ) {
633.1290 + // store className if set
633.1291 + jQuery.data( this, "__className__", this.className );
633.1292 + }
633.1293 +
633.1294 + // toggle whole className
633.1295 + this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
633.1296 + }
633.1297 + });
633.1298 + },
633.1299 +
633.1300 + hasClass: function( selector ) {
633.1301 + var className = " " + selector + " ";
633.1302 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.1303 + if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
633.1304 + return true;
633.1305 + }
633.1306 + }
633.1307 +
633.1308 + return false;
633.1309 + },
633.1310 +
633.1311 + val: function( value ) {
633.1312 + if ( value === undefined ) {
633.1313 + var elem = this[0];
633.1314 +
633.1315 + if ( elem ) {
633.1316 + if ( jQuery.nodeName( elem, "option" ) ) {
633.1317 + return (elem.attributes.value || {}).specified ? elem.value : elem.text;
633.1318 + }
633.1319 +
633.1320 + // We need to handle select boxes special
633.1321 + if ( jQuery.nodeName( elem, "select" ) ) {
633.1322 + var index = elem.selectedIndex,
633.1323 + values = [],
633.1324 + options = elem.options,
633.1325 + one = elem.type === "select-one";
633.1326 +
633.1327 + // Nothing was selected
633.1328 + if ( index < 0 ) {
633.1329 + return null;
633.1330 + }
633.1331 +
633.1332 + // Loop through all the selected options
633.1333 + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
633.1334 + var option = options[ i ];
633.1335 +
633.1336 + if ( option.selected ) {
633.1337 + // Get the specifc value for the option
633.1338 + value = jQuery(option).val();
633.1339 +
633.1340 + // We don't need an array for one selects
633.1341 + if ( one ) {
633.1342 + return value;
633.1343 + }
633.1344 +
633.1345 + // Multi-Selects return an array
633.1346 + values.push( value );
633.1347 + }
633.1348 + }
633.1349 +
633.1350 + return values;
633.1351 + }
633.1352 +
633.1353 + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
633.1354 + if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
633.1355 + return elem.getAttribute("value") === null ? "on" : elem.value;
633.1356 + }
633.1357 +
633.1358 +
633.1359 + // Everything else, we just grab the value
633.1360 + return (elem.value || "").replace(rreturn, "");
633.1361 +
633.1362 + }
633.1363 +
633.1364 + return undefined;
633.1365 + }
633.1366 +
633.1367 + var isFunction = jQuery.isFunction(value);
633.1368 +
633.1369 + return this.each(function(i) {
633.1370 + var self = jQuery(this), val = value;
633.1371 +
633.1372 + if ( this.nodeType !== 1 ) {
633.1373 + return;
633.1374 + }
633.1375 +
633.1376 + if ( isFunction ) {
633.1377 + val = value.call(this, i, self.val());
633.1378 + }
633.1379 +
633.1380 + // Typecast each time if the value is a Function and the appended
633.1381 + // value is therefore different each time.
633.1382 + if ( typeof val === "number" ) {
633.1383 + val += "";
633.1384 + }
633.1385 +
633.1386 + if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
633.1387 + this.checked = jQuery.inArray( self.val(), val ) >= 0;
633.1388 +
633.1389 + } else if ( jQuery.nodeName( this, "select" ) ) {
633.1390 + var values = jQuery.makeArray(val);
633.1391 +
633.1392 + jQuery( "option", this ).each(function() {
633.1393 + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
633.1394 + });
633.1395 +
633.1396 + if ( !values.length ) {
633.1397 + this.selectedIndex = -1;
633.1398 + }
633.1399 +
633.1400 + } else {
633.1401 + this.value = val;
633.1402 + }
633.1403 + });
633.1404 + }
633.1405 +});
633.1406 +
633.1407 +jQuery.extend({
633.1408 + attrFn: {
633.1409 + val: true,
633.1410 + css: true,
633.1411 + html: true,
633.1412 + text: true,
633.1413 + data: true,
633.1414 + width: true,
633.1415 + height: true,
633.1416 + offset: true
633.1417 + },
633.1418 +
633.1419 + attr: function( elem, name, value, pass ) {
633.1420 + // don't set attributes on text and comment nodes
633.1421 + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
633.1422 + return undefined;
633.1423 + }
633.1424 +
633.1425 + if ( pass && name in jQuery.attrFn ) {
633.1426 + return jQuery(elem)[name](value);
633.1427 + }
633.1428 +
633.1429 + var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
633.1430 + // Whether we are setting (or getting)
633.1431 + set = value !== undefined;
633.1432 +
633.1433 + // Try to normalize/fix the name
633.1434 + name = notxml && jQuery.props[ name ] || name;
633.1435 +
633.1436 + // Only do all the following if this is a node (faster for style)
633.1437 + if ( elem.nodeType === 1 ) {
633.1438 + // These attributes require special treatment
633.1439 + var special = rspecialurl.test( name );
633.1440 +
633.1441 + // Safari mis-reports the default selected property of an option
633.1442 + // Accessing the parent's selectedIndex property fixes it
633.1443 + if ( name === "selected" && !jQuery.support.optSelected ) {
633.1444 + var parent = elem.parentNode;
633.1445 + if ( parent ) {
633.1446 + parent.selectedIndex;
633.1447 +
633.1448 + // Make sure that it also works with optgroups, see #5701
633.1449 + if ( parent.parentNode ) {
633.1450 + parent.parentNode.selectedIndex;
633.1451 + }
633.1452 + }
633.1453 + }
633.1454 +
633.1455 + // If applicable, access the attribute via the DOM 0 way
633.1456 + if ( name in elem && notxml && !special ) {
633.1457 + if ( set ) {
633.1458 + // We can't allow the type property to be changed (since it causes problems in IE)
633.1459 + if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
633.1460 + throw "type property can't be changed";
633.1461 + }
633.1462 +
633.1463 + elem[ name ] = value;
633.1464 + }
633.1465 +
633.1466 + // browsers index elements by id/name on forms, give priority to attributes.
633.1467 + if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
633.1468 + return elem.getAttributeNode( name ).nodeValue;
633.1469 + }
633.1470 +
633.1471 + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
633.1472 + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
633.1473 + if ( name === "tabIndex" ) {
633.1474 + var attributeNode = elem.getAttributeNode( "tabIndex" );
633.1475 +
633.1476 + return attributeNode && attributeNode.specified ?
633.1477 + attributeNode.value :
633.1478 + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
633.1479 + 0 :
633.1480 + undefined;
633.1481 + }
633.1482 +
633.1483 + return elem[ name ];
633.1484 + }
633.1485 +
633.1486 + if ( !jQuery.support.style && notxml && name === "style" ) {
633.1487 + if ( set ) {
633.1488 + elem.style.cssText = "" + value;
633.1489 + }
633.1490 +
633.1491 + return elem.style.cssText;
633.1492 + }
633.1493 +
633.1494 + if ( set ) {
633.1495 + // convert the value to a string (all browsers do this but IE) see #1070
633.1496 + elem.setAttribute( name, "" + value );
633.1497 + }
633.1498 +
633.1499 + var attr = !jQuery.support.hrefNormalized && notxml && special ?
633.1500 + // Some attributes require a special call on IE
633.1501 + elem.getAttribute( name, 2 ) :
633.1502 + elem.getAttribute( name );
633.1503 +
633.1504 + // Non-existent attributes return null, we normalize to undefined
633.1505 + return attr === null ? undefined : attr;
633.1506 + }
633.1507 +
633.1508 + // elem is actually elem.style ... set the style
633.1509 + // Using attr for specific style information is now deprecated. Use style insead.
633.1510 + return jQuery.style( elem, name, value );
633.1511 + }
633.1512 +});
633.1513 +var fcleanup = function( nm ) {
633.1514 + return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
633.1515 + return "\\" + ch;
633.1516 + });
633.1517 +};
633.1518 +
633.1519 +/*
633.1520 + * A number of helper functions used for managing events.
633.1521 + * Many of the ideas behind this code originated from
633.1522 + * Dean Edwards' addEvent library.
633.1523 + */
633.1524 +jQuery.event = {
633.1525 +
633.1526 + // Bind an event to an element
633.1527 + // Original by Dean Edwards
633.1528 + add: function( elem, types, handler, data ) {
633.1529 + if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
633.1530 + return;
633.1531 + }
633.1532 +
633.1533 + // For whatever reason, IE has trouble passing the window object
633.1534 + // around, causing it to be cloned in the process
633.1535 + if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
633.1536 + elem = window;
633.1537 + }
633.1538 +
633.1539 + // Make sure that the function being executed has a unique ID
633.1540 + if ( !handler.guid ) {
633.1541 + handler.guid = jQuery.guid++;
633.1542 + }
633.1543 +
633.1544 + // if data is passed, bind to handler
633.1545 + if ( data !== undefined ) {
633.1546 + // Create temporary function pointer to original handler
633.1547 + var fn = handler;
633.1548 +
633.1549 + // Create unique handler function, wrapped around original handler
633.1550 + handler = jQuery.proxy( fn );
633.1551 +
633.1552 + // Store data in unique handler
633.1553 + handler.data = data;
633.1554 + }
633.1555 +
633.1556 + // Init the element's event structure
633.1557 + var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
633.1558 + handle = jQuery.data( elem, "handle" ), eventHandle;
633.1559 +
633.1560 + if ( !handle ) {
633.1561 + eventHandle = function() {
633.1562 + // Handle the second event of a trigger and when
633.1563 + // an event is called after a page has unloaded
633.1564 + return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
633.1565 + jQuery.event.handle.apply( eventHandle.elem, arguments ) :
633.1566 + undefined;
633.1567 + };
633.1568 +
633.1569 + handle = jQuery.data( elem, "handle", eventHandle );
633.1570 + }
633.1571 +
633.1572 + // If no handle is found then we must be trying to bind to one of the
633.1573 + // banned noData elements
633.1574 + if ( !handle ) {
633.1575 + return;
633.1576 + }
633.1577 +
633.1578 + // Add elem as a property of the handle function
633.1579 + // This is to prevent a memory leak with non-native
633.1580 + // event in IE.
633.1581 + handle.elem = elem;
633.1582 +
633.1583 + // Handle multiple events separated by a space
633.1584 + // jQuery(...).bind("mouseover mouseout", fn);
633.1585 + types = types.split( /\s+/ );
633.1586 + var type, i=0;
633.1587 + while ( (type = types[ i++ ]) ) {
633.1588 + // Namespaced event handlers
633.1589 + var namespaces = type.split(".");
633.1590 + type = namespaces.shift();
633.1591 + handler.type = namespaces.slice(0).sort().join(".");
633.1592 +
633.1593 + // Get the current list of functions bound to this event
633.1594 + var handlers = events[ type ],
633.1595 + special = this.special[ type ] || {};
633.1596 +
633.1597 +
633.1598 +
633.1599 + // Init the event handler queue
633.1600 + if ( !handlers ) {
633.1601 + handlers = events[ type ] = {};
633.1602 +
633.1603 + // Check for a special event handler
633.1604 + // Only use addEventListener/attachEvent if the special
633.1605 + // events handler returns false
633.1606 + if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
633.1607 + // Bind the global event handler to the element
633.1608 + if ( elem.addEventListener ) {
633.1609 + elem.addEventListener( type, handle, false );
633.1610 + } else if ( elem.attachEvent ) {
633.1611 + elem.attachEvent( "on" + type, handle );
633.1612 + }
633.1613 + }
633.1614 + }
633.1615 +
633.1616 + if ( special.add ) {
633.1617 + var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
633.1618 + if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
633.1619 + modifiedHandler.guid = modifiedHandler.guid || handler.guid;
633.1620 + handler = modifiedHandler;
633.1621 + }
633.1622 + }
633.1623 +
633.1624 + // Add the function to the element's handler list
633.1625 + handlers[ handler.guid ] = handler;
633.1626 +
633.1627 + // Keep track of which events have been used, for global triggering
633.1628 + this.global[ type ] = true;
633.1629 + }
633.1630 +
633.1631 + // Nullify elem to prevent memory leaks in IE
633.1632 + elem = null;
633.1633 + },
633.1634 +
633.1635 + global: {},
633.1636 +
633.1637 + // Detach an event or set of events from an element
633.1638 + remove: function( elem, types, handler ) {
633.1639 + // don't do events on text and comment nodes
633.1640 + if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
633.1641 + return;
633.1642 + }
633.1643 +
633.1644 + var events = jQuery.data( elem, "events" ), ret, type, fn;
633.1645 +
633.1646 + if ( events ) {
633.1647 + // Unbind all events for the element
633.1648 + if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
633.1649 + for ( type in events ) {
633.1650 + this.remove( elem, type + (types || "") );
633.1651 + }
633.1652 + } else {
633.1653 + // types is actually an event object here
633.1654 + if ( types.type ) {
633.1655 + handler = types.handler;
633.1656 + types = types.type;
633.1657 + }
633.1658 +
633.1659 + // Handle multiple events separated by a space
633.1660 + // jQuery(...).unbind("mouseover mouseout", fn);
633.1661 + types = types.split(/\s+/);
633.1662 + var i = 0;
633.1663 + while ( (type = types[ i++ ]) ) {
633.1664 + // Namespaced event handlers
633.1665 + var namespaces = type.split(".");
633.1666 + type = namespaces.shift();
633.1667 + var all = !namespaces.length,
633.1668 + cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
633.1669 + namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
633.1670 + special = this.special[ type ] || {};
633.1671 +
633.1672 + if ( events[ type ] ) {
633.1673 + // remove the given handler for the given type
633.1674 + if ( handler ) {
633.1675 + fn = events[ type ][ handler.guid ];
633.1676 + delete events[ type ][ handler.guid ];
633.1677 +
633.1678 + // remove all handlers for the given type
633.1679 + } else {
633.1680 + for ( var handle in events[ type ] ) {
633.1681 + // Handle the removal of namespaced events
633.1682 + if ( all || namespace.test( events[ type ][ handle ].type ) ) {
633.1683 + delete events[ type ][ handle ];
633.1684 + }
633.1685 + }
633.1686 + }
633.1687 +
633.1688 + if ( special.remove ) {
633.1689 + special.remove.call( elem, namespaces, fn);
633.1690 + }
633.1691 +
633.1692 + // remove generic event handler if no more handlers exist
633.1693 + for ( ret in events[ type ] ) {
633.1694 + break;
633.1695 + }
633.1696 + if ( !ret ) {
633.1697 + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
633.1698 + if ( elem.removeEventListener ) {
633.1699 + elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
633.1700 + } else if ( elem.detachEvent ) {
633.1701 + elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
633.1702 + }
633.1703 + }
633.1704 + ret = null;
633.1705 + delete events[ type ];
633.1706 + }
633.1707 + }
633.1708 + }
633.1709 + }
633.1710 +
633.1711 + // Remove the expando if it's no longer used
633.1712 + for ( ret in events ) {
633.1713 + break;
633.1714 + }
633.1715 + if ( !ret ) {
633.1716 + var handle = jQuery.data( elem, "handle" );
633.1717 + if ( handle ) {
633.1718 + handle.elem = null;
633.1719 + }
633.1720 + jQuery.removeData( elem, "events" );
633.1721 + jQuery.removeData( elem, "handle" );
633.1722 + }
633.1723 + }
633.1724 + },
633.1725 +
633.1726 + // bubbling is internal
633.1727 + trigger: function( event, data, elem /*, bubbling */ ) {
633.1728 + // Event object or event type
633.1729 + var type = event.type || event,
633.1730 + bubbling = arguments[3];
633.1731 +
633.1732 + if ( !bubbling ) {
633.1733 + event = typeof event === "object" ?
633.1734 + // jQuery.Event object
633.1735 + event[expando] ? event :
633.1736 + // Object literal
633.1737 + jQuery.extend( jQuery.Event(type), event ) :
633.1738 + // Just the event type (string)
633.1739 + jQuery.Event(type);
633.1740 +
633.1741 + if ( type.indexOf("!") >= 0 ) {
633.1742 + event.type = type = type.slice(0, -1);
633.1743 + event.exclusive = true;
633.1744 + }
633.1745 +
633.1746 + // Handle a global trigger
633.1747 + if ( !elem ) {
633.1748 + // Don't bubble custom events when global (to avoid too much overhead)
633.1749 + event.stopPropagation();
633.1750 +
633.1751 + // Only trigger if we've ever bound an event for it
633.1752 + if ( this.global[ type ] ) {
633.1753 + jQuery.each( jQuery.cache, function() {
633.1754 + if ( this.events && this.events[type] ) {
633.1755 + jQuery.event.trigger( event, data, this.handle.elem );
633.1756 + }
633.1757 + });
633.1758 + }
633.1759 + }
633.1760 +
633.1761 + // Handle triggering a single element
633.1762 +
633.1763 + // don't do events on text and comment nodes
633.1764 + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
633.1765 + return undefined;
633.1766 + }
633.1767 +
633.1768 + // Clean up in case it is reused
633.1769 + event.result = undefined;
633.1770 + event.target = elem;
633.1771 +
633.1772 + // Clone the incoming data, if any
633.1773 + data = jQuery.makeArray( data );
633.1774 + data.unshift( event );
633.1775 + }
633.1776 +
633.1777 + event.currentTarget = elem;
633.1778 +
633.1779 + // Trigger the event, it is assumed that "handle" is a function
633.1780 + var handle = jQuery.data( elem, "handle" );
633.1781 + if ( handle ) {
633.1782 + handle.apply( elem, data );
633.1783 + }
633.1784 +
633.1785 + var nativeFn, nativeHandler;
633.1786 + try {
633.1787 + if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
633.1788 + nativeFn = elem[ type ];
633.1789 + nativeHandler = elem[ "on" + type ];
633.1790 + }
633.1791 + // prevent IE from throwing an error for some elements with some event types, see #3533
633.1792 + } catch (e) {}
633.1793 +
633.1794 + var isClick = jQuery.nodeName(elem, "a") && type === "click";
633.1795 +
633.1796 + // Trigger the native events (except for clicks on links)
633.1797 + if ( !bubbling && nativeFn && !event.isDefaultPrevented() && !isClick ) {
633.1798 + this.triggered = true;
633.1799 + try {
633.1800 + elem[ type ]();
633.1801 + // prevent IE from throwing an error for some hidden elements
633.1802 + } catch (e) {}
633.1803 +
633.1804 + // Handle triggering native .onfoo handlers
633.1805 + } else if ( nativeHandler && elem[ "on" + type ].apply( elem, data ) === false ) {
633.1806 + event.result = false;
633.1807 + }
633.1808 +
633.1809 + this.triggered = false;
633.1810 +
633.1811 + if ( !event.isPropagationStopped() ) {
633.1812 + var parent = elem.parentNode || elem.ownerDocument;
633.1813 + if ( parent ) {
633.1814 + jQuery.event.trigger( event, data, parent, true );
633.1815 + }
633.1816 + }
633.1817 + },
633.1818 +
633.1819 + handle: function( event ) {
633.1820 + // returned undefined or false
633.1821 + var all, handlers;
633.1822 +
633.1823 + event = arguments[0] = jQuery.event.fix( event || window.event );
633.1824 + event.currentTarget = this;
633.1825 +
633.1826 + // Namespaced event handlers
633.1827 + var namespaces = event.type.split(".");
633.1828 + event.type = namespaces.shift();
633.1829 +
633.1830 + // Cache this now, all = true means, any handler
633.1831 + all = !namespaces.length && !event.exclusive;
633.1832 +
633.1833 + var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
633.1834 +
633.1835 + handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
633.1836 +
633.1837 + for ( var j in handlers ) {
633.1838 + var handler = handlers[ j ];
633.1839 +
633.1840 + // Filter the functions by class
633.1841 + if ( all || namespace.test(handler.type) ) {
633.1842 + // Pass in a reference to the handler function itself
633.1843 + // So that we can later remove it
633.1844 + event.handler = handler;
633.1845 + event.data = handler.data;
633.1846 +
633.1847 + var ret = handler.apply( this, arguments );
633.1848 +
633.1849 + if ( ret !== undefined ) {
633.1850 + event.result = ret;
633.1851 + if ( ret === false ) {
633.1852 + event.preventDefault();
633.1853 + event.stopPropagation();
633.1854 + }
633.1855 + }
633.1856 +
633.1857 + if ( event.isImmediatePropagationStopped() ) {
633.1858 + break;
633.1859 + }
633.1860 +
633.1861 + }
633.1862 + }
633.1863 +
633.1864 + return event.result;
633.1865 + },
633.1866 +
633.1867 + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
633.1868 +
633.1869 + fix: function( event ) {
633.1870 + if ( event[ expando ] ) {
633.1871 + return event;
633.1872 + }
633.1873 +
633.1874 + // store a copy of the original event object
633.1875 + // and "clone" to set read-only properties
633.1876 + var originalEvent = event;
633.1877 + event = jQuery.Event( originalEvent );
633.1878 +
633.1879 + for ( var i = this.props.length, prop; i; ) {
633.1880 + prop = this.props[ --i ];
633.1881 + event[ prop ] = originalEvent[ prop ];
633.1882 + }
633.1883 +
633.1884 + // Fix target property, if necessary
633.1885 + if ( !event.target ) {
633.1886 + event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
633.1887 + }
633.1888 +
633.1889 + // check if target is a textnode (safari)
633.1890 + if ( event.target.nodeType === 3 ) {
633.1891 + event.target = event.target.parentNode;
633.1892 + }
633.1893 +
633.1894 + // Add relatedTarget, if necessary
633.1895 + if ( !event.relatedTarget && event.fromElement ) {
633.1896 + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
633.1897 + }
633.1898 +
633.1899 + // Calculate pageX/Y if missing and clientX/Y available
633.1900 + if ( event.pageX == null && event.clientX != null ) {
633.1901 + var doc = document.documentElement, body = document.body;
633.1902 + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
633.1903 + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
633.1904 + }
633.1905 +
633.1906 + // Add which for key events
633.1907 + if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
633.1908 + event.which = event.charCode || event.keyCode;
633.1909 + }
633.1910 +
633.1911 + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
633.1912 + if ( !event.metaKey && event.ctrlKey ) {
633.1913 + event.metaKey = event.ctrlKey;
633.1914 + }
633.1915 +
633.1916 + // Add which for click: 1 === left; 2 === middle; 3 === right
633.1917 + // Note: button is not normalized, so don't use it
633.1918 + if ( !event.which && event.button !== undefined ) {
633.1919 + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
633.1920 + }
633.1921 +
633.1922 + return event;
633.1923 + },
633.1924 +
633.1925 + // Deprecated, use jQuery.guid instead
633.1926 + guid: 1E8,
633.1927 +
633.1928 + // Deprecated, use jQuery.proxy instead
633.1929 + proxy: jQuery.proxy,
633.1930 +
633.1931 + special: {
633.1932 + ready: {
633.1933 + // Make sure the ready event is setup
633.1934 + setup: jQuery.bindReady,
633.1935 + teardown: jQuery.noop
633.1936 + },
633.1937 +
633.1938 + live: {
633.1939 + add: function( proxy, data, namespaces, live ) {
633.1940 + jQuery.extend( proxy, data || {} );
633.1941 +
633.1942 + proxy.guid += data.selector + data.live;
633.1943 + jQuery.event.add( this, data.live, liveHandler, data );
633.1944 +
633.1945 + },
633.1946 +
633.1947 + remove: function( namespaces ) {
633.1948 + if ( namespaces.length ) {
633.1949 + var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
633.1950 +
633.1951 + jQuery.each( (jQuery.data(this, "events").live || {}), function() {
633.1952 + if ( name.test(this.type) ) {
633.1953 + remove++;
633.1954 + }
633.1955 + });
633.1956 +
633.1957 + if ( remove < 1 ) {
633.1958 + jQuery.event.remove( this, namespaces[0], liveHandler );
633.1959 + }
633.1960 + }
633.1961 + },
633.1962 + special: {}
633.1963 + },
633.1964 + beforeunload: {
633.1965 + setup: function( data, namespaces, fn ) {
633.1966 + // We only want to do this special case on windows
633.1967 + if ( this.setInterval ) {
633.1968 + this.onbeforeunload = fn;
633.1969 + }
633.1970 +
633.1971 + return false;
633.1972 + },
633.1973 + teardown: function( namespaces, fn ) {
633.1974 + if ( this.onbeforeunload === fn ) {
633.1975 + this.onbeforeunload = null;
633.1976 + }
633.1977 + }
633.1978 + }
633.1979 + }
633.1980 +};
633.1981 +
633.1982 +jQuery.Event = function( src ) {
633.1983 + // Allow instantiation without the 'new' keyword
633.1984 + if ( !this.preventDefault ) {
633.1985 + return new jQuery.Event( src );
633.1986 + }
633.1987 +
633.1988 + // Event object
633.1989 + if ( src && src.type ) {
633.1990 + this.originalEvent = src;
633.1991 + this.type = src.type;
633.1992 + // Event type
633.1993 + } else {
633.1994 + this.type = src;
633.1995 + }
633.1996 +
633.1997 + // timeStamp is buggy for some events on Firefox(#3843)
633.1998 + // So we won't rely on the native value
633.1999 + this.timeStamp = now();
633.2000 +
633.2001 + // Mark it as fixed
633.2002 + this[ expando ] = true;
633.2003 +};
633.2004 +
633.2005 +function returnFalse() {
633.2006 + return false;
633.2007 +}
633.2008 +function returnTrue() {
633.2009 + return true;
633.2010 +}
633.2011 +
633.2012 +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
633.2013 +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
633.2014 +jQuery.Event.prototype = {
633.2015 + preventDefault: function() {
633.2016 + this.isDefaultPrevented = returnTrue;
633.2017 +
633.2018 + var e = this.originalEvent;
633.2019 + if ( !e ) {
633.2020 + return;
633.2021 + }
633.2022 +
633.2023 + // if preventDefault exists run it on the original event
633.2024 + if ( e.preventDefault ) {
633.2025 + e.preventDefault();
633.2026 + }
633.2027 + // otherwise set the returnValue property of the original event to false (IE)
633.2028 + e.returnValue = false;
633.2029 + },
633.2030 + stopPropagation: function() {
633.2031 + this.isPropagationStopped = returnTrue;
633.2032 +
633.2033 + var e = this.originalEvent;
633.2034 + if ( !e ) {
633.2035 + return;
633.2036 + }
633.2037 + // if stopPropagation exists run it on the original event
633.2038 + if ( e.stopPropagation ) {
633.2039 + e.stopPropagation();
633.2040 + }
633.2041 + // otherwise set the cancelBubble property of the original event to true (IE)
633.2042 + e.cancelBubble = true;
633.2043 + },
633.2044 + stopImmediatePropagation: function() {
633.2045 + this.isImmediatePropagationStopped = returnTrue;
633.2046 + this.stopPropagation();
633.2047 + },
633.2048 + isDefaultPrevented: returnFalse,
633.2049 + isPropagationStopped: returnFalse,
633.2050 + isImmediatePropagationStopped: returnFalse
633.2051 +};
633.2052 +
633.2053 +// Checks if an event happened on an element within another element
633.2054 +// Used in jQuery.event.special.mouseenter and mouseleave handlers
633.2055 +var withinElement = function( event ) {
633.2056 + // Check if mouse(over|out) are still within the same parent element
633.2057 + var parent = event.relatedTarget;
633.2058 +
633.2059 + // Traverse up the tree
633.2060 + while ( parent && parent !== this ) {
633.2061 + // Firefox sometimes assigns relatedTarget a XUL element
633.2062 + // which we cannot access the parentNode property of
633.2063 + try {
633.2064 + parent = parent.parentNode;
633.2065 +
633.2066 + // assuming we've left the element since we most likely mousedover a xul element
633.2067 + } catch(e) {
633.2068 + break;
633.2069 + }
633.2070 + }
633.2071 +
633.2072 + if ( parent !== this ) {
633.2073 + // set the correct event type
633.2074 + event.type = event.data;
633.2075 +
633.2076 + // handle event if we actually just moused on to a non sub-element
633.2077 + jQuery.event.handle.apply( this, arguments );
633.2078 + }
633.2079 +
633.2080 +},
633.2081 +
633.2082 +// In case of event delegation, we only need to rename the event.type,
633.2083 +// liveHandler will take care of the rest.
633.2084 +delegate = function( event ) {
633.2085 + event.type = event.data;
633.2086 + jQuery.event.handle.apply( this, arguments );
633.2087 +};
633.2088 +
633.2089 +// Create mouseenter and mouseleave events
633.2090 +jQuery.each({
633.2091 + mouseenter: "mouseover",
633.2092 + mouseleave: "mouseout"
633.2093 +}, function( orig, fix ) {
633.2094 + jQuery.event.special[ orig ] = {
633.2095 + setup: function( data ) {
633.2096 + jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
633.2097 + },
633.2098 + teardown: function( data ) {
633.2099 + jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
633.2100 + }
633.2101 + };
633.2102 +});
633.2103 +
633.2104 +// submit delegation
633.2105 +if ( !jQuery.support.submitBubbles ) {
633.2106 +
633.2107 +jQuery.event.special.submit = {
633.2108 + setup: function( data, namespaces, fn ) {
633.2109 + if ( this.nodeName.toLowerCase() !== "form" ) {
633.2110 + jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
633.2111 + var elem = e.target, type = elem.type;
633.2112 +
633.2113 + if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
633.2114 + return trigger( "submit", this, arguments );
633.2115 + }
633.2116 + });
633.2117 +
633.2118 + jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
633.2119 + var elem = e.target, type = elem.type;
633.2120 +
633.2121 + if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
633.2122 + return trigger( "submit", this, arguments );
633.2123 + }
633.2124 + });
633.2125 +
633.2126 + } else {
633.2127 + return false;
633.2128 + }
633.2129 + },
633.2130 +
633.2131 + remove: function( namespaces, fn ) {
633.2132 + jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
633.2133 + jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
633.2134 + }
633.2135 +};
633.2136 +
633.2137 +}
633.2138 +
633.2139 +// change delegation, happens here so we have bind.
633.2140 +if ( !jQuery.support.changeBubbles ) {
633.2141 +
633.2142 +var formElems = /textarea|input|select/i;
633.2143 +
633.2144 +function getVal( elem ) {
633.2145 + var type = elem.type, val = elem.value;
633.2146 +
633.2147 + if ( type === "radio" || type === "checkbox" ) {
633.2148 + val = elem.checked;
633.2149 +
633.2150 + } else if ( type === "select-multiple" ) {
633.2151 + val = elem.selectedIndex > -1 ?
633.2152 + jQuery.map( elem.options, function( elem ) {
633.2153 + return elem.selected;
633.2154 + }).join("-") :
633.2155 + "";
633.2156 +
633.2157 + } else if ( elem.nodeName.toLowerCase() === "select" ) {
633.2158 + val = elem.selectedIndex;
633.2159 + }
633.2160 +
633.2161 + return val;
633.2162 +}
633.2163 +
633.2164 +function testChange( e ) {
633.2165 + var elem = e.target, data, val;
633.2166 +
633.2167 + if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
633.2168 + return;
633.2169 + }
633.2170 +
633.2171 + data = jQuery.data( elem, "_change_data" );
633.2172 + val = getVal(elem);
633.2173 +
633.2174 + if ( val === data ) {
633.2175 + return;
633.2176 + }
633.2177 +
633.2178 + // the current data will be also retrieved by beforeactivate
633.2179 + if ( e.type !== "focusout" || elem.type !== "radio" ) {
633.2180 + jQuery.data( elem, "_change_data", val );
633.2181 + }
633.2182 +
633.2183 + if ( elem.type !== "select" && (data != null || val) ) {
633.2184 + e.type = "change";
633.2185 + return jQuery.event.trigger( e, arguments[1], this );
633.2186 + }
633.2187 +}
633.2188 +
633.2189 +jQuery.event.special.change = {
633.2190 + filters: {
633.2191 + focusout: testChange,
633.2192 +
633.2193 + click: function( e ) {
633.2194 + var elem = e.target, type = elem.type;
633.2195 +
633.2196 + if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
633.2197 + return testChange.call( this, e );
633.2198 + }
633.2199 + },
633.2200 +
633.2201 + // Change has to be called before submit
633.2202 + // Keydown will be called before keypress, which is used in submit-event delegation
633.2203 + keydown: function( e ) {
633.2204 + var elem = e.target, type = elem.type;
633.2205 +
633.2206 + if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
633.2207 + (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
633.2208 + type === "select-multiple" ) {
633.2209 + return testChange.call( this, e );
633.2210 + }
633.2211 + },
633.2212 +
633.2213 + // Beforeactivate happens also before the previous element is blurred
633.2214 + // with this event you can't trigger a change event, but you can store
633.2215 + // information/focus[in] is not needed anymore
633.2216 + beforeactivate: function( e ) {
633.2217 + var elem = e.target;
633.2218 +
633.2219 + if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
633.2220 + jQuery.data( elem, "_change_data", getVal(elem) );
633.2221 + }
633.2222 + }
633.2223 + },
633.2224 + setup: function( data, namespaces, fn ) {
633.2225 + for ( var type in changeFilters ) {
633.2226 + jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
633.2227 + }
633.2228 +
633.2229 + return formElems.test( this.nodeName );
633.2230 + },
633.2231 + remove: function( namespaces, fn ) {
633.2232 + for ( var type in changeFilters ) {
633.2233 + jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
633.2234 + }
633.2235 +
633.2236 + return formElems.test( this.nodeName );
633.2237 + }
633.2238 +};
633.2239 +
633.2240 +var changeFilters = jQuery.event.special.change.filters;
633.2241 +
633.2242 +}
633.2243 +
633.2244 +function trigger( type, elem, args ) {
633.2245 + args[0].type = type;
633.2246 + return jQuery.event.handle.apply( elem, args );
633.2247 +}
633.2248 +
633.2249 +// Create "bubbling" focus and blur events
633.2250 +if ( document.addEventListener ) {
633.2251 + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
633.2252 + jQuery.event.special[ fix ] = {
633.2253 + setup: function() {
633.2254 + this.addEventListener( orig, handler, true );
633.2255 + },
633.2256 + teardown: function() {
633.2257 + this.removeEventListener( orig, handler, true );
633.2258 + }
633.2259 + };
633.2260 +
633.2261 + function handler( e ) {
633.2262 + e = jQuery.event.fix( e );
633.2263 + e.type = fix;
633.2264 + return jQuery.event.handle.call( this, e );
633.2265 + }
633.2266 + });
633.2267 +}
633.2268 +
633.2269 +jQuery.each(["bind", "one"], function( i, name ) {
633.2270 + jQuery.fn[ name ] = function( type, data, fn ) {
633.2271 + // Handle object literals
633.2272 + if ( typeof type === "object" ) {
633.2273 + for ( var key in type ) {
633.2274 + this[ name ](key, data, type[key], fn);
633.2275 + }
633.2276 + return this;
633.2277 + }
633.2278 +
633.2279 + if ( jQuery.isFunction( data ) ) {
633.2280 + thisObject = fn;
633.2281 + fn = data;
633.2282 + data = undefined;
633.2283 + }
633.2284 +
633.2285 + var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
633.2286 + jQuery( this ).unbind( event, handler );
633.2287 + return fn.apply( this, arguments );
633.2288 + }) : fn;
633.2289 +
633.2290 + return type === "unload" && name !== "one" ?
633.2291 + this.one( type, data, fn, thisObject ) :
633.2292 + this.each(function() {
633.2293 + jQuery.event.add( this, type, handler, data );
633.2294 + });
633.2295 + };
633.2296 +});
633.2297 +
633.2298 +jQuery.fn.extend({
633.2299 + unbind: function( type, fn ) {
633.2300 + // Handle object literals
633.2301 + if ( typeof type === "object" && !type.preventDefault ) {
633.2302 + for ( var key in type ) {
633.2303 + this.unbind(key, type[key]);
633.2304 + }
633.2305 + return this;
633.2306 + }
633.2307 +
633.2308 + return this.each(function() {
633.2309 + jQuery.event.remove( this, type, fn );
633.2310 + });
633.2311 + },
633.2312 + trigger: function( type, data ) {
633.2313 + return this.each(function() {
633.2314 + jQuery.event.trigger( type, data, this );
633.2315 + });
633.2316 + },
633.2317 +
633.2318 + triggerHandler: function( type, data ) {
633.2319 + if ( this[0] ) {
633.2320 + var event = jQuery.Event( type );
633.2321 + event.preventDefault();
633.2322 + event.stopPropagation();
633.2323 + jQuery.event.trigger( event, data, this[0] );
633.2324 + return event.result;
633.2325 + }
633.2326 + },
633.2327 +
633.2328 + toggle: function( fn ) {
633.2329 + // Save reference to arguments for access in closure
633.2330 + var args = arguments, i = 1;
633.2331 +
633.2332 + // link all the functions, so any of them can unbind this click handler
633.2333 + while ( i < args.length ) {
633.2334 + jQuery.proxy( fn, args[ i++ ] );
633.2335 + }
633.2336 +
633.2337 + return this.click( jQuery.proxy( fn, function( event ) {
633.2338 + // Figure out which function to execute
633.2339 + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
633.2340 + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
633.2341 +
633.2342 + // Make sure that clicks stop
633.2343 + event.preventDefault();
633.2344 +
633.2345 + // and execute the function
633.2346 + return args[ lastToggle ].apply( this, arguments ) || false;
633.2347 + }));
633.2348 + },
633.2349 +
633.2350 + hover: function( fnOver, fnOut ) {
633.2351 + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
633.2352 + },
633.2353 +
633.2354 + live: function( type, data, fn ) {
633.2355 + if ( jQuery.isFunction( data ) ) {
633.2356 + fn = data;
633.2357 + data = undefined;
633.2358 + }
633.2359 +
633.2360 + jQuery( this.context ).bind( liveConvert( type, this.selector ), {
633.2361 + data: data, selector: this.selector, live: type
633.2362 + }, fn );
633.2363 +
633.2364 + return this;
633.2365 + },
633.2366 +
633.2367 + die: function( type, fn ) {
633.2368 + jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
633.2369 + return this;
633.2370 + }
633.2371 +});
633.2372 +
633.2373 +function liveHandler( event ) {
633.2374 + var stop = true, elems = [], selectors = [], args = arguments,
633.2375 + related, match, fn, elem, j, i, data,
633.2376 + live = jQuery.extend({}, jQuery.data( this, "events" ).live);
633.2377 +
633.2378 + for ( j in live ) {
633.2379 + fn = live[j];
633.2380 + if ( fn.live === event.type ||
633.2381 + fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
633.2382 +
633.2383 + data = fn.data;
633.2384 + if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
633.2385 + !data.beforeFilter[event.type](event)) ) {
633.2386 + selectors.push( fn.selector );
633.2387 + }
633.2388 + } else {
633.2389 + delete live[j];
633.2390 + }
633.2391 + }
633.2392 +
633.2393 + match = jQuery( event.target ).closest( selectors, event.currentTarget );
633.2394 +
633.2395 + for ( i = 0, l = match.length; i < l; i++ ) {
633.2396 + for ( j in live ) {
633.2397 + fn = live[j];
633.2398 + elem = match[i].elem;
633.2399 + related = null;
633.2400 +
633.2401 + if ( match[i].selector === fn.selector ) {
633.2402 + // Those two events require additional checking
633.2403 + if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
633.2404 + related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
633.2405 + }
633.2406 +
633.2407 + if ( !related || related !== elem ) {
633.2408 + elems.push({ elem: elem, fn: fn });
633.2409 + }
633.2410 + }
633.2411 + }
633.2412 + }
633.2413 +
633.2414 + for ( i = 0, l = elems.length; i < l; i++ ) {
633.2415 + match = elems[i];
633.2416 + event.currentTarget = match.elem;
633.2417 + event.data = match.fn.data;
633.2418 + if ( match.fn.apply( match.elem, args ) === false ) {
633.2419 + stop = false;
633.2420 + break;
633.2421 + }
633.2422 + }
633.2423 +
633.2424 + return stop;
633.2425 +}
633.2426 +
633.2427 +function liveConvert( type, selector ) {
633.2428 + return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "&")].join(".");
633.2429 +}
633.2430 +
633.2431 +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
633.2432 + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
633.2433 + "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
633.2434 +
633.2435 + // Handle event binding
633.2436 + jQuery.fn[ name ] = function( fn ) {
633.2437 + return fn ? this.bind( name, fn ) : this.trigger( name );
633.2438 + };
633.2439 +
633.2440 + if ( jQuery.attrFn ) {
633.2441 + jQuery.attrFn[ name ] = true;
633.2442 + }
633.2443 +});
633.2444 +
633.2445 +// Prevent memory leaks in IE
633.2446 +// Window isn't included so as not to unbind existing unload events
633.2447 +// More info:
633.2448 +// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
633.2449 +if ( window.attachEvent && !window.addEventListener ) {
633.2450 + window.attachEvent("onunload", function() {
633.2451 + for ( var id in jQuery.cache ) {
633.2452 + if ( jQuery.cache[ id ].handle ) {
633.2453 + // Try/Catch is to handle iframes being unloaded, see #4280
633.2454 + try {
633.2455 + jQuery.event.remove( jQuery.cache[ id ].handle.elem );
633.2456 + } catch(e) {}
633.2457 + }
633.2458 + }
633.2459 + });
633.2460 +}
633.2461 +/*!
633.2462 + * Sizzle CSS Selector Engine - v1.0
633.2463 + * Copyright 2009, The Dojo Foundation
633.2464 + * Released under the MIT, BSD, and GPL Licenses.
633.2465 + * More information: http://sizzlejs.com/
633.2466 + */
633.2467 +(function(){
633.2468 +
633.2469 +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
633.2470 + done = 0,
633.2471 + toString = Object.prototype.toString,
633.2472 + hasDuplicate = false,
633.2473 + baseHasDuplicate = true;
633.2474 +
633.2475 +// Here we check if the JavaScript engine is using some sort of
633.2476 +// optimization where it does not always call our comparision
633.2477 +// function. If that is the case, discard the hasDuplicate value.
633.2478 +// Thus far that includes Google Chrome.
633.2479 +[0, 0].sort(function(){
633.2480 + baseHasDuplicate = false;
633.2481 + return 0;
633.2482 +});
633.2483 +
633.2484 +var Sizzle = function(selector, context, results, seed) {
633.2485 + results = results || [];
633.2486 + var origContext = context = context || document;
633.2487 +
633.2488 + if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
633.2489 + return [];
633.2490 + }
633.2491 +
633.2492 + if ( !selector || typeof selector !== "string" ) {
633.2493 + return results;
633.2494 + }
633.2495 +
633.2496 + var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
633.2497 + soFar = selector;
633.2498 +
633.2499 + // Reset the position of the chunker regexp (start from head)
633.2500 + while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
633.2501 + soFar = m[3];
633.2502 +
633.2503 + parts.push( m[1] );
633.2504 +
633.2505 + if ( m[2] ) {
633.2506 + extra = m[3];
633.2507 + break;
633.2508 + }
633.2509 + }
633.2510 +
633.2511 + if ( parts.length > 1 && origPOS.exec( selector ) ) {
633.2512 + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
633.2513 + set = posProcess( parts[0] + parts[1], context );
633.2514 + } else {
633.2515 + set = Expr.relative[ parts[0] ] ?
633.2516 + [ context ] :
633.2517 + Sizzle( parts.shift(), context );
633.2518 +
633.2519 + while ( parts.length ) {
633.2520 + selector = parts.shift();
633.2521 +
633.2522 + if ( Expr.relative[ selector ] ) {
633.2523 + selector += parts.shift();
633.2524 + }
633.2525 +
633.2526 + set = posProcess( selector, set );
633.2527 + }
633.2528 + }
633.2529 + } else {
633.2530 + // Take a shortcut and set the context if the root selector is an ID
633.2531 + // (but not if it'll be faster if the inner selector is an ID)
633.2532 + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
633.2533 + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
633.2534 + var ret = Sizzle.find( parts.shift(), context, contextXML );
633.2535 + context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
633.2536 + }
633.2537 +
633.2538 + if ( context ) {
633.2539 + var ret = seed ?
633.2540 + { expr: parts.pop(), set: makeArray(seed) } :
633.2541 + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
633.2542 + set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
633.2543 +
633.2544 + if ( parts.length > 0 ) {
633.2545 + checkSet = makeArray(set);
633.2546 + } else {
633.2547 + prune = false;
633.2548 + }
633.2549 +
633.2550 + while ( parts.length ) {
633.2551 + var cur = parts.pop(), pop = cur;
633.2552 +
633.2553 + if ( !Expr.relative[ cur ] ) {
633.2554 + cur = "";
633.2555 + } else {
633.2556 + pop = parts.pop();
633.2557 + }
633.2558 +
633.2559 + if ( pop == null ) {
633.2560 + pop = context;
633.2561 + }
633.2562 +
633.2563 + Expr.relative[ cur ]( checkSet, pop, contextXML );
633.2564 + }
633.2565 + } else {
633.2566 + checkSet = parts = [];
633.2567 + }
633.2568 + }
633.2569 +
633.2570 + if ( !checkSet ) {
633.2571 + checkSet = set;
633.2572 + }
633.2573 +
633.2574 + if ( !checkSet ) {
633.2575 + throw "Syntax error, unrecognized expression: " + (cur || selector);
633.2576 + }
633.2577 +
633.2578 + if ( toString.call(checkSet) === "[object Array]" ) {
633.2579 + if ( !prune ) {
633.2580 + results.push.apply( results, checkSet );
633.2581 + } else if ( context && context.nodeType === 1 ) {
633.2582 + for ( var i = 0; checkSet[i] != null; i++ ) {
633.2583 + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
633.2584 + results.push( set[i] );
633.2585 + }
633.2586 + }
633.2587 + } else {
633.2588 + for ( var i = 0; checkSet[i] != null; i++ ) {
633.2589 + if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
633.2590 + results.push( set[i] );
633.2591 + }
633.2592 + }
633.2593 + }
633.2594 + } else {
633.2595 + makeArray( checkSet, results );
633.2596 + }
633.2597 +
633.2598 + if ( extra ) {
633.2599 + Sizzle( extra, origContext, results, seed );
633.2600 + Sizzle.uniqueSort( results );
633.2601 + }
633.2602 +
633.2603 + return results;
633.2604 +};
633.2605 +
633.2606 +Sizzle.uniqueSort = function(results){
633.2607 + if ( sortOrder ) {
633.2608 + hasDuplicate = baseHasDuplicate;
633.2609 + results.sort(sortOrder);
633.2610 +
633.2611 + if ( hasDuplicate ) {
633.2612 + for ( var i = 1; i < results.length; i++ ) {
633.2613 + if ( results[i] === results[i-1] ) {
633.2614 + results.splice(i--, 1);
633.2615 + }
633.2616 + }
633.2617 + }
633.2618 + }
633.2619 +
633.2620 + return results;
633.2621 +};
633.2622 +
633.2623 +Sizzle.matches = function(expr, set){
633.2624 + return Sizzle(expr, null, null, set);
633.2625 +};
633.2626 +
633.2627 +Sizzle.find = function(expr, context, isXML){
633.2628 + var set, match;
633.2629 +
633.2630 + if ( !expr ) {
633.2631 + return [];
633.2632 + }
633.2633 +
633.2634 + for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
633.2635 + var type = Expr.order[i], match;
633.2636 +
633.2637 + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
633.2638 + var left = match[1];
633.2639 + match.splice(1,1);
633.2640 +
633.2641 + if ( left.substr( left.length - 1 ) !== "\\" ) {
633.2642 + match[1] = (match[1] || "").replace(/\\/g, "");
633.2643 + set = Expr.find[ type ]( match, context, isXML );
633.2644 + if ( set != null ) {
633.2645 + expr = expr.replace( Expr.match[ type ], "" );
633.2646 + break;
633.2647 + }
633.2648 + }
633.2649 + }
633.2650 + }
633.2651 +
633.2652 + if ( !set ) {
633.2653 + set = context.getElementsByTagName("*");
633.2654 + }
633.2655 +
633.2656 + return {set: set, expr: expr};
633.2657 +};
633.2658 +
633.2659 +Sizzle.filter = function(expr, set, inplace, not){
633.2660 + var old = expr, result = [], curLoop = set, match, anyFound,
633.2661 + isXMLFilter = set && set[0] && isXML(set[0]);
633.2662 +
633.2663 + while ( expr && set.length ) {
633.2664 + for ( var type in Expr.filter ) {
633.2665 + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
633.2666 + var filter = Expr.filter[ type ], found, item, left = match[1];
633.2667 + anyFound = false;
633.2668 +
633.2669 + match.splice(1,1);
633.2670 +
633.2671 + if ( left.substr( left.length - 1 ) === "\\" ) {
633.2672 + continue;
633.2673 + }
633.2674 +
633.2675 + if ( curLoop === result ) {
633.2676 + result = [];
633.2677 + }
633.2678 +
633.2679 + if ( Expr.preFilter[ type ] ) {
633.2680 + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
633.2681 +
633.2682 + if ( !match ) {
633.2683 + anyFound = found = true;
633.2684 + } else if ( match === true ) {
633.2685 + continue;
633.2686 + }
633.2687 + }
633.2688 +
633.2689 + if ( match ) {
633.2690 + for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
633.2691 + if ( item ) {
633.2692 + found = filter( item, match, i, curLoop );
633.2693 + var pass = not ^ !!found;
633.2694 +
633.2695 + if ( inplace && found != null ) {
633.2696 + if ( pass ) {
633.2697 + anyFound = true;
633.2698 + } else {
633.2699 + curLoop[i] = false;
633.2700 + }
633.2701 + } else if ( pass ) {
633.2702 + result.push( item );
633.2703 + anyFound = true;
633.2704 + }
633.2705 + }
633.2706 + }
633.2707 + }
633.2708 +
633.2709 + if ( found !== undefined ) {
633.2710 + if ( !inplace ) {
633.2711 + curLoop = result;
633.2712 + }
633.2713 +
633.2714 + expr = expr.replace( Expr.match[ type ], "" );
633.2715 +
633.2716 + if ( !anyFound ) {
633.2717 + return [];
633.2718 + }
633.2719 +
633.2720 + break;
633.2721 + }
633.2722 + }
633.2723 + }
633.2724 +
633.2725 + // Improper expression
633.2726 + if ( expr === old ) {
633.2727 + if ( anyFound == null ) {
633.2728 + throw "Syntax error, unrecognized expression: " + expr;
633.2729 + } else {
633.2730 + break;
633.2731 + }
633.2732 + }
633.2733 +
633.2734 + old = expr;
633.2735 + }
633.2736 +
633.2737 + return curLoop;
633.2738 +};
633.2739 +
633.2740 +var Expr = Sizzle.selectors = {
633.2741 + order: [ "ID", "NAME", "TAG" ],
633.2742 + match: {
633.2743 + ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
633.2744 + CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
633.2745 + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
633.2746 + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
633.2747 + TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
633.2748 + CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
633.2749 + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
633.2750 + PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
633.2751 + },
633.2752 + leftMatch: {},
633.2753 + attrMap: {
633.2754 + "class": "className",
633.2755 + "for": "htmlFor"
633.2756 + },
633.2757 + attrHandle: {
633.2758 + href: function(elem){
633.2759 + return elem.getAttribute("href");
633.2760 + }
633.2761 + },
633.2762 + relative: {
633.2763 + "+": function(checkSet, part){
633.2764 + var isPartStr = typeof part === "string",
633.2765 + isTag = isPartStr && !/\W/.test(part),
633.2766 + isPartStrNotTag = isPartStr && !isTag;
633.2767 +
633.2768 + if ( isTag ) {
633.2769 + part = part.toLowerCase();
633.2770 + }
633.2771 +
633.2772 + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
633.2773 + if ( (elem = checkSet[i]) ) {
633.2774 + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
633.2775 +
633.2776 + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
633.2777 + elem || false :
633.2778 + elem === part;
633.2779 + }
633.2780 + }
633.2781 +
633.2782 + if ( isPartStrNotTag ) {
633.2783 + Sizzle.filter( part, checkSet, true );
633.2784 + }
633.2785 + },
633.2786 + ">": function(checkSet, part){
633.2787 + var isPartStr = typeof part === "string";
633.2788 +
633.2789 + if ( isPartStr && !/\W/.test(part) ) {
633.2790 + part = part.toLowerCase();
633.2791 +
633.2792 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
633.2793 + var elem = checkSet[i];
633.2794 + if ( elem ) {
633.2795 + var parent = elem.parentNode;
633.2796 + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
633.2797 + }
633.2798 + }
633.2799 + } else {
633.2800 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
633.2801 + var elem = checkSet[i];
633.2802 + if ( elem ) {
633.2803 + checkSet[i] = isPartStr ?
633.2804 + elem.parentNode :
633.2805 + elem.parentNode === part;
633.2806 + }
633.2807 + }
633.2808 +
633.2809 + if ( isPartStr ) {
633.2810 + Sizzle.filter( part, checkSet, true );
633.2811 + }
633.2812 + }
633.2813 + },
633.2814 + "": function(checkSet, part, isXML){
633.2815 + var doneName = done++, checkFn = dirCheck;
633.2816 +
633.2817 + if ( typeof part === "string" && !/\W/.test(part) ) {
633.2818 + var nodeCheck = part = part.toLowerCase();
633.2819 + checkFn = dirNodeCheck;
633.2820 + }
633.2821 +
633.2822 + checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
633.2823 + },
633.2824 + "~": function(checkSet, part, isXML){
633.2825 + var doneName = done++, checkFn = dirCheck;
633.2826 +
633.2827 + if ( typeof part === "string" && !/\W/.test(part) ) {
633.2828 + var nodeCheck = part = part.toLowerCase();
633.2829 + checkFn = dirNodeCheck;
633.2830 + }
633.2831 +
633.2832 + checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
633.2833 + }
633.2834 + },
633.2835 + find: {
633.2836 + ID: function(match, context, isXML){
633.2837 + if ( typeof context.getElementById !== "undefined" && !isXML ) {
633.2838 + var m = context.getElementById(match[1]);
633.2839 + return m ? [m] : [];
633.2840 + }
633.2841 + },
633.2842 + NAME: function(match, context){
633.2843 + if ( typeof context.getElementsByName !== "undefined" ) {
633.2844 + var ret = [], results = context.getElementsByName(match[1]);
633.2845 +
633.2846 + for ( var i = 0, l = results.length; i < l; i++ ) {
633.2847 + if ( results[i].getAttribute("name") === match[1] ) {
633.2848 + ret.push( results[i] );
633.2849 + }
633.2850 + }
633.2851 +
633.2852 + return ret.length === 0 ? null : ret;
633.2853 + }
633.2854 + },
633.2855 + TAG: function(match, context){
633.2856 + return context.getElementsByTagName(match[1]);
633.2857 + }
633.2858 + },
633.2859 + preFilter: {
633.2860 + CLASS: function(match, curLoop, inplace, result, not, isXML){
633.2861 + match = " " + match[1].replace(/\\/g, "") + " ";
633.2862 +
633.2863 + if ( isXML ) {
633.2864 + return match;
633.2865 + }
633.2866 +
633.2867 + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
633.2868 + if ( elem ) {
633.2869 + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
633.2870 + if ( !inplace ) {
633.2871 + result.push( elem );
633.2872 + }
633.2873 + } else if ( inplace ) {
633.2874 + curLoop[i] = false;
633.2875 + }
633.2876 + }
633.2877 + }
633.2878 +
633.2879 + return false;
633.2880 + },
633.2881 + ID: function(match){
633.2882 + return match[1].replace(/\\/g, "");
633.2883 + },
633.2884 + TAG: function(match, curLoop){
633.2885 + return match[1].toLowerCase();
633.2886 + },
633.2887 + CHILD: function(match){
633.2888 + if ( match[1] === "nth" ) {
633.2889 + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
633.2890 + var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
633.2891 + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
633.2892 + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
633.2893 +
633.2894 + // calculate the numbers (first)n+(last) including if they are negative
633.2895 + match[2] = (test[1] + (test[2] || 1)) - 0;
633.2896 + match[3] = test[3] - 0;
633.2897 + }
633.2898 +
633.2899 + // TODO: Move to normal caching system
633.2900 + match[0] = done++;
633.2901 +
633.2902 + return match;
633.2903 + },
633.2904 + ATTR: function(match, curLoop, inplace, result, not, isXML){
633.2905 + var name = match[1].replace(/\\/g, "");
633.2906 +
633.2907 + if ( !isXML && Expr.attrMap[name] ) {
633.2908 + match[1] = Expr.attrMap[name];
633.2909 + }
633.2910 +
633.2911 + if ( match[2] === "~=" ) {
633.2912 + match[4] = " " + match[4] + " ";
633.2913 + }
633.2914 +
633.2915 + return match;
633.2916 + },
633.2917 + PSEUDO: function(match, curLoop, inplace, result, not){
633.2918 + if ( match[1] === "not" ) {
633.2919 + // If we're dealing with a complex expression, or a simple one
633.2920 + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
633.2921 + match[3] = Sizzle(match[3], null, null, curLoop);
633.2922 + } else {
633.2923 + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
633.2924 + if ( !inplace ) {
633.2925 + result.push.apply( result, ret );
633.2926 + }
633.2927 + return false;
633.2928 + }
633.2929 + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
633.2930 + return true;
633.2931 + }
633.2932 +
633.2933 + return match;
633.2934 + },
633.2935 + POS: function(match){
633.2936 + match.unshift( true );
633.2937 + return match;
633.2938 + }
633.2939 + },
633.2940 + filters: {
633.2941 + enabled: function(elem){
633.2942 + return elem.disabled === false && elem.type !== "hidden";
633.2943 + },
633.2944 + disabled: function(elem){
633.2945 + return elem.disabled === true;
633.2946 + },
633.2947 + checked: function(elem){
633.2948 + return elem.checked === true;
633.2949 + },
633.2950 + selected: function(elem){
633.2951 + // Accessing this property makes selected-by-default
633.2952 + // options in Safari work properly
633.2953 + elem.parentNode.selectedIndex;
633.2954 + return elem.selected === true;
633.2955 + },
633.2956 + parent: function(elem){
633.2957 + return !!elem.firstChild;
633.2958 + },
633.2959 + empty: function(elem){
633.2960 + return !elem.firstChild;
633.2961 + },
633.2962 + has: function(elem, i, match){
633.2963 + return !!Sizzle( match[3], elem ).length;
633.2964 + },
633.2965 + header: function(elem){
633.2966 + return /h\d/i.test( elem.nodeName );
633.2967 + },
633.2968 + text: function(elem){
633.2969 + return "text" === elem.type;
633.2970 + },
633.2971 + radio: function(elem){
633.2972 + return "radio" === elem.type;
633.2973 + },
633.2974 + checkbox: function(elem){
633.2975 + return "checkbox" === elem.type;
633.2976 + },
633.2977 + file: function(elem){
633.2978 + return "file" === elem.type;
633.2979 + },
633.2980 + password: function(elem){
633.2981 + return "password" === elem.type;
633.2982 + },
633.2983 + submit: function(elem){
633.2984 + return "submit" === elem.type;
633.2985 + },
633.2986 + image: function(elem){
633.2987 + return "image" === elem.type;
633.2988 + },
633.2989 + reset: function(elem){
633.2990 + return "reset" === elem.type;
633.2991 + },
633.2992 + button: function(elem){
633.2993 + return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
633.2994 + },
633.2995 + input: function(elem){
633.2996 + return /input|select|textarea|button/i.test(elem.nodeName);
633.2997 + }
633.2998 + },
633.2999 + setFilters: {
633.3000 + first: function(elem, i){
633.3001 + return i === 0;
633.3002 + },
633.3003 + last: function(elem, i, match, array){
633.3004 + return i === array.length - 1;
633.3005 + },
633.3006 + even: function(elem, i){
633.3007 + return i % 2 === 0;
633.3008 + },
633.3009 + odd: function(elem, i){
633.3010 + return i % 2 === 1;
633.3011 + },
633.3012 + lt: function(elem, i, match){
633.3013 + return i < match[3] - 0;
633.3014 + },
633.3015 + gt: function(elem, i, match){
633.3016 + return i > match[3] - 0;
633.3017 + },
633.3018 + nth: function(elem, i, match){
633.3019 + return match[3] - 0 === i;
633.3020 + },
633.3021 + eq: function(elem, i, match){
633.3022 + return match[3] - 0 === i;
633.3023 + }
633.3024 + },
633.3025 + filter: {
633.3026 + PSEUDO: function(elem, match, i, array){
633.3027 + var name = match[1], filter = Expr.filters[ name ];
633.3028 +
633.3029 + if ( filter ) {
633.3030 + return filter( elem, i, match, array );
633.3031 + } else if ( name === "contains" ) {
633.3032 + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
633.3033 + } else if ( name === "not" ) {
633.3034 + var not = match[3];
633.3035 +
633.3036 + for ( var i = 0, l = not.length; i < l; i++ ) {
633.3037 + if ( not[i] === elem ) {
633.3038 + return false;
633.3039 + }
633.3040 + }
633.3041 +
633.3042 + return true;
633.3043 + } else {
633.3044 + throw "Syntax error, unrecognized expression: " + name;
633.3045 + }
633.3046 + },
633.3047 + CHILD: function(elem, match){
633.3048 + var type = match[1], node = elem;
633.3049 + switch (type) {
633.3050 + case 'only':
633.3051 + case 'first':
633.3052 + while ( (node = node.previousSibling) ) {
633.3053 + if ( node.nodeType === 1 ) {
633.3054 + return false;
633.3055 + }
633.3056 + }
633.3057 + if ( type === "first" ) {
633.3058 + return true;
633.3059 + }
633.3060 + node = elem;
633.3061 + case 'last':
633.3062 + while ( (node = node.nextSibling) ) {
633.3063 + if ( node.nodeType === 1 ) {
633.3064 + return false;
633.3065 + }
633.3066 + }
633.3067 + return true;
633.3068 + case 'nth':
633.3069 + var first = match[2], last = match[3];
633.3070 +
633.3071 + if ( first === 1 && last === 0 ) {
633.3072 + return true;
633.3073 + }
633.3074 +
633.3075 + var doneName = match[0],
633.3076 + parent = elem.parentNode;
633.3077 +
633.3078 + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
633.3079 + var count = 0;
633.3080 + for ( node = parent.firstChild; node; node = node.nextSibling ) {
633.3081 + if ( node.nodeType === 1 ) {
633.3082 + node.nodeIndex = ++count;
633.3083 + }
633.3084 + }
633.3085 + parent.sizcache = doneName;
633.3086 + }
633.3087 +
633.3088 + var diff = elem.nodeIndex - last;
633.3089 + if ( first === 0 ) {
633.3090 + return diff === 0;
633.3091 + } else {
633.3092 + return ( diff % first === 0 && diff / first >= 0 );
633.3093 + }
633.3094 + }
633.3095 + },
633.3096 + ID: function(elem, match){
633.3097 + return elem.nodeType === 1 && elem.getAttribute("id") === match;
633.3098 + },
633.3099 + TAG: function(elem, match){
633.3100 + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
633.3101 + },
633.3102 + CLASS: function(elem, match){
633.3103 + return (" " + (elem.className || elem.getAttribute("class")) + " ")
633.3104 + .indexOf( match ) > -1;
633.3105 + },
633.3106 + ATTR: function(elem, match){
633.3107 + var name = match[1],
633.3108 + result = Expr.attrHandle[ name ] ?
633.3109 + Expr.attrHandle[ name ]( elem ) :
633.3110 + elem[ name ] != null ?
633.3111 + elem[ name ] :
633.3112 + elem.getAttribute( name ),
633.3113 + value = result + "",
633.3114 + type = match[2],
633.3115 + check = match[4];
633.3116 +
633.3117 + return result == null ?
633.3118 + type === "!=" :
633.3119 + type === "=" ?
633.3120 + value === check :
633.3121 + type === "*=" ?
633.3122 + value.indexOf(check) >= 0 :
633.3123 + type === "~=" ?
633.3124 + (" " + value + " ").indexOf(check) >= 0 :
633.3125 + !check ?
633.3126 + value && result !== false :
633.3127 + type === "!=" ?
633.3128 + value !== check :
633.3129 + type === "^=" ?
633.3130 + value.indexOf(check) === 0 :
633.3131 + type === "$=" ?
633.3132 + value.substr(value.length - check.length) === check :
633.3133 + type === "|=" ?
633.3134 + value === check || value.substr(0, check.length + 1) === check + "-" :
633.3135 + false;
633.3136 + },
633.3137 + POS: function(elem, match, i, array){
633.3138 + var name = match[2], filter = Expr.setFilters[ name ];
633.3139 +
633.3140 + if ( filter ) {
633.3141 + return filter( elem, i, match, array );
633.3142 + }
633.3143 + }
633.3144 + }
633.3145 +};
633.3146 +
633.3147 +var origPOS = Expr.match.POS;
633.3148 +
633.3149 +for ( var type in Expr.match ) {
633.3150 + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
633.3151 + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
633.3152 + return "\\" + (num - 0 + 1);
633.3153 + }));
633.3154 +}
633.3155 +
633.3156 +var makeArray = function(array, results) {
633.3157 + array = Array.prototype.slice.call( array, 0 );
633.3158 +
633.3159 + if ( results ) {
633.3160 + results.push.apply( results, array );
633.3161 + return results;
633.3162 + }
633.3163 +
633.3164 + return array;
633.3165 +};
633.3166 +
633.3167 +// Perform a simple check to determine if the browser is capable of
633.3168 +// converting a NodeList to an array using builtin methods.
633.3169 +try {
633.3170 + Array.prototype.slice.call( document.documentElement.childNodes, 0 );
633.3171 +
633.3172 +// Provide a fallback method if it does not work
633.3173 +} catch(e){
633.3174 + makeArray = function(array, results) {
633.3175 + var ret = results || [];
633.3176 +
633.3177 + if ( toString.call(array) === "[object Array]" ) {
633.3178 + Array.prototype.push.apply( ret, array );
633.3179 + } else {
633.3180 + if ( typeof array.length === "number" ) {
633.3181 + for ( var i = 0, l = array.length; i < l; i++ ) {
633.3182 + ret.push( array[i] );
633.3183 + }
633.3184 + } else {
633.3185 + for ( var i = 0; array[i]; i++ ) {
633.3186 + ret.push( array[i] );
633.3187 + }
633.3188 + }
633.3189 + }
633.3190 +
633.3191 + return ret;
633.3192 + };
633.3193 +}
633.3194 +
633.3195 +var sortOrder;
633.3196 +
633.3197 +if ( document.documentElement.compareDocumentPosition ) {
633.3198 + sortOrder = function( a, b ) {
633.3199 + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
633.3200 + if ( a == b ) {
633.3201 + hasDuplicate = true;
633.3202 + }
633.3203 + return a.compareDocumentPosition ? -1 : 1;
633.3204 + }
633.3205 +
633.3206 + var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
633.3207 + if ( ret === 0 ) {
633.3208 + hasDuplicate = true;
633.3209 + }
633.3210 + return ret;
633.3211 + };
633.3212 +} else if ( "sourceIndex" in document.documentElement ) {
633.3213 + sortOrder = function( a, b ) {
633.3214 + if ( !a.sourceIndex || !b.sourceIndex ) {
633.3215 + if ( a == b ) {
633.3216 + hasDuplicate = true;
633.3217 + }
633.3218 + return a.sourceIndex ? -1 : 1;
633.3219 + }
633.3220 +
633.3221 + var ret = a.sourceIndex - b.sourceIndex;
633.3222 + if ( ret === 0 ) {
633.3223 + hasDuplicate = true;
633.3224 + }
633.3225 + return ret;
633.3226 + };
633.3227 +} else if ( document.createRange ) {
633.3228 + sortOrder = function( a, b ) {
633.3229 + if ( !a.ownerDocument || !b.ownerDocument ) {
633.3230 + if ( a == b ) {
633.3231 + hasDuplicate = true;
633.3232 + }
633.3233 + return a.ownerDocument ? -1 : 1;
633.3234 + }
633.3235 +
633.3236 + var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
633.3237 + aRange.setStart(a, 0);
633.3238 + aRange.setEnd(a, 0);
633.3239 + bRange.setStart(b, 0);
633.3240 + bRange.setEnd(b, 0);
633.3241 + var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
633.3242 + if ( ret === 0 ) {
633.3243 + hasDuplicate = true;
633.3244 + }
633.3245 + return ret;
633.3246 + };
633.3247 +}
633.3248 +
633.3249 +// Utility function for retreiving the text value of an array of DOM nodes
633.3250 +function getText( elems ) {
633.3251 + var ret = "", elem;
633.3252 +
633.3253 + for ( var i = 0; elems[i]; i++ ) {
633.3254 + elem = elems[i];
633.3255 +
633.3256 + // Get the text from text nodes and CDATA nodes
633.3257 + if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
633.3258 + ret += elem.nodeValue;
633.3259 +
633.3260 + // Traverse everything else, except comment nodes
633.3261 + } else if ( elem.nodeType !== 8 ) {
633.3262 + ret += getText( elem.childNodes );
633.3263 + }
633.3264 + }
633.3265 +
633.3266 + return ret;
633.3267 +}
633.3268 +
633.3269 +// Check to see if the browser returns elements by name when
633.3270 +// querying by getElementById (and provide a workaround)
633.3271 +(function(){
633.3272 + // We're going to inject a fake input element with a specified name
633.3273 + var form = document.createElement("div"),
633.3274 + id = "script" + (new Date).getTime();
633.3275 + form.innerHTML = "<a name='" + id + "'/>";
633.3276 +
633.3277 + // Inject it into the root element, check its status, and remove it quickly
633.3278 + var root = document.documentElement;
633.3279 + root.insertBefore( form, root.firstChild );
633.3280 +
633.3281 + // The workaround has to do additional checks after a getElementById
633.3282 + // Which slows things down for other browsers (hence the branching)
633.3283 + if ( document.getElementById( id ) ) {
633.3284 + Expr.find.ID = function(match, context, isXML){
633.3285 + if ( typeof context.getElementById !== "undefined" && !isXML ) {
633.3286 + var m = context.getElementById(match[1]);
633.3287 + return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
633.3288 + }
633.3289 + };
633.3290 +
633.3291 + Expr.filter.ID = function(elem, match){
633.3292 + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
633.3293 + return elem.nodeType === 1 && node && node.nodeValue === match;
633.3294 + };
633.3295 + }
633.3296 +
633.3297 + root.removeChild( form );
633.3298 + root = form = null; // release memory in IE
633.3299 +})();
633.3300 +
633.3301 +(function(){
633.3302 + // Check to see if the browser returns only elements
633.3303 + // when doing getElementsByTagName("*")
633.3304 +
633.3305 + // Create a fake element
633.3306 + var div = document.createElement("div");
633.3307 + div.appendChild( document.createComment("") );
633.3308 +
633.3309 + // Make sure no comments are found
633.3310 + if ( div.getElementsByTagName("*").length > 0 ) {
633.3311 + Expr.find.TAG = function(match, context){
633.3312 + var results = context.getElementsByTagName(match[1]);
633.3313 +
633.3314 + // Filter out possible comments
633.3315 + if ( match[1] === "*" ) {
633.3316 + var tmp = [];
633.3317 +
633.3318 + for ( var i = 0; results[i]; i++ ) {
633.3319 + if ( results[i].nodeType === 1 ) {
633.3320 + tmp.push( results[i] );
633.3321 + }
633.3322 + }
633.3323 +
633.3324 + results = tmp;
633.3325 + }
633.3326 +
633.3327 + return results;
633.3328 + };
633.3329 + }
633.3330 +
633.3331 + // Check to see if an attribute returns normalized href attributes
633.3332 + div.innerHTML = "<a href='#'></a>";
633.3333 + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
633.3334 + div.firstChild.getAttribute("href") !== "#" ) {
633.3335 + Expr.attrHandle.href = function(elem){
633.3336 + return elem.getAttribute("href", 2);
633.3337 + };
633.3338 + }
633.3339 +
633.3340 + div = null; // release memory in IE
633.3341 +})();
633.3342 +
633.3343 +if ( document.querySelectorAll ) {
633.3344 + (function(){
633.3345 + var oldSizzle = Sizzle, div = document.createElement("div");
633.3346 + div.innerHTML = "<p class='TEST'></p>";
633.3347 +
633.3348 + // Safari can't handle uppercase or unicode characters when
633.3349 + // in quirks mode.
633.3350 + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
633.3351 + return;
633.3352 + }
633.3353 +
633.3354 + Sizzle = function(query, context, extra, seed){
633.3355 + context = context || document;
633.3356 +
633.3357 + // Only use querySelectorAll on non-XML documents
633.3358 + // (ID selectors don't work in non-HTML documents)
633.3359 + if ( !seed && context.nodeType === 9 && !isXML(context) ) {
633.3360 + try {
633.3361 + return makeArray( context.querySelectorAll(query), extra );
633.3362 + } catch(e){}
633.3363 + }
633.3364 +
633.3365 + return oldSizzle(query, context, extra, seed);
633.3366 + };
633.3367 +
633.3368 + for ( var prop in oldSizzle ) {
633.3369 + Sizzle[ prop ] = oldSizzle[ prop ];
633.3370 + }
633.3371 +
633.3372 + div = null; // release memory in IE
633.3373 + })();
633.3374 +}
633.3375 +
633.3376 +(function(){
633.3377 + var div = document.createElement("div");
633.3378 +
633.3379 + div.innerHTML = "<div class='test e'></div><div class='test'></div>";
633.3380 +
633.3381 + // Opera can't find a second classname (in 9.6)
633.3382 + // Also, make sure that getElementsByClassName actually exists
633.3383 + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
633.3384 + return;
633.3385 + }
633.3386 +
633.3387 + // Safari caches class attributes, doesn't catch changes (in 3.2)
633.3388 + div.lastChild.className = "e";
633.3389 +
633.3390 + if ( div.getElementsByClassName("e").length === 1 ) {
633.3391 + return;
633.3392 + }
633.3393 +
633.3394 + Expr.order.splice(1, 0, "CLASS");
633.3395 + Expr.find.CLASS = function(match, context, isXML) {
633.3396 + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
633.3397 + return context.getElementsByClassName(match[1]);
633.3398 + }
633.3399 + };
633.3400 +
633.3401 + div = null; // release memory in IE
633.3402 +})();
633.3403 +
633.3404 +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
633.3405 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
633.3406 + var elem = checkSet[i];
633.3407 + if ( elem ) {
633.3408 + elem = elem[dir];
633.3409 + var match = false;
633.3410 +
633.3411 + while ( elem ) {
633.3412 + if ( elem.sizcache === doneName ) {
633.3413 + match = checkSet[elem.sizset];
633.3414 + break;
633.3415 + }
633.3416 +
633.3417 + if ( elem.nodeType === 1 && !isXML ){
633.3418 + elem.sizcache = doneName;
633.3419 + elem.sizset = i;
633.3420 + }
633.3421 +
633.3422 + if ( elem.nodeName.toLowerCase() === cur ) {
633.3423 + match = elem;
633.3424 + break;
633.3425 + }
633.3426 +
633.3427 + elem = elem[dir];
633.3428 + }
633.3429 +
633.3430 + checkSet[i] = match;
633.3431 + }
633.3432 + }
633.3433 +}
633.3434 +
633.3435 +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
633.3436 + for ( var i = 0, l = checkSet.length; i < l; i++ ) {
633.3437 + var elem = checkSet[i];
633.3438 + if ( elem ) {
633.3439 + elem = elem[dir];
633.3440 + var match = false;
633.3441 +
633.3442 + while ( elem ) {
633.3443 + if ( elem.sizcache === doneName ) {
633.3444 + match = checkSet[elem.sizset];
633.3445 + break;
633.3446 + }
633.3447 +
633.3448 + if ( elem.nodeType === 1 ) {
633.3449 + if ( !isXML ) {
633.3450 + elem.sizcache = doneName;
633.3451 + elem.sizset = i;
633.3452 + }
633.3453 + if ( typeof cur !== "string" ) {
633.3454 + if ( elem === cur ) {
633.3455 + match = true;
633.3456 + break;
633.3457 + }
633.3458 +
633.3459 + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
633.3460 + match = elem;
633.3461 + break;
633.3462 + }
633.3463 + }
633.3464 +
633.3465 + elem = elem[dir];
633.3466 + }
633.3467 +
633.3468 + checkSet[i] = match;
633.3469 + }
633.3470 + }
633.3471 +}
633.3472 +
633.3473 +var contains = document.compareDocumentPosition ? function(a, b){
633.3474 + return a.compareDocumentPosition(b) & 16;
633.3475 +} : function(a, b){
633.3476 + return a !== b && (a.contains ? a.contains(b) : true);
633.3477 +};
633.3478 +
633.3479 +var isXML = function(elem){
633.3480 + // documentElement is verified for cases where it doesn't yet exist
633.3481 + // (such as loading iframes in IE - #4833)
633.3482 + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
633.3483 + return documentElement ? documentElement.nodeName !== "HTML" : false;
633.3484 +};
633.3485 +
633.3486 +var posProcess = function(selector, context){
633.3487 + var tmpSet = [], later = "", match,
633.3488 + root = context.nodeType ? [context] : context;
633.3489 +
633.3490 + // Position selectors must be done after the filter
633.3491 + // And so must :not(positional) so we move all PSEUDOs to the end
633.3492 + while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
633.3493 + later += match[0];
633.3494 + selector = selector.replace( Expr.match.PSEUDO, "" );
633.3495 + }
633.3496 +
633.3497 + selector = Expr.relative[selector] ? selector + "*" : selector;
633.3498 +
633.3499 + for ( var i = 0, l = root.length; i < l; i++ ) {
633.3500 + Sizzle( selector, root[i], tmpSet );
633.3501 + }
633.3502 +
633.3503 + return Sizzle.filter( later, tmpSet );
633.3504 +};
633.3505 +
633.3506 +// EXPOSE
633.3507 +jQuery.find = Sizzle;
633.3508 +jQuery.expr = Sizzle.selectors;
633.3509 +jQuery.expr[":"] = jQuery.expr.filters;
633.3510 +jQuery.unique = Sizzle.uniqueSort;
633.3511 +jQuery.getText = getText;
633.3512 +jQuery.isXMLDoc = isXML;
633.3513 +jQuery.contains = contains;
633.3514 +
633.3515 +return;
633.3516 +
633.3517 +window.Sizzle = Sizzle;
633.3518 +
633.3519 +})();
633.3520 +var runtil = /Until$/,
633.3521 + rparentsprev = /^(?:parents|prevUntil|prevAll)/,
633.3522 + // Note: This RegExp should be improved, or likely pulled from Sizzle
633.3523 + rmultiselector = /,/,
633.3524 + slice = Array.prototype.slice;
633.3525 +
633.3526 +// Implement the identical functionality for filter and not
633.3527 +var winnow = function( elements, qualifier, keep ) {
633.3528 + if ( jQuery.isFunction( qualifier ) ) {
633.3529 + return jQuery.grep(elements, function( elem, i ) {
633.3530 + return !!qualifier.call( elem, i, elem ) === keep;
633.3531 + });
633.3532 +
633.3533 + } else if ( qualifier.nodeType ) {
633.3534 + return jQuery.grep(elements, function( elem, i ) {
633.3535 + return (elem === qualifier) === keep;
633.3536 + });
633.3537 +
633.3538 + } else if ( typeof qualifier === "string" ) {
633.3539 + var filtered = jQuery.grep(elements, function( elem ) {
633.3540 + return elem.nodeType === 1;
633.3541 + });
633.3542 +
633.3543 + if ( isSimple.test( qualifier ) ) {
633.3544 + return jQuery.filter(qualifier, filtered, !keep);
633.3545 + } else {
633.3546 + qualifier = jQuery.filter( qualifier, elements );
633.3547 + }
633.3548 + }
633.3549 +
633.3550 + return jQuery.grep(elements, function( elem, i ) {
633.3551 + return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
633.3552 + });
633.3553 +};
633.3554 +
633.3555 +jQuery.fn.extend({
633.3556 + find: function( selector ) {
633.3557 + var ret = this.pushStack( "", "find", selector ), length = 0;
633.3558 +
633.3559 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.3560 + length = ret.length;
633.3561 + jQuery.find( selector, this[i], ret );
633.3562 +
633.3563 + if ( i > 0 ) {
633.3564 + // Make sure that the results are unique
633.3565 + for ( var n = length; n < ret.length; n++ ) {
633.3566 + for ( var r = 0; r < length; r++ ) {
633.3567 + if ( ret[r] === ret[n] ) {
633.3568 + ret.splice(n--, 1);
633.3569 + break;
633.3570 + }
633.3571 + }
633.3572 + }
633.3573 + }
633.3574 + }
633.3575 +
633.3576 + return ret;
633.3577 + },
633.3578 +
633.3579 + has: function( target ) {
633.3580 + var targets = jQuery( target );
633.3581 + return this.filter(function() {
633.3582 + for ( var i = 0, l = targets.length; i < l; i++ ) {
633.3583 + if ( jQuery.contains( this, targets[i] ) ) {
633.3584 + return true;
633.3585 + }
633.3586 + }
633.3587 + });
633.3588 + },
633.3589 +
633.3590 + not: function( selector ) {
633.3591 + return this.pushStack( winnow(this, selector, false), "not", selector);
633.3592 + },
633.3593 +
633.3594 + filter: function( selector ) {
633.3595 + return this.pushStack( winnow(this, selector, true), "filter", selector );
633.3596 + },
633.3597 +
633.3598 + is: function( selector ) {
633.3599 + return !!selector && jQuery.filter( selector, this ).length > 0;
633.3600 + },
633.3601 +
633.3602 + closest: function( selectors, context ) {
633.3603 + if ( jQuery.isArray( selectors ) ) {
633.3604 + var ret = [], cur = this[0], match, matches = {}, selector;
633.3605 +
633.3606 + if ( cur && selectors.length ) {
633.3607 + for ( var i = 0, l = selectors.length; i < l; i++ ) {
633.3608 + selector = selectors[i];
633.3609 +
633.3610 + if ( !matches[selector] ) {
633.3611 + matches[selector] = jQuery.expr.match.POS.test( selector ) ?
633.3612 + jQuery( selector, context || this.context ) :
633.3613 + selector;
633.3614 + }
633.3615 + }
633.3616 +
633.3617 + while ( cur && cur.ownerDocument && cur !== context ) {
633.3618 + for ( selector in matches ) {
633.3619 + match = matches[selector];
633.3620 +
633.3621 + if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
633.3622 + ret.push({ selector: selector, elem: cur });
633.3623 + delete matches[selector];
633.3624 + }
633.3625 + }
633.3626 + cur = cur.parentNode;
633.3627 + }
633.3628 + }
633.3629 +
633.3630 + return ret;
633.3631 + }
633.3632 +
633.3633 + var pos = jQuery.expr.match.POS.test( selectors ) ?
633.3634 + jQuery( selectors, context || this.context ) : null;
633.3635 +
633.3636 + return this.map(function( i, cur ) {
633.3637 + while ( cur && cur.ownerDocument && cur !== context ) {
633.3638 + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
633.3639 + return cur;
633.3640 + }
633.3641 + cur = cur.parentNode;
633.3642 + }
633.3643 + return null;
633.3644 + });
633.3645 + },
633.3646 +
633.3647 + // Determine the position of an element within
633.3648 + // the matched set of elements
633.3649 + index: function( elem ) {
633.3650 + if ( !elem || typeof elem === "string" ) {
633.3651 + return jQuery.inArray( this[0],
633.3652 + // If it receives a string, the selector is used
633.3653 + // If it receives nothing, the siblings are used
633.3654 + elem ? jQuery( elem ) : this.parent().children() );
633.3655 + }
633.3656 + // Locate the position of the desired element
633.3657 + return jQuery.inArray(
633.3658 + // If it receives a jQuery object, the first element is used
633.3659 + elem.jquery ? elem[0] : elem, this );
633.3660 + },
633.3661 +
633.3662 + add: function( selector, context ) {
633.3663 + var set = typeof selector === "string" ?
633.3664 + jQuery( selector, context || this.context ) :
633.3665 + jQuery.makeArray( selector ),
633.3666 + all = jQuery.merge( this.get(), set );
633.3667 +
633.3668 + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
633.3669 + all :
633.3670 + jQuery.unique( all ) );
633.3671 + },
633.3672 +
633.3673 + andSelf: function() {
633.3674 + return this.add( this.prevObject );
633.3675 + }
633.3676 +});
633.3677 +
633.3678 +// A painfully simple check to see if an element is disconnected
633.3679 +// from a document (should be improved, where feasible).
633.3680 +function isDisconnected( node ) {
633.3681 + return !node || !node.parentNode || node.parentNode.nodeType === 11;
633.3682 +}
633.3683 +
633.3684 +jQuery.each({
633.3685 + parent: function( elem ) {
633.3686 + var parent = elem.parentNode;
633.3687 + return parent && parent.nodeType !== 11 ? parent : null;
633.3688 + },
633.3689 + parents: function( elem ) {
633.3690 + return jQuery.dir( elem, "parentNode" );
633.3691 + },
633.3692 + parentsUntil: function( elem, i, until ) {
633.3693 + return jQuery.dir( elem, "parentNode", until );
633.3694 + },
633.3695 + next: function( elem ) {
633.3696 + return jQuery.nth( elem, 2, "nextSibling" );
633.3697 + },
633.3698 + prev: function( elem ) {
633.3699 + return jQuery.nth( elem, 2, "previousSibling" );
633.3700 + },
633.3701 + nextAll: function( elem ) {
633.3702 + return jQuery.dir( elem, "nextSibling" );
633.3703 + },
633.3704 + prevAll: function( elem ) {
633.3705 + return jQuery.dir( elem, "previousSibling" );
633.3706 + },
633.3707 + nextUntil: function( elem, i, until ) {
633.3708 + return jQuery.dir( elem, "nextSibling", until );
633.3709 + },
633.3710 + prevUntil: function( elem, i, until ) {
633.3711 + return jQuery.dir( elem, "previousSibling", until );
633.3712 + },
633.3713 + siblings: function( elem ) {
633.3714 + return jQuery.sibling( elem.parentNode.firstChild, elem );
633.3715 + },
633.3716 + children: function( elem ) {
633.3717 + return jQuery.sibling( elem.firstChild );
633.3718 + },
633.3719 + contents: function( elem ) {
633.3720 + return jQuery.nodeName( elem, "iframe" ) ?
633.3721 + elem.contentDocument || elem.contentWindow.document :
633.3722 + jQuery.makeArray( elem.childNodes );
633.3723 + }
633.3724 +}, function( name, fn ) {
633.3725 + jQuery.fn[ name ] = function( until, selector ) {
633.3726 + var ret = jQuery.map( this, fn, until );
633.3727 +
633.3728 + if ( !runtil.test( name ) ) {
633.3729 + selector = until;
633.3730 + }
633.3731 +
633.3732 + if ( selector && typeof selector === "string" ) {
633.3733 + ret = jQuery.filter( selector, ret );
633.3734 + }
633.3735 +
633.3736 + ret = this.length > 1 ? jQuery.unique( ret ) : ret;
633.3737 +
633.3738 + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
633.3739 + ret = ret.reverse();
633.3740 + }
633.3741 +
633.3742 + return this.pushStack( ret, name, slice.call(arguments).join(",") );
633.3743 + };
633.3744 +});
633.3745 +
633.3746 +jQuery.extend({
633.3747 + filter: function( expr, elems, not ) {
633.3748 + if ( not ) {
633.3749 + expr = ":not(" + expr + ")";
633.3750 + }
633.3751 +
633.3752 + return jQuery.find.matches(expr, elems);
633.3753 + },
633.3754 +
633.3755 + dir: function( elem, dir, until ) {
633.3756 + var matched = [], cur = elem[dir];
633.3757 + while ( cur && cur.nodeType !== 9 && (until === undefined || !jQuery( cur ).is( until )) ) {
633.3758 + if ( cur.nodeType === 1 ) {
633.3759 + matched.push( cur );
633.3760 + }
633.3761 + cur = cur[dir];
633.3762 + }
633.3763 + return matched;
633.3764 + },
633.3765 +
633.3766 + nth: function( cur, result, dir, elem ) {
633.3767 + result = result || 1;
633.3768 + var num = 0;
633.3769 +
633.3770 + for ( ; cur; cur = cur[dir] ) {
633.3771 + if ( cur.nodeType === 1 && ++num === result ) {
633.3772 + break;
633.3773 + }
633.3774 + }
633.3775 +
633.3776 + return cur;
633.3777 + },
633.3778 +
633.3779 + sibling: function( n, elem ) {
633.3780 + var r = [];
633.3781 +
633.3782 + for ( ; n; n = n.nextSibling ) {
633.3783 + if ( n.nodeType === 1 && n !== elem ) {
633.3784 + r.push( n );
633.3785 + }
633.3786 + }
633.3787 +
633.3788 + return r;
633.3789 + }
633.3790 +});
633.3791 +var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
633.3792 + rleadingWhitespace = /^\s+/,
633.3793 + rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
633.3794 + rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
633.3795 + rtagName = /<([\w:]+)/,
633.3796 + rtbody = /<tbody/i,
633.3797 + rhtml = /<|&\w+;/,
633.3798 + fcloseTag = function( all, front, tag ) {
633.3799 + return rselfClosing.test( tag ) ?
633.3800 + all :
633.3801 + front + "></" + tag + ">";
633.3802 + },
633.3803 + wrapMap = {
633.3804 + option: [ 1, "<select multiple='multiple'>", "</select>" ],
633.3805 + legend: [ 1, "<fieldset>", "</fieldset>" ],
633.3806 + thead: [ 1, "<table>", "</table>" ],
633.3807 + tr: [ 2, "<table><tbody>", "</tbody></table>" ],
633.3808 + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
633.3809 + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
633.3810 + area: [ 1, "<map>", "</map>" ],
633.3811 + _default: [ 0, "", "" ]
633.3812 + };
633.3813 +
633.3814 +wrapMap.optgroup = wrapMap.option;
633.3815 +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
633.3816 +wrapMap.th = wrapMap.td;
633.3817 +
633.3818 +// IE can't serialize <link> and <script> tags normally
633.3819 +if ( !jQuery.support.htmlSerialize ) {
633.3820 + wrapMap._default = [ 1, "div<div>", "</div>" ];
633.3821 +}
633.3822 +
633.3823 +jQuery.fn.extend({
633.3824 + text: function( text ) {
633.3825 + if ( jQuery.isFunction(text) ) {
633.3826 + return this.each(function(i) {
633.3827 + var self = jQuery(this);
633.3828 + return self.text( text.call(this, i, self.text()) );
633.3829 + });
633.3830 + }
633.3831 +
633.3832 + if ( typeof text !== "object" && text !== undefined ) {
633.3833 + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
633.3834 + }
633.3835 +
633.3836 + return jQuery.getText( this );
633.3837 + },
633.3838 +
633.3839 + wrapAll: function( html ) {
633.3840 + if ( jQuery.isFunction( html ) ) {
633.3841 + return this.each(function(i) {
633.3842 + jQuery(this).wrapAll( html.call(this, i) );
633.3843 + });
633.3844 + }
633.3845 +
633.3846 + if ( this[0] ) {
633.3847 + // The elements to wrap the target around
633.3848 + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
633.3849 +
633.3850 + if ( this[0].parentNode ) {
633.3851 + wrap.insertBefore( this[0] );
633.3852 + }
633.3853 +
633.3854 + wrap.map(function() {
633.3855 + var elem = this;
633.3856 +
633.3857 + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
633.3858 + elem = elem.firstChild;
633.3859 + }
633.3860 +
633.3861 + return elem;
633.3862 + }).append(this);
633.3863 + }
633.3864 +
633.3865 + return this;
633.3866 + },
633.3867 +
633.3868 + wrapInner: function( html ) {
633.3869 + return this.each(function() {
633.3870 + var self = jQuery( this ), contents = self.contents();
633.3871 +
633.3872 + if ( contents.length ) {
633.3873 + contents.wrapAll( html );
633.3874 +
633.3875 + } else {
633.3876 + self.append( html );
633.3877 + }
633.3878 + });
633.3879 + },
633.3880 +
633.3881 + wrap: function( html ) {
633.3882 + return this.each(function() {
633.3883 + jQuery( this ).wrapAll( html );
633.3884 + });
633.3885 + },
633.3886 +
633.3887 + unwrap: function() {
633.3888 + return this.parent().each(function() {
633.3889 + if ( !jQuery.nodeName( this, "body" ) ) {
633.3890 + jQuery( this ).replaceWith( this.childNodes );
633.3891 + }
633.3892 + }).end();
633.3893 + },
633.3894 +
633.3895 + append: function() {
633.3896 + return this.domManip(arguments, true, function( elem ) {
633.3897 + if ( this.nodeType === 1 ) {
633.3898 + this.appendChild( elem );
633.3899 + }
633.3900 + });
633.3901 + },
633.3902 +
633.3903 + prepend: function() {
633.3904 + return this.domManip(arguments, true, function( elem ) {
633.3905 + if ( this.nodeType === 1 ) {
633.3906 + this.insertBefore( elem, this.firstChild );
633.3907 + }
633.3908 + });
633.3909 + },
633.3910 +
633.3911 + before: function() {
633.3912 + if ( this[0] && this[0].parentNode ) {
633.3913 + return this.domManip(arguments, false, function( elem ) {
633.3914 + this.parentNode.insertBefore( elem, this );
633.3915 + });
633.3916 + } else if ( arguments.length ) {
633.3917 + var set = jQuery(arguments[0]);
633.3918 + set.push.apply( set, this.toArray() );
633.3919 + return this.pushStack( set, "before", arguments );
633.3920 + }
633.3921 + },
633.3922 +
633.3923 + after: function() {
633.3924 + if ( this[0] && this[0].parentNode ) {
633.3925 + return this.domManip(arguments, false, function( elem ) {
633.3926 + this.parentNode.insertBefore( elem, this.nextSibling );
633.3927 + });
633.3928 + } else if ( arguments.length ) {
633.3929 + var set = this.pushStack( this, "after", arguments );
633.3930 + set.push.apply( set, jQuery(arguments[0]).toArray() );
633.3931 + return set;
633.3932 + }
633.3933 + },
633.3934 +
633.3935 + clone: function( events ) {
633.3936 + // Do the clone
633.3937 + var ret = this.map(function() {
633.3938 + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
633.3939 + // IE copies events bound via attachEvent when
633.3940 + // using cloneNode. Calling detachEvent on the
633.3941 + // clone will also remove the events from the orignal
633.3942 + // In order to get around this, we use innerHTML.
633.3943 + // Unfortunately, this means some modifications to
633.3944 + // attributes in IE that are actually only stored
633.3945 + // as properties will not be copied (such as the
633.3946 + // the name attribute on an input).
633.3947 + var html = this.outerHTML, ownerDocument = this.ownerDocument;
633.3948 + if ( !html ) {
633.3949 + var div = ownerDocument.createElement("div");
633.3950 + div.appendChild( this.cloneNode(true) );
633.3951 + html = div.innerHTML;
633.3952 + }
633.3953 +
633.3954 + return jQuery.clean([html.replace(rinlinejQuery, "")
633.3955 + .replace(rleadingWhitespace, "")], ownerDocument)[0];
633.3956 + } else {
633.3957 + return this.cloneNode(true);
633.3958 + }
633.3959 + });
633.3960 +
633.3961 + // Copy the events from the original to the clone
633.3962 + if ( events === true ) {
633.3963 + cloneCopyEvent( this, ret );
633.3964 + cloneCopyEvent( this.find("*"), ret.find("*") );
633.3965 + }
633.3966 +
633.3967 + // Return the cloned set
633.3968 + return ret;
633.3969 + },
633.3970 +
633.3971 + html: function( value ) {
633.3972 + if ( value === undefined ) {
633.3973 + return this[0] && this[0].nodeType === 1 ?
633.3974 + this[0].innerHTML.replace(rinlinejQuery, "") :
633.3975 + null;
633.3976 +
633.3977 + // See if we can take a shortcut and just use innerHTML
633.3978 + } else if ( typeof value === "string" && !/<script/i.test( value ) &&
633.3979 + (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
633.3980 + !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
633.3981 +
633.3982 + try {
633.3983 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.3984 + // Remove element nodes and prevent memory leaks
633.3985 + if ( this[i].nodeType === 1 ) {
633.3986 + cleanData( this[i].getElementsByTagName("*") );
633.3987 + this[i].innerHTML = value;
633.3988 + }
633.3989 + }
633.3990 +
633.3991 + // If using innerHTML throws an exception, use the fallback method
633.3992 + } catch(e) {
633.3993 + this.empty().append( value );
633.3994 + }
633.3995 +
633.3996 + } else if ( jQuery.isFunction( value ) ) {
633.3997 + this.each(function(i){
633.3998 + var self = jQuery(this), old = self.html();
633.3999 + self.empty().append(function(){
633.4000 + return value.call( this, i, old );
633.4001 + });
633.4002 + });
633.4003 +
633.4004 + } else {
633.4005 + this.empty().append( value );
633.4006 + }
633.4007 +
633.4008 + return this;
633.4009 + },
633.4010 +
633.4011 + replaceWith: function( value ) {
633.4012 + if ( this[0] && this[0].parentNode ) {
633.4013 + // Make sure that the elements are removed from the DOM before they are inserted
633.4014 + // this can help fix replacing a parent with child elements
633.4015 + if ( !jQuery.isFunction( value ) ) {
633.4016 + value = jQuery( value ).detach();
633.4017 + }
633.4018 +
633.4019 + return this.each(function() {
633.4020 + var next = this.nextSibling, parent = this.parentNode;
633.4021 +
633.4022 + jQuery(this).remove();
633.4023 +
633.4024 + if ( next ) {
633.4025 + jQuery(next).before( value );
633.4026 + } else {
633.4027 + jQuery(parent).append( value );
633.4028 + }
633.4029 + });
633.4030 + } else {
633.4031 + return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
633.4032 + }
633.4033 + },
633.4034 +
633.4035 + detach: function( selector ) {
633.4036 + return this.remove( selector, true );
633.4037 + },
633.4038 +
633.4039 + domManip: function( args, table, callback ) {
633.4040 + var results, first, value = args[0], scripts = [];
633.4041 +
633.4042 + if ( jQuery.isFunction(value) ) {
633.4043 + return this.each(function(i) {
633.4044 + var self = jQuery(this);
633.4045 + args[0] = value.call(this, i, table ? self.html() : undefined);
633.4046 + return self.domManip( args, table, callback );
633.4047 + });
633.4048 + }
633.4049 +
633.4050 + if ( this[0] ) {
633.4051 + // If we're in a fragment, just use that instead of building a new one
633.4052 + if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
633.4053 + results = { fragment: args[0].parentNode };
633.4054 + } else {
633.4055 + results = buildFragment( args, this, scripts );
633.4056 + }
633.4057 +
633.4058 + first = results.fragment.firstChild;
633.4059 +
633.4060 + if ( first ) {
633.4061 + table = table && jQuery.nodeName( first, "tr" );
633.4062 +
633.4063 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.4064 + callback.call(
633.4065 + table ?
633.4066 + root(this[i], first) :
633.4067 + this[i],
633.4068 + results.cacheable || this.length > 1 || i > 0 ?
633.4069 + results.fragment.cloneNode(true) :
633.4070 + results.fragment
633.4071 + );
633.4072 + }
633.4073 + }
633.4074 +
633.4075 + if ( scripts ) {
633.4076 + jQuery.each( scripts, evalScript );
633.4077 + }
633.4078 + }
633.4079 +
633.4080 + return this;
633.4081 +
633.4082 + function root( elem, cur ) {
633.4083 + return jQuery.nodeName(elem, "table") ?
633.4084 + (elem.getElementsByTagName("tbody")[0] ||
633.4085 + elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
633.4086 + elem;
633.4087 + }
633.4088 + }
633.4089 +});
633.4090 +
633.4091 +function cloneCopyEvent(orig, ret) {
633.4092 + var i = 0;
633.4093 +
633.4094 + ret.each(function() {
633.4095 + if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
633.4096 + return;
633.4097 + }
633.4098 +
633.4099 + var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
633.4100 +
633.4101 + if ( events ) {
633.4102 + delete curData.handle;
633.4103 + curData.events = {};
633.4104 +
633.4105 + for ( var type in events ) {
633.4106 + for ( var handler in events[ type ] ) {
633.4107 + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
633.4108 + }
633.4109 + }
633.4110 + }
633.4111 + });
633.4112 +}
633.4113 +
633.4114 +function buildFragment( args, nodes, scripts ) {
633.4115 + var fragment, cacheable, cached, cacheresults, doc;
633.4116 +
633.4117 + if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 ) {
633.4118 + cacheable = true;
633.4119 + cacheresults = jQuery.fragments[ args[0] ];
633.4120 + if ( cacheresults ) {
633.4121 + if ( cacheresults !== 1 ) {
633.4122 + fragment = cacheresults;
633.4123 + }
633.4124 + cached = true;
633.4125 + }
633.4126 + }
633.4127 +
633.4128 + if ( !fragment ) {
633.4129 + doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
633.4130 + fragment = doc.createDocumentFragment();
633.4131 + jQuery.clean( args, doc, fragment, scripts );
633.4132 + }
633.4133 +
633.4134 + if ( cacheable ) {
633.4135 + jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
633.4136 + }
633.4137 +
633.4138 + return { fragment: fragment, cacheable: cacheable };
633.4139 +}
633.4140 +
633.4141 +jQuery.fragments = {};
633.4142 +
633.4143 +jQuery.each({
633.4144 + appendTo: "append",
633.4145 + prependTo: "prepend",
633.4146 + insertBefore: "before",
633.4147 + insertAfter: "after",
633.4148 + replaceAll: "replaceWith"
633.4149 +}, function( name, original ) {
633.4150 + jQuery.fn[ name ] = function( selector ) {
633.4151 + var ret = [], insert = jQuery( selector );
633.4152 +
633.4153 + for ( var i = 0, l = insert.length; i < l; i++ ) {
633.4154 + var elems = (i > 0 ? this.clone(true) : this).get();
633.4155 + jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
633.4156 + ret = ret.concat( elems );
633.4157 + }
633.4158 + return this.pushStack( ret, name, insert.selector );
633.4159 + };
633.4160 +});
633.4161 +
633.4162 +jQuery.each({
633.4163 + // keepData is for internal use only--do not document
633.4164 + remove: function( selector, keepData ) {
633.4165 + if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
633.4166 + if ( !keepData && this.nodeType === 1 ) {
633.4167 + cleanData( this.getElementsByTagName("*") );
633.4168 + cleanData( [ this ] );
633.4169 + }
633.4170 +
633.4171 + if ( this.parentNode ) {
633.4172 + this.parentNode.removeChild( this );
633.4173 + }
633.4174 + }
633.4175 + },
633.4176 +
633.4177 + empty: function() {
633.4178 + // Remove element nodes and prevent memory leaks
633.4179 + if ( this.nodeType === 1 ) {
633.4180 + cleanData( this.getElementsByTagName("*") );
633.4181 + }
633.4182 +
633.4183 + // Remove any remaining nodes
633.4184 + while ( this.firstChild ) {
633.4185 + this.removeChild( this.firstChild );
633.4186 + }
633.4187 + }
633.4188 +}, function( name, fn ) {
633.4189 + jQuery.fn[ name ] = function() {
633.4190 + return this.each( fn, arguments );
633.4191 + };
633.4192 +});
633.4193 +
633.4194 +jQuery.extend({
633.4195 + clean: function( elems, context, fragment, scripts ) {
633.4196 + context = context || document;
633.4197 +
633.4198 + // !context.createElement fails in IE with an error but returns typeof 'object'
633.4199 + if ( typeof context.createElement === "undefined" ) {
633.4200 + context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
633.4201 + }
633.4202 +
633.4203 + var ret = [];
633.4204 +
633.4205 + jQuery.each(elems, function( i, elem ) {
633.4206 + if ( typeof elem === "number" ) {
633.4207 + elem += "";
633.4208 + }
633.4209 +
633.4210 + if ( !elem ) {
633.4211 + return;
633.4212 + }
633.4213 +
633.4214 + // Convert html string into DOM nodes
633.4215 + if ( typeof elem === "string" && !rhtml.test( elem ) ) {
633.4216 + elem = context.createTextNode( elem );
633.4217 +
633.4218 + } else if ( typeof elem === "string" ) {
633.4219 + // Fix "XHTML"-style tags in all browsers
633.4220 + elem = elem.replace(rxhtmlTag, fcloseTag);
633.4221 +
633.4222 + // Trim whitespace, otherwise indexOf won't work as expected
633.4223 + var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
633.4224 + wrap = wrapMap[ tag ] || wrapMap._default,
633.4225 + depth = wrap[0],
633.4226 + div = context.createElement("div");
633.4227 +
633.4228 + // Go to html and back, then peel off extra wrappers
633.4229 + div.innerHTML = wrap[1] + elem + wrap[2];
633.4230 +
633.4231 + // Move to the right depth
633.4232 + while ( depth-- ) {
633.4233 + div = div.lastChild;
633.4234 + }
633.4235 +
633.4236 + // Remove IE's autoinserted <tbody> from table fragments
633.4237 + if ( !jQuery.support.tbody ) {
633.4238 +
633.4239 + // String was a <table>, *may* have spurious <tbody>
633.4240 + var hasBody = rtbody.test(elem),
633.4241 + tbody = tag === "table" && !hasBody ?
633.4242 + div.firstChild && div.firstChild.childNodes :
633.4243 +
633.4244 + // String was a bare <thead> or <tfoot>
633.4245 + wrap[1] === "<table>" && !hasBody ?
633.4246 + div.childNodes :
633.4247 + [];
633.4248 +
633.4249 + for ( var j = tbody.length - 1; j >= 0 ; --j ) {
633.4250 + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
633.4251 + tbody[ j ].parentNode.removeChild( tbody[ j ] );
633.4252 + }
633.4253 + }
633.4254 +
633.4255 + }
633.4256 +
633.4257 + // IE completely kills leading whitespace when innerHTML is used
633.4258 + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
633.4259 + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
633.4260 + }
633.4261 +
633.4262 + elem = jQuery.makeArray( div.childNodes );
633.4263 + }
633.4264 +
633.4265 + if ( elem.nodeType ) {
633.4266 + ret.push( elem );
633.4267 + } else {
633.4268 + ret = jQuery.merge( ret, elem );
633.4269 + }
633.4270 +
633.4271 + });
633.4272 +
633.4273 + if ( fragment ) {
633.4274 + for ( var i = 0; ret[i]; i++ ) {
633.4275 + if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
633.4276 + scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
633.4277 + } else {
633.4278 + if ( ret[i].nodeType === 1 ) {
633.4279 + ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
633.4280 + }
633.4281 + fragment.appendChild( ret[i] );
633.4282 + }
633.4283 + }
633.4284 + }
633.4285 +
633.4286 + return ret;
633.4287 + }
633.4288 +});
633.4289 +
633.4290 +function cleanData( elems ) {
633.4291 + for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
633.4292 + if ( !jQuery.noData[elem.nodeName.toLowerCase()] && (id = elem[expando]) ) {
633.4293 + delete jQuery.cache[ id ];
633.4294 + }
633.4295 + }
633.4296 +}
633.4297 +// exclude the following css properties to add px
633.4298 +var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
633.4299 + ralpha = /alpha\([^)]*\)/,
633.4300 + ropacity = /opacity=([^)]*)/,
633.4301 + rfloat = /float/i,
633.4302 + rdashAlpha = /-([a-z])/ig,
633.4303 + rupper = /([A-Z])/g,
633.4304 + rnumpx = /^-?\d+(?:px)?$/i,
633.4305 + rnum = /^-?\d/,
633.4306 +
633.4307 + cssShow = { position: "absolute", visibility: "hidden", display:"block" },
633.4308 + cssWidth = [ "Left", "Right" ],
633.4309 + cssHeight = [ "Top", "Bottom" ],
633.4310 +
633.4311 + // cache check for defaultView.getComputedStyle
633.4312 + getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
633.4313 + // normalize float css property
633.4314 + styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
633.4315 + fcamelCase = function( all, letter ) {
633.4316 + return letter.toUpperCase();
633.4317 + };
633.4318 +
633.4319 +jQuery.fn.css = function( name, value ) {
633.4320 + return access( this, name, value, true, function( elem, name, value ) {
633.4321 + if ( value === undefined ) {
633.4322 + return jQuery.curCSS( elem, name );
633.4323 + }
633.4324 +
633.4325 + if ( typeof value === "number" && !rexclude.test(name) ) {
633.4326 + value += "px";
633.4327 + }
633.4328 +
633.4329 + jQuery.style( elem, name, value );
633.4330 + });
633.4331 +};
633.4332 +
633.4333 +jQuery.extend({
633.4334 + style: function( elem, name, value ) {
633.4335 + // don't set styles on text and comment nodes
633.4336 + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
633.4337 + return undefined;
633.4338 + }
633.4339 +
633.4340 + // ignore negative width and height values #1599
633.4341 + if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
633.4342 + value = undefined;
633.4343 + }
633.4344 +
633.4345 + var style = elem.style || elem, set = value !== undefined;
633.4346 +
633.4347 + // IE uses filters for opacity
633.4348 + if ( !jQuery.support.opacity && name === "opacity" ) {
633.4349 + if ( set ) {
633.4350 + // IE has trouble with opacity if it does not have layout
633.4351 + // Force it by setting the zoom level
633.4352 + style.zoom = 1;
633.4353 +
633.4354 + // Set the alpha filter to set the opacity
633.4355 + var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
633.4356 + var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
633.4357 + style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
633.4358 + }
633.4359 +
633.4360 + return style.filter && style.filter.indexOf("opacity=") >= 0 ?
633.4361 + (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
633.4362 + "";
633.4363 + }
633.4364 +
633.4365 + // Make sure we're using the right name for getting the float value
633.4366 + if ( rfloat.test( name ) ) {
633.4367 + name = styleFloat;
633.4368 + }
633.4369 +
633.4370 + name = name.replace(rdashAlpha, fcamelCase);
633.4371 +
633.4372 + if ( set ) {
633.4373 + style[ name ] = value;
633.4374 + }
633.4375 +
633.4376 + return style[ name ];
633.4377 + },
633.4378 +
633.4379 + css: function( elem, name, force, extra ) {
633.4380 + if ( name === "width" || name === "height" ) {
633.4381 + var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
633.4382 +
633.4383 + function getWH() {
633.4384 + val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
633.4385 +
633.4386 + if ( extra === "border" ) {
633.4387 + return;
633.4388 + }
633.4389 +
633.4390 + jQuery.each( which, function() {
633.4391 + if ( !extra ) {
633.4392 + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
633.4393 + }
633.4394 +
633.4395 + if ( extra === "margin" ) {
633.4396 + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
633.4397 + } else {
633.4398 + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
633.4399 + }
633.4400 + });
633.4401 + }
633.4402 +
633.4403 + if ( elem.offsetWidth !== 0 ) {
633.4404 + getWH();
633.4405 + } else {
633.4406 + jQuery.swap( elem, props, getWH );
633.4407 + }
633.4408 +
633.4409 + return Math.max(0, Math.round(val));
633.4410 + }
633.4411 +
633.4412 + return jQuery.curCSS( elem, name, force );
633.4413 + },
633.4414 +
633.4415 + curCSS: function( elem, name, force ) {
633.4416 + var ret, style = elem.style, filter;
633.4417 +
633.4418 + // IE uses filters for opacity
633.4419 + if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
633.4420 + ret = ropacity.test(elem.currentStyle.filter || "") ?
633.4421 + (parseFloat(RegExp.$1) / 100) + "" :
633.4422 + "";
633.4423 +
633.4424 + return ret === "" ?
633.4425 + "1" :
633.4426 + ret;
633.4427 + }
633.4428 +
633.4429 + // Make sure we're using the right name for getting the float value
633.4430 + if ( rfloat.test( name ) ) {
633.4431 + name = styleFloat;
633.4432 + }
633.4433 +
633.4434 + if ( !force && style && style[ name ] ) {
633.4435 + ret = style[ name ];
633.4436 +
633.4437 + } else if ( getComputedStyle ) {
633.4438 +
633.4439 + // Only "float" is needed here
633.4440 + if ( rfloat.test( name ) ) {
633.4441 + name = "float";
633.4442 + }
633.4443 +
633.4444 + name = name.replace( rupper, "-$1" ).toLowerCase();
633.4445 +
633.4446 + var defaultView = elem.ownerDocument.defaultView;
633.4447 +
633.4448 + if ( !defaultView ) {
633.4449 + return null;
633.4450 + }
633.4451 +
633.4452 + var computedStyle = defaultView.getComputedStyle( elem, null );
633.4453 +
633.4454 + if ( computedStyle ) {
633.4455 + ret = computedStyle.getPropertyValue( name );
633.4456 + }
633.4457 +
633.4458 + // We should always get a number back from opacity
633.4459 + if ( name === "opacity" && ret === "" ) {
633.4460 + ret = "1";
633.4461 + }
633.4462 +
633.4463 + } else if ( elem.currentStyle ) {
633.4464 + var camelCase = name.replace(rdashAlpha, fcamelCase);
633.4465 +
633.4466 + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
633.4467 +
633.4468 + // From the awesome hack by Dean Edwards
633.4469 + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
633.4470 +
633.4471 + // If we're not dealing with a regular pixel number
633.4472 + // but a number that has a weird ending, we need to convert it to pixels
633.4473 + if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
633.4474 + // Remember the original values
633.4475 + var left = style.left, rsLeft = elem.runtimeStyle.left;
633.4476 +
633.4477 + // Put in the new values to get a computed value out
633.4478 + elem.runtimeStyle.left = elem.currentStyle.left;
633.4479 + style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
633.4480 + ret = style.pixelLeft + "px";
633.4481 +
633.4482 + // Revert the changed values
633.4483 + style.left = left;
633.4484 + elem.runtimeStyle.left = rsLeft;
633.4485 + }
633.4486 + }
633.4487 +
633.4488 + return ret;
633.4489 + },
633.4490 +
633.4491 + // A method for quickly swapping in/out CSS properties to get correct calculations
633.4492 + swap: function( elem, options, callback ) {
633.4493 + var old = {};
633.4494 +
633.4495 + // Remember the old values, and insert the new ones
633.4496 + for ( var name in options ) {
633.4497 + old[ name ] = elem.style[ name ];
633.4498 + elem.style[ name ] = options[ name ];
633.4499 + }
633.4500 +
633.4501 + callback.call( elem );
633.4502 +
633.4503 + // Revert the old values
633.4504 + for ( var name in options ) {
633.4505 + elem.style[ name ] = old[ name ];
633.4506 + }
633.4507 + }
633.4508 +});
633.4509 +
633.4510 +if ( jQuery.expr && jQuery.expr.filters ) {
633.4511 + jQuery.expr.filters.hidden = function( elem ) {
633.4512 + var width = elem.offsetWidth, height = elem.offsetHeight,
633.4513 + skip = elem.nodeName.toLowerCase() === "tr";
633.4514 +
633.4515 + return width === 0 && height === 0 && !skip ?
633.4516 + true :
633.4517 + width > 0 && height > 0 && !skip ?
633.4518 + false :
633.4519 + jQuery.curCSS(elem, "display") === "none";
633.4520 + };
633.4521 +
633.4522 + jQuery.expr.filters.visible = function( elem ) {
633.4523 + return !jQuery.expr.filters.hidden( elem );
633.4524 + };
633.4525 +}
633.4526 +var jsc = now(),
633.4527 + rscript = /<script(.|\s)*?\/script>/gi,
633.4528 + rselectTextarea = /select|textarea/i,
633.4529 + rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
633.4530 + jsre = /=\?(&|$)/,
633.4531 + rquery = /\?/,
633.4532 + rts = /(\?|&)_=.*?(&|$)/,
633.4533 + rurl = /^(\w+:)?\/\/([^\/?#]+)/,
633.4534 + r20 = /%20/g;
633.4535 +
633.4536 +jQuery.fn.extend({
633.4537 + // Keep a copy of the old load
633.4538 + _load: jQuery.fn.load,
633.4539 +
633.4540 + load: function( url, params, callback ) {
633.4541 + if ( typeof url !== "string" ) {
633.4542 + return this._load( url );
633.4543 +
633.4544 + // Don't do a request if no elements are being requested
633.4545 + } else if ( !this.length ) {
633.4546 + return this;
633.4547 + }
633.4548 +
633.4549 + var off = url.indexOf(" ");
633.4550 + if ( off >= 0 ) {
633.4551 + var selector = url.slice(off, url.length);
633.4552 + url = url.slice(0, off);
633.4553 + }
633.4554 +
633.4555 + // Default to a GET request
633.4556 + var type = "GET";
633.4557 +
633.4558 + // If the second parameter was provided
633.4559 + if ( params ) {
633.4560 + // If it's a function
633.4561 + if ( jQuery.isFunction( params ) ) {
633.4562 + // We assume that it's the callback
633.4563 + callback = params;
633.4564 + params = null;
633.4565 +
633.4566 + // Otherwise, build a param string
633.4567 + } else if ( typeof params === "object" ) {
633.4568 + params = jQuery.param( params, jQuery.ajaxSettings.traditional );
633.4569 + type = "POST";
633.4570 + }
633.4571 + }
633.4572 +
633.4573 + // Request the remote document
633.4574 + jQuery.ajax({
633.4575 + url: url,
633.4576 + type: type,
633.4577 + dataType: "html",
633.4578 + data: params,
633.4579 + context:this,
633.4580 + complete: function( res, status ) {
633.4581 + // If successful, inject the HTML into all the matched elements
633.4582 + if ( status === "success" || status === "notmodified" ) {
633.4583 + // See if a selector was specified
633.4584 + this.html( selector ?
633.4585 + // Create a dummy div to hold the results
633.4586 + jQuery("<div />")
633.4587 + // inject the contents of the document in, removing the scripts
633.4588 + // to avoid any 'Permission Denied' errors in IE
633.4589 + .append(res.responseText.replace(rscript, ""))
633.4590 +
633.4591 + // Locate the specified elements
633.4592 + .find(selector) :
633.4593 +
633.4594 + // If not, just inject the full result
633.4595 + res.responseText );
633.4596 + }
633.4597 +
633.4598 + if ( callback ) {
633.4599 + this.each( callback, [res.responseText, status, res] );
633.4600 + }
633.4601 + }
633.4602 + });
633.4603 +
633.4604 + return this;
633.4605 + },
633.4606 +
633.4607 + serialize: function() {
633.4608 + return jQuery.param(this.serializeArray());
633.4609 + },
633.4610 + serializeArray: function() {
633.4611 + return this.map(function() {
633.4612 + return this.elements ? jQuery.makeArray(this.elements) : this;
633.4613 + })
633.4614 + .filter(function() {
633.4615 + return this.name && !this.disabled &&
633.4616 + (this.checked || rselectTextarea.test(this.nodeName) ||
633.4617 + rinput.test(this.type));
633.4618 + })
633.4619 + .map(function( i, elem ) {
633.4620 + var val = jQuery(this).val();
633.4621 +
633.4622 + return val == null ?
633.4623 + null :
633.4624 + jQuery.isArray(val) ?
633.4625 + jQuery.map( val, function( val, i ) {
633.4626 + return { name: elem.name, value: val };
633.4627 + }) :
633.4628 + { name: elem.name, value: val };
633.4629 + }).get();
633.4630 + }
633.4631 +});
633.4632 +
633.4633 +// Attach a bunch of functions for handling common AJAX events
633.4634 +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
633.4635 + jQuery.fn[o] = function( f ) {
633.4636 + return this.bind(o, f);
633.4637 + };
633.4638 +});
633.4639 +
633.4640 +jQuery.extend({
633.4641 +
633.4642 + get: function( url, data, callback, type ) {
633.4643 + // shift arguments if data argument was omited
633.4644 + if ( jQuery.isFunction( data ) ) {
633.4645 + type = type || callback;
633.4646 + callback = data;
633.4647 + data = null;
633.4648 + }
633.4649 +
633.4650 + return jQuery.ajax({
633.4651 + type: "GET",
633.4652 + url: url,
633.4653 + data: data,
633.4654 + success: callback,
633.4655 + dataType: type
633.4656 + });
633.4657 + },
633.4658 +
633.4659 + getScript: function( url, callback ) {
633.4660 + return jQuery.get(url, null, callback, "script");
633.4661 + },
633.4662 +
633.4663 + getJSON: function( url, data, callback ) {
633.4664 + return jQuery.get(url, data, callback, "json");
633.4665 + },
633.4666 +
633.4667 + post: function( url, data, callback, type ) {
633.4668 + // shift arguments if data argument was omited
633.4669 + if ( jQuery.isFunction( data ) ) {
633.4670 + type = type || callback;
633.4671 + callback = data;
633.4672 + data = {};
633.4673 + }
633.4674 +
633.4675 + return jQuery.ajax({
633.4676 + type: "POST",
633.4677 + url: url,
633.4678 + data: data,
633.4679 + success: callback,
633.4680 + dataType: type
633.4681 + });
633.4682 + },
633.4683 +
633.4684 + ajaxSetup: function( settings ) {
633.4685 + jQuery.extend( jQuery.ajaxSettings, settings );
633.4686 + },
633.4687 +
633.4688 + ajaxSettings: {
633.4689 + url: location.href,
633.4690 + global: true,
633.4691 + type: "GET",
633.4692 + contentType: "application/x-www-form-urlencoded",
633.4693 + processData: true,
633.4694 + async: true,
633.4695 + /*
633.4696 + timeout: 0,
633.4697 + data: null,
633.4698 + username: null,
633.4699 + password: null,
633.4700 + traditional: false,
633.4701 + */
633.4702 + // Create the request object; Microsoft failed to properly
633.4703 + // implement the XMLHttpRequest in IE7 (can't request local files),
633.4704 + // so we use the ActiveXObject when it is available
633.4705 + // This function can be overriden by calling jQuery.ajaxSetup
633.4706 + xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
633.4707 + function() {
633.4708 + return new window.XMLHttpRequest();
633.4709 + } :
633.4710 + function() {
633.4711 + try {
633.4712 + return new window.ActiveXObject("Microsoft.XMLHTTP");
633.4713 + } catch(e) {}
633.4714 + },
633.4715 + accepts: {
633.4716 + xml: "application/xml, text/xml",
633.4717 + html: "text/html",
633.4718 + script: "text/javascript, application/javascript",
633.4719 + json: "application/json, text/javascript",
633.4720 + text: "text/plain",
633.4721 + _default: "*/*"
633.4722 + }
633.4723 + },
633.4724 +
633.4725 + // Last-Modified header cache for next request
633.4726 + lastModified: {},
633.4727 + etag: {},
633.4728 +
633.4729 + ajax: function( origSettings ) {
633.4730 + var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
633.4731 +
633.4732 + var jsonp, status, data,
633.4733 + callbackContext = s.context || s,
633.4734 + type = s.type.toUpperCase();
633.4735 +
633.4736 + // convert data if not already a string
633.4737 + if ( s.data && s.processData && typeof s.data !== "string" ) {
633.4738 + s.data = jQuery.param( s.data, s.traditional );
633.4739 + }
633.4740 +
633.4741 + // Handle JSONP Parameter Callbacks
633.4742 + if ( s.dataType === "jsonp" ) {
633.4743 + if ( type === "GET" ) {
633.4744 + if ( !jsre.test( s.url ) ) {
633.4745 + s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
633.4746 + }
633.4747 + } else if ( !s.data || !jsre.test(s.data) ) {
633.4748 + s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
633.4749 + }
633.4750 + s.dataType = "json";
633.4751 + }
633.4752 +
633.4753 + // Build temporary JSONP function
633.4754 + if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
633.4755 + jsonp = s.jsonpCallback || ("jsonp" + jsc++);
633.4756 +
633.4757 + // Replace the =? sequence both in the query string and the data
633.4758 + if ( s.data ) {
633.4759 + s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
633.4760 + }
633.4761 +
633.4762 + s.url = s.url.replace(jsre, "=" + jsonp + "$1");
633.4763 +
633.4764 + // We need to make sure
633.4765 + // that a JSONP style response is executed properly
633.4766 + s.dataType = "script";
633.4767 +
633.4768 + // Handle JSONP-style loading
633.4769 + window[ jsonp ] = window[ jsonp ] || function( tmp ) {
633.4770 + data = tmp;
633.4771 + success();
633.4772 + complete();
633.4773 + // Garbage collect
633.4774 + window[ jsonp ] = undefined;
633.4775 +
633.4776 + try {
633.4777 + delete window[ jsonp ];
633.4778 + } catch(e) {}
633.4779 +
633.4780 + if ( head ) {
633.4781 + head.removeChild( script );
633.4782 + }
633.4783 + };
633.4784 + }
633.4785 +
633.4786 + if ( s.dataType === "script" && s.cache === null ) {
633.4787 + s.cache = false;
633.4788 + }
633.4789 +
633.4790 + if ( s.cache === false && type === "GET" ) {
633.4791 + var ts = now();
633.4792 +
633.4793 + // try replacing _= if it is there
633.4794 + var ret = s.url.replace(rts, "$1_=" + ts + "$2");
633.4795 +
633.4796 + // if nothing was replaced, add timestamp to the end
633.4797 + s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
633.4798 + }
633.4799 +
633.4800 + // If data is available, append data to url for get requests
633.4801 + if ( s.data && type === "GET" ) {
633.4802 + s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
633.4803 + }
633.4804 +
633.4805 + // Watch for a new set of requests
633.4806 + if ( s.global && ! jQuery.active++ ) {
633.4807 + jQuery.event.trigger( "ajaxStart" );
633.4808 + }
633.4809 +
633.4810 + // Matches an absolute URL, and saves the domain
633.4811 + var parts = rurl.exec( s.url ),
633.4812 + remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
633.4813 +
633.4814 + // If we're requesting a remote document
633.4815 + // and trying to load JSON or Script with a GET
633.4816 + if ( s.dataType === "script" && type === "GET" && remote ) {
633.4817 + var head = document.getElementsByTagName("head")[0] || document.documentElement;
633.4818 + var script = document.createElement("script");
633.4819 + script.src = s.url;
633.4820 + if ( s.scriptCharset ) {
633.4821 + script.charset = s.scriptCharset;
633.4822 + }
633.4823 +
633.4824 + // Handle Script loading
633.4825 + if ( !jsonp ) {
633.4826 + var done = false;
633.4827 +
633.4828 + // Attach handlers for all browsers
633.4829 + script.onload = script.onreadystatechange = function() {
633.4830 + if ( !done && (!this.readyState ||
633.4831 + this.readyState === "loaded" || this.readyState === "complete") ) {
633.4832 + done = true;
633.4833 + success();
633.4834 + complete();
633.4835 +
633.4836 + // Handle memory leak in IE
633.4837 + script.onload = script.onreadystatechange = null;
633.4838 + if ( head && script.parentNode ) {
633.4839 + head.removeChild( script );
633.4840 + }
633.4841 + }
633.4842 + };
633.4843 + }
633.4844 +
633.4845 + // Use insertBefore instead of appendChild to circumvent an IE6 bug.
633.4846 + // This arises when a base node is used (#2709 and #4378).
633.4847 + head.insertBefore( script, head.firstChild );
633.4848 +
633.4849 + // We handle everything using the script element injection
633.4850 + return undefined;
633.4851 + }
633.4852 +
633.4853 + var requestDone = false;
633.4854 +
633.4855 + // Create the request object
633.4856 + var xhr = s.xhr();
633.4857 +
633.4858 + if ( !xhr ) {
633.4859 + return;
633.4860 + }
633.4861 +
633.4862 + // Open the socket
633.4863 + // Passing null username, generates a login popup on Opera (#2865)
633.4864 + if ( s.username ) {
633.4865 + xhr.open(type, s.url, s.async, s.username, s.password);
633.4866 + } else {
633.4867 + xhr.open(type, s.url, s.async);
633.4868 + }
633.4869 +
633.4870 + // Need an extra try/catch for cross domain requests in Firefox 3
633.4871 + try {
633.4872 + // Set the correct header, if data is being sent
633.4873 + if ( s.data || origSettings && origSettings.contentType ) {
633.4874 + xhr.setRequestHeader("Content-Type", s.contentType);
633.4875 + }
633.4876 +
633.4877 + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
633.4878 + if ( s.ifModified ) {
633.4879 + if ( jQuery.lastModified[s.url] ) {
633.4880 + xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
633.4881 + }
633.4882 +
633.4883 + if ( jQuery.etag[s.url] ) {
633.4884 + xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
633.4885 + }
633.4886 + }
633.4887 +
633.4888 + // Set header so the called script knows that it's an XMLHttpRequest
633.4889 + // Only send the header if it's not a remote XHR
633.4890 + if ( !remote ) {
633.4891 + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
633.4892 + }
633.4893 +
633.4894 + // Set the Accepts header for the server, depending on the dataType
633.4895 + xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
633.4896 + s.accepts[ s.dataType ] + ", */*" :
633.4897 + s.accepts._default );
633.4898 + } catch(e) {}
633.4899 +
633.4900 + // Allow custom headers/mimetypes and early abort
633.4901 + if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
633.4902 + // Handle the global AJAX counter
633.4903 + if ( s.global && ! --jQuery.active ) {
633.4904 + jQuery.event.trigger( "ajaxStop" );
633.4905 + }
633.4906 +
633.4907 + // close opended socket
633.4908 + xhr.abort();
633.4909 + return false;
633.4910 + }
633.4911 +
633.4912 + if ( s.global ) {
633.4913 + trigger("ajaxSend", [xhr, s]);
633.4914 + }
633.4915 +
633.4916 + // Wait for a response to come back
633.4917 + var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
633.4918 + // The request was aborted
633.4919 + if ( !xhr || xhr.readyState === 0 ) {
633.4920 + // Opera doesn't call onreadystatechange before this point
633.4921 + // so we simulate the call
633.4922 + if ( !requestDone ) {
633.4923 + complete();
633.4924 + }
633.4925 +
633.4926 + requestDone = true;
633.4927 + if ( xhr ) {
633.4928 + xhr.onreadystatechange = jQuery.noop;
633.4929 + }
633.4930 +
633.4931 + // The transfer is complete and the data is available, or the request timed out
633.4932 + } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
633.4933 + requestDone = true;
633.4934 + xhr.onreadystatechange = jQuery.noop;
633.4935 +
633.4936 + status = isTimeout === "timeout" ?
633.4937 + "timeout" :
633.4938 + !jQuery.httpSuccess( xhr ) ?
633.4939 + "error" :
633.4940 + s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
633.4941 + "notmodified" :
633.4942 + "success";
633.4943 +
633.4944 + if ( status === "success" ) {
633.4945 + // Watch for, and catch, XML document parse errors
633.4946 + try {
633.4947 + // process the data (runs the xml through httpData regardless of callback)
633.4948 + data = jQuery.httpData( xhr, s.dataType, s );
633.4949 + } catch(e) {
633.4950 + status = "parsererror";
633.4951 + }
633.4952 + }
633.4953 +
633.4954 + // Make sure that the request was successful or notmodified
633.4955 + if ( status === "success" || status === "notmodified" ) {
633.4956 + // JSONP handles its own success callback
633.4957 + if ( !jsonp ) {
633.4958 + success();
633.4959 + }
633.4960 + } else {
633.4961 + jQuery.handleError(s, xhr, status);
633.4962 + }
633.4963 +
633.4964 + // Fire the complete handlers
633.4965 + complete();
633.4966 +
633.4967 + if ( isTimeout === "timeout" ) {
633.4968 + xhr.abort();
633.4969 + }
633.4970 +
633.4971 + // Stop memory leaks
633.4972 + if ( s.async ) {
633.4973 + xhr = null;
633.4974 + }
633.4975 + }
633.4976 + };
633.4977 +
633.4978 + // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
633.4979 + // Opera doesn't fire onreadystatechange at all on abort
633.4980 + try {
633.4981 + var oldAbort = xhr.abort;
633.4982 + xhr.abort = function() {
633.4983 + if ( xhr ) {
633.4984 + oldAbort.call( xhr );
633.4985 + if ( xhr ) {
633.4986 + xhr.readyState = 0;
633.4987 + }
633.4988 + }
633.4989 +
633.4990 + onreadystatechange();
633.4991 + };
633.4992 + } catch(e) { }
633.4993 +
633.4994 + // Timeout checker
633.4995 + if ( s.async && s.timeout > 0 ) {
633.4996 + setTimeout(function() {
633.4997 + // Check to see if the request is still happening
633.4998 + if ( xhr && !requestDone ) {
633.4999 + onreadystatechange( "timeout" );
633.5000 + }
633.5001 + }, s.timeout);
633.5002 + }
633.5003 +
633.5004 + // Send the data
633.5005 + try {
633.5006 + xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
633.5007 + } catch(e) {
633.5008 + jQuery.handleError(s, xhr, null, e);
633.5009 + // Fire the complete handlers
633.5010 + complete();
633.5011 + }
633.5012 +
633.5013 + // firefox 1.5 doesn't fire statechange for sync requests
633.5014 + if ( !s.async ) {
633.5015 + onreadystatechange();
633.5016 + }
633.5017 +
633.5018 + function success() {
633.5019 + // If a local callback was specified, fire it and pass it the data
633.5020 + if ( s.success ) {
633.5021 + s.success.call( callbackContext, data, status, xhr );
633.5022 + }
633.5023 +
633.5024 + // Fire the global callback
633.5025 + if ( s.global ) {
633.5026 + trigger( "ajaxSuccess", [xhr, s] );
633.5027 + }
633.5028 + }
633.5029 +
633.5030 + function complete() {
633.5031 + // Process result
633.5032 + if ( s.complete ) {
633.5033 + s.complete.call( callbackContext, xhr, status);
633.5034 + }
633.5035 +
633.5036 + // The request was completed
633.5037 + if ( s.global ) {
633.5038 + trigger( "ajaxComplete", [xhr, s] );
633.5039 + }
633.5040 +
633.5041 + // Handle the global AJAX counter
633.5042 + if ( s.global && ! --jQuery.active ) {
633.5043 + jQuery.event.trigger( "ajaxStop" );
633.5044 + }
633.5045 + }
633.5046 +
633.5047 + function trigger(type, args) {
633.5048 + (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
633.5049 + }
633.5050 +
633.5051 + // return XMLHttpRequest to allow aborting the request etc.
633.5052 + return xhr;
633.5053 + },
633.5054 +
633.5055 + handleError: function( s, xhr, status, e ) {
633.5056 + // If a local callback was specified, fire it
633.5057 + if ( s.error ) {
633.5058 + s.error.call( s.context || window, xhr, status, e );
633.5059 + }
633.5060 +
633.5061 + // Fire the global callback
633.5062 + if ( s.global ) {
633.5063 + (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
633.5064 + }
633.5065 + },
633.5066 +
633.5067 + // Counter for holding the number of active queries
633.5068 + active: 0,
633.5069 +
633.5070 + // Determines if an XMLHttpRequest was successful or not
633.5071 + httpSuccess: function( xhr ) {
633.5072 + try {
633.5073 + // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
633.5074 + return !xhr.status && location.protocol === "file:" ||
633.5075 + // Opera returns 0 when status is 304
633.5076 + ( xhr.status >= 200 && xhr.status < 300 ) ||
633.5077 + xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
633.5078 + } catch(e) {}
633.5079 +
633.5080 + return false;
633.5081 + },
633.5082 +
633.5083 + // Determines if an XMLHttpRequest returns NotModified
633.5084 + httpNotModified: function( xhr, url ) {
633.5085 + var lastModified = xhr.getResponseHeader("Last-Modified"),
633.5086 + etag = xhr.getResponseHeader("Etag");
633.5087 +
633.5088 + if ( lastModified ) {
633.5089 + jQuery.lastModified[url] = lastModified;
633.5090 + }
633.5091 +
633.5092 + if ( etag ) {
633.5093 + jQuery.etag[url] = etag;
633.5094 + }
633.5095 +
633.5096 + // Opera returns 0 when status is 304
633.5097 + return xhr.status === 304 || xhr.status === 0;
633.5098 + },
633.5099 +
633.5100 + httpData: function( xhr, type, s ) {
633.5101 + var ct = xhr.getResponseHeader("content-type") || "",
633.5102 + xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
633.5103 + data = xml ? xhr.responseXML : xhr.responseText;
633.5104 +
633.5105 + if ( xml && data.documentElement.nodeName === "parsererror" ) {
633.5106 + throw "parsererror";
633.5107 + }
633.5108 +
633.5109 + // Allow a pre-filtering function to sanitize the response
633.5110 + // s is checked to keep backwards compatibility
633.5111 + if ( s && s.dataFilter ) {
633.5112 + data = s.dataFilter( data, type );
633.5113 + }
633.5114 +
633.5115 + // The filter can actually parse the response
633.5116 + if ( typeof data === "string" ) {
633.5117 + // Get the JavaScript object, if JSON is used.
633.5118 + if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
633.5119 + // Make sure the incoming data is actual JSON
633.5120 + // Logic borrowed from http://json.org/json2.js
633.5121 + if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
633.5122 + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
633.5123 + .replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
633.5124 +
633.5125 + // Try to use the native JSON parser first
633.5126 + if ( window.JSON && window.JSON.parse ) {
633.5127 + data = window.JSON.parse( data );
633.5128 +
633.5129 + } else {
633.5130 + data = (new Function("return " + data))();
633.5131 + }
633.5132 +
633.5133 + } else {
633.5134 + throw "Invalid JSON: " + data;
633.5135 + }
633.5136 +
633.5137 + // If the type is "script", eval it in global context
633.5138 + } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
633.5139 + jQuery.globalEval( data );
633.5140 + }
633.5141 + }
633.5142 +
633.5143 + return data;
633.5144 + },
633.5145 +
633.5146 + // Serialize an array of form elements or a set of
633.5147 + // key/values into a query string
633.5148 + param: function( a, traditional ) {
633.5149 +
633.5150 + var s = [];
633.5151 +
633.5152 + // Set traditional to true for jQuery <= 1.3.2 behavior.
633.5153 + if ( traditional === undefined ) {
633.5154 + traditional = jQuery.ajaxSettings.traditional;
633.5155 + }
633.5156 +
633.5157 + function add( key, value ) {
633.5158 + // If value is a function, invoke it and return its value
633.5159 + value = jQuery.isFunction(value) ? value() : value;
633.5160 + s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
633.5161 + }
633.5162 +
633.5163 + // If an array was passed in, assume that it is an array of form elements.
633.5164 + if ( jQuery.isArray(a) || a.jquery ) {
633.5165 + // Serialize the form elements
633.5166 + jQuery.each( a, function() {
633.5167 + add( this.name, this.value );
633.5168 + });
633.5169 +
633.5170 + } else {
633.5171 + // If traditional, encode the "old" way (the way 1.3.2 or older
633.5172 + // did it), otherwise encode params recursively.
633.5173 + jQuery.each( a, function buildParams( prefix, obj ) {
633.5174 +
633.5175 + if ( jQuery.isArray(obj) ) {
633.5176 + // Serialize array item.
633.5177 + jQuery.each( obj, function( i, v ) {
633.5178 + if ( traditional ) {
633.5179 + // Treat each array item as a scalar.
633.5180 + add( prefix, v );
633.5181 + } else {
633.5182 + // If array item is non-scalar (array or object), encode its
633.5183 + // numeric index to resolve deserialization ambiguity issues.
633.5184 + // Note that rack (as of 1.0.0) can't currently deserialize
633.5185 + // nested arrays properly, and attempting to do so may cause
633.5186 + // a server error. Possible fixes are to modify rack's
633.5187 + // deserialization algorithm or to provide an option or flag
633.5188 + // to force array serialization to be shallow.
633.5189 + buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
633.5190 + }
633.5191 + });
633.5192 +
633.5193 + } else if ( !traditional && obj != null && typeof obj === "object" ) {
633.5194 + // Serialize object item.
633.5195 + jQuery.each( obj, function( k, v ) {
633.5196 + buildParams( prefix + "[" + k + "]", v );
633.5197 + });
633.5198 +
633.5199 + } else {
633.5200 + // Serialize scalar item.
633.5201 + add( prefix, obj );
633.5202 + }
633.5203 + });
633.5204 + }
633.5205 +
633.5206 + // Return the resulting serialization
633.5207 + return s.join("&").replace(r20, "+");
633.5208 + }
633.5209 +
633.5210 +});
633.5211 +var elemdisplay = {},
633.5212 + rfxtypes = /toggle|show|hide/,
633.5213 + rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
633.5214 + timerId,
633.5215 + fxAttrs = [
633.5216 + // height animations
633.5217 + [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
633.5218 + // width animations
633.5219 + [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
633.5220 + // opacity animations
633.5221 + [ "opacity" ]
633.5222 + ];
633.5223 +
633.5224 +jQuery.fn.extend({
633.5225 + show: function( speed, callback ) {
633.5226 + if ( speed != null ) {
633.5227 + return this.animate( genFx("show", 3), speed, callback);
633.5228 +
633.5229 + } else {
633.5230 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.5231 + var old = jQuery.data(this[i], "olddisplay");
633.5232 +
633.5233 + this[i].style.display = old || "";
633.5234 +
633.5235 + if ( jQuery.css(this[i], "display") === "none" ) {
633.5236 + var nodeName = this[i].nodeName, display;
633.5237 +
633.5238 + if ( elemdisplay[ nodeName ] ) {
633.5239 + display = elemdisplay[ nodeName ];
633.5240 +
633.5241 + } else {
633.5242 + var elem = jQuery("<" + nodeName + " />").appendTo("body");
633.5243 +
633.5244 + display = elem.css("display");
633.5245 +
633.5246 + if ( display === "none" ) {
633.5247 + display = "block";
633.5248 + }
633.5249 +
633.5250 + elem.remove();
633.5251 +
633.5252 + elemdisplay[ nodeName ] = display;
633.5253 + }
633.5254 +
633.5255 + jQuery.data(this[i], "olddisplay", display);
633.5256 + }
633.5257 + }
633.5258 +
633.5259 + // Set the display of the elements in a second loop
633.5260 + // to avoid the constant reflow
633.5261 + for ( var j = 0, k = this.length; j < k; j++ ) {
633.5262 + this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
633.5263 + }
633.5264 +
633.5265 + return this;
633.5266 + }
633.5267 + },
633.5268 +
633.5269 + hide: function( speed, callback ) {
633.5270 + if ( speed != null ) {
633.5271 + return this.animate( genFx("hide", 3), speed, callback);
633.5272 +
633.5273 + } else {
633.5274 + for ( var i = 0, l = this.length; i < l; i++ ) {
633.5275 + var old = jQuery.data(this[i], "olddisplay");
633.5276 + if ( !old && old !== "none" ) {
633.5277 + jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
633.5278 + }
633.5279 + }
633.5280 +
633.5281 + // Set the display of the elements in a second loop
633.5282 + // to avoid the constant reflow
633.5283 + for ( var j = 0, k = this.length; j < k; j++ ) {
633.5284 + this[j].style.display = "none";
633.5285 + }
633.5286 +
633.5287 + return this;
633.5288 + }
633.5289 + },
633.5290 +
633.5291 + // Save the old toggle function
633.5292 + _toggle: jQuery.fn.toggle,
633.5293 +
633.5294 + toggle: function( fn, fn2 ) {
633.5295 + var bool = typeof fn === "boolean";
633.5296 +
633.5297 + if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
633.5298 + this._toggle.apply( this, arguments );
633.5299 +
633.5300 + } else if ( fn == null || bool ) {
633.5301 + this.each(function() {
633.5302 + var state = bool ? fn : jQuery(this).is(":hidden");
633.5303 + jQuery(this)[ state ? "show" : "hide" ]();
633.5304 + });
633.5305 +
633.5306 + } else {
633.5307 + this.animate(genFx("toggle", 3), fn, fn2);
633.5308 + }
633.5309 +
633.5310 + return this;
633.5311 + },
633.5312 +
633.5313 + fadeTo: function( speed, to, callback ) {
633.5314 + return this.filter(":hidden").css("opacity", 0).show().end()
633.5315 + .animate({opacity: to}, speed, callback);
633.5316 + },
633.5317 +
633.5318 + animate: function( prop, speed, easing, callback ) {
633.5319 + var optall = jQuery.speed(speed, easing, callback);
633.5320 +
633.5321 + if ( jQuery.isEmptyObject( prop ) ) {
633.5322 + return this.each( optall.complete );
633.5323 + }
633.5324 +
633.5325 + return this[ optall.queue === false ? "each" : "queue" ](function() {
633.5326 + var opt = jQuery.extend({}, optall), p,
633.5327 + hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
633.5328 + self = this;
633.5329 +
633.5330 + for ( p in prop ) {
633.5331 + var name = p.replace(rdashAlpha, fcamelCase);
633.5332 +
633.5333 + if ( p !== name ) {
633.5334 + prop[ name ] = prop[ p ];
633.5335 + delete prop[ p ];
633.5336 + p = name;
633.5337 + }
633.5338 +
633.5339 + if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
633.5340 + return opt.complete.call(this);
633.5341 + }
633.5342 +
633.5343 + if ( ( p === "height" || p === "width" ) && this.style ) {
633.5344 + // Store display property
633.5345 + opt.display = jQuery.css(this, "display");
633.5346 +
633.5347 + // Make sure that nothing sneaks out
633.5348 + opt.overflow = this.style.overflow;
633.5349 + }
633.5350 +
633.5351 + if ( jQuery.isArray( prop[p] ) ) {
633.5352 + // Create (if needed) and add to specialEasing
633.5353 + (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
633.5354 + prop[p] = prop[p][0];
633.5355 + }
633.5356 + }
633.5357 +
633.5358 + if ( opt.overflow != null ) {
633.5359 + this.style.overflow = "hidden";
633.5360 + }
633.5361 +
633.5362 + opt.curAnim = jQuery.extend({}, prop);
633.5363 +
633.5364 + jQuery.each( prop, function( name, val ) {
633.5365 + var e = new jQuery.fx( self, opt, name );
633.5366 +
633.5367 + if ( rfxtypes.test(val) ) {
633.5368 + e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
633.5369 +
633.5370 + } else {
633.5371 + var parts = rfxnum.exec(val),
633.5372 + start = e.cur(true) || 0;
633.5373 +
633.5374 + if ( parts ) {
633.5375 + var end = parseFloat( parts[2] ),
633.5376 + unit = parts[3] || "px";
633.5377 +
633.5378 + // We need to compute starting value
633.5379 + if ( unit !== "px" ) {
633.5380 + self.style[ name ] = (end || 1) + unit;
633.5381 + start = ((end || 1) / e.cur(true)) * start;
633.5382 + self.style[ name ] = start + unit;
633.5383 + }
633.5384 +
633.5385 + // If a +=/-= token was provided, we're doing a relative animation
633.5386 + if ( parts[1] ) {
633.5387 + end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
633.5388 + }
633.5389 +
633.5390 + e.custom( start, end, unit );
633.5391 +
633.5392 + } else {
633.5393 + e.custom( start, val, "" );
633.5394 + }
633.5395 + }
633.5396 + });
633.5397 +
633.5398 + // For JS strict compliance
633.5399 + return true;
633.5400 + });
633.5401 + },
633.5402 +
633.5403 + stop: function( clearQueue, gotoEnd ) {
633.5404 + var timers = jQuery.timers;
633.5405 +
633.5406 + if ( clearQueue ) {
633.5407 + this.queue([]);
633.5408 + }
633.5409 +
633.5410 + this.each(function() {
633.5411 + // go in reverse order so anything added to the queue during the loop is ignored
633.5412 + for ( var i = timers.length - 1; i >= 0; i-- ) {
633.5413 + if ( timers[i].elem === this ) {
633.5414 + if (gotoEnd) {
633.5415 + // force the next step to be the last
633.5416 + timers[i](true);
633.5417 + }
633.5418 +
633.5419 + timers.splice(i, 1);
633.5420 + }
633.5421 + }
633.5422 + });
633.5423 +
633.5424 + // start the next in the queue if the last step wasn't forced
633.5425 + if ( !gotoEnd ) {
633.5426 + this.dequeue();
633.5427 + }
633.5428 +
633.5429 + return this;
633.5430 + }
633.5431 +
633.5432 +});
633.5433 +
633.5434 +// Generate shortcuts for custom animations
633.5435 +jQuery.each({
633.5436 + slideDown: genFx("show", 1),
633.5437 + slideUp: genFx("hide", 1),
633.5438 + slideToggle: genFx("toggle", 1),
633.5439 + fadeIn: { opacity: "show" },
633.5440 + fadeOut: { opacity: "hide" }
633.5441 +}, function( name, props ) {
633.5442 + jQuery.fn[ name ] = function( speed, callback ) {
633.5443 + return this.animate( props, speed, callback );
633.5444 + };
633.5445 +});
633.5446 +
633.5447 +jQuery.extend({
633.5448 + speed: function( speed, easing, fn ) {
633.5449 + var opt = speed && typeof speed === "object" ? speed : {
633.5450 + complete: fn || !fn && easing ||
633.5451 + jQuery.isFunction( speed ) && speed,
633.5452 + duration: speed,
633.5453 + easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
633.5454 + };
633.5455 +
633.5456 + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
633.5457 + jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
633.5458 +
633.5459 + // Queueing
633.5460 + opt.old = opt.complete;
633.5461 + opt.complete = function() {
633.5462 + if ( opt.queue !== false ) {
633.5463 + jQuery(this).dequeue();
633.5464 + }
633.5465 + if ( jQuery.isFunction( opt.old ) ) {
633.5466 + opt.old.call( this );
633.5467 + }
633.5468 + };
633.5469 +
633.5470 + return opt;
633.5471 + },
633.5472 +
633.5473 + easing: {
633.5474 + linear: function( p, n, firstNum, diff ) {
633.5475 + return firstNum + diff * p;
633.5476 + },
633.5477 + swing: function( p, n, firstNum, diff ) {
633.5478 + return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
633.5479 + }
633.5480 + },
633.5481 +
633.5482 + timers: [],
633.5483 +
633.5484 + fx: function( elem, options, prop ) {
633.5485 + this.options = options;
633.5486 + this.elem = elem;
633.5487 + this.prop = prop;
633.5488 +
633.5489 + if ( !options.orig ) {
633.5490 + options.orig = {};
633.5491 + }
633.5492 + }
633.5493 +
633.5494 +});
633.5495 +
633.5496 +jQuery.fx.prototype = {
633.5497 + // Simple function for setting a style value
633.5498 + update: function() {
633.5499 + if ( this.options.step ) {
633.5500 + this.options.step.call( this.elem, this.now, this );
633.5501 + }
633.5502 +
633.5503 + (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
633.5504 +
633.5505 + // Set display property to block for height/width animations
633.5506 + if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
633.5507 + this.elem.style.display = "block";
633.5508 + }
633.5509 + },
633.5510 +
633.5511 + // Get the current size
633.5512 + cur: function( force ) {
633.5513 + if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
633.5514 + return this.elem[ this.prop ];
633.5515 + }
633.5516 +
633.5517 + var r = parseFloat(jQuery.css(this.elem, this.prop, force));
633.5518 + return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
633.5519 + },
633.5520 +
633.5521 + // Start an animation from one number to another
633.5522 + custom: function( from, to, unit ) {
633.5523 + this.startTime = now();
633.5524 + this.start = from;
633.5525 + this.end = to;
633.5526 + this.unit = unit || this.unit || "px";
633.5527 + this.now = this.start;
633.5528 + this.pos = this.state = 0;
633.5529 +
633.5530 + var self = this;
633.5531 + function t( gotoEnd ) {
633.5532 + return self.step(gotoEnd);
633.5533 + }
633.5534 +
633.5535 + t.elem = this.elem;
633.5536 +
633.5537 + if ( t() && jQuery.timers.push(t) && !timerId ) {
633.5538 + timerId = setInterval(jQuery.fx.tick, 13);
633.5539 + }
633.5540 + },
633.5541 +
633.5542 + // Simple 'show' function
633.5543 + show: function() {
633.5544 + // Remember where we started, so that we can go back to it later
633.5545 + this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
633.5546 + this.options.show = true;
633.5547 +
633.5548 + // Begin the animation
633.5549 + // Make sure that we start at a small width/height to avoid any
633.5550 + // flash of content
633.5551 + this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
633.5552 +
633.5553 + // Start by showing the element
633.5554 + jQuery( this.elem ).show();
633.5555 + },
633.5556 +
633.5557 + // Simple 'hide' function
633.5558 + hide: function() {
633.5559 + // Remember where we started, so that we can go back to it later
633.5560 + this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
633.5561 + this.options.hide = true;
633.5562 +
633.5563 + // Begin the animation
633.5564 + this.custom(this.cur(), 0);
633.5565 + },
633.5566 +
633.5567 + // Each step of an animation
633.5568 + step: function( gotoEnd ) {
633.5569 + var t = now(), done = true;
633.5570 +
633.5571 + if ( gotoEnd || t >= this.options.duration + this.startTime ) {
633.5572 + this.now = this.end;
633.5573 + this.pos = this.state = 1;
633.5574 + this.update();
633.5575 +
633.5576 + this.options.curAnim[ this.prop ] = true;
633.5577 +
633.5578 + for ( var i in this.options.curAnim ) {
633.5579 + if ( this.options.curAnim[i] !== true ) {
633.5580 + done = false;
633.5581 + }
633.5582 + }
633.5583 +
633.5584 + if ( done ) {
633.5585 + if ( this.options.display != null ) {
633.5586 + // Reset the overflow
633.5587 + this.elem.style.overflow = this.options.overflow;
633.5588 +
633.5589 + // Reset the display
633.5590 + var old = jQuery.data(this.elem, "olddisplay");
633.5591 + this.elem.style.display = old ? old : this.options.display;
633.5592 +
633.5593 + if ( jQuery.css(this.elem, "display") === "none" ) {
633.5594 + this.elem.style.display = "block";
633.5595 + }
633.5596 + }
633.5597 +
633.5598 + // Hide the element if the "hide" operation was done
633.5599 + if ( this.options.hide ) {
633.5600 + jQuery(this.elem).hide();
633.5601 + }
633.5602 +
633.5603 + // Reset the properties, if the item has been hidden or shown
633.5604 + if ( this.options.hide || this.options.show ) {
633.5605 + for ( var p in this.options.curAnim ) {
633.5606 + jQuery.style(this.elem, p, this.options.orig[p]);
633.5607 + }
633.5608 + }
633.5609 +
633.5610 + // Execute the complete function
633.5611 + this.options.complete.call( this.elem );
633.5612 + }
633.5613 +
633.5614 + return false;
633.5615 +
633.5616 + } else {
633.5617 + var n = t - this.startTime;
633.5618 + this.state = n / this.options.duration;
633.5619 +
633.5620 + // Perform the easing function, defaults to swing
633.5621 + var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
633.5622 + var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
633.5623 + this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
633.5624 + this.now = this.start + ((this.end - this.start) * this.pos);
633.5625 +
633.5626 + // Perform the next step of the animation
633.5627 + this.update();
633.5628 + }
633.5629 +
633.5630 + return true;
633.5631 + }
633.5632 +};
633.5633 +
633.5634 +jQuery.extend( jQuery.fx, {
633.5635 + tick: function() {
633.5636 + var timers = jQuery.timers;
633.5637 +
633.5638 + for ( var i = 0; i < timers.length; i++ ) {
633.5639 + if ( !timers[i]() ) {
633.5640 + timers.splice(i--, 1);
633.5641 + }
633.5642 + }
633.5643 +
633.5644 + if ( !timers.length ) {
633.5645 + jQuery.fx.stop();
633.5646 + }
633.5647 + },
633.5648 +
633.5649 + stop: function() {
633.5650 + clearInterval( timerId );
633.5651 + timerId = null;
633.5652 + },
633.5653 +
633.5654 + speeds: {
633.5655 + slow: 600,
633.5656 + fast: 200,
633.5657 + // Default speed
633.5658 + _default: 400
633.5659 + },
633.5660 +
633.5661 + step: {
633.5662 + opacity: function( fx ) {
633.5663 + jQuery.style(fx.elem, "opacity", fx.now);
633.5664 + },
633.5665 +
633.5666 + _default: function( fx ) {
633.5667 + if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
633.5668 + fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
633.5669 + } else {
633.5670 + fx.elem[ fx.prop ] = fx.now;
633.5671 + }
633.5672 + }
633.5673 + }
633.5674 +});
633.5675 +
633.5676 +if ( jQuery.expr && jQuery.expr.filters ) {
633.5677 + jQuery.expr.filters.animated = function( elem ) {
633.5678 + return jQuery.grep(jQuery.timers, function( fn ) {
633.5679 + return elem === fn.elem;
633.5680 + }).length;
633.5681 + };
633.5682 +}
633.5683 +
633.5684 +function genFx( type, num ) {
633.5685 + var obj = {};
633.5686 +
633.5687 + jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
633.5688 + obj[ this ] = type;
633.5689 + });
633.5690 +
633.5691 + return obj;
633.5692 +}
633.5693 +if ( "getBoundingClientRect" in document.documentElement ) {
633.5694 + jQuery.fn.offset = function( options ) {
633.5695 + var elem = this[0];
633.5696 +
633.5697 + if ( !elem || !elem.ownerDocument ) {
633.5698 + return null;
633.5699 + }
633.5700 +
633.5701 + if ( options ) {
633.5702 + return this.each(function( i ) {
633.5703 + jQuery.offset.setOffset( this, options, i );
633.5704 + });
633.5705 + }
633.5706 +
633.5707 + if ( elem === elem.ownerDocument.body ) {
633.5708 + return jQuery.offset.bodyOffset( elem );
633.5709 + }
633.5710 +
633.5711 + var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
633.5712 + clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
633.5713 + top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
633.5714 + left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
633.5715 +
633.5716 + return { top: top, left: left };
633.5717 + };
633.5718 +
633.5719 +} else {
633.5720 + jQuery.fn.offset = function( options ) {
633.5721 + var elem = this[0];
633.5722 +
633.5723 + if ( !elem || !elem.ownerDocument ) {
633.5724 + return null;
633.5725 + }
633.5726 +
633.5727 + if ( options ) {
633.5728 + return this.each(function( i ) {
633.5729 + jQuery.offset.setOffset( this, options, i );
633.5730 + });
633.5731 + }
633.5732 +
633.5733 + if ( elem === elem.ownerDocument.body ) {
633.5734 + return jQuery.offset.bodyOffset( elem );
633.5735 + }
633.5736 +
633.5737 + jQuery.offset.initialize();
633.5738 +
633.5739 + var offsetParent = elem.offsetParent, prevOffsetParent = elem,
633.5740 + doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
633.5741 + body = doc.body, defaultView = doc.defaultView,
633.5742 + prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
633.5743 + top = elem.offsetTop, left = elem.offsetLeft;
633.5744 +
633.5745 + while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
633.5746 + if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
633.5747 + break;
633.5748 + }
633.5749 +
633.5750 + computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
633.5751 + top -= elem.scrollTop;
633.5752 + left -= elem.scrollLeft;
633.5753 +
633.5754 + if ( elem === offsetParent ) {
633.5755 + top += elem.offsetTop;
633.5756 + left += elem.offsetLeft;
633.5757 +
633.5758 + if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
633.5759 + top += parseFloat( computedStyle.borderTopWidth ) || 0;
633.5760 + left += parseFloat( computedStyle.borderLeftWidth ) || 0;
633.5761 + }
633.5762 +
633.5763 + prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
633.5764 + }
633.5765 +
633.5766 + if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
633.5767 + top += parseFloat( computedStyle.borderTopWidth ) || 0;
633.5768 + left += parseFloat( computedStyle.borderLeftWidth ) || 0;
633.5769 + }
633.5770 +
633.5771 + prevComputedStyle = computedStyle;
633.5772 + }
633.5773 +
633.5774 + if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
633.5775 + top += body.offsetTop;
633.5776 + left += body.offsetLeft;
633.5777 + }
633.5778 +
633.5779 + if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
633.5780 + top += Math.max( docElem.scrollTop, body.scrollTop );
633.5781 + left += Math.max( docElem.scrollLeft, body.scrollLeft );
633.5782 + }
633.5783 +
633.5784 + return { top: top, left: left };
633.5785 + };
633.5786 +}
633.5787 +
633.5788 +jQuery.offset = {
633.5789 + initialize: function() {
633.5790 + var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
633.5791 + html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
633.5792 +
633.5793 + jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
633.5794 +
633.5795 + container.innerHTML = html;
633.5796 + body.insertBefore( container, body.firstChild );
633.5797 + innerDiv = container.firstChild;
633.5798 + checkDiv = innerDiv.firstChild;
633.5799 + td = innerDiv.nextSibling.firstChild.firstChild;
633.5800 +
633.5801 + this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
633.5802 + this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
633.5803 +
633.5804 + checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
633.5805 + // safari subtracts parent border width here which is 5px
633.5806 + this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
633.5807 + checkDiv.style.position = checkDiv.style.top = "";
633.5808 +
633.5809 + innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
633.5810 + this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
633.5811 +
633.5812 + this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
633.5813 +
633.5814 + body.removeChild( container );
633.5815 + body = container = innerDiv = checkDiv = table = td = null;
633.5816 + jQuery.offset.initialize = jQuery.noop;
633.5817 + },
633.5818 +
633.5819 + bodyOffset: function( body ) {
633.5820 + var top = body.offsetTop, left = body.offsetLeft;
633.5821 +
633.5822 + jQuery.offset.initialize();
633.5823 +
633.5824 + if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
633.5825 + top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
633.5826 + left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
633.5827 + }
633.5828 +
633.5829 + return { top: top, left: left };
633.5830 + },
633.5831 +
633.5832 + setOffset: function( elem, options, i ) {
633.5833 + // set position first, in-case top/left are set even on static elem
633.5834 + if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
633.5835 + elem.style.position = "relative";
633.5836 + }
633.5837 + var curElem = jQuery( elem ),
633.5838 + curOffset = curElem.offset(),
633.5839 + curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
633.5840 + curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
633.5841 +
633.5842 + if ( jQuery.isFunction( options ) ) {
633.5843 + options = options.call( elem, i, curOffset );
633.5844 + }
633.5845 +
633.5846 + var props = {
633.5847 + top: (options.top - curOffset.top) + curTop,
633.5848 + left: (options.left - curOffset.left) + curLeft
633.5849 + };
633.5850 +
633.5851 + if ( "using" in options ) {
633.5852 + options.using.call( elem, props );
633.5853 + } else {
633.5854 + curElem.css( props );
633.5855 + }
633.5856 + }
633.5857 +};
633.5858 +
633.5859 +
633.5860 +jQuery.fn.extend({
633.5861 + position: function() {
633.5862 + if ( !this[0] ) {
633.5863 + return null;
633.5864 + }
633.5865 +
633.5866 + var elem = this[0],
633.5867 +
633.5868 + // Get *real* offsetParent
633.5869 + offsetParent = this.offsetParent(),
633.5870 +
633.5871 + // Get correct offsets
633.5872 + offset = this.offset(),
633.5873 + parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
633.5874 +
633.5875 + // Subtract element margins
633.5876 + // note: when an element has margin: auto the offsetLeft and marginLeft
633.5877 + // are the same in Safari causing offset.left to incorrectly be 0
633.5878 + offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
633.5879 + offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
633.5880 +
633.5881 + // Add offsetParent borders
633.5882 + parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
633.5883 + parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
633.5884 +
633.5885 + // Subtract the two offsets
633.5886 + return {
633.5887 + top: offset.top - parentOffset.top,
633.5888 + left: offset.left - parentOffset.left
633.5889 + };
633.5890 + },
633.5891 +
633.5892 + offsetParent: function() {
633.5893 + return this.map(function() {
633.5894 + var offsetParent = this.offsetParent || document.body;
633.5895 + while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
633.5896 + offsetParent = offsetParent.offsetParent;
633.5897 + }
633.5898 + return offsetParent;
633.5899 + });
633.5900 + }
633.5901 +});
633.5902 +
633.5903 +
633.5904 +// Create scrollLeft and scrollTop methods
633.5905 +jQuery.each( ["Left", "Top"], function( i, name ) {
633.5906 + var method = "scroll" + name;
633.5907 +
633.5908 + jQuery.fn[ method ] = function(val) {
633.5909 + var elem = this[0], win;
633.5910 +
633.5911 + if ( !elem ) {
633.5912 + return null;
633.5913 + }
633.5914 +
633.5915 + if ( val !== undefined ) {
633.5916 + // Set the scroll offset
633.5917 + return this.each(function() {
633.5918 + win = getWindow( this );
633.5919 +
633.5920 + if ( win ) {
633.5921 + win.scrollTo(
633.5922 + !i ? val : jQuery(win).scrollLeft(),
633.5923 + i ? val : jQuery(win).scrollTop()
633.5924 + );
633.5925 +
633.5926 + } else {
633.5927 + this[ method ] = val;
633.5928 + }
633.5929 + });
633.5930 + } else {
633.5931 + win = getWindow( elem );
633.5932 +
633.5933 + // Return the scroll offset
633.5934 + return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
633.5935 + jQuery.support.boxModel && win.document.documentElement[ method ] ||
633.5936 + win.document.body[ method ] :
633.5937 + elem[ method ];
633.5938 + }
633.5939 + };
633.5940 +});
633.5941 +
633.5942 +function getWindow( elem ) {
633.5943 + return ("scrollTo" in elem && elem.document) ?
633.5944 + elem :
633.5945 + elem.nodeType === 9 ?
633.5946 + elem.defaultView || elem.parentWindow :
633.5947 + false;
633.5948 +}
633.5949 +// Create innerHeight, innerWidth, outerHeight and outerWidth methods
633.5950 +jQuery.each([ "Height", "Width" ], function( i, name ) {
633.5951 +
633.5952 + var type = name.toLowerCase();
633.5953 +
633.5954 + // innerHeight and innerWidth
633.5955 + jQuery.fn["inner" + name] = function() {
633.5956 + return this[0] ?
633.5957 + jQuery.css( this[0], type, false, "padding" ) :
633.5958 + null;
633.5959 + };
633.5960 +
633.5961 + // outerHeight and outerWidth
633.5962 + jQuery.fn["outer" + name] = function( margin ) {
633.5963 + return this[0] ?
633.5964 + jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
633.5965 + null;
633.5966 + };
633.5967 +
633.5968 + jQuery.fn[ type ] = function( size ) {
633.5969 + // Get window width or height
633.5970 + var elem = this[0];
633.5971 + if ( !elem ) {
633.5972 + return size == null ? null : this;
633.5973 + }
633.5974 +
633.5975 + return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
633.5976 + // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
633.5977 + elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
633.5978 + elem.document.body[ "client" + name ] :
633.5979 +
633.5980 + // Get document width or height
633.5981 + (elem.nodeType === 9) ? // is it a document
633.5982 + // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
633.5983 + Math.max(
633.5984 + elem.documentElement["client" + name],
633.5985 + elem.body["scroll" + name], elem.documentElement["scroll" + name],
633.5986 + elem.body["offset" + name], elem.documentElement["offset" + name]
633.5987 + ) :
633.5988 +
633.5989 + // Get or set width or height on the element
633.5990 + size === undefined ?
633.5991 + // Get width or height on the element
633.5992 + jQuery.css( elem, type ) :
633.5993 +
633.5994 + // Set the width or height on the element (default to pixels if value is unitless)
633.5995 + this.css( type, typeof size === "string" ? size : size + "px" );
633.5996 + };
633.5997 +
633.5998 +});
633.5999 +// Expose jQuery to the global object
633.6000 +window.jQuery = window.$ = jQuery;
633.6001 +
633.6002 +})(window);
634.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
634.2 +++ b/web/static/js/cluetip-1.0.6/lib/jquery.bgiframe.min.js Mon Apr 26 11:16:23 2010 +0200
634.3 @@ -0,0 +1,10 @@
634.4 +/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
634.5 + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
634.6 + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
634.7 + *
634.8 + * $LastChangedDate: 2021-07-21 19:45:56 -0400 (Sat, 21 Jul 2021) $
634.9 + * $Rev: 2447 $
634.10 + *
634.11 + * Version 2.1.1
634.12 + */
634.13 +(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
634.14 \ No newline at end of file
635.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
635.2 +++ b/web/static/js/cluetip-1.0.6/lib/jquery.hoverIntent.js Mon Apr 26 11:16:23 2010 +0200
635.3 @@ -0,0 +1,114 @@
635.4 +/**
635.5 +* hoverIntent is similar to jQuery's built-in "hover" function except that
635.6 +* instead of firing the onMouseOver event immediately, hoverIntent checks
635.7 +* to see if the user's mouse has slowed down (beneath the sensitivity
635.8 +* threshold) before firing the onMouseOver event.
635.9 +*
635.10 +* hoverIntent r5 // 2022.03.27 // jQuery 1.1.2
635.11 +* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
635.12 +*
635.13 +* hoverIntent is currently available for use in all personal or commercial
635.14 +* projects under both MIT and GPL licenses. This means that you can choose
635.15 +* the license that best suits your project, and use it accordingly.
635.16 +*
635.17 +* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
635.18 +* $("ul li").hoverIntent( showNav , hideNav );
635.19 +*
635.20 +* // advanced usage receives configuration object only
635.21 +* $("ul li").hoverIntent({
635.22 +* sensitivity: 2, // number = sensitivity threshold (must be 1 or higher)
635.23 +* interval: 50, // number = milliseconds of polling interval
635.24 +* over: showNav, // function = onMouseOver callback (required)
635.25 +* timeout: 100, // number = milliseconds delay before onMouseOut function call
635.26 +* out: hideNav // function = onMouseOut callback (required)
635.27 +* });
635.28 +*
635.29 +* @param f onMouseOver function || An object with configuration options
635.30 +* @param g onMouseOut function || Nothing (use configuration options object)
635.31 +* @return The object (aka "this") that called hoverIntent, and the event object
635.32 +* @author Brian Cherne <[email protected]>
635.33 +*
635.34 +* modified by Karl Swedberg. Namespaced events in order to work better with clueTip plugin
635.35 +*/
635.36 +(function($) {
635.37 + $.fn.hoverIntent = function(f,g) {
635.38 + // default configuration options
635.39 + var cfg = {
635.40 + sensitivity: 7,
635.41 + interval: 100,
635.42 + timeout: 0
635.43 + };
635.44 + // override configuration options with user supplied object
635.45 + cfg = $.extend(cfg, g ? { over: f, out: g } : f );
635.46 +
635.47 + // instantiate variables
635.48 + // cX, cY = current X and Y position of mouse, updated by mousemove event
635.49 + // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
635.50 + var cX, cY, pX, pY;
635.51 +
635.52 + // A private function for getting mouse position
635.53 + var track = function(ev) {
635.54 + cX = ev.pageX;
635.55 + cY = ev.pageY;
635.56 + };
635.57 +
635.58 + // A private function for comparing current and previous mouse position
635.59 + var compare = function(ev,ob) {
635.60 + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
635.61 + // compare mouse positions to see if they've crossed the threshold
635.62 + if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
635.63 + $(ob).unbind("mousemove",track);
635.64 + // set hoverIntent state to true (so mouseOut can be called)
635.65 + ob.hoverIntent_s = 1;
635.66 + return cfg.over.apply(ob,[ev]);
635.67 + } else {
635.68 + // set previous coordinates for next time
635.69 + pX = cX; pY = cY;
635.70 + // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
635.71 + ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
635.72 + }
635.73 + };
635.74 +
635.75 + // A private function for delaying the mouseOut function
635.76 + var delay = function(ev,ob) {
635.77 + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
635.78 + ob.hoverIntent_s = 0;
635.79 + return cfg.out.apply(ob,[ev]);
635.80 + };
635.81 +
635.82 + // A private function for handling mouse 'hovering'
635.83 + var handleHover = function(e) {
635.84 + // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
635.85 + var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
635.86 + while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
635.87 + if ( p == this ) { return false; }
635.88 +
635.89 + // copy objects to be passed into t (required for event object to be passed in IE)
635.90 + var ev = jQuery.extend({},e);
635.91 + var ob = this;
635.92 +
635.93 + // cancel hoverIntent timer if it exists
635.94 + if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
635.95 +
635.96 + // else e.type == "onmouseover"
635.97 + if (e.type == "mouseover") {
635.98 + // set "previous" X and Y position based on initial entry point
635.99 + pX = ev.pageX; pY = ev.pageY;
635.100 + // update "current" X and Y position based on mousemove
635.101 + $(ob).bind("mousemove.cluetip",track);
635.102 + // start polling interval (self-calling timeout) to compare mouse coordinates over time
635.103 + if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
635.104 +
635.105 + // else e.type == "onmouseout"
635.106 + } else {
635.107 + // unbind expensive mousemove event
635.108 + $(ob).unbind("mousemove.cluetip",track);
635.109 + // if hoverIntent state is true, then call the mouseOut function after the specified delay
635.110 + if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
635.111 + }
635.112 + };
635.113 +
635.114 + // bind the function to the two event listeners
635.115 + return this.bind('mouseover.cluetip', handleHover).bind('mouseout.cluetip', handleHover);
635.116 + };
635.117 +})(jQuery);
635.118 \ No newline at end of file
636.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
636.2 +++ b/web/static/js/cluetip-1.0.6/sdemo.html Mon Apr 26 11:16:23 2010 +0200
636.3 @@ -0,0 +1,47 @@
636.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
636.5 +<html>
636.6 + <head>
636.7 + <title>Prova</title>
636.8 + <link href="cluetip/jquery.cluetip.css" rel="stylesheet" type="text/css" media="screen" />
636.9 + </head>
636.10 +
636.11 + <body>
636.12 + <h1>Test</h1>
636.13 +
636.14 +
636.15 + <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
636.16 + <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
636.17 + <script type="text/javascript" src="cluetip/lib/jquery.hoverIntent.js"></script>
636.18 + <script type="text/javascript" src="cluetip/lib/jquery.bgiframe.min.js"></script>
636.19 + <script type="text/javascript" src="cluetip/jquery.cluetip.js"></script>
636.20 +
636.21 +<a class="title" href="#" title="This is the title|The first set of contents comes after the first delimiter in the title.|In this case, the delimiter is a pipe">
636.22 +
636.23 +Chi ben <a href="#" title"Comincium|Gia sem chi">incomincia</a>
636.24 +
636.25 +<table>
636.26 + <tr>
636.27 + <td class="title" title="Versione di logon.conf|
636.28 + NOTA per WIN98: il numero di versione DEVE ESSERE INCREMENTATO
636.29 + AD OGNI MODIFICA di logon.conf se si vuole che il client Win98
636.30 + aggiorni i parametri di registro già precedentemente settati)">Versione</td>
636.31 + <td></td>
636.32 + </tr>
636.33 +</table>
636.34 +
636.35 +
636.36 +<script>
636.37 +$(document).ready(function () {
636.38 +
636.39 + $('td.title').cluetip({splitTitle: '|', });
636.40 + $('a.title').cluetip();
636.41 +});
636.42 +</script>
636.43 + <hr>
636.44 + <address><a href="mailto:sandro@ubuntu">Sandro Dentella</a></address>
636.45 +<!-- Created: Thu Feb 4 15:26:02 CET 2010 -->
636.46 +<!-- hhmts start -->
636.47 +Last modified: Thu Feb 4 16:05:29 CET 2010
636.48 +<!-- hhmts end -->
636.49 + </body>
636.50 +</html>
637.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
637.2 +++ b/web/static/js/jquery-ui.min.js Mon Apr 26 11:16:23 2010 +0200
637.3 @@ -0,0 +1,9 @@
637.4 +/*
637.5 + * jQuery UI 1.7.2
637.6 + *
637.7 + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
637.8 + * Dual licensed under the MIT (MIT-LICENSE.txt)
637.9 + * and GPL (GPL-LICENSE.txt) licenses.
637.10 + *
637.11 + * http://docs.jquery.com/UI
637.12 + */
637.13 jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);(function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},_trigger:function(b,c,d){d=d||this._uiHash();a.ui.plugin.call(this,b,[c,d]);if(b=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return a.widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(b){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,offset:this.positionAbs}}}));a.extend(a.ui.draggable,{version:"1.7.2",eventPrefix:"drag",defaults:{addClasses:true,appendTo:"parent",axis:false,cancel:":input,option",connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false}});a.ui.plugin.add("draggable","connectToSortable",{start:function(c,e){var d=a(this).data("draggable"),f=d.options,b=a.extend({},e,{item:d.element});d.sortables=[];a(f.connectToSortable).each(function(){var g=a.data(this,"sortable");if(g&&!g.options.disabled){d.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",c,b)}})},stop:function(c,e){var d=a(this).data("draggable"),b=a.extend({},e,{item:d.element});a.each(d.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;d.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(c);this.instance.options.helper=this.instance.options._helper;if(d.options.helper=="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",c,b)}})},drag:function(c,f){var e=a(this).data("draggable"),b=this;var d=function(i){var n=this.offset.click.top,m=this.offset.click.left;var g=this.positionAbs.top,k=this.positionAbs.left;var j=i.height,l=i.width;var p=i.top,h=i.left;return a.ui.isOver(g+n,k+m,p,h,j,l)};a.each(e.sortables,function(g){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(b).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return f.helper[0]};c.target=this.instance.currentItem[0];this.instance._mouseCapture(c,true);this.instance._mouseStart(c,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;e._trigger("toSortable",c);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}if(this.instance.currentItem){this.instance._mouseDrag(c)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",c,this.instance._uiHash(this.instance));this.instance._mouseStop(c,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}e._trigger("fromSortable",c);e.dropped=false}}})}});a.ui.plugin.add("draggable","cursor",{start:function(c,d){var b=a("body"),e=a(this).data("draggable").options;if(b.css("cursor")){e._cursor=b.css("cursor")}b.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._cursor){a("body").css("cursor",d._cursor)}}});a.ui.plugin.add("draggable","iframeFix",{start:function(b,c){var d=a(this).data("draggable").options;a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop+f.scrollSpeed}else{if(d.pageY-c.overflowOffset.top<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop-f.scrollSpeed}}}if(!f.axis||f.axis!="y"){if((c.overflowOffset.left+c.scrollParent[0].offsetWidth)-d.pageX<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft+f.scrollSpeed}else{if(d.pageX-c.overflowOffset.left<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft-f.scrollSpeed}}}}else{if(!f.axis||f.axis!="x"){if(d.pageY-a(document).scrollTop()<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-f.scrollSpeed)}else{if(a(window).height()-(d.pageY-a(document).scrollTop())<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+f.scrollSpeed)}}}if(!f.axis||f.axis!="y"){if(d.pageX-a(document).scrollLeft()<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-f.scrollSpeed)}else{if(a(window).width()-(d.pageX-a(document).scrollLeft())<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+f.scrollSpeed)}}}}if(b!==false&&a.ui.ddmanager&&!f.dropBehaviour){a.ui.ddmanager.prepareOffsets(c,d)}}});a.ui.plugin.add("draggable","snap",{start:function(c,d){var b=a(this).data("draggable"),e=b.options;b.snapElements=[];a(e.snap.constructor!=String?(e.snap.items||":data(draggable)"):e.snap).each(function(){var g=a(this);var f=g.offset();if(this!=b.element[0]){b.snapElements.push({item:this,width:g.outerWidth(),height:g.outerHeight(),top:f.top,left:f.left})}})},drag:function(u,p){var g=a(this).data("draggable"),q=g.options;var y=q.snapTolerance;var x=p.offset.left,w=x+g.helperProportions.width,f=p.offset.top,e=f+g.helperProportions.height;for(var v=g.snapElements.length-1;v>=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y<x&&x<n+y&&m-y<f&&f<A+y)||(s-y<x&&x<n+y&&m-y<e&&e<A+y)||(s-y<w&&w<n+y&&m-y<f&&f<A+y)||(s-y<w&&w<n+y&&m-y<e&&e<A+y))){if(g.snapElements[v].snapping){(g.options.snap.release&&g.options.snap.release.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=false;continue}if(q.snapMode!="inner"){var c=Math.abs(m-e)<=y;var z=Math.abs(A-f)<=y;var j=Math.abs(s-w)<=y;var k=Math.abs(n-x)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m-g.helperProportions.height,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s-g.helperProportions.width}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n}).left-g.margins.left}}var h=(c||z||j||k);if(q.snapMode!="outer"){var c=Math.abs(m-f)<=y;var z=Math.abs(A-e)<=y;var j=Math.abs(s-x)<=y;var k=Math.abs(n-w)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A-g.helperProportions.height,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n-g.helperProportions.width}).left-g.margins.left}}if(!g.snapElements[v].snapping&&(c||z||j||k||h)){(g.options.snap.snap&&g.options.snap.snap.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=(c||z||j||k||h)}}});a.ui.plugin.add("draggable","stack",{start:function(b,c){var e=a(this).data("draggable").options;var d=a.makeArray(a(e.stack.group)).sort(function(g,f){return(parseInt(a(g).css("zIndex"),10)||e.stack.min)-(parseInt(a(f).css("zIndex"),10)||e.stack.min)});a(d).each(function(f){this.style.zIndex=e.stack.min+f});this[0].style.zIndex=e.stack.min+d.length}});a.ui.plugin.add("draggable","zIndex",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("zIndex")){e._zIndex=b.css("zIndex")}b.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._zIndex){a(c.helper).css("zIndex",d._zIndex)}}})})(jQuery);(function(a){a.widget("ui.droppable",{_init:function(){var c=this.options,b=c.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&a.isFunction(this.options.accept)?this.options.accept:function(e){return e.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[this.options.scope]=a.ui.ddmanager.droppables[this.options.scope]||[];a.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.addClasses&&this.element.addClass("ui-droppable"))},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++){if(b[c]==this){b.splice(c,1)}}this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_setData:function(b,c){if(b=="accept"){this.options.accept=c&&a.isFunction(c)?c:function(e){return e.is(c)}}else{a.widget.prototype._setData.apply(this,arguments)}},_activate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.addClass(this.options.activeClass)}(b&&this._trigger("activate",c,this.ui(b)))},_deactivate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}(b&&this._trigger("deactivate",c,this.ui(b)))},_over:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.addClass(this.options.hoverClass)}this._trigger("over",c,this.ui(b))}},_out:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("out",c,this.ui(b))}},_drop:function(c,d){var b=d||a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return false}var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var f=a.data(this,"droppable");if(f.options.greedy&&a.ui.intersect(b,a.extend(f,{offset:f.element.offset()}),f.options.tolerance)){e=true;return false}});if(e){return false}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("drop",c,this.ui(b));return this.element}return false},ui:function(b){return{draggable:(b.currentItem||b.element),helper:b.helper,position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs}}});a.extend(a.ui.droppable,{version:"1.7.2",eventPrefix:"drop",defaults:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"}});a.ui.intersect=function(q,j,o){if(!j.offset){return false}var e=(q.positionAbs||q.position.absolute).left,d=e+q.helperProportions.width,n=(q.positionAbs||q.position.absolute).top,m=n+q.helperProportions.height;var g=j.offset.left,c=g+j.proportions.width,p=j.offset.top,k=p+j.proportions.height;switch(o){case"fit":return(g<e&&d<c&&p<n&&m<k);break;case"intersect":return(g<e+(q.helperProportions.width/2)&&d-(q.helperProportions.width/2)<c&&p<n+(q.helperProportions.height/2)&&m-(q.helperProportions.height/2)<k);break;case"pointer":var h=((q.positionAbs||q.position.absolute).left+(q.clickOffset||q.offset.click).left),i=((q.positionAbs||q.position.absolute).top+(q.clickOffset||q.offset.click).top),f=a.ui.isOver(i,h,p,g,j.proportions.height,j.proportions.width);return f;break;case"touch":return((n>=p&&n<=k)||(m>=p&&m<=k)||(n<p&&m>k))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(e<g&&d>c));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d<b.length;d++){if(b[d].options.disabled||(e&&!b[d].options.accept.call(b[d].element[0],(e.currentItem||e.element)))){continue}for(var c=0;c<h.length;c++){if(h[c]==b[d].element[0]){b[d].proportions.height=0;continue droppablesLoop}}b[d].visible=b[d].element.css("display")!="none";if(!b[d].visible){continue}b[d].offset=b[d].element.offset();b[d].proportions={width:b[d].element[0].offsetWidth,height:b[d].element[0].offsetHeight};if(f=="mousedown"){b[d]._activate.call(b[d],g)}}},drop:function(b,c){var d=false;a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(!this.options){return}if(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)){d=this._drop.call(this,c)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element[0],(b.currentItem||b.element))){this.isout=1;this.isover=0;this._deactivate.call(this,c)}});return d},drag:function(b,c){if(b.options.refreshPositions){a.ui.ddmanager.prepareOffsets(b,c)}a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(this.options.disabled||this.greedyChild||!this.visible){return}var e=a.ui.intersect(b,this,this.options.tolerance);var g=!e&&this.isover==1?"isout":(e&&this.isover==0?"isover":null);if(!g){return}var f;if(this.options.greedy){var d=this.element.parents(":data(droppable):eq(0)");if(d.length){f=a.data(d[0],"droppable");f.greedyChild=(g=="isover"?1:0)}}if(f&&g=="isover"){f.isover=0;f.isout=1;f._out.call(f,c)}this[g]=1;this[g=="isout"?"isover":"isout"]=0;this[g=="isover"?"_over":"_out"].call(this,c);if(f&&g=="isout"){f.isout=0;f.isover=1;f._over.call(f,c)}})}}})(jQuery);(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,u){var s=(q[u]||0)+(j[u]||0);if(s&&s>=0){o[u]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);(function(a){a.widget("ui.selectable",a.extend({},a.ui.mouse,{_init:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]);c.each(function(){var d=a(this);var e=d.offset();a.data(this,"selectable-item",{element:this,$element:d,left:e.left,top:e.top,right:e.left+d.outerWidth(),bottom:e.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(d){var b=this;this.opos=[d.pageX,d.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",d);a(c.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:d.clientX,top:d.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!d.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting=true;b._trigger("unselecting",d,{unselecting:e.element})}});a(d.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){e.$element.removeClass("ui-unselecting").addClass("ui-selecting");e.unselecting=false;e.selecting=true;e.selected=true;b._trigger("selecting",d,{selecting:e.element});return false}})},_mouseDrag:function(i){var c=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],b=i.pageX,g=i.pageY;if(d>b){var f=b;b=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:b-d,height:g-h});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!j||j.element==c.element[0]){return}var k=false;if(e.tolerance=="touch"){k=(!(j.left>b||j.right<d||j.top>g||j.bottom<h))}else{if(e.tolerance=="fit"){k=(j.left>d&&j.right<b&&j.top>h&&j.bottom<g)}}if(k){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",i,{selecting:j.element})}}else{if(j.selecting){if(i.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",i,{unselecting:j.element})}}if(j.selected){if(!i.metaKey&&!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",i,{unselecting:j.element})}}}});return false},_mouseStop:function(d){var b=this;this.dragged=false;var c=this.options;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;b._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;b._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}}));a.extend(a.ui.selectable,{version:"1.7.2",defaults:{appendTo:"body",autoRefresh:true,cancel:":input,option",delay:0,distance:0,filter:"*",tolerance:"touch"}})})(jQuery);(function(a){a.widget("ui.sortable",a.extend({},a.ui.mouse,{_init:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop+g.scrollSpeed}else{if(f.pageY-this.overflowOffset.top<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop-g.scrollSpeed}}if((this.overflowOffset.left+this.scrollParent[0].offsetWidth)-f.pageX<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft+g.scrollSpeed}else{if(f.pageX-this.overflowOffset.left<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft-g.scrollSpeed}}}else{if(f.pageY-a(document).scrollTop()<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-g.scrollSpeed)}else{if(a(window).height()-(f.pageY-a(document).scrollTop())<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+g.scrollSpeed)}}if(f.pageX-a(document).scrollLeft()<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-g.scrollSpeed)}else{if(a(window).width()-(f.pageX-a(document).scrollLeft())<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+g.scrollSpeed)}}}if(b!==false&&a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,f)}}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)<i&&(e+h)>f&&(e+h)<c;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>m[this.floating?"width":"height"])){return g}else{return(f<e+(this.helperProportions.width/2)&&d-(this.helperProportions.width/2)<c&&n<k+(this.helperProportions.height/2)&&j-(this.helperProportions.height/2)<i)}},_intersectsWithPointer:function(d){var e=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height),c=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width),g=e&&c,b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(!g){return false}return this.floating?(((f&&f=="right")||b=="down")?2:1):(b&&(b=="down"?2:1))},_intersectsWithSides:function(e){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+(e.height/2),e.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+(e.width/2),e.width),b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(this.floating&&f){return((f=="right"&&d)||(f=="left"&&!d))}else{return b&&((b=="down"&&c)||(b=="up"&&!c))}},_getDragVerticalDirection:function(){var b=this.positionAbs.top-this.lastPositionAbs.top;return b!=0&&(b>0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c<this.items.length;c++){for(var b=0;b<d.length;b++){if(d[b]==this.items[c].item[0]){this.items.splice(c,1)}}}},_refreshItems:function(b){this.items=[];this.containers=[this];var h=this.items;var p=this;var f=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]];var l=this._connectWith();if(l){for(var e=l.length-1;e>=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d<n;d++){var o=a(c[d]);o.data("sortable-item",k);h.push({item:o,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){if(this.offsetParent&&this.helper){this.offset.parent=this._getParentOffset()}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)<h){h=Math.abs(f-e);g=this.items[b]}}if(!g&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[c];g?this._rearrange(d,g,null,true):this._rearrange(d,null,this.containers[c].element,true);this._trigger("change",d,this._uiHash());this.containers[c]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[c]._trigger("over",d,this._uiHash(this));this.containers[c].containerCache.over=1}}else{if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",d,this._uiHash(this));this.containers[c].containerCache.over=0}}}},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c,this.currentItem])):(d.helper=="clone"?this.currentItem.clone():this.currentItem);if(!b.parents("body").length){a(d.appendTo!="parent"?d.appendTo:this.currentItem[0].parentNode)[0].appendChild(b[0])}if(b[0]==this.currentItem[0]){this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}}if(b[0].style.width==""||d.forceHelperSize){b.width(this.currentItem.width())}if(b[0].style.height==""||d.forceHelperSize){b.height(this.currentItem.height())}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.currentItem.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.currentItem.css("marginLeft"),10)||0),top:(parseInt(this.currentItem.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)){var c=a(e.containment)[0];var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_rearrange:function(g,f,c,e){c?c[0].appendChild(this.placeholder[0]):f.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?f.item[0]:f.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var d=this,b=this.counter;window.setTimeout(function(){if(b==d.counter){d.refreshPositions(!e)}},0)},_clear:function(d,e){this.reverting=false;var f=[],b=this;if(!this._noFinalSort&&this.currentItem[0].parentNode){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var c in this._storedCSS){if(this._storedCSS[c]=="auto"||this._storedCSS[c]=="static"){this._storedCSS[c]=""}}this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.fromOutside&&!e){f.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))})}if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!e){f.push(function(g){this._trigger("update",g,this._uiHash())})}if(!a.ui.contains(this.element[0],this.currentItem[0])){if(!e){f.push(function(g){this._trigger("remove",g,this._uiHash())})}for(var c=this.containers.length-1;c>=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}return false}if(!e){this._trigger("beforeStop",d,this._uiHash())}this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.helper[0]!=this.currentItem[0]){this.helper.remove()}this.helper=null;if(!e){for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){if(a.widget.prototype._trigger.apply(this,arguments)===false){this.cancel()}},_uiHash:function(c){var b=c||this;return{helper:b.helper,placeholder:b.placeholder||a([]),position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs,item:b.currentItem,sender:c?c.element:null}}}));a.extend(a.ui.sortable,{getter:"serialize toArray",version:"1.7.2",eventPrefix:"sort",defaults:{appendTo:"parent",axis:false,cancel:":input,option",connectWith:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);(function(a){a.effects.blind=function(b){return this.queue(function(){var d=a(this),c=["position","top","left"];var h=a.effects.setMode(d,b.options.mode||"hide");var g=b.options.direction||"vertical";a.effects.save(d,c);d.show();var j=a.effects.createWrapper(d).css({overflow:"hidden"});var e=(g=="vertical")?"height":"width";var i=(g=="vertical")?j.height():j.width();if(h=="show"){j.css(e,0)}var f={};f[e]=h=="show"?i:0;j.animate(f,b.duration,b.options.easing,function(){if(h=="hide"){d.hide()}a.effects.restore(d,c);a.effects.removeWrapper(d);if(b.callback){b.callback.apply(d[0],arguments)}d.dequeue()})})}})(jQuery);(function(a){a.effects.bounce=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"up";var c=b.options.distance||20;var d=b.options.times||5;var g=b.duration||250;if(/show|hide/.test(k)){l.push("opacity")}a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var c=b.options.distance||(f=="top"?e.outerHeight({margin:true})/3:e.outerWidth({margin:true})/3);if(k=="show"){e.css("opacity",0).css(f,p=="pos"?-c:c)}if(k=="hide"){c=c/(d*2)}if(k!="hide"){d--}if(k=="show"){var h={opacity:1};h[f]=(p=="pos"?"+=":"-=")+c;e.animate(h,g/2,b.options.easing);c=c/2;d--}for(var j=0;j<d;j++){var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing);c=(k=="hide")?c*2:c/2}if(k=="hide"){var h={opacity:0};h[f]=(p=="pos"?"-=":"+=")+c;e.animate(h,g/2,b.options.easing,function(){e.hide();a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}else{var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);(function(a){a.effects.clip=function(b){return this.queue(function(){var f=a(this),j=["position","top","left","height","width"];var i=a.effects.setMode(f,b.options.mode||"hide");var k=b.options.direction||"vertical";a.effects.save(f,j);f.show();var c=a.effects.createWrapper(f).css({overflow:"hidden"});var e=f[0].tagName=="IMG"?c:f;var g={size:(k=="vertical")?"height":"width",position:(k=="vertical")?"top":"left"};var d=(k=="vertical")?e.height():e.width();if(i=="show"){e.css(g.size,0);e.css(g.position,d/2)}var h={};h[g.size]=i=="show"?d:0;h[g.position]=i=="show"?0:d/2;e.animate(h,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){f.hide()}a.effects.restore(f,j);a.effects.removeWrapper(f);if(b.callback){b.callback.apply(f[0],arguments)}f.dequeue()}})})}})(jQuery);(function(a){a.effects.drop=function(b){return this.queue(function(){var e=a(this),d=["position","top","left","opacity"];var i=a.effects.setMode(e,b.options.mode||"hide");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e);var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true})/2:e.outerWidth({margin:true})/2);if(i=="show"){e.css("opacity",0).css(f,c=="pos"?-j:j)}var g={opacity:i=="show"?1:0};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);(function(a){a.effects.explode=function(b){return this.queue(function(){var k=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;var e=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?(a(this).is(":visible")?"hide":"show"):b.options.mode;var h=a(this).show().css("visibility","hidden");var l=h.offset();l.top-=parseInt(h.css("marginTop"),10)||0;l.left-=parseInt(h.css("marginLeft"),10)||0;var g=h.outerWidth(true);var c=h.outerHeight(true);for(var f=0;f<k;f++){for(var d=0;d<e;d++){h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);(function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1],10)/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);(function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);(function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c<f;c++){d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing)}if(g=="hide"){d.animate({opacity:0},e,b.options.easing,function(){d.hide();if(b.callback){b.callback.apply(this,arguments)}})}else{d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing,function(){if(b.callback){b.callback.apply(this,arguments)}})}d.queue("fx",function(){d.dequeue()});d.dequeue()})}})(jQuery);(function(a){a.effects.puff=function(b){return this.queue(function(){var f=a(this);var c=a.extend(true,{},b.options);var h=a.effects.setMode(f,b.options.mode||"hide");var g=parseInt(b.options.percent,10)||150;c.fade=true;var e={height:f.height(),width:f.width()};var d=g/100;f.from=(h=="hide")?e:{height:e.height*d,width:e.width*d};c.from=f.from;c.percent=(h=="hide")?g:100;c.mode=h;f.effect("scale",c,b.duration,b.callback);f.dequeue()})};a.effects.scale=function(b){return this.queue(function(){var g=a(this);var d=a.extend(true,{},b.options);var j=a.effects.setMode(g,b.options.mode||"effect");var h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:(j=="hide"?0:100));var i=b.options.direction||"both";var c=b.options.origin;if(j!="effect"){d.origin=c||["middle","center"];d.restore=true}var f={height:g.height(),width:g.width()};g.from=b.options.from||(j=="show"?{height:0,width:0}:f);var e={y:i!="horizontal"?(h/100):1,x:i!="vertical"?(h/100):1};g.to={height:f.height*e.y,width:f.width*e.x};if(b.options.fade){if(j=="show"){g.from.opacity=0;g.to.opacity=1}if(j=="hide"){g.from.opacity=1;g.to.opacity=0}}d.from=g.from;d.to=g.to;d.mode=j;g.effect("size",d,b.duration,b.callback);g.dequeue()})};a.effects.size=function(b){return this.queue(function(){var c=a(this),n=["position","top","left","width","height","overflow","opacity"];var m=["position","top","left","overflow","opacity"];var j=["width","height","overflow"];var p=["fontSize"];var k=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var g=a.effects.setMode(c,b.options.mode||"effect");var i=b.options.restore||false;var e=b.options.scale||"both";var o=b.options.origin;var d={height:c.height(),width:c.width()};c.from=b.options.from||d;c.to=b.options.to||d;if(o){var h=a.effects.getBaseline(o,d);c.from.top=(d.height-c.from.height)*h.y;c.from.left=(d.width-c.from.width)*h.x;c.to.top=(d.height-c.to.height)*h.y;c.to.left=(d.width-c.to.width)*h.x}var l={from:{y:c.from.height/d.height,x:c.from.width/d.width},to:{y:c.to.height/d.height,x:c.to.width/d.width}};if(e=="box"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(k);c.from=a.effects.setTransition(c,k,l.from.y,c.from);c.to=a.effects.setTransition(c,k,l.to.y,c.to)}if(l.from.x!=l.to.x){n=n.concat(f);c.from=a.effects.setTransition(c,f,l.from.x,c.from);c.to=a.effects.setTransition(c,f,l.to.x,c.to)}}if(e=="content"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(p);c.from=a.effects.setTransition(c,p,l.from.y,c.from);c.to=a.effects.setTransition(c,p,l.to.y,c.to)}}a.effects.save(c,i?n:m);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(e=="content"||e=="both"){k=k.concat(["marginTop","marginBottom"]).concat(p);f=f.concat(["marginLeft","marginRight"]);j=n.concat(k).concat(f);c.find("*[width]").each(function(){child=a(this);if(i){a.effects.save(child,j)}var q={height:child.height(),width:child.width()};child.from={height:q.height*l.from.y,width:q.width*l.from.x};child.to={height:q.height*l.to.y,width:q.width*l.to.x};if(l.from.y!=l.to.y){child.from=a.effects.setTransition(child,k,l.from.y,child.from);child.to=a.effects.setTransition(child,k,l.to.y,child.to)}if(l.from.x!=l.to.x){child.from=a.effects.setTransition(child,f,l.from.x,child.from);child.to=a.effects.setTransition(child,f,l.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){if(i){a.effects.restore(child,j)}})})}c.animate(c.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(g=="hide"){c.hide()}a.effects.restore(c,i?n:m);a.effects.removeWrapper(c);if(b.callback){b.callback.apply(this,arguments)}c.dequeue()}})})}})(jQuery);(function(a){a.effects.shake=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"left";var c=b.options.distance||20;var d=b.options.times||3;var g=b.duration||b.options.duration||140;a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var h={},o={},m={};h[f]=(p=="pos"?"-=":"+=")+c;o[f]=(p=="pos"?"+=":"-=")+c*2;m[f]=(p=="pos"?"-=":"+=")+c*2;e.animate(h,g,b.options.easing);for(var j=1;j<d;j++){e.animate(o,g,b.options.easing).animate(m,g,b.options.easing)}e.animate(o,g,b.options.easing).animate(h,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}});e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);(function(a){a.effects.slide=function(b){return this.queue(function(){var e=a(this),d=["position","top","left"];var i=a.effects.setMode(e,b.options.mode||"show");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e).css({overflow:"hidden"});var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true}):e.outerWidth({margin:true}));if(i=="show"){e.css(f,c=="pos"?-j:j)}var g={};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);(function(a){a.widget("ui.accordion",{_init:function(){var d=this.options,b=this;this.running=0;if(d.collapsible==a.ui.accordion.defaults.collapsible&&d.alwaysOpen!=a.ui.accordion.defaults.alwaysOpen){d.collapsible=!d.alwaysOpen}if(d.navigation){var c=this.element.find("a").filter(d.navigationFilter);if(c.length){if(c.filter(d.header).length){this.active=c}else{this.active=c.parent().parent().prev();c.addClass("ui-accordion-content-active")}}}this.element.addClass("ui-accordion ui-widget ui-helper-reset");if(this.element[0].nodeName=="UL"){this.element.children("li").addClass("ui-accordion-li-fix")}this.headers=this.element.find(d.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){a(this).removeClass("ui-state-focus")});this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");this.active=this._findActive(this.active||d.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");a("<span/>").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.find(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);if(a.browser.msie){this.element.find("a").css("zoom","1")}this.resize();this.element.attr("role","tablist");this.headers.attr("role","tab").bind("keydown",function(e){return b._keydown(e)}).next().attr("role","tabpanel");this.headers.not(this.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();if(!this.active.length){this.headers.eq(0).attr("tabIndex","0")}else{this.active.attr("aria-expanded","true").attr("tabIndex","0")}if(!a.browser.safari){this.headers.find("a").attr("tabIndex","-1")}if(d.event){this.headers.bind((d.event)+".accordion",function(e){return b._clickHandler.call(b,e,this)})}},destroy:function(){var c=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role").unbind(".accordion").removeData("accordion");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex");this.headers.find("a").removeAttr("tabindex");this.headers.children(".ui-icon").remove();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active");if(c.autoHeight||c.fillHeight){b.css("height","")}},_setData:function(b,c){if(b=="alwaysOpen"){b="collapsible";c=!c}a.widget.prototype._setData.apply(this,arguments)},_keydown:function(e){var g=this.options,f=a.ui.keyCode;if(g.disabled||e.altKey||e.ctrlKey){return}var d=this.headers.length;var b=this.headers.index(e.target);var c=false;switch(e.keyCode){case f.RIGHT:case f.DOWN:c=this.headers[(b+1)%d];break;case f.LEFT:case f.UP:c=this.headers[(b-1+d)%d];break;case f.SPACE:case f.ENTER:return this._clickHandler({target:e.target},e.target)}if(c){a(e.target).attr("tabIndex","-1");a(c).attr("tabIndex","0");c.focus();return false}return true},resize:function(){var e=this.options,d;if(e.fillSpace){if(a.browser.msie){var b=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}d=this.element.parent().height();if(a.browser.msie){this.element.parent().css("overflow",b)}this.headers.each(function(){d-=a(this).outerHeight()});var c=0;this.headers.next().each(function(){c=Math.max(c,a(this).innerHeight()-a(this).height())}).height(Math.max(0,d-c)).css("overflow","auto")}else{if(e.autoHeight){d=0;this.headers.next().each(function(){d=Math.max(d,a(this).outerHeight())}).height(d)}}},activate:function(b){var c=this._findActive(b)[0];this._clickHandler({target:c},c)},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,f){var d=this.options;if(d.disabled){return false}if(!b.target&&d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var h=this.active.next(),e={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:h},c=(this.active=a([]));this._toggle(c,h,e);return false}var g=a(b.currentTarget||f);var i=g[0]==this.active[0];if(this.running||(!d.collapsible&&i)){return false}this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");if(!i){g.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").find(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);g.next().addClass("ui-accordion-content-active")}var c=g.next(),h=this.active.next(),e={options:d,newHeader:i&&d.collapsible?a([]):g,oldHeader:this.active,newContent:i&&d.collapsible?a([]):c.find("> *"),oldContent:h.find("> *")},j=this.headers.index(this.active[0])>this.headers.index(g[0]);this.active=i?a([]):g;this._toggle(c,h,e,i,j);return false},_toggle:function(b,i,g,j,k){var d=this.options,m=this;this.toShow=b;this.toHide=i;this.data=g;var c=function(){if(!m){return}return m._completed.apply(m,arguments)};this._trigger("changestart",null,this.data);this.running=i.size()===0?b.size():i.size();if(d.animated){var f={};if(d.collapsible&&j){f={toShow:a([]),toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}else{f={toShow:b,toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}if(!d.proxied){d.proxied=d.animated}if(!d.proxiedDuration){d.proxiedDuration=d.duration}d.animated=a.isFunction(d.proxied)?d.proxied(f):d.proxied;d.duration=a.isFunction(d.proxiedDuration)?d.proxiedDuration(f):d.proxiedDuration;var l=a.ui.accordion.animations,e=d.duration,h=d.animated;if(!l[h]){l[h]=function(n){this.slide(n,{easing:h,duration:e||700})}}l[h](f)}else{if(d.collapsible&&j){b.toggle()}else{i.hide();b.show()}c(true)}i.prev().attr("aria-expanded","false").attr("tabIndex","-1").blur();b.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()},_completed:function(b){var c=this.options;this.running=b?0:--this.running;if(this.running){return}if(c.clearStyle){this.toShow.add(this.toHide).css({height:"",overflow:""})}this._trigger("change",null,this.data)}});a.extend(a.ui.accordion,{version:"1.7.2",defaults:{active:null,alwaysOpen:true,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(j,h){j=a.extend({easing:"swing",duration:300},j,h);if(!j.toHide.size()){j.toShow.animate({height:"show"},j);return}if(!j.toShow.size()){j.toHide.animate({height:"hide"},j);return}var c=j.toShow.css("overflow"),g,d={},f={},e=["height","paddingTop","paddingBottom"],b;var i=j.toShow;b=i[0].style.width;i.width(parseInt(i.parent().width(),10)-parseInt(i.css("paddingLeft"),10)-parseInt(i.css("paddingRight"),10)-(parseInt(i.css("borderLeftWidth"),10)||0)-(parseInt(i.css("borderRightWidth"),10)||0));a.each(e,function(k,m){f[m]="hide";var l=(""+a.css(j.toShow[0],m)).match(/^([\d+-.]+)(.*)$/);d[m]={value:l[1],unit:l[2]||"px"}});j.toShow.css({height:0,overflow:"hidden"}).show();j.toHide.filter(":hidden").each(j.complete).end().filter(":visible").animate(f,{step:function(k,l){if(l.prop=="height"){g=(l.now-l.start)/(l.end-l.start)}j.toShow[0].style[l.prop]=(g*d[l.prop].value)+d[l.prop].unit},duration:j.duration,easing:j.easing,complete:function(){if(!j.autoHeight){j.toShow.css("height","")}j.toShow.css("width",b);j.toShow.css({overflow:c});j.complete()}})},bounceslide:function(b){this.slide(b,{easing:b.down?"easeOutBounce":"swing",duration:b.down?1000:200})},easeslide:function(b){this.slide(b,{easing:"easeinout",duration:700})}}})})(jQuery);(function($){$.extend($.ui,{datepicker:{version:"1.7.2"}});var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,showMonthAfterYear:false,yearRange:"-10:+10",showOtherMonths:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);inst.append=$([]);inst.trigger=$([]);if(input.hasClass(this.markerClassName)){return}var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){inst.append=$('<span class="'+this._appendClass+'">'+appendText+"</span>");input[isRTL?"before":"after"](inst.append)}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");inst.trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](inst.trigger);inst.trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return}divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){inst.append.remove();inst.trigger.remove();$target.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;inst.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().removeClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;inst.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().addClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(target,name,value){var inst=this._getInst(target);if(arguments.length==2&&typeof name=="string"){return(name=="defaults"?$.extend({},$.datepicker._defaults):(inst?(name=="all"?$.extend({},inst.settings):this._get(inst,name)):null))}var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}if(inst){if(this._curInst==inst){this._hideDatepicker(null)}var date=this._getDateDatepicker(target);extendRemove(inst.settings,settings);this._setDateDatepicker(target,date);this._updateDatepicker(inst)}},_changeDatepicker:function(target,name,value){this._optionDatepicker(target,name,value)},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(event){var inst=$.datepicker._getInst(event.target);var handled=true;var isRTL=inst.dpDiv.is(".ui-datepicker-rtl");inst._keyEvent=true;if($.datepicker._datepickerShowing){switch(event.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:var sel=$("td."+$.datepicker._dayOverClass+", td."+$.datepicker._currentClass,inst.dpDiv);if(sel[0]){$.datepicker._selectDay(event.target,inst.selectedMonth,inst.selectedYear,sel[0])}else{$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"))}return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(event.ctrlKey||event.metaKey){$.datepicker._clearDate(event.target)}handled=event.ctrlKey||event.metaKey;break;case 36:if(event.ctrlKey||event.metaKey){$.datepicker._gotoToday(event.target)}handled=event.ctrlKey||event.metaKey;break;case 37:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?+1:-1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M")}break;case 38:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,-7,"D")}handled=event.ctrlKey||event.metaKey;break;case 39:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?-1:+1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M")}break;case 40:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,+7,"D")}handled=event.ctrlKey||event.metaKey;break;default:handled=false}}else{if(event.keyCode==36&&event.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){event.preventDefault();event.stopPropagation()}},_doKeyPress:function(event){var inst=$.datepicker._getInst(event.target);if($.datepicker._get(inst,"constrainInput")){var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(event.charCode==undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return}var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};var self=this;inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).bind("mouseover",function(){if(!self._isDisabledDatepicker(inst.inline?inst.dpDiv.parent()[0]:inst.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();var numMonths=this._getNumberOfMonths(inst);var cols=numMonths[1];var width=17;if(cols>1){inst.dpDiv.addClass("ui-datepicker-multi-"+cols).css("width",(width*cols)+"em")}else{inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("")}inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var dpWidth=inst.dpDiv.outerWidth();var dpHeight=inst.dpDiv.outerHeight();var inputWidth=inst.input?inst.input.outerWidth():0;var inputHeight=inst.input?inst.input.outerHeight():0;var viewWidth=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)+$(document).scrollLeft();var viewHeight=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)+$(document).scrollTop();offset.left-=(this._get(inst,"isRTL")?(dpWidth-inputWidth):0);offset.left-=(isFixed&&offset.left==inst.input.offset().left)?$(document).scrollLeft():0;offset.top-=(isFixed&&offset.top==(inst.input.offset().top+inputHeight))?$(document).scrollTop():0;offset.left-=(offset.left+dpWidth>viewWidth&&viewWidth>dpWidth)?Math.abs(offset.left+dpWidth-viewWidth):0;offset.top-=(offset.top+dpHeight>viewHeight&&viewHeight>dpHeight)?Math.abs(offset.top+dpHeight+inputHeight*2-viewHeight):0;return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return}if(inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(event){if(!$.datepicker._curInst){return}var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);if(this._isDisabledDatepicker(target[0])){return}this._adjustInstDate(inst,offset+(period=="M"?this._get(inst,"showCurrentAtPos"):0),period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_selectDay:function(id,month,year,td){var target=$(id);if($(td).hasClass(this._unselectableClass)||this._isDisabledDatepicker(target[0])){return}var inst=this._getInst(target[0]);inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof(inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=this.formatDate(altFormat,date,this._getFormatConfig(inst));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year==-1){year=new Date().getFullYear()}else{if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val():null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);var settings=this._getFormatConfig(inst);try{date=this.parseDate(dateFormat,dates,settings)||defaultDate}catch(event){this.log(event);date=defaultDate}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates?date.getDate():0);inst.currentMonth=(dates?date.getMonth():0);inst.currentYear=(dates?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return startDate},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var isRTL=this._get(inst,"isRTL");var showButtonPanel=this._get(inst,"showButtonPanel");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(this._daylightSavingAdjust(new Date(drawYear,drawMonth,1))>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}inst.drawMonth=drawMonth;inst.drawYear=drawYear;var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prev=(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', -"+stepMonths+", 'M');\" title=\""+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>"));var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var next=(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', +"+stepMonths+", 'M');\" title=\""+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>"));var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var controls=(!inst.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">'+this._get(inst,"closeText")+"</button>":"");var buttonPanel=(showButtonPanel)?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(isRTL?controls:"")+(this._isInRange(inst,gotoDate)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#'+inst.id+"');\">"+currentText+"</button>":"")+(isRTL?"":controls)+"</div>":"";var firstDay=parseInt(this._get(inst,"firstDay"),10);firstDay=(isNaN(firstDay)?0:firstDay);var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var monthNamesShort=this._get(inst,"monthNamesShort");var beforeShowDay=this._get(inst,"beforeShowDay");var showOtherMonths=this._get(inst,"showOtherMonths");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);var html="";for(var row=0;row<numMonths[0];row++){var group="";for(var col=0;col<numMonths[1];col++){var selectedDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,inst.selectedDay));var cornerClass=" ui-corner-all";var calender="";if(isMultiMonth){calender+='<div class="ui-datepicker-group ui-datepicker-group-';switch(col){case 0:calender+="first";cornerClass=" ui-corner-"+(isRTL?"right":"left");break;case numMonths[1]-1:calender+="last";cornerClass=" ui-corner-"+(isRTL?"left":"right");break;default:calender+="middle";cornerClass="";break}calender+='">'}calender+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+cornerClass+'">'+(/all|left/.test(cornerClass)&&row==0?(isRTL?next:prev):"")+(/all|right/.test(cornerClass)&&row==0?(isRTL?prev:next):"")+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,monthNames,monthNamesShort)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var thead="";for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="<th"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+dayNames[day]+'">'+dayNamesMin[day]+"</span></th>"}calender+=thead+"</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow<numRows;dRow++){calender+="<tr>";var tbody="";for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);tbody+='<td class="'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end":"")+(otherMonth?" ui-datepicker-other-month":"")+((printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth&&inst._keyEvent)||(defaultDate.getTime()==printDate.getTime()&&defaultDate.getTime()==selectedDate.getTime())?" "+this._dayOverClass:"")+(unselectable?" "+this._unselectableClass+" ui-state-disabled":"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?"":" onclick=\"DP_jQuery.datepicker._selectDay('#"+inst.id+"',"+drawMonth+","+drawYear+', this);return false;"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():" "):(unselectable?'<span class="ui-state-default">'+printDate.getDate()+"</span>":'<a class="ui-state-default'+(printDate.getTime()==today.getTime()?" ui-state-highlight":"")+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" ui-state-active":"")+'" href="#">'+printDate.getDate()+"</a>"))+"</td>";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+"</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="</tbody></table>"+(isMultiMonth?"</div>"+((numMonths[0]>0&&col==numMonths[1]-1)?'<div class="ui-datepicker-row-break"></div>':""):"");group+=calender}html+=group}html+=buttonPanel+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-title">';var monthHtml="";if(secondary||!changeMonth){monthHtml+='<span class="ui-datepicker-month">'+monthNames[drawMonth]+"</span> "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-month" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNamesShort[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?" ":"")}if(secondary||!changeYear){html+='<span class="ui-datepicker-year">'+drawYear+"</span>"}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-year" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?" ":"")+monthHtml}html+="</div>";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);(function(c){var b={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"},a="ui-dialog ui-widget ui-widget-content ui-corner-all ";c.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");var l=this,m=this.options,j=m.title||this.originalTitle||" ",e=c.ui.dialog.getTitleId(this.element),k=(this.uiDialog=c("<div/>")).appendTo(document.body).hide().addClass(a+m.dialogClass).css({position:"absolute",overflow:"hidden",zIndex:m.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){(m.closeOnEscape&&n.keyCode&&n.keyCode==c.ui.keyCode.ESCAPE&&l.close(n))}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(n){l.moveToTop(false,n)}),g=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(k),f=(this.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(k),i=c('<a href="#"/>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){i.addClass("ui-state-hover")},function(){i.removeClass("ui-state-hover")}).focus(function(){i.addClass("ui-state-focus")}).blur(function(){i.removeClass("ui-state-focus")}).mousedown(function(n){n.stopPropagation()}).click(function(n){l.close(n);return false}).appendTo(f),h=(this.uiDialogTitlebarCloseText=c("<span/>")).addClass("ui-icon ui-icon-closethick").text(m.closeText).appendTo(i),d=c("<span/>").addClass("ui-dialog-title").attr("id",e).html(j).prependTo(f);f.find("*").add(f).disableSelection();(m.draggable&&c.fn.draggable&&this._makeDraggable());(m.resizable&&c.fn.resizable&&this._makeResizable());this._createButtons(m.buttons);this._isOpen=false;(m.bgiframe&&c.fn.bgiframe&&k.bgiframe());(m.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(f){var d=this;if(false===d._trigger("beforeclose",f)){return}(d.overlay&&d.overlay.destroy());d.uiDialog.unbind("keypress.ui-dialog");(d.options.hide?d.uiDialog.hide(d.options.hide,function(){d._trigger("close",f)}):d.uiDialog.hide()&&d._trigger("close",f));c.ui.dialog.overlay.resize();d._isOpen=false;if(d.options.modal){var e=0;c(".ui-dialog").each(function(){if(this!=d.uiDialog[0]){e=Math.max(e,c(this).css("z-index"))}});c.ui.dialog.maxZ=e}},isOpen:function(){return this._isOpen},moveToTop:function(f,e){if((this.options.modal&&!f)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",e)}if(this.options.zIndex>c.ui.dialog.maxZ){c.ui.dialog.maxZ=this.options.zIndex}(this.overlay&&this.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=++c.ui.dialog.maxZ));var d={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++c.ui.dialog.maxZ);this.element.attr(d);this._trigger("focus",e)},open:function(){if(this._isOpen){return}var e=this.options,d=this.uiDialog;this.overlay=e.modal?new c.ui.dialog.overlay(this):null;(d.next().length&&d.appendTo("body"));this._size();this._position(e.position);d.show(e.show);this.moveToTop(true);(e.modal&&d.bind("keypress.ui-dialog",function(h){if(h.keyCode!=c.ui.keyCode.TAB){return}var g=c(":tabbable",this),i=g.filter(":first")[0],f=g.filter(":last")[0];if(h.target==f&&!h.shiftKey){setTimeout(function(){i.focus()},1)}else{if(h.target==i&&h.shiftKey){setTimeout(function(){f.focus()},1)}}}));c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();this._trigger("open");this._isOpen=true},_createButtons:function(g){var f=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");this.uiDialog.find(".ui-dialog-buttonpane").remove();(typeof g=="object"&&g!==null&&c.each(g,function(){return !(d=true)}));if(d){c.each(g,function(h,i){c('<button type="button"></button>').addClass("ui-state-default ui-corner-all").text(h).click(function(){i.apply(f.element[0],arguments)}).hover(function(){c(this).addClass("ui-state-hover")},function(){c(this).removeClass("ui-state-hover")}).focus(function(){c(this).addClass("ui-state-focus")}).blur(function(){c(this).removeClass("ui-state-focus")}).appendTo(e)});e.appendTo(this.uiDialog)}},_makeDraggable:function(){var d=this,f=this.options,e;this.uiDialog.draggable({cancel:".ui-dialog-content",handle:".ui-dialog-titlebar",containment:"document",start:function(){e=f.height;c(this).height(c(this).height()).addClass("ui-dialog-dragging");(f.dragStart&&f.dragStart.apply(d.element[0],arguments))},drag:function(){(f.drag&&f.drag.apply(d.element[0],arguments))},stop:function(){c(this).removeClass("ui-dialog-dragging").height(e);(f.dragStop&&f.dragStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}})},_makeResizable:function(g){g=(g===undefined?this.options.resizable:g);var d=this,f=this.options,e=typeof g=="string"?g:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",alsoResize:this.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:f.minHeight,start:function(){c(this).addClass("ui-dialog-resizing");(f.resizeStart&&f.resizeStart.apply(d.element[0],arguments))},resize:function(){(f.resize&&f.resize.apply(d.element[0],arguments))},handles:e,stop:function(){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();(f.resizeStop&&f.resizeStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}}).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_position:function(i){var e=c(window),f=c(document),g=f.scrollTop(),d=f.scrollLeft(),h=g;if(c.inArray(i,["center","top","right","bottom","left"])>=0){i=[i=="right"||i=="left"?i:"center",i=="top"||i=="bottom"?i:"middle"]}if(i.constructor!=Array){i=["center","middle"]}if(i[0].constructor==Number){d+=i[0]}else{switch(i[0]){case"left":d+=0;break;case"right":d+=e.width()-this.uiDialog.outerWidth();break;default:case"center":d+=(e.width()-this.uiDialog.outerWidth())/2}}if(i[1].constructor==Number){g+=i[1]}else{switch(i[1]){case"top":g+=0;break;case"bottom":g+=e.height()-this.uiDialog.outerHeight();break;default:case"middle":g+=(e.height()-this.uiDialog.outerHeight())/2}}g=Math.max(g,h);this.uiDialog.css({top:g,left:d})},_setData:function(e,f){(b[e]&&this.uiDialog.data(b[e],f));switch(e){case"buttons":this._createButtons(f);break;case"closeText":this.uiDialogTitlebarCloseText.text(f);break;case"dialogClass":this.uiDialog.removeClass(this.options.dialogClass).addClass(a+f);break;case"draggable":(f?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(f);break;case"position":this._position(f);break;case"resizable":var d=this.uiDialog,g=this.uiDialog.is(":data(resizable)");(g&&!f&&d.resizable("destroy"));(g&&typeof f=="string"&&d.resizable("option","handles",f));(g||this._makeResizable(f));break;case"title":c(".ui-dialog-title",this.uiDialogTitlebar).html(f||" ");break;case"width":this.uiDialog.width(f);break}c.widget.prototype._setData.apply(this,arguments)},_size:function(){var e=this.options;this.element.css({height:0,minHeight:0,width:"auto"});var d=this.uiDialog.css({height:"auto",width:e.width}).height();this.element.css({minHeight:Math.max(e.minHeight-d,0),height:e.height=="auto"?"auto":Math.max(e.height-d,0)})}});c.extend(c.ui.dialog,{version:"1.7.2",defaults:{autoOpen:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1000},getter:"isOpen",uuid:0,maxZ:0,getTitleId:function(d){return"ui-dialog-title-"+(d.attr("id")||++this.uuid)},overlay:function(d){this.$el=c.ui.dialog.overlay.create(d)}});c.extend(c.ui.dialog.overlay,{instances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(d){return d+".dialog-overlay"}).join(" "),create:function(e){if(this.instances.length===0){setTimeout(function(){if(c.ui.dialog.overlay.instances.length){c(document).bind(c.ui.dialog.overlay.events,function(f){var g=c(f.target).parents(".ui-dialog").css("zIndex")||0;return(g>c.ui.dialog.overlay.maxZ)})}},1);c(document).bind("keydown.dialog-overlay",function(f){(e.options.closeOnEscape&&f.keyCode&&f.keyCode==c.ui.keyCode.ESCAPE&&e.close(f))});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var d=c("<div></div>").appendTo(document.body).addClass("ui-widget-overlay").css({width:this.width(),height:this.height()});(e.options.bgiframe&&c.fn.bgiframe&&d.bgiframe());this.instances.push(d);return d},destroy:function(d){this.instances.splice(c.inArray(this.instances,d),1);if(this.instances.length===0){c([document,window]).unbind(".dialog-overlay")}d.remove();var e=0;c.each(this.instances,function(){e=Math.max(e,this.css("z-index"))});this.maxZ=e},height:function(){if(c.browser.msie&&c.browser.version<7){var e=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var d=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(e<d){return c(window).height()+"px"}else{return e+"px"}}else{return c(document).height()+"px"}},width:function(){if(c.browser.msie&&c.browser.version<7){var d=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var e=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(d<e){return c(window).width()+"px"}else{return d+"px"}}else{return c(document).width()+"px"}},resize:function(){var d=c([]);c.each(c.ui.dialog.overlay.instances,function(){d=d.add(this)});d.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('<div class="ui-progressbar-value ui-widget-header ui-corner-left"></div>').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);(function(a){a.widget("ui.slider",a.extend({},a.ui.mouse,{_init:function(){var b=this,c=this.options;this._keySliding=false;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");this.range=a([]);if(c.range){if(c.range===true){this.range=a("<div></div>");if(!c.values){c.values=[this._valueMin(),this._valueMin()]}if(c.values.length&&c.values.length!=2){c.values=[c.values[0],c.values[0]]}}else{this.range=a("<div></div>")}this.range.appendTo(this.element).addClass("ui-slider-range");if(c.range=="min"||c.range=="max"){this.range.addClass("ui-slider-range-"+c.range)}this.range.addClass("ui-widget-header")}if(a(".ui-slider-handle",this.element).length==0){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}if(c.values&&c.values.length){while(a(".ui-slider-handle",this.element).length<c.values.length){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}}this.handles=a(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(d){d.preventDefault()}).hover(function(){if(!c.disabled){a(this).addClass("ui-state-hover")}},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(!c.disabled){a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}else{a(this).blur()}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(d){a(this).data("index.ui-slider-handle",d)});this.handles.keydown(function(i){var f=true;var e=a(this).data("index.ui-slider-handle");if(b.options.disabled){return}switch(i.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!b._keySliding){b._keySliding=true;a(this).addClass("ui-state-active");b._start(i,e)}break}var g,d,h=b._step();if(b.options.values&&b.options.values.length){g=d=b.values(e)}else{g=d=b.value()}switch(i.keyCode){case a.ui.keyCode.HOME:d=b._valueMin();break;case a.ui.keyCode.END:d=b._valueMax();break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g==b._valueMax()){return}d=g+h;break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g==b._valueMin()){return}d=g-h;break}b._slide(i,e,d);return f}).keyup(function(e){var d=a(this).data("index.ui-slider-handle");if(b._keySliding){b._stop(e,d);b._change(e,d);b._keySliding=false;a(this).removeClass("ui-state-active")}});this._refreshValue()},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy()},_mouseCapture:function(d){var e=this.options;if(e.disabled){return false}this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();var h={x:d.pageX,y:d.pageY};var j=this._normValueFromMouse(h);var c=this._valueMax()-this._valueMin()+1,f;var k=this,i;this.handles.each(function(l){var m=Math.abs(j-k.values(l));if(c>m){c=m;f=a(this);i=l}});if(e.range==true&&this.values(1)==e.min){f=a(this.handles[++i])}this._start(d,i);k._handleIndex=i;f.addClass("ui-state-active").focus();var g=f.offset();var b=!a(d.target).parents().andSelf().is(".ui-slider-handle");this._clickOffset=b?{left:0,top:0}:{left:d.pageX-g.left-(f.width()/2),top:d.pageY-g.top-(f.height()/2)-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};j=this._normValueFromMouse(h);this._slide(d,i,j);return true},_mouseStart:function(b){return true},_mouseDrag:function(d){var b={x:d.pageX,y:d.pageY};var c=this._normValueFromMouse(b);this._slide(d,this._handleIndex,c);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._handleIndex=null;this._clickOffset=null;return false},_detectOrientation:function(){this.orientation=this.options.orientation=="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c,h;if("horizontal"==this.orientation){c=this.elementSize.width;h=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;h=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}var f=(h/c);if(f>1){f=1}if(f<0){f=0}if("vertical"==this.orientation){f=1-f}var e=this._valueMax()-this._valueMin(),i=f*e,b=i%this.options.step,g=this._valueMin()+i-b;if(b>(this.options.step/2)){g+=this.options.step}return parseFloat(g.toFixed(5))},_start:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("start",d,b)},_slide:function(f,e,d){var g=this.handles[e];if(this.options.values&&this.options.values.length){var b=this.values(e?0:1);if((this.options.values.length==2&&this.options.range===true)&&((e==0&&d>b)||(e==1&&d<b))){d=b}if(d!=this.values(e)){var c=this.values();c[e]=d;var h=this._trigger("slide",f,{handle:this.handles[e],value:d,values:c});var b=this.values(e?0:1);if(h!==false){this.values(e,d,(f.type=="mousedown"&&this.options.animate),true)}}}else{if(d!=this.value()){var h=this._trigger("slide",f,{handle:this.handles[e],value:d});if(h!==false){this._setData("value",d,(f.type=="mousedown"&&this.options.animate))}}}},_stop:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("stop",d,b)},_change:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("change",d,b)},value:function(b){if(arguments.length){this._setData("value",b);this._change(null,0)}return this._value()},values:function(b,e,c,d){if(arguments.length>1){this.options.values[b]=e;this._refreshValue(c);if(!d){this._change(null,b)}}if(arguments.length){if(this.options.values&&this.options.values.length){return this._values(b)}else{return this.value()}}else{return this._values()}},_setData:function(b,d,c){a.widget.prototype._setData.apply(this,arguments);switch(b){case"disabled":if(d){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled")}else{this.handles.removeAttr("disabled")}case"orientation":this._detectOrientation();this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue(c);break;case"value":this._refreshValue(c);break}},_step:function(){var b=this.options.step;return b},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_values:function(b){if(arguments.length){var c=this.options.values[b];if(c<this._valueMin()){c=this._valueMin()}if(c>this._valueMax()){c=this._valueMax()}return c}else{return this.options.values}},_valueMin:function(){var b=this.options.min;return b},_valueMax:function(){var b=this.options.max;return b},_refreshValue:function(c){var f=this.options.range,d=this.options,l=this;if(this.options.values&&this.options.values.length){var i,h;this.handles.each(function(p,n){var o=(l.values(p)-l._valueMin())/(l._valueMax()-l._valueMin())*100;var m={};m[l.orientation=="horizontal"?"left":"bottom"]=o+"%";a(this).stop(1,1)[c?"animate":"css"](m,d.animate);if(l.options.range===true){if(l.orientation=="horizontal"){(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({left:o+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({width:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}else{(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({bottom:(o)+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({height:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}}lastValPercent=o})}else{var j=this.value(),g=this._valueMin(),k=this._valueMax(),e=k!=g?(j-g)/(k-g)*100:0;var b={};b[l.orientation=="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[c?"animate":"css"](b,d.animate);(f=="min")&&(this.orientation=="horizontal")&&this.range.stop(1,1)[c?"animate":"css"]({width:e+"%"},d.animate);(f=="max")&&(this.orientation=="horizontal")&&this.range[c?"animate":"css"]({width:(100-e)+"%"},{queue:false,duration:d.animate});(f=="min")&&(this.orientation=="vertical")&&this.range.stop(1,1)[c?"animate":"css"]({height:e+"%"},d.animate);(f=="max")&&(this.orientation=="vertical")&&this.range[c?"animate":"css"]({height:(100-e)+"%"},{queue:false,duration:d.animate})}}}));a.extend(a.ui.slider,{getter:"value values",version:"1.7.2",eventPrefix:"slide",defaults:{animate:false,delay:0,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null}})})(jQuery);(function(a){a.widget("ui.tabs",{_init:function(){if(this.options.deselectable!==undefined){this.options.collapsible=this.options.deselectable}this._tabify(true)},_setData:function(b,c){if(b=="selected"){if(this.options.collapsible&&c==this.options.selected){return}this.select(c)}else{this.options[b]=c;if(b=="deselectable"){this.options.collapsible=c}this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+a.data(b)},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+a.data(this.list[0]));return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(c,b){return{tab:c,panel:b,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(n){this.list=this.element.children("ul:first");this.lis=a("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);var p=this,d=this.options;var c=/^#.+/;this.anchors.each(function(r,o){var q=a(o).attr("href");var s=q.split("#")[0],u;if(s&&(s===location.toString().split("#")[0]||(u=a("base")[0])&&s===u.href)){q=o.hash;o.href=q}if(c.test(q)){p.panels=p.panels.add(p._sanitizeSelector(q))}else{if(q!="#"){a.data(o,"href.tabs",q);a.data(o,"load.tabs",q.replace(/#.*$/,""));var w=p._tabId(o);o.href="#"+w;var v=a("#"+w);if(!v.length){v=a(d.panelTemplate).attr("id",w).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(p.panels[r-1]||p.list);v.data("destroy.tabs",true)}p.panels=p.panels.add(v)}else{d.disabled.push(r)}}});if(n){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(d.selected===undefined){if(location.hash){this.anchors.each(function(q,o){if(o.hash==location.hash){d.selected=q;return false}})}if(typeof d.selected!="number"&&d.cookie){d.selected=parseInt(p._cookie(),10)}if(typeof d.selected!="number"&&this.lis.filter(".ui-tabs-selected").length){d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}d.selected=d.selected||0}else{if(d.selected===null){d.selected=-1}}d.selected=((d.selected>=0&&this.anchors[d.selected])||d.selected<0)?d.selected:0;d.disabled=a.unique(d.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(q,o){return p.lis.index(q)}))).sort();if(a.inArray(d.selected,d.disabled)!=-1){d.disabled.splice(a.inArray(d.selected,d.disabled),1)}this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(d.selected>=0&&this.anchors.length){this.panels.eq(d.selected).removeClass("ui-tabs-hide");this.lis.eq(d.selected).addClass("ui-tabs-selected ui-state-active");p.element.queue("tabs",function(){p._trigger("show",null,p._ui(p.anchors[d.selected],p.panels[d.selected]))});this.load(d.selected)}a(window).bind("unload",function(){p.lis.add(p.anchors).unbind(".tabs");p.lis=p.anchors=p.panels=null})}else{d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}this.element[d.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");if(d.cookie){this._cookie(d.selected,d.cookie)}for(var g=0,m;(m=this.lis[g]);g++){a(m)[a.inArray(g,d.disabled)!=-1&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled")}if(d.cache===false){this.anchors.removeData("cache.tabs")}this.lis.add(this.anchors).unbind(".tabs");if(d.event!="mouseover"){var f=function(o,i){if(i.is(":not(.ui-state-disabled)")){i.addClass("ui-state-"+o)}};var j=function(o,i){i.removeClass("ui-state-"+o)};this.lis.bind("mouseover.tabs",function(){f("hover",a(this))});this.lis.bind("mouseout.tabs",function(){j("hover",a(this))});this.anchors.bind("focus.tabs",function(){f("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var b,h;if(d.fx){if(a.isArray(d.fx)){b=d.fx[0];h=d.fx[1]}else{b=h=d.fx}}function e(i,o){i.css({display:""});if(a.browser.msie&&o.opacity){i[0].style.removeAttribute("filter")}}var k=h?function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.hide().removeClass("ui-tabs-hide").animate(h,h.duration||"normal",function(){e(o,h);p._trigger("show",null,p._ui(i,o[0]))})}:function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");p._trigger("show",null,p._ui(i,o[0]))};var l=b?function(o,i){i.animate(b,b.duration||"normal",function(){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");e(i,b);p.element.dequeue("tabs")})}:function(o,i,q){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");p.element.dequeue("tabs")};this.anchors.bind(d.event+".tabs",function(){var o=this,r=a(this).closest("li"),i=p.panels.filter(":not(.ui-tabs-hide)"),q=a(p._sanitizeSelector(this.hash));if((r.hasClass("ui-tabs-selected")&&!d.collapsible)||r.hasClass("ui-state-disabled")||r.hasClass("ui-state-processing")||p._trigger("select",null,p._ui(this,q[0]))===false){this.blur();return false}d.selected=p.anchors.index(this);p.abort();if(d.collapsible){if(r.hasClass("ui-tabs-selected")){d.selected=-1;if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){l(o,i)}).dequeue("tabs");this.blur();return false}else{if(!i.length){if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this));this.blur();return false}}}if(d.cookie){p._cookie(d.selected,d.cookie)}if(q.length){if(i.length){p.element.queue("tabs",function(){l(o,i)})}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this))}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(a.browser.msie){this.blur()}});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var c=a.data(this,"href.tabs");if(c){this.href=c}var d=a(this).unbind(".tabs");a.each(["href","load","cache"],function(e,f){d.removeData(f+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){if(a.data(this,"destroy.tabs")){a(this).remove()}else{a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}});if(b.cookie){this._cookie(null,b.cookie)}},add:function(e,d,c){if(c===undefined){c=this.anchors.length}var b=this,g=this.options,i=a(g.tabTemplate.replace(/#\{href\}/g,e).replace(/#\{label\}/g,d)),h=!e.indexOf("#")?e.replace("#",""):this._tabId(a("a",i)[0]);i.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var f=a("#"+h);if(!f.length){f=a(g.panelTemplate).attr("id",h).data("destroy.tabs",true)}f.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(c>=this.lis.length){i.appendTo(this.list);f.appendTo(this.list[0].parentNode)}else{i.insertBefore(this.lis[c]);f.insertBefore(this.panels[c])}g.disabled=a.map(g.disabled,function(k,j){return k>=c?++k:k});this._tabify();if(this.anchors.length==1){i.addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[c],this.panels[c]))},remove:function(b){var d=this.options,e=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();if(e.hasClass("ui-tabs-selected")&&this.anchors.length>1){this.select(b+(b+1<this.anchors.length?1:-1))}d.disabled=a.map(a.grep(d.disabled,function(g,f){return g!=b}),function(g,f){return g>=b?--g:g});this._tabify();this._trigger("remove",null,this._ui(e.find("a")[0],c[0]))},enable:function(b){var c=this.options;if(a.inArray(b,c.disabled)==-1){return}this.lis.eq(b).removeClass("ui-state-disabled");c.disabled=a.grep(c.disabled,function(e,d){return e!=b});this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]))},disable:function(c){var b=this,d=this.options;if(c!=d.selected){this.lis.eq(c).addClass("ui-state-disabled");d.disabled.push(c);d.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}},select:function(b){if(typeof b=="string"){b=this.anchors.index(this.anchors.filter("[href$="+b+"]"))}else{if(b===null){b=-1}}if(b==-1&&this.options.collapsible){b=this.options.selected}this.anchors.eq(b).trigger(this.options.event+".tabs")},load:function(e){var c=this,g=this.options,b=this.anchors.eq(e)[0],d=a.data(b,"load.tabs");this.abort();if(!d||this.element.queue("tabs").length!==0&&a.data(b,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(e).addClass("ui-state-processing");if(g.spinner){var f=a("span",b);f.data("label.tabs",f.html()).html(g.spinner)}this.xhr=a.ajax(a.extend({},g.ajaxOptions,{url:d,success:function(i,h){a(c._sanitizeSelector(b.hash)).html(i);c._cleanup();if(g.cache){a.data(b,"cache.tabs",true)}c._trigger("load",null,c._ui(c.anchors[e],c.panels[e]));try{g.ajaxOptions.success(i,h)}catch(j){}c.element.dequeue("tabs")}}))},abort:function(){this.element.queue([]);this.panels.stop(false,true);if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup()},url:function(c,b){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",b)},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.7.2",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,collapsible:false,disabled:[],event:"click",fx:null,idPrefix:"ui-tabs-",panelTemplate:"<div></div>",spinner:"<em>Loading…</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'}});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(d,f){var b=this,g=this.options;var c=b._rotate||(b._rotate=function(h){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var i=g.selected;b.select(++i<b.anchors.length?i:0)},d);if(h){h.stopPropagation()}});var e=b._unrotate||(b._unrotate=!f?function(h){if(h.clientX){b.rotate(null)}}:function(h){t=g.selected;c()});if(d){this.element.bind("tabsshow",c);this.anchors.bind(g.event+".tabs",e);c()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",c);this.anchors.unbind(g.event+".tabs",e);delete this._rotate;delete this._unrotate}}})})(jQuery);
637.14 \ No newline at end of file
638.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
638.2 +++ b/web/static/js/jquery.dataTables.min.js Mon Apr 26 11:16:23 2010 +0200
638.3 @@ -0,0 +1,568 @@
638.4 +/*
638.5 + * File: jquery.dataTables.min.js
638.6 + * Version: 1.6.0
638.7 + * Author: Allan Jardine (www.sprymedia.co.uk)
638.8 + * Info: www.datatables.net
638.9 + *
638.10 + * Copyright 2008-2010 Allan Jardine, all rights reserved.
638.11 + *
638.12 + * This source file is free software, under either the GPL v2 license or a
638.13 + * BSD style license, as supplied with this software.
638.14 + *
638.15 + * This source file is distributed in the hope that it will be useful, but
638.16 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
638.17 + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
638.18 + */
638.19 +(function($){$.fn.dataTableSettings=[];var _aoSettings=$.fn.dataTableSettings;$.fn.dataTableExt={};
638.20 +var _oExt=$.fn.dataTableExt;_oExt.sVersion="1.6.0";_oExt.iApiIndex=0;_oExt.oApi={};
638.21 +_oExt.afnFiltering=[];_oExt.aoFeatures=[];_oExt.ofnSearch={};_oExt.afnSortData=[];
638.22 +_oExt.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",sPageButtonStaticDisabled:"paginate_button",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:""};
638.23 +_oExt.oJUIClasses={sPagePrevEnabled:"fg-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-state-default",sPageButtonActive:"fg-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset fg-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s"};
638.24 +_oExt.oPagination={two_button:{fnInit:function(oSettings,nPaging,fnCallbackDraw){var nPrevious,nNext,nPreviousInner,nNextInner;
638.25 +if(!oSettings.bJUI){nPrevious=document.createElement("div");nNext=document.createElement("div")
638.26 +}else{nPrevious=document.createElement("a");nNext=document.createElement("a");nNextInner=document.createElement("span");
638.27 +nNextInner.className=oSettings.oClasses.sPageJUINext;nNext.appendChild(nNextInner);
638.28 +nPreviousInner=document.createElement("span");nPreviousInner.className=oSettings.oClasses.sPageJUIPrev;
638.29 +nPrevious.appendChild(nPreviousInner)}nPrevious.className=oSettings.oClasses.sPagePrevDisabled;
638.30 +nNext.className=oSettings.oClasses.sPageNextDisabled;nPrevious.title=oSettings.oLanguage.oPaginate.sPrevious;
638.31 +nNext.title=oSettings.oLanguage.oPaginate.sNext;nPaging.appendChild(nPrevious);nPaging.appendChild(nNext);
638.32 +$(nPrevious).click(function(){oSettings.oApi._fnPageChange(oSettings,"previous");
638.33 +fnCallbackDraw(oSettings)});$(nNext).click(function(){oSettings.oApi._fnPageChange(oSettings,"next");
638.34 +fnCallbackDraw(oSettings)});$(nPrevious).bind("selectstart",function(){return false
638.35 +});$(nNext).bind("selectstart",function(){return false});if(oSettings.sTableId!==""&&typeof oSettings.aanFeatures.p=="undefined"){nPaging.setAttribute("id",oSettings.sTableId+"_paginate");
638.36 +nPrevious.setAttribute("id",oSettings.sTableId+"_previous");nNext.setAttribute("id",oSettings.sTableId+"_next")
638.37 +}},fnUpdate:function(oSettings,fnCallbackDraw){if(!oSettings.aanFeatures.p){return
638.38 +}var an=oSettings.aanFeatures.p;for(var i=0,iLen=an.length;i<iLen;i++){if(an[i].childNodes.length!==0){an[i].childNodes[0].className=(oSettings._iDisplayStart===0)?oSettings.oClasses.sPagePrevDisabled:oSettings.oClasses.sPagePrevEnabled;
638.39 +an[i].childNodes[1].className=(oSettings.fnDisplayEnd()==oSettings.fnRecordsDisplay())?oSettings.oClasses.sPageNextDisabled:oSettings.oClasses.sPageNextEnabled
638.40 +}}}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(oSettings,nPaging,fnCallbackDraw){var nFirst=document.createElement("span");
638.41 +var nPrevious=document.createElement("span");var nList=document.createElement("span");
638.42 +var nNext=document.createElement("span");var nLast=document.createElement("span");
638.43 +nFirst.innerHTML=oSettings.oLanguage.oPaginate.sFirst;nPrevious.innerHTML=oSettings.oLanguage.oPaginate.sPrevious;
638.44 +nNext.innerHTML=oSettings.oLanguage.oPaginate.sNext;nLast.innerHTML=oSettings.oLanguage.oPaginate.sLast;
638.45 +var oClasses=oSettings.oClasses;nFirst.className=oClasses.sPageButton+" "+oClasses.sPageFirst;
638.46 +nPrevious.className=oClasses.sPageButton+" "+oClasses.sPagePrevious;nNext.className=oClasses.sPageButton+" "+oClasses.sPageNext;
638.47 +nLast.className=oClasses.sPageButton+" "+oClasses.sPageLast;nPaging.appendChild(nFirst);
638.48 +nPaging.appendChild(nPrevious);nPaging.appendChild(nList);nPaging.appendChild(nNext);
638.49 +nPaging.appendChild(nLast);$(nFirst).click(function(){oSettings.oApi._fnPageChange(oSettings,"first");
638.50 +fnCallbackDraw(oSettings)});$(nPrevious).click(function(){oSettings.oApi._fnPageChange(oSettings,"previous");
638.51 +fnCallbackDraw(oSettings)});$(nNext).click(function(){oSettings.oApi._fnPageChange(oSettings,"next");
638.52 +fnCallbackDraw(oSettings)});$(nLast).click(function(){oSettings.oApi._fnPageChange(oSettings,"last");
638.53 +fnCallbackDraw(oSettings)});$("span",nPaging).bind("mousedown",function(){return false
638.54 +}).bind("selectstart",function(){return false});if(oSettings.sTableId!==""&&typeof oSettings.aanFeatures.p=="undefined"){nPaging.setAttribute("id",oSettings.sTableId+"_paginate");
638.55 +nFirst.setAttribute("id",oSettings.sTableId+"_first");nPrevious.setAttribute("id",oSettings.sTableId+"_previous");
638.56 +nNext.setAttribute("id",oSettings.sTableId+"_next");nLast.setAttribute("id",oSettings.sTableId+"_last")
638.57 +}},fnUpdate:function(oSettings,fnCallbackDraw){if(!oSettings.aanFeatures.p){return
638.58 +}var iPageCount=_oExt.oPagination.iFullNumbersShowPages;var iPageCountHalf=Math.floor(iPageCount/2);
638.59 +var iPages=Math.ceil((oSettings.fnRecordsDisplay())/oSettings._iDisplayLength);var iCurrentPage=Math.ceil(oSettings._iDisplayStart/oSettings._iDisplayLength)+1;
638.60 +var sList="";var iStartButton,iEndButton,i,iLen;var oClasses=oSettings.oClasses;if(iPages<iPageCount){iStartButton=1;
638.61 +iEndButton=iPages}else{if(iCurrentPage<=iPageCountHalf){iStartButton=1;iEndButton=iPageCount
638.62 +}else{if(iCurrentPage>=(iPages-iPageCountHalf)){iStartButton=iPages-iPageCount+1;
638.63 +iEndButton=iPages}else{iStartButton=iCurrentPage-Math.ceil(iPageCount/2)+1;iEndButton=iStartButton+iPageCount-1
638.64 +}}}for(i=iStartButton;i<=iEndButton;i++){if(iCurrentPage!=i){sList+='<span class="'+oClasses.sPageButton+'">'+i+"</span>"
638.65 +}else{sList+='<span class="'+oClasses.sPageButtonActive+'">'+i+"</span>"}}var an=oSettings.aanFeatures.p;
638.66 +var anButtons,anStatic,nPaginateList;var fnClick=function(){var iTarget=(this.innerHTML*1)-1;
638.67 +oSettings._iDisplayStart=iTarget*oSettings._iDisplayLength;fnCallbackDraw(oSettings);
638.68 +return false};var fnFalse=function(){return false};for(i=0,iLen=an.length;i<iLen;
638.69 +i++){if(an[i].childNodes.length===0){continue}nPaginateList=an[i].childNodes[2];nPaginateList.innerHTML=sList;
638.70 +$("span",nPaginateList).click(fnClick).bind("mousedown",fnFalse).bind("selectstart",fnFalse);
638.71 +anButtons=an[i].getElementsByTagName("span");anStatic=[anButtons[0],anButtons[1],anButtons[anButtons.length-2],anButtons[anButtons.length-1]];
638.72 +$(anStatic).removeClass(oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled);
638.73 +if(iCurrentPage==1){anStatic[0].className+=" "+oClasses.sPageButtonStaticDisabled;
638.74 +anStatic[1].className+=" "+oClasses.sPageButtonStaticDisabled}else{anStatic[0].className+=" "+oClasses.sPageButton;
638.75 +anStatic[1].className+=" "+oClasses.sPageButton}if(iCurrentPage==iPages||oSettings._iDisplayLength==-1){anStatic[2].className+=" "+oClasses.sPageButtonStaticDisabled;
638.76 +anStatic[3].className+=" "+oClasses.sPageButtonStaticDisabled}else{anStatic[2].className+=" "+oClasses.sPageButton;
638.77 +anStatic[3].className+=" "+oClasses.sPageButton}}}}};_oExt.oSort={"string-asc":function(a,b){var x=a.toLowerCase();
638.78 +var y=b.toLowerCase();return((x<y)?-1:((x>y)?1:0))},"string-desc":function(a,b){var x=a.toLowerCase();
638.79 +var y=b.toLowerCase();return((x<y)?1:((x>y)?-1:0))},"html-asc":function(a,b){var x=a.replace(/<.*?>/g,"").toLowerCase();
638.80 +var y=b.replace(/<.*?>/g,"").toLowerCase();return((x<y)?-1:((x>y)?1:0))},"html-desc":function(a,b){var x=a.replace(/<.*?>/g,"").toLowerCase();
638.81 +var y=b.replace(/<.*?>/g,"").toLowerCase();return((x<y)?1:((x>y)?-1:0))},"date-asc":function(a,b){var x=Date.parse(a);
638.82 +var y=Date.parse(b);if(isNaN(x)){x=Date.parse("01/01/1970 00:00:00")}if(isNaN(y)){y=Date.parse("01/01/1970 00:00:00")
638.83 +}return x-y},"date-desc":function(a,b){var x=Date.parse(a);var y=Date.parse(b);if(isNaN(x)){x=Date.parse("01/01/1970 00:00:00")
638.84 +}if(isNaN(y)){y=Date.parse("01/01/1970 00:00:00")}return y-x},"numeric-asc":function(a,b){var x=a=="-"?0:a;
638.85 +var y=b=="-"?0:b;return x-y},"numeric-desc":function(a,b){var x=a=="-"?0:a;var y=b=="-"?0:b;
638.86 +return y-x}};_oExt.aTypes=[function(sData){if(typeof sData=="number"){return"numeric"
638.87 +}else{if(typeof sData.charAt!="function"){return null}}var sValidFirstChars="0123456789-";
638.88 +var sValidChars="0123456789.";var Char;var bDecimal=false;Char=sData.charAt(0);if(sValidFirstChars.indexOf(Char)==-1){return null
638.89 +}for(var i=1;i<sData.length;i++){Char=sData.charAt(i);if(sValidChars.indexOf(Char)==-1){return null
638.90 +}if(Char=="."){if(bDecimal){return null}bDecimal=true}}return"numeric"},function(sData){var iParse=Date.parse(sData);
638.91 +if(iParse!==null&&!isNaN(iParse)){return"date"}return null}];_oExt._oExternConfig={iNextUnique:0};
638.92 +$.fn.dataTable=function(oInit){function classSettings(){this.fnRecordsTotal=function(){if(this.oFeatures.bServerSide){return this._iRecordsTotal
638.93 +}else{return this.aiDisplayMaster.length}};this.fnRecordsDisplay=function(){if(this.oFeatures.bServerSide){return this._iRecordsDisplay
638.94 +}else{return this.aiDisplay.length}};this.fnDisplayEnd=function(){if(this.oFeatures.bServerSide){return this._iDisplayStart+this.aiDisplay.length
638.95 +}else{return this._iDisplayEnd}};this.sInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false};
638.96 +this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"}};
638.97 +this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.iNextId=0;
638.98 +this.asDataSearch=[];this.oPreviousSearch={sSearch:"",bEscapeRegex:true};this.aoPreSearchCols=[];
638.99 +this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripClasses=[];this.fnRowCallback=null;
638.100 +this.fnHeaderCallback=null;this.fnFooterCallback=null;this.aoDrawCallback=[];this.fnInitComplete=null;
638.101 +this.sTableId="";this.nTable=null;this.iDefaultSortIndex=0;this.bInitialised=false;
638.102 +this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType="two_button";this.iCookieDuration=60*60*2;
638.103 +this.sAjaxSource=null;this.bAjaxDataGet=true;this.fnServerData=$.getJSON;this.iServerDraw=0;
638.104 +this._iDisplayLength=10;this._iDisplayStart=0;this._iDisplayEnd=10;this._iRecordsTotal=0;
638.105 +this._iRecordsDisplay=0;this.bJUI=false;this.oClasses=_oExt.oStdClasses;this.bFiltered=false;
638.106 +this.bSorted=false}this.oApi={};this.fnDraw=function(bComplete){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.107 +if(typeof bComplete!="undefined"&&bComplete===false){_fnCalculateEnd(oSettings);_fnDraw(oSettings)
638.108 +}else{_fnReDraw(oSettings)}};this.fnFilter=function(sInput,iColumn,bEscapeRegex){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.109 +if(typeof bEscapeRegex=="undefined"){bEscapeRegex=true}if(typeof iColumn=="undefined"||iColumn===null){_fnFilterComplete(oSettings,{sSearch:sInput,bEscapeRegex:bEscapeRegex},1)
638.110 +}else{oSettings.aoPreSearchCols[iColumn].sSearch=sInput;oSettings.aoPreSearchCols[iColumn].bEscapeRegex=bEscapeRegex;
638.111 +_fnFilterComplete(oSettings,oSettings.oPreviousSearch,1)}};this.fnSettings=function(nNode){return _fnSettingsFromNode(this[_oExt.iApiIndex])
638.112 +};this.fnVersionCheck=function(sVersion){var fnZPad=function(Zpad,count){while(Zpad.length<count){Zpad+="0"
638.113 +}return Zpad};var aThis=_oExt.sVersion.split(".");var aThat=sVersion.split(".");var sThis="",sThat="";
638.114 +for(var i=0,iLen=aThat.length;i<iLen;i++){sThis+=fnZPad(aThis[i],3);sThat+=fnZPad(aThat[i],3)
638.115 +}return parseInt(sThis)>=parseInt(sThat)};this.fnSort=function(aaSort){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.116 +oSettings.aaSorting=aaSort;_fnSort(oSettings)};this.fnSortListener=function(nNode,iColumn,fnCallback){_fnSortAttachListener(_fnSettingsFromNode(this[_oExt.iApiIndex]),nNode,iColumn,fnCallback)
638.117 +};this.fnAddData=function(mData,bRedraw){if(mData.length===0){return[]}var aiReturn=[];
638.118 +var iTest;var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);if(typeof mData[0]=="object"){for(var i=0;
638.119 +i<mData.length;i++){iTest=_fnAddData(oSettings,mData[i]);if(iTest==-1){return aiReturn
638.120 +}aiReturn.push(iTest)}}else{iTest=_fnAddData(oSettings,mData);if(iTest==-1){return aiReturn
638.121 +}aiReturn.push(iTest)}oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();_fnBuildSearchArray(oSettings,1);
638.122 +if(typeof bRedraw=="undefined"||bRedraw){_fnReDraw(oSettings)}return aiReturn};this.fnDeleteRow=function(mTarget,fnCallBack,bNullRow){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.123 +var i,iAODataIndex;iAODataIndex=(typeof mTarget=="object")?_fnNodeToDataIndex(oSettings,mTarget):mTarget;
638.124 +for(i=0;i<oSettings.aiDisplayMaster.length;i++){if(oSettings.aiDisplayMaster[i]==iAODataIndex){oSettings.aiDisplayMaster.splice(i,1);
638.125 +break}}for(i=0;i<oSettings.aiDisplay.length;i++){if(oSettings.aiDisplay[i]==iAODataIndex){oSettings.aiDisplay.splice(i,1);
638.126 +break}}_fnBuildSearchArray(oSettings,1);if(typeof fnCallBack=="function"){fnCallBack.call(this)
638.127 +}if(oSettings._iDisplayStart>=oSettings.aiDisplay.length){oSettings._iDisplayStart-=oSettings._iDisplayLength;
638.128 +if(oSettings._iDisplayStart<0){oSettings._iDisplayStart=0}}_fnCalculateEnd(oSettings);
638.129 +_fnDraw(oSettings);var aData=oSettings.aoData[iAODataIndex]._aData.slice();if(typeof bNullRow!="undefined"&&bNullRow===true){oSettings.aoData[iAODataIndex]=null
638.130 +}return aData};this.fnClearTable=function(bRedraw){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.131 +_fnClearTable(oSettings);if(typeof bRedraw=="undefined"||bRedraw){_fnDraw(oSettings)
638.132 +}};this.fnOpen=function(nTr,sHtml,sClass){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.133 +this.fnClose(nTr);var nNewRow=document.createElement("tr");var nNewCell=document.createElement("td");
638.134 +nNewRow.appendChild(nNewCell);nNewCell.className=sClass;nNewCell.colSpan=_fnVisbleColumns(oSettings);
638.135 +nNewCell.innerHTML=sHtml;var nTrs=$("tbody tr",oSettings.nTable);if($.inArray(nTr,nTrs)!=-1){$(nNewRow).insertAfter(nTr)
638.136 +}if(!oSettings.oFeatures.bServerSide){oSettings.aoOpenRows.push({nTr:nNewRow,nParent:nTr})
638.137 +}};this.fnClose=function(nTr){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.138 +for(var i=0;i<oSettings.aoOpenRows.length;i++){if(oSettings.aoOpenRows[i].nParent==nTr){var nTrParent=oSettings.aoOpenRows[i].nTr.parentNode;
638.139 +if(nTrParent){nTrParent.removeChild(oSettings.aoOpenRows[i].nTr)}oSettings.aoOpenRows.splice(i,1);
638.140 +return 0}}return 1};this.fnGetData=function(mRow){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.141 +if(typeof mRow!="undefined"){var iRow=(typeof mRow=="object")?_fnNodeToDataIndex(oSettings,mRow):mRow;
638.142 +return oSettings.aoData[iRow]._aData}return _fnGetDataMaster(oSettings)};this.fnGetNodes=function(iRow){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.143 +if(typeof iRow!="undefined"){return oSettings.aoData[iRow].nTr}return _fnGetTrNodes(oSettings)
638.144 +};this.fnGetPosition=function(nNode){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.145 +var i;if(nNode.nodeName=="TR"){return _fnNodeToDataIndex(oSettings,nNode)}else{if(nNode.nodeName=="TD"){var iDataIndex=_fnNodeToDataIndex(oSettings,nNode.parentNode);
638.146 +var iCorrector=0;for(var j=0;j<oSettings.aoColumns.length;j++){if(oSettings.aoColumns[j].bVisible){if(oSettings.aoData[iDataIndex].nTr.getElementsByTagName("td")[j-iCorrector]==nNode){return[iDataIndex,j-iCorrector,j]
638.147 +}}else{iCorrector++}}}}return null};this.fnUpdate=function(mData,mRow,iColumn,bRedraw){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.148 +var iVisibleColumn;var sDisplay;var iRow=(typeof mRow=="object")?_fnNodeToDataIndex(oSettings,mRow):mRow;
638.149 +if(typeof mData!="object"){sDisplay=mData;oSettings.aoData[iRow]._aData[iColumn]=sDisplay;
638.150 +if(oSettings.aoColumns[iColumn].fnRender!==null){sDisplay=oSettings.aoColumns[iColumn].fnRender({iDataRow:iRow,iDataColumn:iColumn,aData:oSettings.aoData[iRow]._aData,oSettings:oSettings});
638.151 +if(oSettings.aoColumns[iColumn].bUseRendered){oSettings.aoData[iRow]._aData[iColumn]=sDisplay
638.152 +}}iVisibleColumn=_fnColumnIndexToVisible(oSettings,iColumn);if(iVisibleColumn!==null){oSettings.aoData[iRow].nTr.getElementsByTagName("td")[iVisibleColumn].innerHTML=sDisplay
638.153 +}}else{if(mData.length!=oSettings.aoColumns.length){alert("DataTables warning: An array passed to fnUpdate must have the same number of columns as the table in question - in this case "+oSettings.aoColumns.length);
638.154 +return 1}for(var i=0;i<mData.length;i++){sDisplay=mData[i];oSettings.aoData[iRow]._aData[i]=sDisplay;
638.155 +if(oSettings.aoColumns[i].fnRender!==null){sDisplay=oSettings.aoColumns[i].fnRender({iDataRow:iRow,iDataColumn:i,aData:oSettings.aoData[iRow]._aData,oSettings:oSettings});
638.156 +if(oSettings.aoColumns[i].bUseRendered){oSettings.aoData[iRow]._aData[i]=sDisplay
638.157 +}}iVisibleColumn=_fnColumnIndexToVisible(oSettings,i);if(iVisibleColumn!==null){oSettings.aoData[iRow].nTr.getElementsByTagName("td")[iVisibleColumn].innerHTML=sDisplay
638.158 +}}}_fnBuildSearchArray(oSettings,1);if(typeof bRedraw!="undefined"&&bRedraw){_fnReDraw(oSettings)
638.159 +}return 0};this.fnSetColumnVis=function(iCol,bShow){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.160 +var i,iLen;var iColumns=oSettings.aoColumns.length;var nTd;if(oSettings.aoColumns[iCol].bVisible==bShow){return
638.161 +}var nTrHead=$("thead:eq(0)>tr",oSettings.nTable)[0];var nTrFoot=$("tfoot:eq(0)>tr",oSettings.nTable)[0];
638.162 +var anTheadTh=[];var anTfootTh=[];for(i=0;i<iColumns;i++){anTheadTh.push(oSettings.aoColumns[i].nTh);
638.163 +anTfootTh.push(oSettings.aoColumns[i].nTf)}if(bShow){var iInsert=0;for(i=0;i<iCol;
638.164 +i++){if(oSettings.aoColumns[i].bVisible){iInsert++}}if(iInsert>=_fnVisbleColumns(oSettings)){nTrHead.appendChild(anTheadTh[iCol]);
638.165 +if(nTrFoot){nTrFoot.appendChild(anTfootTh[iCol])}for(i=0,iLen=oSettings.aoData.length;
638.166 +i<iLen;i++){nTd=oSettings.aoData[i]._anHidden[iCol];oSettings.aoData[i].nTr.appendChild(nTd)
638.167 +}}else{var iBefore;for(i=iCol;i<iColumns;i++){iBefore=_fnColumnIndexToVisible(oSettings,i);
638.168 +if(iBefore!==null){break}}nTrHead.insertBefore(anTheadTh[iCol],nTrHead.getElementsByTagName("th")[iBefore]);
638.169 +if(nTrFoot){nTrFoot.insertBefore(anTfootTh[iCol],nTrFoot.getElementsByTagName("th")[iBefore])
638.170 +}for(i=0,iLen=oSettings.aoData.length;i<iLen;i++){nTd=oSettings.aoData[i]._anHidden[iCol];
638.171 +oSettings.aoData[i].nTr.insertBefore(nTd,oSettings.aoData[i].nTr.getElementsByTagName("td")[iBefore])
638.172 +}}oSettings.aoColumns[iCol].bVisible=true}else{nTrHead.removeChild(anTheadTh[iCol]);
638.173 +if(nTrFoot){nTrFoot.removeChild(anTfootTh[iCol])}var iVisCol=_fnColumnIndexToVisible(oSettings,iCol);
638.174 +for(i=0,iLen=oSettings.aoData.length;i<iLen;i++){nTd=oSettings.aoData[i].nTr.getElementsByTagName("td")[iVisCol];
638.175 +oSettings.aoData[i]._anHidden[iCol]=nTd;nTd.parentNode.removeChild(nTd)}oSettings.aoColumns[iCol].bVisible=false
638.176 +}for(i=0,iLen=oSettings.aoOpenRows.length;i<iLen;i++){oSettings.aoOpenRows[i].nTr.colSpan=_fnVisbleColumns(oSettings)
638.177 +}_fnSaveState(oSettings)};this.fnPageChange=function(sAction,bRedraw){var oSettings=_fnSettingsFromNode(this[_oExt.iApiIndex]);
638.178 +_fnPageChange(oSettings,sAction);if(typeof bRedraw=="undefined"||bRedraw){_fnReDraw(oSettings)
638.179 +}};function _fnExternApiFunc(sFunc){return function(){var aArgs=[_fnSettingsFromNode(this[_oExt.iApiIndex])].concat(Array.prototype.slice.call(arguments));
638.180 +return _oExt.oApi[sFunc].apply(this,aArgs)}}for(var sFunc in _oExt.oApi){if(sFunc){this[sFunc]=_fnExternApiFunc(sFunc)
638.181 +}}function _fnInitalise(oSettings){if(oSettings.bInitialised===false){setTimeout(function(){_fnInitalise(oSettings)
638.182 +},200);return}_fnAddOptionsHtml(oSettings);_fnDrawHead(oSettings);if(oSettings.oFeatures.bSort){_fnSort(oSettings,false);
638.183 +_fnSortingClasses(oSettings)}else{oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();
638.184 +_fnCalculateEnd(oSettings);_fnDraw(oSettings)}if(oSettings.sAjaxSource!==null&&!oSettings.oFeatures.bServerSide){_fnProcessingDisplay(oSettings,true);
638.185 +oSettings.fnServerData(oSettings.sAjaxSource,null,function(json){for(var i=0;i<json.aaData.length;
638.186 +i++){_fnAddData(oSettings,json.aaData[i])}oSettings.iInitDisplayStart=oSettings._iDisplayStart;
638.187 +if(oSettings.oFeatures.bSort){_fnSort(oSettings)}else{oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();
638.188 +_fnCalculateEnd(oSettings);_fnDraw(oSettings)}_fnProcessingDisplay(oSettings,false);
638.189 +if(typeof oSettings.fnInitComplete=="function"){oSettings.fnInitComplete(oSettings,json)
638.190 +}});return}if(typeof oSettings.fnInitComplete=="function"){oSettings.fnInitComplete(oSettings)
638.191 +}if(!oSettings.oFeatures.bServerSide){_fnProcessingDisplay(oSettings,false)}}function _fnLanguageProcess(oSettings,oLanguage,bInit){_fnMap(oSettings.oLanguage,oLanguage,"sProcessing");
638.192 +_fnMap(oSettings.oLanguage,oLanguage,"sLengthMenu");_fnMap(oSettings.oLanguage,oLanguage,"sZeroRecords");
638.193 +_fnMap(oSettings.oLanguage,oLanguage,"sInfo");_fnMap(oSettings.oLanguage,oLanguage,"sInfoEmpty");
638.194 +_fnMap(oSettings.oLanguage,oLanguage,"sInfoFiltered");_fnMap(oSettings.oLanguage,oLanguage,"sInfoPostFix");
638.195 +_fnMap(oSettings.oLanguage,oLanguage,"sSearch");if(typeof oLanguage.oPaginate!="undefined"){_fnMap(oSettings.oLanguage.oPaginate,oLanguage.oPaginate,"sFirst");
638.196 +_fnMap(oSettings.oLanguage.oPaginate,oLanguage.oPaginate,"sPrevious");_fnMap(oSettings.oLanguage.oPaginate,oLanguage.oPaginate,"sNext");
638.197 +_fnMap(oSettings.oLanguage.oPaginate,oLanguage.oPaginate,"sLast")}if(bInit){_fnInitalise(oSettings)
638.198 +}}function _fnAddColumn(oSettings,oOptions,nTh){oSettings.aoColumns[oSettings.aoColumns.length++]={sType:null,_bAutoType:true,bVisible:true,bSearchable:true,bSortable:true,asSorting:["asc","desc"],sSortingClass:oSettings.oClasses.sSortable,sSortingClassJUI:oSettings.oClasses.sSortJUI,sTitle:nTh?nTh.innerHTML:"",sName:"",sWidth:null,sClass:null,fnRender:null,bUseRendered:true,iDataSort:oSettings.aoColumns.length-1,sSortDataType:"std",nTh:nTh?nTh:document.createElement("th"),nTf:null};
638.199 +var iLength=oSettings.aoColumns.length-1;var oCol=oSettings.aoColumns[iLength];if(typeof oOptions!="undefined"&&oOptions!==null){if(typeof oOptions.sType!="undefined"){oCol.sType=oOptions.sType;
638.200 +oCol._bAutoType=false}_fnMap(oCol,oOptions,"bVisible");_fnMap(oCol,oOptions,"bSearchable");
638.201 +_fnMap(oCol,oOptions,"bSortable");_fnMap(oCol,oOptions,"sTitle");_fnMap(oCol,oOptions,"sName");
638.202 +_fnMap(oCol,oOptions,"sWidth");_fnMap(oCol,oOptions,"sClass");_fnMap(oCol,oOptions,"fnRender");
638.203 +_fnMap(oCol,oOptions,"bUseRendered");_fnMap(oCol,oOptions,"iDataSort");_fnMap(oCol,oOptions,"asSorting");
638.204 +_fnMap(oCol,oOptions,"sSortDataType")}if(!oSettings.oFeatures.bSort){oCol.bSortable=false
638.205 +}if(!oCol.bSortable||($.inArray("asc",oCol.asSorting)==-1&&$.inArray("desc",oCol.asSorting)==-1)){oCol.sSortingClass=oSettings.oClasses.sSortableNone;
638.206 +oCol.sSortingClassJUI=""}else{if($.inArray("asc",oCol.asSorting)!=-1&&$.inArray("desc",oCol.asSorting)==-1){oCol.sSortingClass=oSettings.oClasses.sSortableAsc;
638.207 +oCol.sSortingClassJUI=oSettings.oClasses.sSortJUIAscAllowed}else{if($.inArray("asc",oCol.asSorting)==-1&&$.inArray("desc",oCol.asSorting)!=-1){oCol.sSortingClass=oSettings.oClasses.sSortableDesc;
638.208 +oCol.sSortingClassJUI=oSettings.oClasses.sSortJUIDescAllowed}}}if(typeof oSettings.aoPreSearchCols[iLength]=="undefined"||oSettings.aoPreSearchCols[iLength]===null){oSettings.aoPreSearchCols[iLength]={sSearch:"",bEscapeRegex:true}
638.209 +}else{if(typeof oSettings.aoPreSearchCols[iLength].bEscapeRegex=="undefined"){oSettings.aoPreSearchCols[iLength].bEscapeRegex=true
638.210 +}}}function _fnAddData(oSettings,aData){if(aData.length!=oSettings.aoColumns.length){alert("DataTables warning: Added data does not match known number of columns");
638.211 +return -1}var iThisIndex=oSettings.aoData.length;oSettings.aoData.push({nTr:document.createElement("tr"),_iId:oSettings.iNextId++,_aData:aData.slice(),_anHidden:[],_sRowStripe:""});
638.212 +var nTd;for(var i=0;i<aData.length;i++){nTd=document.createElement("td");if(typeof oSettings.aoColumns[i].fnRender=="function"){var sRendered=oSettings.aoColumns[i].fnRender({iDataRow:iThisIndex,iDataColumn:i,aData:aData,oSettings:oSettings});
638.213 +nTd.innerHTML=sRendered;if(oSettings.aoColumns[i].bUseRendered){oSettings.aoData[iThisIndex]._aData[i]=sRendered
638.214 +}}else{nTd.innerHTML=aData[i]}if(oSettings.aoColumns[i].sClass!==null){nTd.className=oSettings.aoColumns[i].sClass
638.215 +}if(oSettings.aoColumns[i]._bAutoType&&oSettings.aoColumns[i].sType!="string"){if(oSettings.aoColumns[i].sType===null){oSettings.aoColumns[i].sType=_fnDetectType(aData[i])
638.216 +}else{if(oSettings.aoColumns[i].sType=="date"||oSettings.aoColumns[i].sType=="numeric"){oSettings.aoColumns[i].sType=_fnDetectType(aData[i])
638.217 +}}}if(oSettings.aoColumns[i].bVisible){oSettings.aoData[iThisIndex].nTr.appendChild(nTd)
638.218 +}else{oSettings.aoData[iThisIndex]._anHidden[i]=nTd}}oSettings.aiDisplayMaster.push(iThisIndex);
638.219 +return iThisIndex}function _fnGatherData(oSettings){var iLoop;var i,j;if(oSettings.sAjaxSource===null){$("tbody:eq(0)>tr",oSettings.nTable).each(function(){var iThisIndex=oSettings.aoData.length;
638.220 +oSettings.aoData.push({nTr:this,_iId:oSettings.iNextId++,_aData:[],_anHidden:[],_sRowStripe:""});
638.221 +oSettings.aiDisplayMaster.push(iThisIndex);var aLocalData=oSettings.aoData[iThisIndex]._aData;
638.222 +$("td",this).each(function(i){aLocalData[i]=this.innerHTML})})}var iCorrector=0;for(i=0;
638.223 +i<oSettings.aoColumns.length;i++){if(oSettings.aoColumns[i].sTitle===null){oSettings.aoColumns[i].sTitle=oSettings.aoColumns[i].nTh.innerHTML
638.224 +}var bAutoType=oSettings.aoColumns[i]._bAutoType;var bRender=typeof oSettings.aoColumns[i].fnRender=="function";
638.225 +var bClass=oSettings.aoColumns[i].sClass!==null;var bVisible=oSettings.aoColumns[i].bVisible;
638.226 +if(bAutoType||bRender||bClass||!bVisible){iLoop=oSettings.aoData.length;for(j=0;j<iLoop;
638.227 +j++){var nCellNode=oSettings.aoData[j].nTr.getElementsByTagName("td")[i-iCorrector];
638.228 +if(bAutoType){if(oSettings.aoColumns[i].sType===null){oSettings.aoColumns[i].sType=_fnDetectType(oSettings.aoData[j]._aData[i])
638.229 +}else{if(oSettings.aoColumns[i].sType=="date"||oSettings.aoColumns[i].sType=="numeric"){oSettings.aoColumns[i].sType=_fnDetectType(oSettings.aoData[j]._aData[i])
638.230 +}}}if(bRender){var sRendered=oSettings.aoColumns[i].fnRender({iDataRow:j,iDataColumn:i,aData:oSettings.aoData[j]._aData,oSettings:oSettings});
638.231 +nCellNode.innerHTML=sRendered;if(oSettings.aoColumns[i].bUseRendered){oSettings.aoData[j]._aData[i]=sRendered
638.232 +}}if(bClass){nCellNode.className+=" "+oSettings.aoColumns[i].sClass}if(!bVisible){oSettings.aoData[j]._anHidden[i]=nCellNode;
638.233 +nCellNode.parentNode.removeChild(nCellNode)}}if(!bVisible){iCorrector++}}}}function _fnDrawHead(oSettings){var i,nTh,iLen;
638.234 +var iThs=oSettings.nTable.getElementsByTagName("thead")[0].getElementsByTagName("th").length;
638.235 +var iCorrector=0;if(iThs!==0){for(i=0,iLen=oSettings.aoColumns.length;i<iLen;i++){nTh=oSettings.aoColumns[i].nTh;
638.236 +if(oSettings.aoColumns[i].bVisible){if(oSettings.aoColumns[i].sWidth!==null){nTh.style.width=oSettings.aoColumns[i].sWidth
638.237 +}if(oSettings.aoColumns[i].sTitle!=nTh.innerHTML){nTh.innerHTML=oSettings.aoColumns[i].sTitle
638.238 +}}else{nTh.parentNode.removeChild(nTh);iCorrector++}}}else{var nTr=document.createElement("tr");
638.239 +for(i=0,iLen=oSettings.aoColumns.length;i<iLen;i++){nTh=oSettings.aoColumns[i].nTh;
638.240 +nTh.innerHTML=oSettings.aoColumns[i].sTitle;if(oSettings.aoColumns[i].bVisible){if(oSettings.aoColumns[i].sClass!==null){nTh.className=oSettings.aoColumns[i].sClass
638.241 +}if(oSettings.aoColumns[i].sWidth!==null){nTh.style.width=oSettings.aoColumns[i].sWidth
638.242 +}nTr.appendChild(nTh)}}$("thead:eq(0)",oSettings.nTable).html("")[0].appendChild(nTr)
638.243 +}if(oSettings.bJUI){for(i=0,iLen=oSettings.aoColumns.length;i<iLen;i++){oSettings.aoColumns[i].nTh.insertBefore(document.createElement("span"),oSettings.aoColumns[i].nTh.firstChild)
638.244 +}}if(oSettings.oFeatures.bSort){for(i=0;i<oSettings.aoColumns.length;i++){if(oSettings.aoColumns[i].bSortable!==false){_fnSortAttachListener(oSettings,oSettings.aoColumns[i].nTh,i)
638.245 +}else{$(oSettings.aoColumns[i].nTh).addClass(oSettings.oClasses.sSortableNone)}}$("thead:eq(0) th",oSettings.nTable).mousedown(function(e){if(e.shiftKey){this.onselectstart=function(){return false
638.246 +};return false}})}if(oSettings.oFeatures.bAutoWidth&&oSettings.nTable.offsetWidth!==0){oSettings.nTable.style.width=oSettings.nTable.offsetWidth+"px"
638.247 +}var nTfoot=oSettings.nTable.getElementsByTagName("tfoot");if(nTfoot.length!==0){iCorrector=0;
638.248 +var nTfs=nTfoot[0].getElementsByTagName("th");for(i=0,iLen=nTfs.length;i<iLen;i++){oSettings.aoColumns[i].nTf=nTfs[i-iCorrector];
638.249 +if(!oSettings.aoColumns[i].bVisible){nTfs[i-iCorrector].parentNode.removeChild(nTfs[i-iCorrector]);
638.250 +iCorrector++}}}}function _fnDraw(oSettings){var i,iLen;var anRows=[];var iRowCount=0;
638.251 +var bRowError=false;var iStrips=oSettings.asStripClasses.length;var iOpenRows=oSettings.aoOpenRows.length;
638.252 +if(oSettings.oFeatures.bServerSide&&!_fnAjaxUpdate(oSettings)){return}if(typeof oSettings.iInitDisplayStart!="undefined"&&oSettings.iInitDisplayStart!=-1){oSettings._iDisplayStart=oSettings.iInitDisplayStart;
638.253 +oSettings.iInitDisplayStart=-1;_fnCalculateEnd(oSettings)}if(oSettings.aiDisplay.length!==0){var iStart=oSettings._iDisplayStart;
638.254 +var iEnd=oSettings._iDisplayEnd;if(oSettings.oFeatures.bServerSide){iStart=0;iEnd=oSettings.aoData.length
638.255 +}for(var j=iStart;j<iEnd;j++){var aoData=oSettings.aoData[oSettings.aiDisplay[j]];
638.256 +var nRow=aoData.nTr;if(iStrips!==0){var sStrip=oSettings.asStripClasses[iRowCount%iStrips];
638.257 +if(aoData._sRowStripe!=sStrip){$(nRow).removeClass(aoData._sRowStripe).addClass(sStrip);
638.258 +aoData._sRowStripe=sStrip}}if(typeof oSettings.fnRowCallback=="function"){nRow=oSettings.fnRowCallback(nRow,oSettings.aoData[oSettings.aiDisplay[j]]._aData,iRowCount,j);
638.259 +if(!nRow&&!bRowError){alert("DataTables warning: A node was not returned by fnRowCallback");
638.260 +bRowError=true}}anRows.push(nRow);iRowCount++;if(iOpenRows!==0){for(var k=0;k<iOpenRows;
638.261 +k++){if(nRow==oSettings.aoOpenRows[k].nParent){anRows.push(oSettings.aoOpenRows[k].nTr)
638.262 +}}}}}else{anRows[0]=document.createElement("tr");if(typeof oSettings.asStripClasses[0]!="undefined"){anRows[0].className=oSettings.asStripClasses[0]
638.263 +}var nTd=document.createElement("td");nTd.setAttribute("valign","top");nTd.colSpan=oSettings.aoColumns.length;
638.264 +nTd.className=oSettings.oClasses.sRowEmpty;nTd.innerHTML=oSettings.oLanguage.sZeroRecords;
638.265 +anRows[iRowCount].appendChild(nTd)}if(typeof oSettings.fnHeaderCallback=="function"){oSettings.fnHeaderCallback($("thead:eq(0)>tr",oSettings.nTable)[0],_fnGetDataMaster(oSettings),oSettings._iDisplayStart,oSettings.fnDisplayEnd(),oSettings.aiDisplay)
638.266 +}if(typeof oSettings.fnFooterCallback=="function"){oSettings.fnFooterCallback($("tfoot:eq(0)>tr",oSettings.nTable)[0],_fnGetDataMaster(oSettings),oSettings._iDisplayStart,oSettings.fnDisplayEnd(),oSettings.aiDisplay)
638.267 +}var nTrs=$("tbody:eq(0)>tr",oSettings.nTable);for(i=0,iLen=nTrs.length;i<iLen;i++){nTrs[i].parentNode.removeChild(nTrs[i])
638.268 +}var nBody=$("tbody:eq(0)",oSettings.nTable);if(nBody[0]){for(i=0,iLen=anRows.length;
638.269 +i<iLen;i++){nBody[0].appendChild(anRows[i])}}for(i=0,iLen=oSettings.aoDrawCallback.length;
638.270 +i<iLen;i++){oSettings.aoDrawCallback[i].fn(oSettings)}oSettings.bSorted=false;oSettings.bFiltered=false
638.271 +}function _fnReDraw(oSettings){if(oSettings.oFeatures.bSort){_fnSort(oSettings,oSettings.oPreviousSearch)
638.272 +}else{if(oSettings.oFeatures.bFilter){_fnFilterComplete(oSettings,oSettings.oPreviousSearch)
638.273 +}else{_fnCalculateEnd(oSettings);_fnDraw(oSettings)}}}function _fnAjaxUpdate(oSettings){if(oSettings.bAjaxDataGet){_fnProcessingDisplay(oSettings,true);
638.274 +var iColumns=oSettings.aoColumns.length;var aoData=[];var i;oSettings.iServerDraw++;
638.275 +aoData.push({name:"sEcho",value:oSettings.iServerDraw});aoData.push({name:"iColumns",value:iColumns});
638.276 +aoData.push({name:"sColumns",value:_fnColumnOrdering(oSettings)});aoData.push({name:"iDisplayStart",value:oSettings._iDisplayStart});
638.277 +aoData.push({name:"iDisplayLength",value:oSettings.oFeatures.bPaginate!==false?oSettings._iDisplayLength:-1});
638.278 +if(oSettings.oFeatures.bFilter!==false){aoData.push({name:"sSearch",value:oSettings.oPreviousSearch.sSearch});
638.279 +aoData.push({name:"bEscapeRegex",value:oSettings.oPreviousSearch.bEscapeRegex});for(i=0;
638.280 +i<iColumns;i++){aoData.push({name:"sSearch_"+i,value:oSettings.aoPreSearchCols[i].sSearch});
638.281 +aoData.push({name:"bEscapeRegex_"+i,value:oSettings.aoPreSearchCols[i].bEscapeRegex});
638.282 +aoData.push({name:"bSearchable_"+i,value:oSettings.aoColumns[i].bSearchable})}}if(oSettings.oFeatures.bSort!==false){var iFixed=oSettings.aaSortingFixed!==null?oSettings.aaSortingFixed.length:0;
638.283 +var iUser=oSettings.aaSorting.length;aoData.push({name:"iSortingCols",value:iFixed+iUser});
638.284 +for(i=0;i<iFixed;i++){aoData.push({name:"iSortCol_"+i,value:oSettings.aaSortingFixed[i][0]});
638.285 +aoData.push({name:"sSortDir_"+i,value:oSettings.aaSortingFixed[i][1]})}for(i=0;i<iUser;
638.286 +i++){aoData.push({name:"iSortCol_"+(i+iFixed),value:oSettings.aaSorting[i][0]});aoData.push({name:"sSortDir_"+(i+iFixed),value:oSettings.aaSorting[i][1]})
638.287 +}for(i=0;i<iColumns;i++){aoData.push({name:"bSortable_"+i,value:oSettings.aoColumns[i].bSortable})
638.288 +}}oSettings.fnServerData(oSettings.sAjaxSource,aoData,function(json){_fnAjaxUpdateDraw(oSettings,json)
638.289 +});return false}else{return true}}function _fnAjaxUpdateDraw(oSettings,json){if(typeof json.sEcho!="undefined"){if(json.sEcho*1<oSettings.iServerDraw){return
638.290 +}else{oSettings.iServerDraw=json.sEcho*1}}_fnClearTable(oSettings);oSettings._iRecordsTotal=json.iTotalRecords;
638.291 +oSettings._iRecordsDisplay=json.iTotalDisplayRecords;var sOrdering=_fnColumnOrdering(oSettings);
638.292 +var bReOrder=(typeof json.sColumns!="undefined"&&sOrdering!==""&&json.sColumns!=sOrdering);
638.293 +if(bReOrder){var aiIndex=_fnReOrderIndex(oSettings,json.sColumns)}for(var i=0,iLen=json.aaData.length;
638.294 +i<iLen;i++){if(bReOrder){var aData=[];for(var j=0,jLen=oSettings.aoColumns.length;
638.295 +j<jLen;j++){aData.push(json.aaData[i][aiIndex[j]])}_fnAddData(oSettings,aData)}else{_fnAddData(oSettings,json.aaData[i])
638.296 +}}oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();oSettings.bAjaxDataGet=false;
638.297 +_fnDraw(oSettings);oSettings.bAjaxDataGet=true;_fnProcessingDisplay(oSettings,false)
638.298 +}function _fnAddOptionsHtml(oSettings){var nHolding=document.createElement("div");
638.299 +oSettings.nTable.parentNode.insertBefore(nHolding,oSettings.nTable);var nWrapper=document.createElement("div");
638.300 +nWrapper.className=oSettings.oClasses.sWrapper;if(oSettings.sTableId!==""){nWrapper.setAttribute("id",oSettings.sTableId+"_wrapper")
638.301 +}var nInsertNode=nWrapper;var sDom=oSettings.sDom.replace("H","fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix");
638.302 +sDom=sDom.replace("F","fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix");
638.303 +var aDom=sDom.split("");var nTmp,iPushFeature,cOption,nNewNode,cNext,sClass,j;for(var i=0;
638.304 +i<aDom.length;i++){iPushFeature=0;cOption=aDom[i];if(cOption=="<"){nNewNode=document.createElement("div");
638.305 +cNext=aDom[i+1];if(cNext=="'"||cNext=='"'){sClass="";j=2;while(aDom[i+j]!=cNext){sClass+=aDom[i+j];
638.306 +j++}nNewNode.className=sClass;i+=j}nInsertNode.appendChild(nNewNode);nInsertNode=nNewNode
638.307 +}else{if(cOption==">"){nInsertNode=nInsertNode.parentNode}else{if(cOption=="l"&&oSettings.oFeatures.bPaginate&&oSettings.oFeatures.bLengthChange){nTmp=_fnFeatureHtmlLength(oSettings);
638.308 +iPushFeature=1}else{if(cOption=="f"&&oSettings.oFeatures.bFilter){nTmp=_fnFeatureHtmlFilter(oSettings);
638.309 +iPushFeature=1}else{if(cOption=="r"&&oSettings.oFeatures.bProcessing){nTmp=_fnFeatureHtmlProcessing(oSettings);
638.310 +iPushFeature=1}else{if(cOption=="t"){nTmp=oSettings.nTable;iPushFeature=1}else{if(cOption=="i"&&oSettings.oFeatures.bInfo){nTmp=_fnFeatureHtmlInfo(oSettings);
638.311 +iPushFeature=1}else{if(cOption=="p"&&oSettings.oFeatures.bPaginate){nTmp=_fnFeatureHtmlPaginate(oSettings);
638.312 +iPushFeature=1}else{if(_oExt.aoFeatures.length!==0){var aoFeatures=_oExt.aoFeatures;
638.313 +for(var k=0,kLen=aoFeatures.length;k<kLen;k++){if(cOption==aoFeatures[k].cFeature){nTmp=aoFeatures[k].fnInit(oSettings);
638.314 +if(nTmp){iPushFeature=1}break}}}}}}}}}}}if(iPushFeature==1){if(typeof oSettings.aanFeatures[cOption]!="object"){oSettings.aanFeatures[cOption]=[]
638.315 +}oSettings.aanFeatures[cOption].push(nTmp);nInsertNode.appendChild(nTmp)}}nHolding.parentNode.replaceChild(nWrapper,nHolding)
638.316 +}function _fnFeatureHtmlFilter(oSettings){var nFilter=document.createElement("div");
638.317 +if(oSettings.sTableId!==""&&typeof oSettings.aanFeatures.f=="undefined"){nFilter.setAttribute("id",oSettings.sTableId+"_filter")
638.318 +}nFilter.className=oSettings.oClasses.sFilter;var sSpace=oSettings.oLanguage.sSearch===""?"":" ";
638.319 +nFilter.innerHTML=oSettings.oLanguage.sSearch+sSpace+'<input type="text" />';var jqFilter=$("input",nFilter);
638.320 +jqFilter.val(oSettings.oPreviousSearch.sSearch.replace('"',"""));jqFilter.keyup(function(e){var n=oSettings.aanFeatures.f;
638.321 +for(var i=0,iLen=n.length;i<iLen;i++){if(n[i]!=this.parentNode){$("input",n[i]).val(this.value)
638.322 +}}_fnFilterComplete(oSettings,{sSearch:this.value,bEscapeRegex:oSettings.oPreviousSearch.bEscapeRegex})
638.323 +});jqFilter.keypress(function(e){if(e.keyCode==13){return false}});return nFilter
638.324 +}function _fnFilterComplete(oSettings,oInput,iForce){_fnFilter(oSettings,oInput.sSearch,iForce,oInput.bEscapeRegex);
638.325 +for(var i=0;i<oSettings.aoPreSearchCols.length;i++){_fnFilterColumn(oSettings,oSettings.aoPreSearchCols[i].sSearch,i,oSettings.aoPreSearchCols[i].bEscapeRegex)
638.326 +}if(_oExt.afnFiltering.length!==0){_fnFilterCustom(oSettings)}oSettings.bFiltered=true;
638.327 +oSettings._iDisplayStart=0;_fnCalculateEnd(oSettings);_fnDraw(oSettings);_fnBuildSearchArray(oSettings,0)
638.328 +}function _fnFilterCustom(oSettings){var afnFilters=_oExt.afnFiltering;for(var i=0,iLen=afnFilters.length;
638.329 +i<iLen;i++){var iCorrector=0;for(var j=0,jLen=oSettings.aiDisplay.length;j<jLen;j++){var iDisIndex=oSettings.aiDisplay[j-iCorrector];
638.330 +if(!afnFilters[i](oSettings,oSettings.aoData[iDisIndex]._aData,iDisIndex)){oSettings.aiDisplay.splice(j-iCorrector,1);
638.331 +iCorrector++}}}}function _fnFilterColumn(oSettings,sInput,iColumn,bEscapeRegex){if(sInput===""){return
638.332 +}var iIndexCorrector=0;var sRegexMatch=bEscapeRegex?_fnEscapeRegex(sInput):sInput;
638.333 +var rpSearch=new RegExp(sRegexMatch,"i");for(var i=oSettings.aiDisplay.length-1;i>=0;
638.334 +i--){var sData=_fnDataToSearch(oSettings.aoData[oSettings.aiDisplay[i]]._aData[iColumn],oSettings.aoColumns[iColumn].sType);
638.335 +if(!rpSearch.test(sData)){oSettings.aiDisplay.splice(i,1);iIndexCorrector++}}}function _fnFilter(oSettings,sInput,iForce,bEscapeRegex){var i;
638.336 +if(typeof iForce=="undefined"||iForce===null){iForce=0}if(_oExt.afnFiltering.length!==0){iForce=1
638.337 +}var asSearch=bEscapeRegex?_fnEscapeRegex(sInput).split(" "):sInput.split(" ");var sRegExpString="^(?=.*?"+asSearch.join(")(?=.*?")+").*$";
638.338 +var rpSearch=new RegExp(sRegExpString,"i");if(sInput.length<=0){oSettings.aiDisplay.splice(0,oSettings.aiDisplay.length);
638.339 +oSettings.aiDisplay=oSettings.aiDisplayMaster.slice()}else{if(oSettings.aiDisplay.length==oSettings.aiDisplayMaster.length||oSettings.oPreviousSearch.sSearch.length>sInput.length||iForce==1||sInput.indexOf(oSettings.oPreviousSearch.sSearch)!==0){oSettings.aiDisplay.splice(0,oSettings.aiDisplay.length);
638.340 +_fnBuildSearchArray(oSettings,1);for(i=0;i<oSettings.aiDisplayMaster.length;i++){if(rpSearch.test(oSettings.asDataSearch[i])){oSettings.aiDisplay.push(oSettings.aiDisplayMaster[i])
638.341 +}}}else{var iIndexCorrector=0;for(i=0;i<oSettings.asDataSearch.length;i++){if(!rpSearch.test(oSettings.asDataSearch[i])){oSettings.aiDisplay.splice(i-iIndexCorrector,1);
638.342 +iIndexCorrector++}}}}oSettings.oPreviousSearch.sSearch=sInput;oSettings.oPreviousSearch.bEscapeRegex=bEscapeRegex
638.343 +}function _fnBuildSearchArray(oSettings,iMaster){oSettings.asDataSearch.splice(0,oSettings.asDataSearch.length);
638.344 +var aArray=(typeof iMaster!="undefined"&&iMaster==1)?oSettings.aiDisplayMaster:oSettings.aiDisplay;
638.345 +for(var i=0,iLen=aArray.length;i<iLen;i++){oSettings.asDataSearch[i]="";for(var j=0,jLen=oSettings.aoColumns.length;
638.346 +j<jLen;j++){if(oSettings.aoColumns[j].bSearchable){var sData=oSettings.aoData[aArray[i]]._aData[j];
638.347 +oSettings.asDataSearch[i]+=_fnDataToSearch(sData,oSettings.aoColumns[j].sType)+" "
638.348 +}}}}function _fnDataToSearch(sData,sType){if(typeof _oExt.ofnSearch[sType]=="function"){return _oExt.ofnSearch[sType](sData)
638.349 +}else{if(sType=="html"){return sData.replace(/\n/g," ").replace(/<.*?>/g,"")}else{if(typeof sData=="string"){return sData.replace(/\n/g," ")
638.350 +}}}return sData}function _fnSort(oSettings,bApplyClasses){var aaSort=[];var oSort=_oExt.oSort;
638.351 +var aoData=oSettings.aoData;var iDataSort;var iDataType;var i,j,jLen;if(!oSettings.oFeatures.bServerSide&&(oSettings.aaSorting.length!==0||oSettings.aaSortingFixed!==null)){if(oSettings.aaSortingFixed!==null){aaSort=oSettings.aaSortingFixed.concat(oSettings.aaSorting)
638.352 +}else{aaSort=oSettings.aaSorting.slice()}for(i=0;i<aaSort.length;i++){var iColumn=aaSort[i][0];
638.353 +var sDataType=oSettings.aoColumns[iColumn].sSortDataType;if(typeof _oExt.afnSortData[sDataType]!="undefined"){var iCorrector=0;
638.354 +var aData=_oExt.afnSortData[sDataType](oSettings,iColumn);for(j=0,jLen=aoData.length;
638.355 +j<jLen;j++){if(aoData[j]!==null){aoData[j]._aData[iColumn]=aData[iCorrector];iCorrector++
638.356 +}}}}if(!window.runtime){var fnLocalSorting;var sDynamicSort="fnLocalSorting = function(a,b){var iTest;";
638.357 +for(i=0;i<aaSort.length-1;i++){iDataSort=oSettings.aoColumns[aaSort[i][0]].iDataSort;
638.358 +iDataType=oSettings.aoColumns[iDataSort].sType;sDynamicSort+="iTest = oSort['"+iDataType+"-"+aaSort[i][1]+"']( aoData[a]._aData["+iDataSort+"], aoData[b]._aData["+iDataSort+"] ); if ( iTest === 0 )"
638.359 +}iDataSort=oSettings.aoColumns[aaSort[aaSort.length-1][0]].iDataSort;iDataType=oSettings.aoColumns[iDataSort].sType;
638.360 +sDynamicSort+="iTest = oSort['"+iDataType+"-"+aaSort[aaSort.length-1][1]+"']( aoData[a]._aData["+iDataSort+"], aoData[b]._aData["+iDataSort+"] );if (iTest===0) return oSort['numeric-"+aaSort[aaSort.length-1][1]+"'](a, b); return iTest;}";
638.361 +eval(sDynamicSort);oSettings.aiDisplayMaster.sort(fnLocalSorting)}else{var aAirSort=[];
638.362 +var iLen=aaSort.length;for(i=0;i<iLen;i++){iDataSort=oSettings.aoColumns[aaSort[i][0]].iDataSort;
638.363 +aAirSort.push([iDataSort,oSettings.aoColumns[iDataSort].sType+"-"+aaSort[i][1]])}oSettings.aiDisplayMaster.sort(function(a,b){var iTest;
638.364 +for(var i=0;i<iLen;i++){iTest=oSort[aAirSort[i][1]](aoData[a]._aData[aAirSort[i][0]],aoData[b]._aData[aAirSort[i][0]]);
638.365 +if(iTest!==0){return iTest}}return 0})}}if(typeof bApplyClasses=="undefined"||bApplyClasses){_fnSortingClasses(oSettings)
638.366 +}oSettings.bSorted=true;if(oSettings.oFeatures.bFilter){_fnFilterComplete(oSettings,oSettings.oPreviousSearch,1)
638.367 +}else{oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();oSettings._iDisplayStart=0;
638.368 +_fnCalculateEnd(oSettings);_fnDraw(oSettings)}}function _fnSortAttachListener(oSettings,nNode,iDataIndex,fnCallback){$(nNode).click(function(e){if(oSettings.aoColumns[iDataIndex].bSortable===false){return
638.369 +}var fnInnerSorting=function(){var iColumn,iNextSort;if(e.shiftKey){var bFound=false;
638.370 +for(var i=0;i<oSettings.aaSorting.length;i++){if(oSettings.aaSorting[i][0]==iDataIndex){bFound=true;
638.371 +iColumn=oSettings.aaSorting[i][0];iNextSort=oSettings.aaSorting[i][2]+1;if(typeof oSettings.aoColumns[iColumn].asSorting[iNextSort]=="undefined"){oSettings.aaSorting.splice(i,1)
638.372 +}else{oSettings.aaSorting[i][1]=oSettings.aoColumns[iColumn].asSorting[iNextSort];
638.373 +oSettings.aaSorting[i][2]=iNextSort}break}}if(bFound===false){oSettings.aaSorting.push([iDataIndex,oSettings.aoColumns[iDataIndex].asSorting[0],0])
638.374 +}}else{if(oSettings.aaSorting.length==1&&oSettings.aaSorting[0][0]==iDataIndex){iColumn=oSettings.aaSorting[0][0];
638.375 +iNextSort=oSettings.aaSorting[0][2]+1;if(typeof oSettings.aoColumns[iColumn].asSorting[iNextSort]=="undefined"){iNextSort=0
638.376 +}oSettings.aaSorting[0][1]=oSettings.aoColumns[iColumn].asSorting[iNextSort];oSettings.aaSorting[0][2]=iNextSort
638.377 +}else{oSettings.aaSorting.splice(0,oSettings.aaSorting.length);oSettings.aaSorting.push([iDataIndex,oSettings.aoColumns[iDataIndex].asSorting[0],0])
638.378 +}}_fnSort(oSettings)};if(!oSettings.oFeatures.bProcessing){fnInnerSorting()}else{_fnProcessingDisplay(oSettings,true);
638.379 +setTimeout(function(){fnInnerSorting();if(!oSettings.oFeatures.bServerSide){_fnProcessingDisplay(oSettings,false)
638.380 +}},0)}if(typeof fnCallback=="function"){fnCallback(oSettings)}})}function _fnSortingClasses(oSettings){var i,j,iFound;
638.381 +var aaSort,sClass;var iColumns=oSettings.aoColumns.length;var oClasses=oSettings.oClasses;
638.382 +for(i=0;i<iColumns;i++){if(oSettings.aoColumns[i].bSortable){$(oSettings.aoColumns[i].nTh).removeClass(oClasses.sSortAsc+" "+oClasses.sSortDesc+" "+oSettings.aoColumns[i].sSortingClass)
638.383 +}}if(oSettings.aaSortingFixed!==null){aaSort=oSettings.aaSortingFixed.concat(oSettings.aaSorting)
638.384 +}else{aaSort=oSettings.aaSorting.slice()}for(i=0;i<oSettings.aoColumns.length;i++){if(oSettings.aoColumns[i].bSortable){sClass=oSettings.aoColumns[i].sSortingClass;
638.385 +iFound=-1;for(j=0;j<aaSort.length;j++){if(aaSort[j][0]==i){sClass=(aaSort[j][1]=="asc")?oClasses.sSortAsc:oClasses.sSortDesc;
638.386 +iFound=j;break}}$(oSettings.aoColumns[i].nTh).addClass(sClass);if(oSettings.bJUI){var jqSpan=$("span",oSettings.aoColumns[i].nTh);
638.387 +jqSpan.removeClass(oClasses.sSortJUIAsc+" "+oClasses.sSortJUIDesc+" "+oClasses.sSortJUI+" "+oClasses.sSortJUIAscAllowed+" "+oClasses.sSortJUIDescAllowed);
638.388 +var sSpanClass;if(iFound==-1){sSpanClass=oSettings.aoColumns[i].sSortingClassJUI}else{if(aaSort[iFound][1]=="asc"){sSpanClass=oClasses.sSortJUIAsc
638.389 +}else{sSpanClass=oClasses.sSortJUIDesc}}jqSpan.addClass(sSpanClass)}}else{$(oSettings.aoColumns[i].nTh).addClass(oSettings.aoColumns[i].sSortingClass)
638.390 +}}if(oSettings.oFeatures.bSort&&oSettings.oFeatures.bSortClasses){var nTrs=_fnGetTrNodes(oSettings);
638.391 +sClass=oClasses.sSortColumn;$("td",nTrs).removeClass(sClass+"1 "+sClass+"2 "+sClass+"3");
638.392 +var iClass=1;for(i=0;i<aaSort.length;i++){var iVis=_fnColumnIndexToVisible(oSettings,aaSort[i][0]);
638.393 +if(iVis!==null){if(iClass<=2){$("td:eq("+iVis+")",nTrs).addClass(sClass+iClass)}else{$("td:eq("+iVis+")",nTrs).addClass(sClass+"3")
638.394 +}iClass++}}}}function _fnFeatureHtmlPaginate(oSettings){var nPaginate=document.createElement("div");
638.395 +nPaginate.className=oSettings.oClasses.sPaging+oSettings.sPaginationType;_oExt.oPagination[oSettings.sPaginationType].fnInit(oSettings,nPaginate,function(oSettings){_fnCalculateEnd(oSettings);
638.396 +_fnDraw(oSettings)});if(typeof oSettings.aanFeatures.p=="undefined"){oSettings.aoDrawCallback.push({fn:function(oSettings){_oExt.oPagination[oSettings.sPaginationType].fnUpdate(oSettings,function(oSettings){_fnCalculateEnd(oSettings);
638.397 +_fnDraw(oSettings)})},sName:"pagination"})}return nPaginate}function _fnPageChange(oSettings,sAction){if(sAction=="first"){oSettings._iDisplayStart=0
638.398 +}else{if(sAction=="previous"){oSettings._iDisplayStart=oSettings._iDisplayLength>=0?oSettings._iDisplayStart-oSettings._iDisplayLength:0;
638.399 +if(oSettings._iDisplayStart<0){oSettings._iDisplayStart=0}}else{if(sAction=="next"){if(oSettings._iDisplayLength>=0){if(oSettings._iDisplayStart+oSettings._iDisplayLength<oSettings.fnRecordsDisplay()){oSettings._iDisplayStart+=oSettings._iDisplayLength
638.400 +}}else{oSettings._iDisplayStart=0}}else{if(sAction=="last"){if(oSettings._iDisplayLength>=0){var iPages=parseInt((oSettings.fnRecordsDisplay()-1)/oSettings._iDisplayLength,10)+1;
638.401 +oSettings._iDisplayStart=(iPages-1)*oSettings._iDisplayLength}else{oSettings._iDisplayStart=0
638.402 +}}else{alert("DataTables warning: unknown paging action: "+sAction)}}}}}function _fnFeatureHtmlInfo(oSettings){var nInfo=document.createElement("div");
638.403 +nInfo.className=oSettings.oClasses.sInfo;if(typeof oSettings.aanFeatures.i=="undefined"){oSettings.aoDrawCallback.push({fn:_fnUpdateInfo,sName:"information"});
638.404 +if(oSettings.sTableId!==""){nInfo.setAttribute("id",oSettings.sTableId+"_info")}}return nInfo
638.405 +}function _fnUpdateInfo(oSettings){if(!oSettings.oFeatures.bInfo||oSettings.aanFeatures.i.length===0){return
638.406 +}var nFirst=oSettings.aanFeatures.i[0];if(oSettings.fnRecordsDisplay()===0&&oSettings.fnRecordsDisplay()==oSettings.fnRecordsTotal()){nFirst.innerHTML=oSettings.oLanguage.sInfoEmpty+oSettings.oLanguage.sInfoPostFix
638.407 +}else{if(oSettings.fnRecordsDisplay()===0){nFirst.innerHTML=oSettings.oLanguage.sInfoEmpty+" "+oSettings.oLanguage.sInfoFiltered.replace("_MAX_",oSettings.fnRecordsTotal())+oSettings.oLanguage.sInfoPostFix
638.408 +}else{if(oSettings.fnRecordsDisplay()==oSettings.fnRecordsTotal()){nFirst.innerHTML=oSettings.oLanguage.sInfo.replace("_START_",oSettings._iDisplayStart+1).replace("_END_",oSettings.fnDisplayEnd()).replace("_TOTAL_",oSettings.fnRecordsDisplay())+oSettings.oLanguage.sInfoPostFix
638.409 +}else{nFirst.innerHTML=oSettings.oLanguage.sInfo.replace("_START_",oSettings._iDisplayStart+1).replace("_END_",oSettings.fnDisplayEnd()).replace("_TOTAL_",oSettings.fnRecordsDisplay())+" "+oSettings.oLanguage.sInfoFiltered.replace("_MAX_",oSettings.fnRecordsTotal())+oSettings.oLanguage.sInfoPostFix
638.410 +}}}var n=oSettings.aanFeatures.i;if(n.length>1){var sInfo=nFirst.innerHTML;for(var i=1,iLen=n.length;
638.411 +i<iLen;i++){n[i].innerHTML=sInfo}}}function _fnFeatureHtmlLength(oSettings){var sName=(oSettings.sTableId==="")?"":'name="'+oSettings.sTableId+'_length"';
638.412 +var sStdMenu='<select size="1" '+sName+'><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select>';
638.413 +var nLength=document.createElement("div");if(oSettings.sTableId!==""&&typeof oSettings.aanFeatures.l=="undefined"){nLength.setAttribute("id",oSettings.sTableId+"_length")
638.414 +}nLength.className=oSettings.oClasses.sLength;nLength.innerHTML=oSettings.oLanguage.sLengthMenu.replace("_MENU_",sStdMenu);
638.415 +$('select option[value="'+oSettings._iDisplayLength+'"]',nLength).attr("selected",true);
638.416 +$("select",nLength).change(function(e){var iVal=$(this).val();var n=oSettings.aanFeatures.l;
638.417 +for(var i=0,iLen=n.length;i<iLen;i++){if(n[i]!=this.parentNode){$("select",n[i]).val(iVal)
638.418 +}}oSettings._iDisplayLength=parseInt(iVal,10);_fnCalculateEnd(oSettings);if(oSettings._iDisplayEnd==oSettings.aiDisplay.length){oSettings._iDisplayStart=oSettings._iDisplayEnd-oSettings._iDisplayLength;
638.419 +if(oSettings._iDisplayStart<0){oSettings._iDisplayStart=0}}if(oSettings._iDisplayLength==-1){oSettings._iDisplayStart=0
638.420 +}_fnDraw(oSettings)});return nLength}function _fnFeatureHtmlProcessing(oSettings){var nProcessing=document.createElement("div");
638.421 +if(oSettings.sTableId!==""&&typeof oSettings.aanFeatures.r=="undefined"){nProcessing.setAttribute("id",oSettings.sTableId+"_processing")
638.422 +}nProcessing.innerHTML=oSettings.oLanguage.sProcessing;nProcessing.className=oSettings.oClasses.sProcessing;
638.423 +oSettings.nTable.parentNode.insertBefore(nProcessing,oSettings.nTable);return nProcessing
638.424 +}function _fnProcessingDisplay(oSettings,bShow){if(oSettings.oFeatures.bProcessing){var an=oSettings.aanFeatures.r;
638.425 +for(var i=0,iLen=an.length;i<iLen;i++){an[i].style.visibility=bShow?"visible":"hidden"
638.426 +}}}function _fnVisibleToColumnIndex(oSettings,iMatch){var iColumn=-1;for(var i=0;
638.427 +i<oSettings.aoColumns.length;i++){if(oSettings.aoColumns[i].bVisible===true){iColumn++
638.428 +}if(iColumn==iMatch){return i}}return null}function _fnColumnIndexToVisible(oSettings,iMatch){var iVisible=-1;
638.429 +for(var i=0;i<oSettings.aoColumns.length;i++){if(oSettings.aoColumns[i].bVisible===true){iVisible++
638.430 +}if(i==iMatch){return oSettings.aoColumns[i].bVisible===true?iVisible:null}}return null
638.431 +}function _fnNodeToDataIndex(s,n){for(var i=0,iLen=s.aoData.length;i<iLen;i++){if(s.aoData[i]!==null&&s.aoData[i].nTr==n){return i
638.432 +}}return null}function _fnVisbleColumns(oS){var iVis=0;for(var i=0;i<oS.aoColumns.length;
638.433 +i++){if(oS.aoColumns[i].bVisible===true){iVis++}}return iVis}function _fnCalculateEnd(oSettings){if(oSettings.oFeatures.bPaginate===false){oSettings._iDisplayEnd=oSettings.aiDisplay.length
638.434 +}else{if(oSettings._iDisplayStart+oSettings._iDisplayLength>oSettings.aiDisplay.length||oSettings._iDisplayLength==-1){oSettings._iDisplayEnd=oSettings.aiDisplay.length
638.435 +}else{oSettings._iDisplayEnd=oSettings._iDisplayStart+oSettings._iDisplayLength}}}function _fnConvertToWidth(sWidth,nParent){if(!sWidth||sWidth===null||sWidth===""){return 0
638.436 +}if(typeof nParent=="undefined"){nParent=document.getElementsByTagName("body")[0]
638.437 +}var iWidth;var nTmp=document.createElement("div");nTmp.style.width=sWidth;nParent.appendChild(nTmp);
638.438 +iWidth=nTmp.offsetWidth;nParent.removeChild(nTmp);return(iWidth)}function _fnCalculateColumnWidths(oSettings){var iTableWidth=oSettings.nTable.offsetWidth;
638.439 +var iTotalUserIpSize=0;var iTmpWidth;var iVisibleColumns=0;var iColums=oSettings.aoColumns.length;
638.440 +var i;var oHeaders=$("thead:eq(0)>th",oSettings.nTable);for(i=0;i<iColums;i++){if(oSettings.aoColumns[i].bVisible){iVisibleColumns++;
638.441 +if(oSettings.aoColumns[i].sWidth!==null){iTmpWidth=_fnConvertToWidth(oSettings.aoColumns[i].sWidth,oSettings.nTable.parentNode);
638.442 +iTotalUserIpSize+=iTmpWidth;oSettings.aoColumns[i].sWidth=iTmpWidth+"px"}}}if(iColums==oHeaders.length&&iTotalUserIpSize===0&&iVisibleColumns==iColums){for(i=0;
638.443 +i<oSettings.aoColumns.length;i++){oSettings.aoColumns[i].sWidth=oHeaders[i].offsetWidth+"px"
638.444 +}}else{var nCalcTmp=oSettings.nTable.cloneNode(false);nCalcTmp.setAttribute("id","");
638.445 +var sTableTmp='<table class="'+nCalcTmp.className+'">';var sCalcHead="<tr>";var sCalcHtml="<tr>";
638.446 +for(i=0;i<iColums;i++){if(oSettings.aoColumns[i].bVisible){sCalcHead+="<th>"+oSettings.aoColumns[i].sTitle+"</th>";
638.447 +if(oSettings.aoColumns[i].sWidth!==null){var sWidth="";if(oSettings.aoColumns[i].sWidth!==null){sWidth=' style="width:'+oSettings.aoColumns[i].sWidth+';"'
638.448 +}sCalcHtml+="<td"+sWidth+' tag_index="'+i+'">'+fnGetMaxLenString(oSettings,i)+"</td>"
638.449 +}else{sCalcHtml+='<td tag_index="'+i+'">'+fnGetMaxLenString(oSettings,i)+"</td>"}}}sCalcHead+="</tr>";
638.450 +sCalcHtml+="</tr>";nCalcTmp=$(sTableTmp+sCalcHead+sCalcHtml+"</table>")[0];nCalcTmp.style.width=iTableWidth+"px";
638.451 +nCalcTmp.style.visibility="hidden";nCalcTmp.style.position="absolute";oSettings.nTable.parentNode.appendChild(nCalcTmp);
638.452 +var oNodes=$("tr:eq(1)>td",nCalcTmp);var iIndex;for(i=0;i<oNodes.length;i++){iIndex=oNodes[i].getAttribute("tag_index");
638.453 +oSettings.aoColumns[iIndex].sWidth=$("td",nCalcTmp)[i].offsetWidth+"px"}oSettings.nTable.parentNode.removeChild(nCalcTmp)
638.454 +}}function fnGetMaxLenString(oSettings,iCol){var iMax=0;var iMaxIndex=-1;for(var i=0;
638.455 +i<oSettings.aoData.length;i++){if(oSettings.aoData[i]._aData[iCol].length>iMax){iMax=oSettings.aoData[i]._aData[iCol].length;
638.456 +iMaxIndex=i}}if(iMaxIndex>=0){return oSettings.aoData[iMaxIndex]._aData[iCol]}return""
638.457 +}function _fnArrayCmp(aArray1,aArray2){if(aArray1.length!=aArray2.length){return 1
638.458 +}for(var i=0;i<aArray1.length;i++){if(aArray1[i]!=aArray2[i]){return 2}}return 0}function _fnDetectType(sData){var aTypes=_oExt.aTypes;
638.459 +var iLen=aTypes.length;for(var i=0;i<iLen;i++){var sType=aTypes[i](sData);if(sType!==null){return sType
638.460 +}}return"string"}function _fnSettingsFromNode(nTable){for(var i=0;i<_aoSettings.length;
638.461 +i++){if(_aoSettings[i].nTable==nTable){return _aoSettings[i]}}return null}function _fnGetDataMaster(oSettings){var aData=[];
638.462 +var iLen=oSettings.aoData.length;for(var i=0;i<iLen;i++){if(oSettings.aoData[i]===null){aData.push(null)
638.463 +}else{aData.push(oSettings.aoData[i]._aData)}}return aData}function _fnGetTrNodes(oSettings){var aNodes=[];
638.464 +var iLen=oSettings.aoData.length;for(var i=0;i<iLen;i++){if(oSettings.aoData[i]===null){aNodes.push(null)
638.465 +}else{aNodes.push(oSettings.aoData[i].nTr)}}return aNodes}function _fnEscapeRegex(sVal){var acEscape=["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^"];
638.466 +var reReplace=new RegExp("(\\"+acEscape.join("|\\")+")","g");return sVal.replace(reReplace,"\\$1")
638.467 +}function _fnReOrderIndex(oSettings,sColumns){var aColumns=sColumns.split(",");var aiReturn=[];
638.468 +for(var i=0,iLen=oSettings.aoColumns.length;i<iLen;i++){for(var j=0;j<iLen;j++){if(oSettings.aoColumns[i].sName==aColumns[j]){aiReturn.push(j);
638.469 +break}}}return aiReturn}function _fnColumnOrdering(oSettings){var sNames="";for(var i=0,iLen=oSettings.aoColumns.length;
638.470 +i<iLen;i++){sNames+=oSettings.aoColumns[i].sName+","}if(sNames.length==iLen){return""
638.471 +}return sNames.slice(0,-1)}function _fnClearTable(oSettings){oSettings.aoData.length=0;
638.472 +oSettings.aiDisplayMaster.length=0;oSettings.aiDisplay.length=0;_fnCalculateEnd(oSettings)
638.473 +}function _fnSaveState(oSettings){if(!oSettings.oFeatures.bStateSave){return}var i;
638.474 +var sValue="{";sValue+='"iStart": '+oSettings._iDisplayStart+",";sValue+='"iEnd": '+oSettings._iDisplayEnd+",";
638.475 +sValue+='"iLength": '+oSettings._iDisplayLength+",";sValue+='"sFilter": "'+oSettings.oPreviousSearch.sSearch.replace('"','\\"')+'",';
638.476 +sValue+='"sFilterEsc": '+oSettings.oPreviousSearch.bEscapeRegex+",";sValue+='"aaSorting": [ ';
638.477 +for(i=0;i<oSettings.aaSorting.length;i++){sValue+="["+oSettings.aaSorting[i][0]+",'"+oSettings.aaSorting[i][1]+"'],"
638.478 +}sValue=sValue.substring(0,sValue.length-1);sValue+="],";sValue+='"aaSearchCols": [ ';
638.479 +for(i=0;i<oSettings.aoPreSearchCols.length;i++){sValue+="['"+oSettings.aoPreSearchCols[i].sSearch.replace("'","'")+"',"+oSettings.aoPreSearchCols[i].bEscapeRegex+"],"
638.480 +}sValue=sValue.substring(0,sValue.length-1);sValue+="],";sValue+='"abVisCols": [ ';
638.481 +for(i=0;i<oSettings.aoColumns.length;i++){sValue+=oSettings.aoColumns[i].bVisible+","
638.482 +}sValue=sValue.substring(0,sValue.length-1);sValue+="]";sValue+="}";_fnCreateCookie("SpryMedia_DataTables_"+oSettings.sInstance,sValue,oSettings.iCookieDuration)
638.483 +}function _fnLoadState(oSettings,oInit){if(!oSettings.oFeatures.bStateSave){return
638.484 +}var oData;var sData=_fnReadCookie("SpryMedia_DataTables_"+oSettings.sInstance);if(sData!==null&&sData!==""){try{if(typeof JSON=="object"&&typeof JSON.parse=="function"){oData=JSON.parse(sData.replace(/'/g,'"'))
638.485 +}else{oData=eval("("+sData+")")}}catch(e){return}oSettings._iDisplayStart=oData.iStart;
638.486 +oSettings.iInitDisplayStart=oData.iStart;oSettings._iDisplayEnd=oData.iEnd;oSettings._iDisplayLength=oData.iLength;
638.487 +oSettings.oPreviousSearch.sSearch=oData.sFilter;oSettings.aaSorting=oData.aaSorting.slice();
638.488 +if(typeof oData.sFilterEsc!="undefined"){oSettings.oPreviousSearch.bEscapeRegex=oData.sFilterEsc
638.489 +}if(typeof oData.aaSearchCols!="undefined"){for(var i=0;i<oData.aaSearchCols.length;
638.490 +i++){oSettings.aoPreSearchCols[i]={sSearch:oData.aaSearchCols[i][0],bEscapeRegex:oData.aaSearchCols[i][1]}
638.491 +}}if(typeof oData.abVisCols!="undefined"){oInit.saved_aoColumns=[];for(i=0;i<oData.abVisCols.length;
638.492 +i++){oInit.saved_aoColumns[i]={};oInit.saved_aoColumns[i].bVisible=oData.abVisCols[i]
638.493 +}}}}function _fnCreateCookie(sName,sValue,iSecs){var date=new Date();date.setTime(date.getTime()+(iSecs*1000));
638.494 +sName+="_"+window.location.pathname.replace(/[\/:]/g,"").toLowerCase();document.cookie=sName+"="+sValue+"; expires="+date.toGMTString()+"; path=/"
638.495 +}function _fnReadCookie(sName){var sNameEQ=sName+"_"+window.location.pathname.replace(/[\/:]/g,"").toLowerCase()+"=";
638.496 +var sCookieContents=document.cookie.split(";");for(var i=0;i<sCookieContents.length;
638.497 +i++){var c=sCookieContents[i];while(c.charAt(0)==" "){c=c.substring(1,c.length)}if(c.indexOf(sNameEQ)===0){return c.substring(sNameEQ.length,c.length)
638.498 +}}return null}function _fnGetUniqueThs(nThead){var nTrs=nThead.getElementsByTagName("tr");
638.499 +if(nTrs.length==1){return nTrs[0].getElementsByTagName("th")}var aLayout=[],aReturn=[];
638.500 +var ROWSPAN=2,COLSPAN=3,TDELEM=4;var i,j,k,iLen,jLen,iColumnShifted;var fnShiftCol=function(a,i,j){while(typeof a[i][j]!="undefined"){j++
638.501 +}return j};var fnAddRow=function(i){if(typeof aLayout[i]=="undefined"){aLayout[i]=[]
638.502 +}};for(i=0,iLen=nTrs.length;i<iLen;i++){fnAddRow(i);var iColumn=0;var nTds=[];for(j=0,jLen=nTrs[i].childNodes.length;
638.503 +j<jLen;j++){if(nTrs[i].childNodes[j].nodeName=="TD"||nTrs[i].childNodes[j].nodeName=="TH"){nTds.push(nTrs[i].childNodes[j])
638.504 +}}for(j=0,jLen=nTds.length;j<jLen;j++){var iColspan=nTds[j].getAttribute("colspan")*1;
638.505 +var iRowspan=nTds[j].getAttribute("rowspan")*1;if(!iColspan||iColspan===0||iColspan===1){iColumnShifted=fnShiftCol(aLayout,i,iColumn);
638.506 +aLayout[i][iColumnShifted]=(nTds[j].nodeName=="TD")?TDELEM:nTds[j];if(iRowspan||iRowspan===0||iRowspan===1){for(k=1;
638.507 +k<iRowspan;k++){fnAddRow(i+k);aLayout[i+k][iColumnShifted]=ROWSPAN}}iColumn++}else{iColumnShifted=fnShiftCol(aLayout,i,iColumn);
638.508 +for(k=0;k<iColspan;k++){aLayout[i][iColumnShifted+k]=COLSPAN}iColumn+=iColspan}}}for(i=0,iLen=aLayout[0].length;
638.509 +i<iLen;i++){for(j=0,jLen=aLayout.length;j<jLen;j++){if(typeof aLayout[j][i]=="object"){aReturn.push(aLayout[j][i])
638.510 +}}}return aReturn}function _fnMap(oRet,oSrc,sName,sMappedName){if(typeof sMappedName=="undefined"){sMappedName=sName
638.511 +}if(typeof oSrc[sName]!="undefined"){oRet[sMappedName]=oSrc[sName]}}this.oApi._fnInitalise=_fnInitalise;
638.512 +this.oApi._fnLanguageProcess=_fnLanguageProcess;this.oApi._fnAddColumn=_fnAddColumn;
638.513 +this.oApi._fnAddData=_fnAddData;this.oApi._fnGatherData=_fnGatherData;this.oApi._fnDrawHead=_fnDrawHead;
638.514 +this.oApi._fnDraw=_fnDraw;this.oApi._fnAjaxUpdate=_fnAjaxUpdate;this.oApi._fnAddOptionsHtml=_fnAddOptionsHtml;
638.515 +this.oApi._fnFeatureHtmlFilter=_fnFeatureHtmlFilter;this.oApi._fnFeatureHtmlInfo=_fnFeatureHtmlInfo;
638.516 +this.oApi._fnFeatureHtmlPaginate=_fnFeatureHtmlPaginate;this.oApi._fnPageChange=_fnPageChange;
638.517 +this.oApi._fnFeatureHtmlLength=_fnFeatureHtmlLength;this.oApi._fnFeatureHtmlProcessing=_fnFeatureHtmlProcessing;
638.518 +this.oApi._fnProcessingDisplay=_fnProcessingDisplay;this.oApi._fnFilterComplete=_fnFilterComplete;
638.519 +this.oApi._fnFilterColumn=_fnFilterColumn;this.oApi._fnFilter=_fnFilter;this.oApi._fnSortingClasses=_fnSortingClasses;
638.520 +this.oApi._fnVisibleToColumnIndex=_fnVisibleToColumnIndex;this.oApi._fnColumnIndexToVisible=_fnColumnIndexToVisible;
638.521 +this.oApi._fnNodeToDataIndex=_fnNodeToDataIndex;this.oApi._fnVisbleColumns=_fnVisbleColumns;
638.522 +this.oApi._fnBuildSearchArray=_fnBuildSearchArray;this.oApi._fnDataToSearch=_fnDataToSearch;
638.523 +this.oApi._fnCalculateEnd=_fnCalculateEnd;this.oApi._fnConvertToWidth=_fnConvertToWidth;
638.524 +this.oApi._fnCalculateColumnWidths=_fnCalculateColumnWidths;this.oApi._fnArrayCmp=_fnArrayCmp;
638.525 +this.oApi._fnDetectType=_fnDetectType;this.oApi._fnGetDataMaster=_fnGetDataMaster;
638.526 +this.oApi._fnGetTrNodes=_fnGetTrNodes;this.oApi._fnEscapeRegex=_fnEscapeRegex;this.oApi._fnReOrderIndex=_fnReOrderIndex;
638.527 +this.oApi._fnColumnOrdering=_fnColumnOrdering;this.oApi._fnClearTable=_fnClearTable;
638.528 +this.oApi._fnSaveState=_fnSaveState;this.oApi._fnLoadState=_fnLoadState;this.oApi._fnCreateCookie=_fnCreateCookie;
638.529 +this.oApi._fnReadCookie=_fnReadCookie;this.oApi._fnGetUniqueThs=_fnGetUniqueThs;this.oApi._fnReDraw=_fnReDraw;
638.530 +var _that=this;return this.each(function(){var i=0,iLen,j,jLen;for(i=0,iLen=_aoSettings.length;
638.531 +i<iLen;i++){if(_aoSettings[i].nTable==this){alert("DataTables warning: Unable to re-initialise DataTable. Please use the API to make any configuration changes required.");
638.532 +return _aoSettings[i]}}var oSettings=new classSettings();_aoSettings.push(oSettings);
638.533 +var bInitHandedOff=false;var bUsePassedData=false;var sId=this.getAttribute("id");
638.534 +if(sId!==null){oSettings.sTableId=sId;oSettings.sInstance=sId}else{oSettings.sInstance=_oExt._oExternConfig.iNextUnique++
638.535 +}oSettings.nTable=this;oSettings.oApi=_that.oApi;if(typeof oInit!="undefined"&&oInit!==null){_fnMap(oSettings.oFeatures,oInit,"bPaginate");
638.536 +_fnMap(oSettings.oFeatures,oInit,"bLengthChange");_fnMap(oSettings.oFeatures,oInit,"bFilter");
638.537 +_fnMap(oSettings.oFeatures,oInit,"bSort");_fnMap(oSettings.oFeatures,oInit,"bInfo");
638.538 +_fnMap(oSettings.oFeatures,oInit,"bProcessing");_fnMap(oSettings.oFeatures,oInit,"bAutoWidth");
638.539 +_fnMap(oSettings.oFeatures,oInit,"bSortClasses");_fnMap(oSettings.oFeatures,oInit,"bServerSide");
638.540 +_fnMap(oSettings,oInit,"asStripClasses");_fnMap(oSettings,oInit,"fnRowCallback");
638.541 +_fnMap(oSettings,oInit,"fnHeaderCallback");_fnMap(oSettings,oInit,"fnFooterCallback");
638.542 +_fnMap(oSettings,oInit,"fnInitComplete");_fnMap(oSettings,oInit,"fnServerData");_fnMap(oSettings,oInit,"aaSorting");
638.543 +_fnMap(oSettings,oInit,"aaSortingFixed");_fnMap(oSettings,oInit,"sPaginationType");
638.544 +_fnMap(oSettings,oInit,"sAjaxSource");_fnMap(oSettings,oInit,"iCookieDuration");_fnMap(oSettings,oInit,"sDom");
638.545 +_fnMap(oSettings,oInit,"oSearch","oPreviousSearch");_fnMap(oSettings,oInit,"aoSearchCols","aoPreSearchCols");
638.546 +_fnMap(oSettings,oInit,"iDisplayLength","_iDisplayLength");_fnMap(oSettings,oInit,"bJQueryUI","bJUI");
638.547 +if(typeof oInit.fnDrawCallback=="function"){oSettings.aoDrawCallback.push({fn:oInit.fnDrawCallback,sName:"user"})
638.548 +}if(oSettings.oFeatures.bServerSide&&oSettings.oFeatures.bSort&&oSettings.oFeatures.bSortClasses){oSettings.aoDrawCallback.push({fn:_fnSortingClasses,sName:"server_side_sort_classes"})
638.549 +}if(typeof oInit.bJQueryUI!="undefined"&&oInit.bJQueryUI){oSettings.oClasses=_oExt.oJUIClasses;
638.550 +if(typeof oInit.sDom=="undefined"){oSettings.sDom='<"H"lfr>t<"F"ip>'}}if(typeof oInit.iDisplayStart!="undefined"&&typeof oSettings.iInitDisplayStart=="undefined"){oSettings.iInitDisplayStart=oInit.iDisplayStart;
638.551 +oSettings._iDisplayStart=oInit.iDisplayStart}if(typeof oInit.bStateSave!="undefined"){oSettings.oFeatures.bStateSave=oInit.bStateSave;
638.552 +_fnLoadState(oSettings,oInit);oSettings.aoDrawCallback.push({fn:_fnSaveState,sName:"state_save"})
638.553 +}if(typeof oInit.aaData!="undefined"){bUsePassedData=true}if(typeof oInit!="undefined"&&typeof oInit.aoData!="undefined"){oInit.aoColumns=oInit.aoData
638.554 +}if(typeof oInit.oLanguage!="undefined"){if(typeof oInit.oLanguage.sUrl!="undefined"&&oInit.oLanguage.sUrl!==""){oSettings.oLanguage.sUrl=oInit.oLanguage.sUrl;
638.555 +$.getJSON(oSettings.oLanguage.sUrl,null,function(json){_fnLanguageProcess(oSettings,json,true)
638.556 +});bInitHandedOff=true}else{_fnLanguageProcess(oSettings,oInit.oLanguage,false)}}}else{oInit={}
638.557 +}if(typeof oInit.asStripClasses=="undefined"){oSettings.asStripClasses.push(oSettings.oClasses.sStripOdd);
638.558 +oSettings.asStripClasses.push(oSettings.oClasses.sStripEven)}var nThead=this.getElementsByTagName("thead");
638.559 +var nThs=nThead.length===0?null:_fnGetUniqueThs(nThead[0]);var bUseCols=typeof oInit.aoColumns!="undefined";
638.560 +for(i=0,iLen=bUseCols?oInit.aoColumns.length:nThs.length;i<iLen;i++){var oCol=bUseCols?oInit.aoColumns[i]:null;
638.561 +var nTh=nThs?nThs[i]:null;if(typeof oInit.saved_aoColumns!="undefined"&&oInit.saved_aoColumns.length==iLen){if(oCol===null){oCol={}
638.562 +}oCol.bVisible=oInit.saved_aoColumns[i].bVisible}_fnAddColumn(oSettings,oCol,nTh)
638.563 +}for(i=0,iLen=oSettings.aaSorting.length;i<iLen;i++){if(typeof oSettings.aaSorting[i][2]=="undefined"){oSettings.aaSorting[i][2]=0
638.564 +}var oColumn=oSettings.aoColumns[oSettings.aaSorting[i][0]];for(j=0,jLen=oColumn.asSorting.length;
638.565 +j<jLen;j++){if(oSettings.aaSorting[i][1]==oColumn.asSorting[j]){oSettings.aaSorting[i][2]=j;
638.566 +break}}}if(this.getElementsByTagName("thead").length===0){this.appendChild(document.createElement("thead"))
638.567 +}if(this.getElementsByTagName("tbody").length===0){this.appendChild(document.createElement("tbody"))
638.568 +}if(bUsePassedData){for(i=0;i<oInit.aaData.length;i++){_fnAddData(oSettings,oInit.aaData[i])
638.569 +}}else{_fnGatherData(oSettings)}oSettings.aiDisplay=oSettings.aiDisplayMaster.slice();
638.570 +if(oSettings.oFeatures.bAutoWidth){_fnCalculateColumnWidths(oSettings)}oSettings.bInitialised=true;
638.571 +if(bInitHandedOff===false){_fnInitalise(oSettings)}})}})(jQuery);
638.572 \ No newline at end of file
639.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
639.2 +++ b/web/static/js/jquery.min.js Mon Apr 26 11:16:23 2010 +0200
639.3 @@ -0,0 +1,151 @@
639.4 +/*!
639.5 + * jQuery JavaScript Library v1.4
639.6 + * http://jquery.com/
639.7 + *
639.8 + * Copyright 2010, John Resig
639.9 + * Dual licensed under the MIT or GPL Version 2 licenses.
639.10 + * http://docs.jquery.com/License
639.11 + *
639.12 + * Includes Sizzle.js
639.13 + * http://sizzlejs.com/
639.14 + * Copyright 2010, The Dojo Foundation
639.15 + * Released under the MIT, BSD, and GPL Licenses.
639.16 + *
639.17 + * Date: Wed Jan 13 15:23:05 2010 -0500
639.18 + */
639.19 +(function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o<j;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,i);return a}return j?
639.20 +e(a[0],b):null}function K(){return(new Date).getTime()}function aa(){return false}function ba(){return true}function pa(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function qa(a){var b=true,d=[],f=[],e=arguments,i,j,o,p,n,t=c.extend({},c.data(this,"events").live);for(p in t){j=t[p];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget);
639.21 +n=0;for(l=i.length;n<l;n++)for(p in t){j=t[p];o=i[n].elem;f=null;if(i[n].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==o)d.push({elem:o,fn:j})}}n=0;for(l=d.length;n<l;n++){i=d[n];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}function ra(a,b){return["live",a,b.replace(/\./g,"`").replace(/ /g,"&")].join(".")}function sa(a){return!a||!a.parentNode||a.parentNode.nodeType===
639.22 +11}function ta(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ua(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:s;f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=
639.23 +i?f:1;return{fragment:f,cacheable:e}}function T(a){for(var b=0,d,f;(d=a[b])!=null;b++)if(!c.noData[d.nodeName.toLowerCase()]&&(f=d[H]))delete c.cache[f]}function L(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ma=A.jQuery,Na=A.$,s=A.document,U,Oa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/,
639.24 +Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
639.25 +c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector;
639.26 +this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=
639.27 +0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||
639.28 +c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];o=e[i];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(o)?[]:{};a[i]=c.extend(f,j,o)}else if(o!==w)a[i]=
639.29 +o}return a};c.extend({noConflict:function(a){A.$=Na;if(a)A.jQuery=Ma;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",M,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",
639.30 +M);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&oa()}}},isFunction:function(a){return ca.call(a)==="[object Function]"},isArray:function(a){return ca.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||ca.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!da.call(a,"constructor")&&!da.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===w||da.call(a,b)},
639.31 +isEmptyObject:function(a){for(var b in a)return false;return true},noop:function(){},globalEval:function(a){if(a&&Qa.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===w||c.isFunction(a);
639.32 +if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Ra,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ea.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=
639.33 +0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b===
639.34 +"string"){d=a;a=d[b];b=w}else if(b&&!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){var b={browser:""};a=a.toLowerCase();if(/webkit/.test(a))b={browser:"webkit",version:/webkit[\/ ]([\w.]+)/};else if(/opera/.test(a))b={browser:"opera",version:/version/.test(a)?/version[\/ ]([\w.]+)/:/opera[\/ ]([\w.]+)/};else if(/msie/.test(a))b={browser:"msie",version:/msie ([\w.]+)/};else if(/mozilla/.test(a)&&
639.35 +!/compatible/.test(a))b={browser:"mozilla",version:/rv:([\w.]+)/};b.version=(b.version&&b.version.exec(a)||[0,"0"])[1];return b},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=true;if(V)c.inArray=function(a,b){return V.call(b,a)};U=c(s);if(s.addEventListener)M=function(){s.removeEventListener("DOMContentLoaded",M,false);c.ready()};else if(s.attachEvent)M=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",
639.36 +M);c.ready()}};if(V)c.inArray=function(a,b){return V.call(b,a)};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+K();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,
639.37 +htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,
639.38 +a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in
639.39 +p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a,
639.40 +b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&&
639.41 +a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,
639.42 +a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,
639.43 +a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a,
639.44 +b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,o=b.length;j<o;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=
639.45 +" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.removeClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(za," "),j=0,o=b.length;j<o;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,
639.46 +b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),o=b,p=a.split(fa);e=p[i++];){o=f?o:!j.hasClass(e);j[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=
639.47 +" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(za," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(Aa.test(b.type)&&
639.48 +!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Va,"")}return w}var o=c.isFunction(a);return this.each(function(p){var n=c(this),t=a;if(this.nodeType===1){if(o)t=a.call(this,p,n.val());if(typeof t==="number")t+="";if(c.isArray(t)&&Aa.test(this.type))this.checked=c.inArray(n.val(),t)>=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex=
639.49 +-1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;
639.50 +if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===
639.51 +3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={};
639.52 +if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);
639.53 +for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+
639.54 +i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
639.55 +8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)},
639.56 +handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},
639.57 +props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||
639.58 +s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&
639.59 +a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a,
639.60 +b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=
639.61 +ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",
639.62 +mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+
639.63 +d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>
639.64 +-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d===
639.65 +"radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)},
639.66 +remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,
639.67 +f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,
639.68 +b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||
639.69 +a)},live:function(a,b,d){if(c.isFunction(b)){d=b;b=w}c(this.context).bind(ra(a,this.selector),{data:b,selector:this.selector,live:a},d);return this},die:function(a,b){c(this.context).unbind(ra(a,this.selector),b?{guid:b.guid+this.selector+a}:null);return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?
639.70 +this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",k,m=0;g[m];m++){k=g[m];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===
639.71 +k){y=m[u.sizset];break}if(u.nodeType===1&&!q){u.sizcache=k;u.sizset=r}if(u.nodeName.toLowerCase()===h){y=u;break}u=u[g]}m[r]=y}}}function d(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===k){y=m[u.sizset];break}if(u.nodeType===1){if(!q){u.sizcache=k;u.sizset=r}if(typeof h!=="string"){if(u===h){y=true;break}}else if(p.filter(h,[u]).length>0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
639.72 +e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();
639.73 +u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+
639.74 +(E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};p.matches=function(g,h){return p(g,null,null,h)};p.find=function(g,h,k){var m,r;if(!g)return[];
639.75 +for(var q=0,v=n.order.length;q<v;q++){var u=n.order[q];if(r=n.leftMatch[u].exec(g)){var y=r[1];r.splice(1,1);if(y.substr(y.length-1)!=="\\"){r[1]=(r[1]||"").replace(/\\/g,"");m=n.find[u](r,h,k);if(m!=null){g=g.replace(n.match[u],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};p.filter=function(g,h,k,m){for(var r=g,q=[],v=h,u,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var I in n.filter)if((u=n.leftMatch[I].exec(g))!=null&&u[2]){var N=n.filter[I],J,E;E=u[1];y=false;u.splice(1,1);if(E.substr(E.length-
639.76 +1)!=="\\"){if(v===q)q=[];if(n.preFilter[I])if(u=n.preFilter[I](u,v,k,q,m,S)){if(u===true)continue}else y=J=true;if(u)for(var X=0;(E=v[X])!=null;X++)if(E){J=N(E,u,X,v);var Ea=m^!!J;if(k&&J!=null)if(Ea)y=true;else v[X]=false;else if(Ea){q.push(E);y=true}}if(J!==w){k||(v=q);g=g.replace(n.match[I],"");if(!y)return[];break}}}if(g===r)if(y==null)throw"Syntax error, unrecognized expression: "+g;else break;r=g}return v};var n=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
639.77 +CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
639.78 +relative:{"+":function(g,h){var k=typeof h==="string",m=k&&!/\W/.test(h);k=k&&!m;if(m)h=h.toLowerCase();m=0;for(var r=g.length,q;m<r;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=k||q&&q.nodeName.toLowerCase()===h?q||false:q===h}k&&p.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m<r;m++){var q=g[m];if(q){k=q.parentNode;g[m]=k.nodeName.toLowerCase()===h?k:false}}}else{m=0;for(r=g.length;m<r;m++)if(q=g[m])g[m]=
639.79 +k?q.parentNode:q.parentNode===h;k&&p.filter(h,g,true)}},"":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("parentNode",h,m,g,q,k)},"~":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("previousSibling",h,m,g,q,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];
639.80 +h=h.getElementsByName(g[1]);for(var m=0,r=h.length;m<r;m++)h[m].getAttribute("name")===g[1]&&k.push(h[m]);return k.length===0?null:k}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,m,r,q){g=" "+g[1].replace(/\\/g,"")+" ";if(q)return g;q=0;for(var v;(v=h[q])!=null;q++)if(v)if(r^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
639.81 +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m,
639.82 +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
639.83 +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
639.84 +setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h=
639.85 +h[3];k=0;for(m=h.length;k<m;k++)if(h[k]===g)return false;return true}else throw"Syntax error, unrecognized expression: "+r;},CHILD:function(g,h){var k=h[1],m=g;switch(k){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(k==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":k=h[2];var r=h[3];if(k===1&&r===0)return true;h=h[0];var q=g.parentNode;if(q&&(q.sizcache!==h||!g.nodeIndex)){var v=0;for(m=q.firstChild;m;m=
639.86 +m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;q.sizcache=h}g=g.nodeIndex-r;return k===0?g===0:g%k===0&&g/k>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
639.87 +"="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g,
639.88 +h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k<m;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var D;if(s.documentElement.compareDocumentPosition)D=function(g,h){if(!g.compareDocumentPosition||
639.89 +!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in s.documentElement)D=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(s.createRange)D=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),m=
639.90 +h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)j=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&&
639.91 +r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML="<a href='#'></a>";
639.92 +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}();
639.93 +(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,
639.94 +h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r<q;r++)p(g,h[r],k);return p.filter(m,k)};c.find=p;c.expr=p.selectors;c.expr[":"]=c.expr.filters;c.unique=p.uniqueSort;c.getText=a;c.isXMLDoc=x;c.contains=F})();var ab=/Until$/,bb=/^(?:parents|prevUntil|prevAll)/,
639.95 +cb=/,/;R=Array.prototype.slice;var Fa=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Pa.test(b))return c.filter(b,f,!d);else b=c.filter(b,a)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
639.96 +c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Fa(this,a,false),"not",a)},filter:function(a){return this.pushStack(Fa(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i=
639.97 +{},j;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a===
639.98 +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
639.99 +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
639.100 +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType===
639.101 +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,hb=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},G={option:[1,"<select multiple='multiple'>","</select>"],
639.102 +legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);
639.103 +return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
639.104 +wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&
639.105 +this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,
639.106 +"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===
639.107 +1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!Y.test(a))&&!G[(Ha.exec(a)||["",""])[1].toLowerCase()])try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){T(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
639.108 +this[0].parentNode){c.isFunction(a)||(a=c(a).detach());return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(t){return c.nodeName(t,"table")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}var e,i,j=a[0],o=[];if(c.isFunction(j))return this.each(function(t){var z=
639.109 +c(this);a[0]=j.call(this,t,b?z.html():w);return z.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ua(a,this,o);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var p=0,n=this.length;p<n;p++)d.call(b?f(this[p],i):this[p],e.cacheable||this.length>1||p>0?e.fragment.cloneNode(true):e.fragment)}o&&c.each(o,La)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
639.110 +function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){T(this.getElementsByTagName("*"));T([this])}this.parentNode&&this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&T(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},
639.111 +function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j==="string"){j=j.replace(db,hb);var o=(Ha.exec(j)||["",""])[1].toLowerCase(),p=G[o]||G._default,n=p[0];i=b.createElement("div");for(i.innerHTML=p[1]+j+p[2];n--;)i=i.lastChild;
639.112 +if(!c.support.tbody){n=fb.test(j);o=o==="table"&&!n?i.firstChild&&i.firstChild.childNodes:p[1]==="<table>"&&!n?i.childNodes:[];for(p=o.length-1;p>=0;--p)c.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!c.support.leadingWhitespace&&Y.test(j)&&i.insertBefore(b.createTextNode(Y.exec(j)[0]),i.firstChild);j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()===
639.113 +"text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e}});var ib=/z-?index|font-?weight|opacity|zoom|line-?height/i,Ia=/alpha\([^)]*\)/,Ja=/opacity=([^)]*)/,ja=/float/i,ka=/-([a-z])/ig,jb=/([A-Z])/g,kb=/^-?\d+(?:px)?$/i,lb=/^-?\d/,mb={position:"absolute",visibility:"hidden",display:"block"},nb=["Left","Right"],ob=["Top","Bottom"],pb=s.defaultView&&
639.114 +s.defaultView.getComputedStyle,Ka=c.support.cssFloat?"cssFloat":"styleFloat",la=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return $(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!ib.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""===
639.115 +"NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ia.test(a)?a.replace(Ia,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ja.exec(f.filter)[1])/100+"":""}if(ja.test(b))b=Ka;b=b.replace(ka,la);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?nb:ob;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=
639.116 +parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,mb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Ja.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ja.test(b))b=Ka;if(!d&&e&&e[b])f=e[b];else if(pb){if(ja.test(b))b="float";b=b.replace(jb,"-$1").toLowerCase();e=
639.117 +a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ka,la);f=a.currentStyle[b]||a.currentStyle[d];if(!kb.test(f)&&lb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=
639.118 +f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var qb=K(),rb=/<script(.|\s)*?\/script>/gi,sb=/select|textarea/i,tb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,O=/=\?(&|$)/,ma=/\?/,ub=/(\?|&)_=.*?(&|$)/,vb=/^(\w+:)?\/\/([^\/?#]+)/,
639.119 +wb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}c.ajax({url:a,type:f,dataType:"html",data:b,context:this,complete:function(i,j){if(j==="success"||j==="notmodified")this.html(e?c("<div />").append(i.responseText.replace(rb,
639.120 +"")).find(e):i.responseText);d&&this.each(d,[i.responseText,j,i])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sb.test(this.nodeName)||tb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});
639.121 +c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},
639.122 +ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",
639.123 +text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(p,o,j,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(p,x,j);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(r,q){(e.context?c(e.context):c.event).trigger(r,q)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,o,p=e.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,
639.124 +e.traditional);if(e.dataType==="jsonp"){if(n==="GET")O.test(e.url)||(e.url+=(ma.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!O.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&O.test(e.data)||O.test(e.url))){i=e.jsonpCallback||"jsonp"+qb++;if(e.data)e.data=(e.data+"").replace(O,"="+i+"$1");e.url=e.url.replace(O,"="+i+"$1");e.dataType="script";A[i]=A[i]||function(r){o=r;b();d();A[i]=w;try{delete A[i]}catch(q){}B&&
639.125 +B.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&n==="GET"){var t=K(),z=e.url.replace(ub,"$1_="+t+"$2");e.url=z+(z===e.url?(ma.test(e.url)?"&":"?")+"_="+t:"")}if(e.data&&n==="GET")e.url+=(ma.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");t=(t=vb.exec(e.url))&&(t[1]&&t[1]!==location.protocol||t[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&t){var B=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");
639.126 +C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!i){var D=false;C.onload=C.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;b();d();C.onload=C.onreadystatechange=null;B&&C.parentNode&&B.removeChild(C)}}}B.insertBefore(C,B.firstChild);return w}var F=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",
639.127 +e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}t||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ia){}if(e.beforeSend&&e.beforeSend.call(p,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",
639.128 +[x,e]);var g=x.onreadystatechange=function(r){if(!x||x.readyState===0){F||d();F=true;if(x)x.onreadystatechange=c.noop}else if(!F&&x&&(x.readyState===4||r==="timeout")){F=true;x.onreadystatechange=c.noop;j=r==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";if(j==="success")try{o=c.httpData(x,e.dataType,e)}catch(q){j="parsererror"}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,x,j);d();r==="timeout"&&x.abort();if(e.async)x=
639.129 +null}};try{var h=x.abort;x.abort=function(){if(x){h.call(x);if(x)x.readyState=0}g()}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){x&&!F&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||A,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol===
639.130 +"file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;if(e&&a.documentElement.nodeName==="parsererror")throw"parsererror";if(d&&
639.131 +d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))a=A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+a))();else throw"Invalid JSON: "+a;else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(e,i){i=
639.132 +c.isFunction(i)?i():i;f[f.length]=encodeURIComponent(e)+"="+encodeURIComponent(i)}var f=[];if(b===w)b=c.ajaxSettings.traditional;c.isArray(a)||a.jquery?c.each(a,function(){d(this.name,this.value)}):c.each(a,function e(i,j){if(c.isArray(j))c.each(j,function(o,p){b?d(i,p):e(i+"["+(typeof p==="object"||c.isArray(p)?o:"")+"]",p)});else!b&&j!=null&&typeof j==="object"?c.each(j,function(o,p){e(i+"["+o+"]",p)}):d(i,j)});return f.join("&").replace(wb,"+")}});var na={},xb=/toggle|show|hide/,yb=/^([+-]=)?([\d+-.]+)(.*)$/,
639.133 +Z,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a!=null)return this.animate(L("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(na[d])f=na[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
639.134 +na[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a!=null)return this.animate(L("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
639.135 +c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(L("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,o=this.nodeType===1&&c(this).is(":hidden"),
639.136 +p=this;for(j in a){var n=j.replace(ka,la);if(j!==n){a[n]=a[j];delete a[j];j=n}if(a[j]==="hide"&&o||a[j]==="show"&&!o)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(t,z){var B=new c.fx(p,i,t);if(xb.test(z))B[z==="toggle"?o?"show":"hide":z](a);
639.137 +else{var C=yb.exec(z),D=B.cur(true)||0;if(C){z=parseFloat(C[2]);var F=C[3]||"px";if(F!=="px"){p.style[t]=(z||1)+F;D=(z||1)/B.cur(true)*D;p.style[t]=D+F}if(C[1])z=(C[1]==="-="?-1:1)*z+D;B.custom(D,z,F)}else B.custom(D,z,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:L("show",1),slideUp:L("hide",1),slideToggle:L("toggle",
639.138 +1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
639.139 +b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
639.140 +null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=K();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!Z)Z=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
639.141 +"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=K(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
639.142 +this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
639.143 +c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(Z);Z=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
639.144 +null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
639.145 +f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(t){c.offset.setOffset(this,a,t)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
639.146 +b,e=b.ownerDocument,i,j=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var p=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;p-=b.scrollTop;n-=b.scrollLeft;if(b===d){p+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){p+=parseFloat(i.borderTopWidth)||
639.147 +0;n+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){p+=parseFloat(i.borderTopWidth)||0;n+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){p+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){p+=Math.max(j.scrollTop,o.scrollTop);n+=Math.max(j.scrollLeft,o.scrollLeft)}return{top:p,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),
639.148 +d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
639.149 +d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
639.150 +bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
639.151 +e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
639.152 +this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==w)return this.each(function(){if(i=wa(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=wa(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
639.153 +c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+
639.154 +b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
640.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
640.2 +++ b/web/static/js/sdemo.html Mon Apr 26 11:16:23 2010 +0200
640.3 @@ -0,0 +1,40 @@
640.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
640.5 +<html>
640.6 + <head>
640.7 + <title>Prova</title>
640.8 + </head>
640.9 +
640.10 + <body>
640.11 + <h1>Test</h1>
640.12 +
640.13 + <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
640.14 + <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
640.15 + <script type="text/javascript" src="./jquery.dataTables.min.js"></script>
640.16 + <script type="text/javascript" src="./lib/jquery.hoverIntent.js"></script>
640.17 + <script type="text/javascript" src="./lib/jquery.bgiframe.min.js"></script>
640.18 + <script type="text/javascript" src="./jquery.cluetip.js"></script>
640.19 +<table>
640.20 + <tr>
640.21 + <td title="Versione di logon.conf
640.22 + NOTA per WIN98: il numero di versione DEVE ESSERE INCREMENTATO
640.23 + AD OGNI MODIFICA di logon.conf se si vuole che il client Win98
640.24 + aggiorni i parametri di registro già precedentemente settati)">Versione</td>
640.25 + <td></td>
640.26 + </tr>
640.27 +</table>
640.28 +
640.29 +
640.30 +<script>
640.31 +$(document).ready(function () {
640.32 +
640.33 + $('td.title').cluetip({splitTitle: '|'});
640.34 +});
640.35 +</script>
640.36 + <hr>
640.37 + <address><a href="mailto:sandro@ubuntu">Sandro Dentella</a></address>
640.38 +<!-- Created: Thu Feb 4 15:26:02 CET 2010 -->
640.39 +<!-- hhmts start -->
640.40 +Last modified: Thu Feb 4 15:46:36 CET 2010
640.41 +<!-- hhmts end -->
640.42 + </body>
640.43 +</html>
641.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
641.2 +++ b/web/sync_src Mon Apr 26 11:16:23 2010 +0200
641.3 @@ -0,0 +1,5 @@
641.4 +#!/bin/bash
641.5 +
641.6 +rsync -a . --exclude local_settings.py --exclude .hg /misc/src/hg/isi/isi-web/shared/isiweb_
641.7 +rsync -a . --exclude local_settings.py --exclude .hg --exclude isi.db [email protected]:/usr/share/isi/isiweb
641.8 +ssh [email protected] /etc/init.d/isiweb restart
642.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
642.2 +++ b/web/templates/base.mako Mon Apr 26 11:16:23 2010 +0200
642.3 @@ -0,0 +1,83 @@
642.4 +<%inherit file="/static/base.mako"/>
642.5 +
642.6 +<%def name="title()">Reteidra</%def>
642.7 +## navigation menu
642.8 +<%def name="navigation_menu()"></%def>
642.9 +
642.10 +<%def name="main_menu()">
642.11 + <div id="main_menu" class="horizontal_menu">
642.12 + <ul id="treemenu">
642.13 + % if user.is_staff:
642.14 + <li class="mainli"><a href="/users/start/" title="Gestione gruppi/utenti"
642.15 + class="mainfoldericon "><span>Utenti</span></a></li>
642.16 + <li class="mainli"><a href="/samba/conf/?nt=0" title="Configurazione Dominio samba"
642.17 + class="mainfoldericon "><span>Samba</span></a></li>
642.18 + <li class="mainli"><a href="/logon/conf/?nt=0" title="Configurazione logon dei client"
642.19 + class="mainfoldericon "><span>Logon</span></a></li>
642.20 + <li class="mainli"><a href="/dnsmasq/conf/?nt=0" title="Configurazione dhcp/dns"
642.21 + class="mainfoldericon "><span>DnsMasq</span></a></li>
642.22 + % endif
642.23 + <li class="mainli"><a href="/navigazione/conf/?nt=0" title="Inibizione navigazione"
642.24 + class="mainfoldericon "><span>Navigazione</span></a></li>
642.25 + </ul>
642.26 + </div>
642.27 + <div style="clear:left;"></div>
642.28 +</%def>
642.29 +
642.30 +
642.31 +<%def name="js()">
642.32 + <script type="text/javascript" src="/jsi18n/"></script>
642.33 + <script type="text/javascript" src="/media/js/core.js"></script>
642.34 + <script type="text/javascript" src="/media/js/admin/RelatedObjectLookups.js"></script>
642.35 + <script type="text/javascript" src="/media/js/SelectBox.js"></script>
642.36 + <script type="text/javascript" src="/media/js/SelectFilter2.js"></script>
642.37 + <script type="text/javascript" src="/media/js/calendar.js"></script>
642.38 + <script type="text/javascript" src="/media/js/admin/DateTimeShortcuts.js"></script>
642.39 + <script type="text/javascript" src="/static/js/jquery.min.js"></script>
642.40 + <script type="text/javascript" src="/static/js/jquery-ui.min.js"></script>
642.41 + <script type="text/javascript" src="/static/js/jquery.dataTables.min.js"></script>
642.42 + <script type="text/javascript" src="/static/js/cluetip/lib/jquery.hoverIntent.js"></script>
642.43 + <script type="text/javascript" src="/static/js/cluetip/lib/jquery.bgiframe.min.js"></script>
642.44 + <script type="text/javascript" src="/static/js/cluetip/jquery.cluetip.js"></script>
642.45 +</%def>
642.46 +
642.47 +<%def name="css()">
642.48 + <link rel="stylesheet" type="text/css" href="/static/css/ui/themes/isi/ui.all.css" />
642.49 + <link rel="stylesheet" type="text/css" href="/static/css/ui/themes/isi/ui.theme.css" />
642.50 + <link rel="stylesheet" type="text/css" href="/static/css/cluetip.css" />
642.51 + ${parent.css()}
642.52 +</%def>
642.53 +
642.54 +<%def name="footer()">
642.55 + ${parent.footer()}
642.56 + <a href="http://www.python.org"><img
642.57 + src="/static/img/python-powered-w-70x28.png" alt="Python-powered" /></a> - Written by Alessandro Dentella
642.58 +</%def>
642.59 +
642.60 +<%def name="calendar_js()">
642.61 +</%def>
642.62 +
642.63 +<%def name="header()">
642.64 + <div id="header">
642.65 + <div id="logo"></div>
642.66 +
642.67 + <div id="user-tools">
642.68 + % if user.is_authenticated():
642.69 + <a href="/accounts/logout/?next=/accounts/login">Logout ${user.username} </a>
642.70 + <a href="/accounts/change_password/"> | Password </a>
642.71 + % if user.is_staff:
642.72 + | <a href="/admin/"> Admin</a>
642.73 + % endif
642.74 + % else:
642.75 + <a href="/accounts/login/">Login</a>
642.76 + % endif
642.77 +## | <a href="/help${request.path.replace('/help', '')}" >Help</a>
642.78 + | <a href="/docs/" >Docs</a>
642.79 + </div> <!-- user-tools-->
642.80 + <div style="clear:left;"></div>
642.81 +
642.82 + ${self.main_menu()}
642.83 + </div> <!-- header -->
642.84 + <div id="bottomheader"></div>
642.85 +</%def>
642.86 +
643.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
643.2 +++ b/web/urls.py Mon Apr 26 11:16:23 2010 +0200
643.3 @@ -0,0 +1,27 @@
643.4 +from django.conf.urls.defaults import *
643.5 +from vov.functions import conf
643.6 +
643.7 +# Uncomment the next two lines to enable the admin:
643.8 +from django.contrib import admin
643.9 +admin.autodiscover()
643.10 +
643.11 +urlpatterns = patterns('',
643.12 + # Example:
643.13 + (r'^$', include('isiweb.users.urls')),
643.14 +# (r'^', include('isiweb.samba.urls')),
643.15 + (r'^users/', include('isiweb.users.urls')),
643.16 + (r'^samba/', include('isiweb.samba.urls')),
643.17 + (r'^dnsmasq/', include('isiweb.dnsmasq.urls')),
643.18 + (r'^logon/', include('isiweb.logon.urls')),
643.19 + (r'^navigazione/', include('isiweb.navigazione.urls')),
643.20 +
643.21 +
643.22 + # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
643.23 + # to INSTALLED_APPS to enable admin documentation:
643.24 + # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
643.25 +
643.26 + # Uncomment the next line to enable the admin:
643.27 + (r'^admin/', include(admin.site.urls)),
643.28 +)
643.29 +urlpatterns += conf.vov_default_patterns(
643.30 + default_url='/users/start/')
644.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
644.2 +++ b/web/users/isildap.py Mon Apr 26 11:16:23 2010 +0200
644.3 @@ -0,0 +1,94 @@
644.4 +# import pumpkin
644.5 +# from pumpkin import fields, filters
644.6 +# from pumpkin.resource import LDAPResource
644.7 +# from pumpkin.directory import Directory
644.8 +# from pumpkin.base import Model
644.9 +# from django.conf import settings
644.10 +# from isi import IsiConn
644.11 +
644.12 +
644.13 +
644.14 +
644.15 +# def get_conn():
644.16 +
644.17 +# isiconn = IsiConn()
644.18 +# LDAP_RES = LDAPResource()
644.19 +# LDAP_RES.server = getattr(settings, 'LDAP_SERVER', isiconn.uri)
644.20 +# LDAP_RES.login = getattr(settings, 'LDAP_ROOTBINDDN', isiconn.rootdn)
644.21 +# LDAP_RES.password = getattr(settings, 'LDAP_PASSWORD', isiconn.passwd)
644.22 +# LDAP_RES.TLS = False
644.23 +# LDAP_RES.basedn = getattr(settings, 'LDAP_BASEDN', isiconn.base)
644.24 +# LDAP_RES.method = pumpkin.resource.AUTH_SIMPLE
644.25 +
644.26 +# LDAP_CONN = Directory()
644.27 +# LDAP_CONN.connect(LDAP_RES)
644.28 +# return LDAP_CONN
644.29 +
644.30 +# def get_user(username, conn=None):
644.31 +# return (conn or get_conn()).get(IsiUser, search_filter=filters.eq('uid', username))
644.32 +
644.33 +# def get_group(group_name):
644.34 +# return get_conn().get(PosixGroup, search_filter=filters.eq('name', group_name))
644.35 +
644.36 +# class IsiUser(Model):
644.37 +
644.38 +# """This is my custom model"""
644.39 +
644.40 +# _object_class_ = ['posixAccount', 'inetOrgPerson', 'posixAccount', 'shadowAccount', 'sambaSamAccount']
644.41 +# _rdn_ = 'logname'
644.42 +
644.43 +# logname = fields.StringField('uid')
644.44 +# classe = fields.StringField('departmentNumber')
644.45 +# uid = fields.IntegerField('uidNumber')
644.46 +# gid = fields.IntegerField('gidNumber')
644.47 +# fullname = fields.StringField('cn')
644.48 +# firstname = fields.StringField('givenName')
644.49 +# surname = fields.StringField('sn')
644.50 +# shell = fields.StringField('loginShell')
644.51 +# home = fields.StringField('homeDirectory')
644.52 +# mail = fields.StringListField('mail')
644.53 +
644.54 +# def get_logname(self):
644.55 +# return self.logname
644.56 +
644.57 +# def url(self, text=None):
644.58 +# return u'<a href="/users/user/detail/%s">%s</a>' % (self.logname, text or self.logname)
644.59 +
644.60 +# class PosixGroup(Model):
644.61 +# _object_class_ = 'posixGroup'
644.62 +# _rdn_ = 'name'
644.63 +# name = fields.StringField('cn')
644.64 +# gid = fields.IntegerField('gidNumber')
644.65 +# members = fields.StringListField('memberUid')
644.66 +
644.67 +
644.68 +# def __repr__(self):
644.69 +# return u'<%s %s >' % (self.__class__.__name__, self.name)
644.70 +
644.71 +# def __str__(self):
644.72 +# return u'%s' % (self.name)
644.73 +
644.74 +# def url(self, text=None):
644.75 +# return u'<a href="/users/group/%s">%s</a>' % (self.name, text or self.name)
644.76 +
644.77 +# def members_info(self):
644.78 +# if self.members:
644.79 +# return "members: %s (%s)" % (len(self.members), ",".join(self.members))
644.80 +# return ''
644.81 +
644.82 +# def members_as_users(self):
644.83 +
644.84 +# conn = get_conn()
644.85 +# return [get_user(u, conn) for u in sorted(self.members)]
644.86 +
644.87 +
644.88 +# #pg = PosixGroup(LDAP_CONN, 'cn=admins,ou=Groups,dc=isi,dc=lan')
644.89 +
644.90 +# # sci = PosixGroup(LDAP_CONN)
644.91 +# # sci.name = u'sciabattoni'
644.92 +# # sci.members = [u'sandro']
644.93 +# # sci.set_parent('ou=Groups,dc=isi,dc=lan')
644.94 +# # sci.gid = 1111
644.95 +# # sci.save()
644.96 +
644.97 +
645.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
645.2 +++ b/web/users/menu.txt Mon Apr 26 11:16:23 2010 +0200
645.3 @@ -0,0 +1,4 @@
645.4 +Utenti, users/user/, Utenti,
645.5 +Samba, samba/conf/, Samba,
645.6 +Logon, logon/conf/, Logon,
645.7 +DnsMasq, dnsmas/user/, DnsMasq,
646.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
646.2 +++ b/web/users/models.py Mon Apr 26 11:16:23 2010 +0200
646.3 @@ -0,0 +1,3 @@
646.4 +from django.db import models
646.5 +
646.6 +# Create your models here.
647.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
647.2 +++ b/web/users/templates/users/change_password_form.mako Mon Apr 26 11:16:23 2010 +0200
647.3 @@ -0,0 +1,22 @@
647.4 +<%inherit file="${jun.get_parent_template(context)}"/>
647.5 +
647.6 +<%def name="title()">Cambio Password</%def>
647.7 +
647.8 +<%def name="layout()">
647.9 +
647.10 +h=username=$!username
647.11 +password
647.12 +--
647.13 +admin_password s=Imposta
647.14 +
647.15 +</%def>
647.16 +
647.17 +${jun.show_form_errors(form)}
647.18 +${forms.mako_create_nform(context, layout, form, style='-')}
647.19 +
647.20 +
647.21 +<script type="text/javascript">
647.22 + $(document).ready(function() {
647.23 + $('td label[title]').cluetip({splitTitle: '|'});
647.24 + });
647.25 +</script>
648.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
648.2 +++ b/web/users/templates/users/classe_detail.mako Mon Apr 26 11:16:23 2010 +0200
648.3 @@ -0,0 +1,25 @@
648.4 +<%inherit file="${jun.get_parent_template(context)}"/>
648.5 +
648.6 +<h2>${classe.name}</h2>
648.7 +
648.8 +<table id="utable" >
648.9 +<thead>
648.10 +<tr>
648.11 + <th>logname</th>
648.12 + <th>nome</th>
648.13 + <th>cognome</th>
648.14 +</tr>
648.15 +</thead>
648.16 +<tbody>
648.17 +% for u in classe.members_as_users(order_by='last_name'):
648.18 +
648.19 + <tr>
648.20 + <td>${u.logname}</td>
648.21 + <td>${u.first_name}</td>
648.22 + <td>${u.last_name}</td>
648.23 + </tr>
648.24 +
648.25 +% endfor
648.26 +</tbody>
648.27 +</table>
648.28 +
649.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
649.2 +++ b/web/users/templates/users/create_links.mako Mon Apr 26 11:16:23 2010 +0200
649.3 @@ -0,0 +1,25 @@
649.4 +<%inherit file="${jun.get_parent_template(context)}"/>
649.5 +
649.6 +<%def name="title()">Creazione link</%def>
649.7 +
649.8 +<%def name="layout()">
649.9 +
649.10 +h=name=${name}
649.11 +s=Procedi
649.12 +
649.13 +</%def>
649.14 +
649.15 +<h2>Crea link studenti</h2>
649.16 +
649.17 +<div id="content_popup">
649.18 + <div id="testo_popup" class="ui-dialog-titlebar ui-widget-header
649.19 + ui-corner-all ui-helper-clearfix" style="margin: 20px; padding: 10px;">
649.20 +
649.21 + Desideri rigenerare i link degli utenti per la classe ${name}?
649.22 +
649.23 + </div>
649.24 +${jun.show_form_errors(form)}
649.25 +${forms.mako_create_nform(context, layout, form, style='-')}
649.26 +
649.27 +
649.28 +</div>
650.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
650.2 +++ b/web/users/templates/users/expire_password.mako Mon Apr 26 11:16:23 2010 +0200
650.3 @@ -0,0 +1,26 @@
650.4 +<%inherit file="${jun.get_parent_template(context)}"/>
650.5 +
650.6 +<%def name="title()">Forza scadenza password</%def>
650.7 +
650.8 +<%def name="layout()">
650.9 +
650.10 +h=name=${name}
650.11 +h=model=${model}
650.12 +s=Procedi
650.13 +
650.14 +</%def>
650.15 +
650.16 +<h2>Scadenza password</h2>
650.17 +
650.18 +<div id="content_popup">
650.19 + <div id="testo_popup" class="ui-dialog-titlebar ui-widget-header
650.20 + ui-corner-all ui-helper-clearfix" style="margin: 20px; padding: 10px;">
650.21 +
650.22 + Desideri forzarela scadenza password per la classe ${name}?
650.23 +
650.24 + </div>
650.25 +${jun.show_form_errors(form)}
650.26 +${forms.mako_create_nform(context, layout, form, style='-')}
650.27 +
650.28 +
650.29 +</div>
651.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
651.2 +++ b/web/users/templates/users/group_detail.mako Mon Apr 26 11:16:23 2010 +0200
651.3 @@ -0,0 +1,85 @@
651.4 +<%inherit file="${jun.get_parent_template(context)}"/>
651.5 +
651.6 +% if group_name:
651.7 + <h2>${group_name}</h2>
651.8 +%else:
651.9 + <h2>Tutti gli utenti</h2>
651.10 +%endif
651.11 +
651.12 +<table id="utable" >
651.13 +<thead>
651.14 +<tr>
651.15 + <th></th>
651.16 + <th>logname</th>
651.17 + <th>nome</th>
651.18 + <th>cognome</th>
651.19 + <th>maingroup</th>
651.20 + <th>classe</th>
651.21 +</tr>
651.22 +</thead>
651.23 +<tbody>
651.24 +% for u in users:
651.25 +
651.26 + <tr>
651.27 + <td><a href="/users/user/edit/${u.logname}/" class="wpopup"><img src="/static/img/icon_changelink.gif"></a></td>
651.28 + <td><a href="/users/user/detail/${u.logname}/" class="logname">${u.logname}</a></td>
651.29 + <td>${u.first_name or ''}</td>
651.30 + <td>${u.last_name or ''}</td>
651.31 + <td>${u.maingroup}</td>
651.32 + <td>${u.classe or ''}</td>
651.33 + </tr>
651.34 +
651.35 +% endfor
651.36 +</tbody>
651.37 +</table>
651.38 +
651.39 + % if group:
651.40 + <h2>Azioni</h2>
651.41 + <ul>
651.42 + <li><a href="/users/group/set_quota/${group.name}/" class="wpopup">Imposta quota</a></li>
651.43 + % if group.is_class() or group.is_course():
651.44 + <li><a href="/users/group/create_links/${group.name}" class="wpopup">Crea link agli alunni</a></li>
651.45 + % endif
651.46 + <li><a href="/users/group/expire_password/${group.name}/"
651.47 + class="wpopup">Forsa scadenza password</a></li>
651.48 +## <li><a href="/users/group/${group.name}/show_expire/" class="wpopup">Mostra scadenza password</a></li>
651.49 + % endif
651.50 +</ul>
651.51 +
651.52 +<script type="text/javascript" >
651.53 +
651.54 + $(document).ready(function() {
651.55 + $('.popup').click(function() {
651.56 + $('<div></div>').load(this.href + '?&nt=1').dialog({modal:true, width:660});
651.57 + return false;
651.58 + });
651.59 +
651.60 + $('td label[title]').cluetip({splitTitle: '|'});
651.61 +
651.62 + $('#utable').dataTable( {
651.63 +## "aaSorting": [[0,'asc'],],
651.64 + "bPaginate": false,
651.65 + "bLengthChange": true,
651.66 + "bFilter": true,
651.67 + "bSort": true,
651.68 + "bInfo": true,
651.69 + "bAutoWidth": false}
651.70 + );
651.71 +
651.72 + ## overlay popup per descrizione
651.73 + $('.logname').click(function() {
651.74 + $('<div></div>').load(this.href + '?&nt=1').dialog({modal:true, width:660});
651.75 + return false;
651.76 + });
651.77 +
651.78 + ## window popup per edit
651.79 + $('.wpopup').click(function() {
651.80 + window.open(this.href + '?&popup=1', '', 'width=600, height=400, status=status, scrollbars=yes');
651.81 + return false;
651.82 + });
651.83 + });
651.84 +
651.85 +
651.86 +</script>
651.87 +
651.88 +
652.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
652.2 +++ b/web/users/templates/users/group_form.mako Mon Apr 26 11:16:23 2010 +0200
652.3 @@ -0,0 +1,23 @@
652.4 +<%inherit file="${jun.get_parent_template(context)}"/>
652.5 +
652.6 +<%def name="title()">Aggiunti un gruppo</%def>
652.7 +
652.8 +<%def name="layout()">
652.9 +
652.10 +name
652.11 +--
652.12 +s=Aggiungi
652.13 +
652.14 +</%def>
652.15 +
652.16 +<h2>Aggiungi un gruppo</h2>
652.17 +
652.18 +${jun.show_form_errors(form)}
652.19 +${forms.mako_create_nform(context, layout, form, style='-')}
652.20 +
652.21 +
652.22 +<script type="text/javascript" >
652.23 + $(document).ready(function() {
652.24 + $('td label[title]').cluetip({splitTitle: '|'});
652.25 + });
652.26 +</script>
653.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
653.2 +++ b/web/users/templates/users/group_list.mako Mon Apr 26 11:16:23 2010 +0200
653.3 @@ -0,0 +1,51 @@
653.4 +<%inherit file="${jun.get_parent_template(context)}"/>
653.5 +
653.6 +
653.7 +<table id="gtable" >
653.8 +<thead>
653.9 +<tr>
653.10 + <th>nome gruppo</th>
653.11 + <th>members</th>
653.12 +</tr>
653.13 +</thead>
653.14 +<tbody>
653.15 +% for g in groups:
653.16 +
653.17 + <tr>
653.18 + <td><a class="gr_popup" href="/users/group/detail/${g.name}/">${g}</a>
653.19 + </td>
653.20 + </td>
653.21 + <td>
653.22 + ${g.members_info()}
653.23 + </td>
653.24 + </tr>
653.25 +
653.26 +% endfor
653.27 +</tbody>
653.28 +</table>
653.29 +
653.30 +<script type="text/javascript" >
653.31 +
653.32 + $(document).ready(function() {
653.33 + $('.gr_popup').click(function() {
653.34 + $('<div></div>').load(this.href + '?&nt=1').dialog({modal:true, width:660});
653.35 + return false;
653.36 + });
653.37 +
653.38 + });
653.39 +
653.40 +
653.41 + $(document).ready(function(){
653.42 + $('#gtable').dataTable( {
653.43 +## "aaSorting": [[0,'asc']],
653.44 + "bPaginate": false,
653.45 + "bLengthChange": true,
653.46 + "bFilter": true,
653.47 + "bSort": true,
653.48 + "bInfo": true,
653.49 + "bAutoWidth": false}
653.50 + );
653.51 + });
653.52 +</script>
653.53 +
653.54 +
654.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
654.2 +++ b/web/users/templates/users/missing_object.mako Mon Apr 26 11:16:23 2010 +0200
654.3 @@ -0,0 +1,6 @@
654.4 +<%inherit file="${jun.get_parent_template(context)}"/>
654.5 +
654.6 +
654.7 +<h2>Richiesta fallita</h2>
654.8 +
654.9 +L'oggetto richiesto (${name}) non esiste
655.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
655.2 +++ b/web/users/templates/users/quota_set.mako Mon Apr 26 11:16:23 2010 +0200
655.3 @@ -0,0 +1,32 @@
655.4 +<%inherit file="${jun.get_parent_template(context)}"/>
655.5 +
655.6 +<%def name="title()">Imposta quota</%def>
655.7 +
655.8 +<%def name="layout()">
655.9 +
655.10 +h=name=${name}
655.11 +h=model=${model}
655.12 +soft_space_limit
655.13 +hard_space_limit
655.14 +##soft_file_limit hard_file_limit
655.15 +
655.16 +s=Procedi
655.17 +
655.18 +</%def>
655.19 +
655.20 +<h2>Imposta quota</h2>
655.21 +
655.22 +La quota viene impotata per tutti gli utenti del gruppo che siano membri in
655.23 + questo momento. Membri aggiunti in futuro *non* hanno impostata la quota.
655.24 +
655.25 +${jun.show_form_errors(form)}
655.26 +${forms.mako_create_nform(context, layout, form, style='-')}
655.27 +
655.28 +
655.29 +</div>
655.30 +
655.31 +<script type="text/javascript" >
655.32 + $(document).ready(function() {
655.33 + $('td label[title]').cluetip({splitTitle: '|'});
655.34 + });
655.35 +</script>
656.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
656.2 +++ b/web/users/templates/users/start.mako Mon Apr 26 11:16:23 2010 +0200
656.3 @@ -0,0 +1,117 @@
656.4 +<%inherit file="${jun.get_parent_template(context)}"/>
656.5 +
656.6 +<%def name="sezione(sez)">
656.7 +
656.8 + <div id="${sez}" class="ui-tabs-hide tab" >
656.9 + </div>
656.10 +</%def>
656.11 +
656.12 +<div id="tabs">
656.13 + <ul >
656.14 + %for sez in ('utenti', 'gruppi', 'classi'):
656.15 + <li><a href="#${sez}">${sez}</a></li>
656.16 + %endfor
656.17 + </ul>
656.18 + ${self.users()}
656.19 + ${self.gruppi()}
656.20 + ${self.classi()}
656.21 +
656.22 +</div> <!-- tabs -->
656.23 +
656.24 +
656.25 +<%def name="gruppi()">
656.26 +<div id="gruppi">
656.27 + <ul>
656.28 + <li><a href="/users/group/add/" class="w1popup">Aggiungi un gruppo</a>
656.29 + <li><a href="/users/group/list/" id="mostra_gruppi">Mostra tutti i gruppi</a>
656.30 + </ul>
656.31 +
656.32 + <div id="list_group">
656.33 + </div>
656.34 +
656.35 +
656.36 + </div>
656.37 +</%def>
656.38 +
656.39 +<%def name="users()">
656.40 +<div id="utenti">
656.41 +
656.42 + <ul>
656.43 + <li><a href="/users/user/add/" class="w1popup">Aggiungi un utente</a>
656.44 + <li><a href="/users/user/fileadd/" class="w1popup">Aggiungi utenti da file</a>
656.45 + <li><a href="/users/user/convert/" class="w1popup">Converti formato utenti:</a>
656.46 + permette di importare da 'sissi' e 'isi' e di gestire nomi doppi
656.47 + <li><a href="/users/user/list/" class="mostra_users">Mostra tutti gli utenti</a>
656.48 + <li>Mostra gli utenti del gruppo
656.49 + %for g in ('docenti', 'alunni', 'admins', 'ata', 'segreteria', 'esterni'):
656.50 + <a href="/users/user/list/${g}" class="mostra_users">${g}</a>
656.51 + %endfor
656.52 + </li>
656.53 + </ul>
656.54 +
656.55 + <div id="list_users">
656.56 + </div>
656.57 +
656.58 +
656.59 +</div>
656.60 + </%def>
656.61 +
656.62 +<%def name="classi()">
656.63 + <div id="classi">
656.64 + <ul>
656.65 + %for c in classes:
656.66 + <li><a href="/users/user/list/${c}/" class="popup_classe">${c}</a></li>
656.67 + %endfor
656.68 + </ul>
656.69 +
656.70 + </div>
656.71 +</%def>
656.72 +
656.73 +
656.74 +
656.75 +
656.76 +
656.77 +
656.78 +<script type="text/javascript" >
656.79 +$(document).ready(function () {
656.80 +
656.81 + $('#tabs').tabs();
656.82 + $('td.title').cluetip({splitTitle: '|' });
656.83 +## $('td.title').cluetip({splitTitle: '|', sticky: true, closePosition: 'title', arrows: true });
656.84 +
656.85 + $('.toggle').click(function(){
656.86 + $('.advanced').toggle();
656.87 + });
656.88 +
656.89 + ## Mostra gruppi
656.90 + $('#mostra_gruppi').click(function() {
656.91 + var ref = this;
656.92 + $('#list_group').load(ref.href + '?nt=1');
656.93 + return false;
656.94 + });
656.95 + ## Mostra users
656.96 + $('.mostra_users').click(function() {
656.97 + var ref = this;
656.98 + $('#list_users').load(ref.href + '?nt=1');
656.99 + return false;
656.100 + });
656.101 +
656.102 + ## Mostra classe
656.103 + $('.popup_classe').click(function() {
656.104 + var ref = this;
656.105 + $('<div></div>').load(ref.href + '?nt=1').dialog({modal: true,
656.106 + width:800, heigh: 600});
656.107 + return false;
656.108 + });
656.109 +
656.110 + $('.w1popup').click(function() {
656.111 + window.open(this.href + '?&popup=1', '', 'width=650, height=550, scrollbars=yes');
656.112 + return false;
656.113 + });
656.114 +
656.115 +
656.116 +
656.117 +});
656.118 +</script>
656.119 +
656.120 +
657.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
657.2 +++ b/web/users/templates/users/user_bulk_form.mako Mon Apr 26 11:16:23 2010 +0200
657.3 @@ -0,0 +1,40 @@
657.4 +<%inherit file="${jun.get_parent_template(context)}"/>
657.5 +
657.6 +<%def name="title()">Aggiunti utenti da file</%def>
657.7 +
657.8 +<%def name="layout()">
657.9 +
657.10 +user_file
657.11 +--
657.12 +expire use_cf
657.13 +update_users default_password
657.14 +--
657.15 +s=Importa
657.16 +
657.17 +</%def>
657.18 +
657.19 +<h2>Aggiungi utenti da file</h2>
657.20 +
657.21 +L'aggiunta utenti da file prende un tempo lungo, circa 1 secondo ad utente
657.22 +ovvero fino a 2 minuti per 100 utenti. Non interrrompete il caricamento.
657.23 +
657.24 +<h3>Conversione</h3>
657.25 +
657.26 +Se temete collisioni nei nomi dei dati potete passare il file utenti tramite
657.27 +l'importazione con <a href="/users/user/convert/?popup=1">conversione dei dati</a>, che
657.28 +accetta anche il formato 'isi' nonché file in formato excel
657.29 +
657.30 +<h3>Password</h3>
657.31 +Potete usare un password di default o usar il CF come password (primi o
657.32 +caratteri con prima lettera maiuscola). Se volete password casuali dovete
657.33 +passare il file attraverso la conversione del formato.
657.34 +
657.35 +${jun.show_form_errors(form)}
657.36 +${forms.mako_create_nform(context, layout, form, style='-')}
657.37 +
657.38 +
657.39 +<script type="text/javascript" >
657.40 +$(document).ready(function () {
657.41 + $('td label[title]').cluetip({splitTitle: '|'});
657.42 +});
657.43 +</script>
658.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
658.2 +++ b/web/users/templates/users/user_convert.mako Mon Apr 26 11:16:23 2010 +0200
658.3 @@ -0,0 +1,55 @@
658.4 +<%inherit file="${jun.get_parent_template(context)}"/>
658.5 +
658.6 +
658.7 +<%def name="create_table(user_list)">
658.8 + <table>
658.9 + <thead>
658.10 + <tr><td>Logname</td><td>Nome</td><td>Classe</td></tr>
658.11 + </thead>
658.12 + <tbody>
658.13 + % for u in user_list:
658.14 + <tr>
658.15 + <td>${u.logname}</td><td>${'%s %s' % (u.first_name or '',
658.16 + u.last_name)}</td><td>${u.classe or ''}</td>
658.17 + </tr>
658.18 + % endfor
658.19 + </tbody>
658.20 + </table>
658.21 +</%def>
658.22 +
658.23 +
658.24 +<%def name="title()">File</%def>
658.25 +
658.26 +<h2>File definizione utenti</h2>
658.27 +Il file con la definizione degli utenti può essere scaricato <a
658.28 + href="/static/utenti/users.csv">qui</a>. L'immissione deve
658.29 + essere fatta tramite il normale <a href="/users/user/fileadd/?popup=1">inserimento utenti</a>
658.30 +
658.31 +% if bulk.renamed:
658.32 + <h3>Utenti da rinominare per nomi doppi</h3>
658.33 + Nel file ci sono ${len(bulk.renamed)} utenti da rinominare:
658.34 + ${create_table(bulk.renamed)}
658.35 +% endif
658.36 +
658.37 +% if bulk.deleted:
658.38 + <h3>Utenti da cancellare <img src="/static/img/icon_deletelink.gif"></h3>
658.39 +
658.40 + Nel file ci sono ${len(bulk.deleted)} utenti che verranno cancellati:
658.41 + ${create_table(bulk.deleted)}
658.42 +
658.43 +% endif
658.44 +
658.45 +% if bulk.get_updated_users(logname=True):
658.46 + <h3>Utenti da aggiornare</h3>
658.47 + Nel file ci sono ${len(bulk.get_updated_users(logname=True))} utenti che
658.48 + verranno aggiornati
658.49 + ${create_table(bulk.get_updated_users(logname=False))}
658.50 +
658.51 +% endif
658.52 +
658.53 +% if bulk.get_new_users(logname=True):
658.54 + <h3>Utenti nuovi</h3>
658.55 + Nel file ci sono ${len(bulk.get_new_users(logname=True))} utenti nuovi
658.56 + ${create_table(bulk.get_new_users(logname=False))}
658.57 +% endif
658.58 +
659.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
659.2 +++ b/web/users/templates/users/user_convert_form.mako Mon Apr 26 11:16:23 2010 +0200
659.3 @@ -0,0 +1,51 @@
659.4 +<%inherit file="${jun.get_parent_template(context)}"/>
659.5 +
659.6 +<%def name="title()">Aggiunti utenti da file</%def>
659.7 +
659.8 +<%def name="layout()">
659.9 +
659.10 +user_file
659.11 +file_format
659.12 +user_format
659.13 +maingroup
659.14 +extended
659.15 +random_password
659.16 +--
659.17 +s=Converti
659.18 +
659.19 +</%def>
659.20 +
659.21 +<h2>Conversione formato utenti</h2>
659.22 +
659.23 +Al momento questa pagina permette la conversione di un file di utenti
659.24 +in formato <tt>.isi</tt> a partire da
659.25 +<ul>
659.26 +<li><a href="/docs/gestione/comandi_isi.html#formato-sissi">Sissi - il sistema usato da molte amministrazioni scolastiche</li>
659.27 +<li><a href="/docs/gestione/comandi_isi.html#formato-file-isi">.isi</a> - isi stesso. Questa conversione ha senso per gestire doppioni e
659.28 + password casuali</li>
659.29 +</ul>
659.30 +
659.31 +La documentazione ufficiale di <a href="/docs/">ReteISI</a> riporta la definizione dei due
659.32 +formati.
659.33 +
659.34 +Il file che si carica deve contenere *tutti* gli utenti per il gruppo
659.35 +definito, gli utenti del gruppo non compresi nel file verranno
659.36 +marcati per la cancellazione (avranno un '-' attaccato alla logname).
659.37 +
659.38 +Questo garantisce che utenti che non sono più della scuola vengano
659.39 +eliminati. Lo scenario normale è che il maingroup è 'alunni'.
659.40 +
659.41 +Questa form mostra una pagina con il link degli utenti da passare alla
659.42 + sezione di gestione utenti e mostra cosa succede ma *non effettua alcuna
659.43 + cancellazione*, le righe contrassegnate dal '-' indicano gli utenti che
659.44 + verranno eliminati.
659.45 +
659.46 +${jun.show_form_errors(form)}
659.47 +${forms.mako_create_nform(context, layout, form, style='-')}
659.48 +
659.49 +
659.50 +<script type="text/javascript" >
659.51 +$(document).ready(function () {
659.52 + $('td label[title]').cluetip({splitTitle: '|'});
659.53 +});
659.54 +</script>
660.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
660.2 +++ b/web/users/templates/users/user_detail.mako Mon Apr 26 11:16:23 2010 +0200
660.3 @@ -0,0 +1,56 @@
660.4 +<%inherit file="${jun.get_parent_template(context)}"/>
660.5 +
660.6 +
660.7 +<h2>Utente: ${"%s (%s %s)" % (u.logname, u.first_name or '', u.last_name)}</h2>
660.8 +
660.9 +
660.10 +<table>
660.11 +
660.12 +% for at in ( 'logname first_name last_name maingroup home uid gid classe cf'.split()):
660.13 + <tr>
660.14 + <td><b>${at}:</b> </td><td>${getattr(u, at) or ''} </td>
660.15 + </tr>
660.16 +% endfor
660.17 + <tr>
660.18 + <td><b>gruppi</b></td><td>${u.get_my_groups(as_text=True)}</td>
660.19 + </tr>
660.20 +</table>
660.21 +
660.22 +<h3>Azioni</h3>
660.23 +<ul>
660.24 + <li> <a href="/users/user/password/change/${u.logname}/" class="popup">Imposta password</a>
660.25 + </li>
660.26 +
660.27 +## <li>Imposta la <a href="/users/user/quota/${obj.logname}/">quota</a></li>
660.28 + <li>
660.29 + <a href="/users/user/delete/${u.logname}/?home_mode=tar" class="w2popup">Elimina e zippa la HOME</a>
660.30 + </li>
660.31 + <li>
660.32 + <a href="/users/user/delete/${u.logname}/?home_mode=rm" class="w2popup">Elimina anche la HOME</a>
660.33 + </li>
660.34 +</ul>
660.35 +
660.36 +<script type="text/javascript" >
660.37 + $(document).ready(function() {
660.38 + $('.popup').click(function() {
660.39 + window.open(this.href + '?&popup=1', '', 'width=500, height=400, status=status');
660.40 + return false;
660.41 + });
660.42 + ## window popup per delete
660.43 + $('.w2popup').click(function() {
660.44 + window.open(this.href + '&popup=1', '', 'width=450, height=600, status=status');
660.45 + return false;
660.46 + });
660.47 +
660.48 + });
660.49 +
660.50 +## ## cambio passwordx
660.51 +## $('.kpopup').click(function() {
660.52 +## var ref = this;
660.53 +## $('<div></div>').load(ref.href + '?popup=1').dialog({modal: true, width:600, heigh: 250});
660.54 +## return false;
660.55 +## });
660.56 +##
660.57 +##
660.58 +## $('td label[title]').cluetip({splitTitle: '|'});
660.59 +</script>
661.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
661.2 +++ b/web/users/templates/users/user_form.mako Mon Apr 26 11:16:23 2010 +0200
661.3 @@ -0,0 +1,34 @@
661.4 +<%inherit file="${jun.get_parent_template(context)}"/>
661.5 +
661.6 +<%def name="title()">Aggiunti utente</%def>
661.7 +
661.8 +<%def name="layout()">
661.9 +
661.10 +username
661.11 +first_name
661.12 +last_name
661.13 +maingroup
661.14 +## home
661.15 +cf
661.16 +classe
661.17 +groups
661.18 +--
661.19 +expire
661.20 +use_cf
661.21 +##password
661.22 +--
661.23 +s=Salva
661.24 +
661.25 +</%def>
661.26 +
661.27 +<h2>Aggiungi utente</h2>
661.28 +
661.29 +${jun.show_form_errors(form)}
661.30 +${forms.mako_create_nform(context, layout, form, style='-')}
661.31 +
661.32 +
661.33 +<script type="text/javascript" >
661.34 +$(document).ready(function () {
661.35 + $('td label[title]').cluetip({splitTitle: '|'});
661.36 +});
661.37 +</script>
662.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
662.2 +++ b/web/users/templates/users/user_form_update.mako Mon Apr 26 11:16:23 2010 +0200
662.3 @@ -0,0 +1,31 @@
662.4 +<%inherit file="${jun.get_parent_template(context)}"/>
662.5 +
662.6 +<%def name="title()">modifica utente ${obj.logname}</%def>
662.7 +
662.8 +<%def name="layout()">
662.9 +
662.10 +h=username=${obj.logname}
662.11 +first_name
662.12 +last_name
662.13 +h=maingroup=${obj.maingroup}
662.14 +##home
662.15 +cf
662.16 +classe
662.17 +groups
662.18 +--
662.19 +s=Salva
662.20 +
662.21 +</%def>
662.22 +
662.23 +<h2>${"%s %s" % (obj.first_name, obj.last_name)}</h2>
662.24 +
662.25 +${jun.show_form_errors(form)}
662.26 +${forms.mako_create_nform(context, layout, form, style='-')}
662.27 +
662.28 +
662.29 +<script type="text/javascript" >
662.30 + $(document).ready(function() {
662.31 + $('td label[title]').cluetip({splitTitle: '|'});
662.32 + });
662.33 +</script>
662.34 +
663.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
663.2 +++ b/web/users/templates/users/user_list.mako Mon Apr 26 11:16:23 2010 +0200
663.3 @@ -0,0 +1,70 @@
663.4 +<%inherit file="${jun.get_parent_template(context)}"/>
663.5 +
663.6 +% if group_name:
663.7 + <h2>${group_name}</h2>
663.8 +%else:
663.9 + <h2>Tutti gli utenti</h2>
663.10 +%endif
663.11 +
663.12 +<table id="utable" >
663.13 +<thead>
663.14 +<tr>
663.15 + <th></th>
663.16 + <th>logname</th>
663.17 + <th>nome</th>
663.18 + <th>cognome</th>
663.19 +</tr>
663.20 +</thead>
663.21 +<tbody>
663.22 +% for u in users:
663.23 +
663.24 + <tr>
663.25 + <td><a href="/users/user/edit/${u.logname}/" class="wpopup"><img src="/static/img/icon_changelink.gif"></a></td>
663.26 + <td><a href="/users/user/detail/${u.logname}/" class="logname">${u.logname}</a></td>
663.27 + <td>${u.first_name or ''}</td>
663.28 + <td>${u.last_name or ''}</td>
663.29 + </tr>
663.30 +
663.31 +% endfor
663.32 +</tbody>
663.33 +</table>
663.34 +
663.35 +<script type="text/javascript" >
663.36 +
663.37 + $(document).ready(function() {
663.38 + $('.popup').click(function() {
663.39 + $('<div></div>').load(this.href + '?&nt=1').dialog({modal:true, width:660});
663.40 + return false;
663.41 + });
663.42 +
663.43 + $('#utable').dataTable( {
663.44 +## "aaSorting": [[0,'asc'],],
663.45 + "bPaginate": false,
663.46 + "bLengthChange": true,
663.47 + "bFilter": true,
663.48 + "bSort": true,
663.49 + "bInfo": true,
663.50 + "bAutoWidth": false }
663.51 + );
663.52 +
663.53 + ## overlay popup per descrizione
663.54 + $('.logname').click(function() {
663.55 + $('<div></div>').load(this.href + '?&nt=1').dialog({modal:true, width:660});
663.56 + return false;
663.57 + });
663.58 +
663.59 + ## window popup per edit
663.60 + $('.wpopup').click(function() {
663.61 + window.open(this.href + '?&popup=1', '', 'width=450, height=600, status=status, scrollbars=yes');
663.62 + return false;
663.63 + });
663.64 +
663.65 + $('td label[title]').cluetip({splitTitle: '|'});
663.66 +
663.67 + });
663.68 +
663.69 +
663.70 +
663.71 +</script>
663.72 +
663.73 +
664.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
664.2 +++ b/web/users/templates/users/user_opts.mako Mon Apr 26 11:16:23 2010 +0200
664.3 @@ -0,0 +1,30 @@
664.4 +<%inherit file="/base.mako"/>
664.5 +
664.6 +
664.7 +
664.8 +<ul class="css-tabs">
664.9 + <li><a href="/users/group/list/?nt=1">gruppi</a></li>
664.10 + <li><a href="/users/user/list/">utenti</a></li>
664.11 + <li><a href="/users/user/passwd">password</a></li>
664.12 +</ul>
664.13 +
664.14 +<!-- single pane. it is always visible -->
664.15 +<div class="css-panes">
664.16 + <div style="display:block"></div>
664.17 +</div>
664.18 +
664.19 +<!-- activate tabs with JavaScript -->
664.20 +<script type="text/javascript">
664.21 +
664.22 +
664.23 +$(function() {
664.24 +
664.25 + $("ul.css-tabs").tabs("div.css-panes > div", {effect: 'ajax'});
664.26 +
664.27 +});
664.28 +</script>
664.29 +
664.30 +<div id="dialog" title="Basic modal dialog">
664.31 + <p>Adding the modal overlay screen makes the dialog look more prominent because it dims out the page content.</p>
664.32 +</div>
664.33 +
665.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
665.2 +++ b/web/users/tests.py Mon Apr 26 11:16:23 2010 +0200
665.3 @@ -0,0 +1,23 @@
665.4 +"""
665.5 +This file demonstrates two different styles of tests (one doctest and one
665.6 +unittest). These will both pass when you run "manage.py test".
665.7 +
665.8 +Replace these with more appropriate tests for your application.
665.9 +"""
665.10 +
665.11 +from django.test import TestCase
665.12 +
665.13 +class SimpleTest(TestCase):
665.14 + def test_basic_addition(self):
665.15 + """
665.16 + Tests that 1 + 1 always equals 2.
665.17 + """
665.18 + self.failUnlessEqual(1 + 1, 2)
665.19 +
665.20 +__test__ = {"doctest": """
665.21 +Another way to test that 1 + 1 is equal to 2.
665.22 +
665.23 +>>> 1 + 1 == 2
665.24 +True
665.25 +"""}
665.26 +
666.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
666.2 +++ b/web/users/urls.py Mon Apr 26 11:16:23 2010 +0200
666.3 @@ -0,0 +1,40 @@
666.4 +from django.conf.urls.defaults import *
666.5 +models = 'user|group|classe'
666.6 +default_model = 'user'
666.7 +
666.8 +M = {
666.9 + 'model' : '(?P<model>%s)' % models,
666.10 + 'name' : '(?P<name>\w+)',
666.11 + }
666.12 +
666.13 +
666.14 +# Uncomment the next two lines to enable the admin:
666.15 +# from django.contrib import admin
666.16 +# admin.autodiscover()
666.17 +
666.18 +urlpatterns = patterns('isiweb.users.views',
666.19 + # Example:
666.20 + ('^$', 'start', ),
666.21 + ('^start', 'start', ),
666.22 + ('^user/password/change/(?P<username>.*)/', 'change_password', ),
666.23 + ('^%(model)s/list/$' % M, 'object_list'),
666.24 + ('^%(model)s/list/(?P<group_name>.*)/' % M, 'object_list'),
666.25 + ('^%(model)s/detail/(?P<name>.*)/' % M, 'object_detail'),
666.26 + ('^%(model)s/expire_password/(?P<name>.*)/' % M, 'expire_password'),
666.27 +# ('^%(model)s/show_expire/(?P<name>.*)/' % M, 'show_expire'),
666.28 + ('^%(model)s/set_quota/(?P<name>.*)/' % M, 'set_quota'),
666.29 + ('^group/create_links/(?P<name>.*)/' % M, 'create_links'),
666.30 + ('^user/edit/(?P<logname>.*)/' % M, 'edit_user'),
666.31 + ('^user/add/' % M, 'add_user'),
666.32 + ('^group/add/' % M, 'add_group'),
666.33 + ('^user/delete/(?P<logname>.*)/' % M, 'del_user'),
666.34 + ('^user/fileadd/' % M, 'add_bulk_user'),
666.35 + ('^user/convert/' % M, 'convert'),
666.36 +
666.37 + # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
666.38 + # to INSTALLED_APPS to enable admin documentation:
666.39 + # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
666.40 +
666.41 + # Uncomment the next line to enable the admin:
666.42 + # (r'^admin/', include(admin.site.urls)),
666.43 +)
667.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
667.2 +++ b/web/users/user_forms.py Mon Apr 26 11:16:23 2010 +0200
667.3 @@ -0,0 +1,359 @@
667.4 +# -*- coding: utf-8 -*-
667.5 +
667.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
667.7 +#
667.8 +# This program is free software: you can redistribute it and/or modify
667.9 +# it under the terms of the GNU General Public License as published by
667.10 +# the Free Software Foundation, either version 3 of the License, or
667.11 +# (at your option) any later version.
667.12 +#
667.13 +# This program is distributed in the hope that it will be useful,
667.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
667.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
667.16 +# GNU General Public License for more details.
667.17 +#
667.18 +# You should have received a copy of the GNU General Public License
667.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
667.20 +
667.21 +
667.22 +import re
667.23 +import os
667.24 +from django import forms
667.25 +from django.forms import util
667.26 +from django.conf import settings
667.27 +import isi
667.28 +from isi import bulk_users
667.29 +from django.contrib import messages
667.30 +from isiweb.logger import logger
667.31 +from vov.middleware.thread_local import get_current_user
667.32 +import tempfile
667.33 +
667.34 +l = isi.Manager()
667.35 +
667.36 +class PasswordForm(forms.Form):
667.37 +
667.38 + username = forms.CharField(help_text=u"Inserire il nome della persona di cui volete cambiare la password")
667.39 + password = forms.CharField(label=u'Nuova password',widget=forms.PasswordInput(render_value=False))
667.40 + admin_password = forms.CharField(label=u'Admin Password',widget=forms.PasswordInput(render_value=False),
667.41 + help_text=u"""Un insegnante può cambiare la password ad un alunno.
667.42 + La password da immettere qui è quella con cui ci si è autenticati""")
667.43 + def clean(self):
667.44 +
667.45 + username = self.cleaned_data['username']
667.46 + password = self.cleaned_data['password']
667.47 + admin = self.admin_username # set in the view
667.48 + admin_password = self.cleaned_data['admin_password']
667.49 +
667.50 + if self.admin_username == username:
667.51 + return self.cleaned_data
667.52 + elif self.admin_username == 'admin':
667.53 + if not admin_password == l.srv.passwd:
667.54 + raise util.ValidationError(u"Password incorretta per 'admin'")
667.55 + else:
667.56 + return self.cleaned_data
667.57 +
667.58 + user = l.get_user(username, quiet=True)
667.59 + admin = l.get_user(self.admin_username, quiet=True)
667.60 + if not user:
667.61 + raise util.ValidationError(u"Lo user '%s' non esiste" % username)
667.62 + else:
667.63 + if not l.test_password(self.admin_username, admin_password):
667.64 + logger.warning(u"L'utente '%s' ha cercato di cambiare password a %s" % (admin, username))
667.65 + raise util.ValidationError(u"Password di chi compie l' operazione non corretta (%s/%s)" % (admin, admin_password))
667.66 +
667.67 + if user.maingroup in ('alunni', 'esterni'):
667.68 + if admin.maingroup in ('alunni', 'esterni'):
667.69 + raise util.ValidationError("Gi alunni non possono cambiare la password ad *altri* alunni")
667.70 +
667.71 + else:
667.72 + if admin.maingroup in ('admins',):
667.73 + return self.cleaned_data
667.74 + else:
667.75 + raise util.ValidationError("Solo admin possono cambiare la password a non-alunni user: %s (%s)/ admin: %s (%s)" % (username, user.maingroup, admin.logname, admin.maingroup))
667.76 +
667.77 + def save(self):
667.78 + username = self.cleaned_data['username']
667.79 + user = l.get_samba_user(username)
667.80 + user.set_password(self.cleaned_data['password'])
667.81 + return user.logname
667.82 +
667.83 +def get_maingroups():
667.84 + yield ('', '-------')
667.85 + for i in sorted(isi.get_main_groups()):
667.86 + yield (i, i)
667.87 +
667.88 +class UserForm(forms.Form):
667.89 +
667.90 + username = forms.CharField(max_length=50)
667.91 + first_name = forms.CharField(max_length=50, required=False)
667.92 + last_name = forms.CharField(max_length=50)
667.93 + home = forms.CharField(max_length=50, required=False)
667.94 + cf = forms.CharField(max_length=11, required=False, help_text="CF|Necessario per avere il corretto aggiornamento al cambio anno (chiave primaria)")
667.95 + classe = forms.CharField(max_length=20, required=False, help_text="classe|Obbligatoria se alunni")
667.96 + maingroup = forms.ChoiceField(choices=get_maingroups())
667.97 + groups = forms.CharField(max_length=100, required=False, help_text="Separati da virgole!!!|non serve rimettere la classe")
667.98 + expire = forms.BooleanField(required=False, help_text="Forza cambio password|Marca questo campo per costringere cambio password (in Windows)")
667.99 + password = forms.CharField(label=u'Password',required=False, widget=forms.PasswordInput(render_value=False))
667.100 + use_cf = forms.BooleanField(required=False, help_text="CF|Usa il CF per comporre la password (8 caratteri con iniziale maiuscola)")
667.101 +
667.102 + def clean(self):
667.103 +
667.104 + if not 'maingroup' in self.cleaned_data:
667.105 + raise util.ValidationError("Manca maingroup")
667.106 +
667.107 + if self.cleaned_data['maingroup'] in ('alunni',):
667.108 + if not self.cleaned_data['classe']:
667.109 + raise util.ValidationError("Ogni alunno deve avere una classe")
667.110 +
667.111 + class_ = self.cleaned_data['classe']
667.112 +
667.113 + if class_ and (class_ not in self.cleaned_data['groups']):
667.114 + self.cleaned_data['groups'].insert(0, class_)
667.115 +
667.116 + return self.cleaned_data
667.117 +
667.118 + def clean_groups(self):
667.119 +
667.120 + if self.cleaned_data['groups']:
667.121 + return [x.strip() for x in self.cleaned_data['groups'].split(',')]
667.122 + else:
667.123 + return []
667.124 +
667.125 + def get_opts(self):
667.126 +
667.127 + d = self.cleaned_data
667.128 +
667.129 + kw = {
667.130 + 'use_cf' : d['use_cf'],
667.131 + 'last_name' : d['last_name'],
667.132 + 'first_name' : d['first_name'],
667.133 + 'full_name' : "%s %s" % (d['first_name'], d['last_name']),
667.134 + 'groups' : d['groups'] or [],
667.135 + 'passwd' : d['password'] or None,
667.136 + 'classe' : d['classe'] or None,
667.137 + 'cf' : d['cf'] or None,
667.138 + 'use_cf' : d['use_cf'],
667.139 +# 'sex' : self.sex,
667.140 +# 'address' : self.address,
667.141 +# 'city' : self.city,
667.142 +# 'zip_code' : self.zip,
667.143 +# 'phone' : self.phone,
667.144 + }
667.145 + return kw
667.146 +
667.147 + def save(self):
667.148 +
667.149 + d = self.cleaned_data
667.150 + kw = self.get_opts()
667.151 +
667.152 + u = l.get_samba_user(self.cleaned_data['username'])
667.153 +
667.154 + user = l.modify_user(d['username'], d['maingroup'], no_filesystem=False,
667.155 + force_passwd_change=d['expire'], interactive=False,
667.156 + run_alulink=True, update_passwd=False, **kw)
667.157 + user.home = self.cleaned_data['home']
667.158 + user.save()
667.159 + return user
667.160 +
667.161 +class NewUserForm(UserForm):
667.162 +
667.163 +# password = forms.CharField(label=u'Password',widget=forms.PasswordInput(render_value=False), required=False)
667.164 +# use_cf = forms.BooleanField(help_text="Usa CF come password DNTLSN63D07 diventa Dntlsn63")
667.165 +
667.166 +
667.167 + def clean_logname(self):
667.168 +
667.169 + if not re.search('^[A-Za-z0-9_]*$', self.cleaned_data['logname']):
667.170 + raise util.ValidationError("Caratteri non permessi nel logname (deve essere asci 0-127)")
667.171 +
667.172 + if l.get_user(self.cleaned_data['logname'], quiet=True):
667.173 + raise util.ValidationError(u"Un utente '%s' esiste già" % self.cleaned_data['logname'])
667.174 + return self.cleaned_data['logname']
667.175 +
667.176 + def save(self):
667.177 +
667.178 +
667.179 + d = self.cleaned_data
667.180 +
667.181 + kw = self.get_opts()
667.182 + user = l.add_user(d['username'], d['maingroup'], d['expire'], interactive=False,
667.183 + run_alulink=True, **kw)
667.184 + return user
667.185 +
667.186 +class BulkUserForm(forms.Form):
667.187 +
667.188 + user_file = forms.FileField(required=True,
667.189 + help_text="File in formato .isi|Il formato '.isi' si riferisce ai dati contenuti, il file deve invece essere in formato .csv. il formato .xls e' supportato dalla procedura di conversione")
667.190 + expire = forms.BooleanField(required=False,
667.191 + help_text="Forza cambio password|Marca questo campo per costringere cambio password (in Windows)")
667.192 + default_password = forms.CharField(label=u'Password', required=False,
667.193 + widget=forms.PasswordInput(render_value=False))
667.194 + use_cf = forms.BooleanField(required=False,
667.195 + help_text="CF|Usa il CF per comporre la password (8 caratteri con iniziale maiuscola)")
667.196 + update_users = forms.BooleanField(required=False,
667.197 + help_text="Modo aggiornamento|Se un utente è gia presente (stessa logname) lo modifica")
667.198 +
667.199 + def clean(self):
667.200 + self._file_name = None
667.201 +
667.202 + for key in ('user_file',):
667.203 + if key not in self.cleaned_data:
667.204 + raise util.ValidationError("Missing key '%s'" % key)
667.205 +
667.206 + if not self.cleaned_data['update_users']:
667.207 + idf, name = tempfile.mkstemp()
667.208 + f = open(name, 'w')
667.209 + txt = self.cleaned_data['user_file'].read()
667.210 + f.write(txt)
667.211 + f.close()
667.212 + self._file_name = name
667.213 + add, delete, update = l.check_file(name)
667.214 +
667.215 + if update:
667.216 + msg = u"""Alcuni utenti esistono gia' e non e' stata usata l'opzione "update_user":\n%s """ % (
667.217 + "\n".join("%s (%s %s)" % (u.logname, u.last_name, u.first_name) for u in update))
667.218 + raise util.ValidationError(msg)
667.219 + return self.cleaned_data
667.220 +
667.221 + def save(self):
667.222 +
667.223 + return l.read_file(
667.224 + self._file_name or self.cleaned_data['user_file'],
667.225 + update_user = self.cleaned_data['update_users'],
667.226 + use_cf = self.cleaned_data['use_cf'],
667.227 + force_passwd_change = self.cleaned_data['expire'],
667.228 + default_passwd = self.cleaned_data['default_password'],
667.229 + interactive = False,
667.230 + run_alulink = True,
667.231 + )
667.232 +
667.233 +USERNAME_FORMATS = (
667.234 + ('', 'default di sistema'),
667.235 + ('name', 'nome.cognome'),
667.236 + ('id-name', 'd_nome.cognome, a_nome.cognome'),
667.237 + ('cf', 'a_dntlsn63d07'),
667.238 + )
667.239 +
667.240 +FILE_FORMAT = (
667.241 + ('isi', 'isi'),
667.242 + ('sissi', 'sissi'),
667.243 + )
667.244 +class ConvertUserForm(forms.Form):
667.245 +
667.246 + user_file = forms.FileField(required=True, help_text="file|File utenti da importare/convertire")
667.247 + file_format = forms.ChoiceField(required=False, choices=FILE_FORMAT,
667.248 + help_text="Formato file|Al momento sono accettati: 'isi' e 'sissi'")
667.249 + user_format = forms.ChoiceField(required=False, choices=USERNAME_FORMATS,
667.250 + help_text="Formato username|Puoi decidere quale formato per lo username")
667.251 + maingroup = forms.ChoiceField(choices=get_maingroups(), help_text="gruppo|Il gruppo per il quale si stanno convertendo gli utenti", required=True)
667.252 + extended = forms.BooleanField(required=False, help_text="record estesi|I record avranno anche i campi per la gestione della biblioteca (se presenti nel file di input)")
667.253 + random_password = forms.BooleanField(required=False,
667.254 + help_text="Generazione password|forza generazione di password casuali di 8 caratteri")
667.255 +
667.256 + def clean_maingroup(self):
667.257 + if not self.cleaned_data['maingroup']:
667.258 + raise util.ValidationError("Devi indicare il 'maingroup'")
667.259 + return self.cleaned_data['maingroup']
667.260 +
667.261 + def clean(self):
667.262 +
667.263 + for key in ('user_file', 'maingroup'):
667.264 + if key not in self.cleaned_data:
667.265 + raise util.ValidationError("Missing key '%s'" % key)
667.266 +
667.267 +
667.268 + name, ext = os.path.splitext(self.cleaned_data['user_file'].name)
667.269 + idf, file_name = tempfile.mkstemp(suffix="." + ext)
667.270 + f = open(file_name, 'w')
667.271 + txt = self.cleaned_data['user_file'].read()
667.272 + f.write(txt)
667.273 + f.close()
667.274 +
667.275 + b = bulk_users.BulkUsers(maingroup=self.cleaned_data['maingroup'],
667.276 + random_password=self.cleaned_data['random_password'],
667.277 + )
667.278 + b.user_format = self.cleaned_data['user_format']
667.279 + try:
667.280 + b.read_file(file_name, file_format=self.cleaned_data['file_format'],)
667.281 + self.bulk = b
667.282 + except isi.exc.WrongFileFormat, e:
667.283 + raise util.ValidationError(e.message.replace('di input', self.cleaned_data['user_file'].name))
667.284 + except isi.exc.MissingCourseMapping, e:
667.285 + raise util.ValidationError(e.message)
667.286 + return self.cleaned_data
667.287 +
667.288 + def save(self):
667.289 + self.bulk.as_isi(filename="%s/static/utenti/users.csv" % settings.CWD,
667.290 + extended=self.cleaned_data['extended'])
667.291 + return self.bulk
667.292 +
667.293 +
667.294 +class ExpirePassword(forms.Form):
667.295 +
667.296 + model = forms.CharField(max_length=20)
667.297 + name = forms.CharField(max_length=20)
667.298 +
667.299 + def get_obj(self):
667.300 + if self.cleaned_data['model'] == 'user':
667.301 + obj = l.get_samba_user(self.cleaned_data['name'])
667.302 + else:
667.303 + obj = l.get_group(self.cleaned_data['name'])
667.304 + return obj
667.305 +
667.306 + def save(self):
667.307 +
667.308 + self.get_obj().expire_password(samba=True)
667.309 + return obj
667.310 +
667.311 +class CreateLinks(forms.Form):
667.312 +
667.313 + name = forms.CharField(max_length=20)
667.314 +
667.315 + def save(self):
667.316 + obj = l.get_group(self.cleaned_data['name'])
667.317 + obj.create_links()
667.318 + return obj
667.319 +
667.320 +
667.321 +class NewGroupForm(forms.Form):
667.322 +
667.323 + name = forms.CharField(max_length=20)
667.324 +
667.325 + def save(self):
667.326 + try:
667.327 + group = l.add_group(self.cleaned_data['name'])
667.328 + except:
667.329 + pass
667.330 + return group
667.331 +
667.332 +
667.333 +class QuotaSet(ExpirePassword):
667.334 +
667.335 + soft_space_limit = forms.IntegerField(help_text="Space|limite accettato, superabile per un breve periodo di tempo",
667.336 + label="Spazio permesso (MB)")
667.337 + hard_space_limit = forms.IntegerField(help_text="Space|limite massimo (maggiore di 'spazio permesso')", label="Spazio massimo (MB)")
667.338 +
667.339 +## soft_file_limit = forms.IntegerField(help_text="Numero file|limite accettato per un breve periodo di tempo")
667.340 +## hard_file_limit = forms.IntegerField(help_text="numero file|limite massimo")
667.341 +
667.342 + def clean(self):
667.343 + s1 = self.cleaned_data['soft_space_limit'] * 1024
667.344 + s2 = self.cleaned_data['hard_space_limit'] * 1024
667.345 +
667.346 + if s2 < s1:
667.347 + raise util.ValidationError("Spazio massimo deve essere superiore a spazio permesso")
667.348 +
667.349 + return self.cleaned_data
667.350 +
667.351 + def save(self):
667.352 + s1 = self.cleaned_data['soft_space_limit'] * 1024
667.353 + s2 = self.cleaned_data['soft_space_limit'] * 1024
667.354 +# l1 = self.cleaned_data['soft_file_limit']
667.355 +# l2 = self.cleaned_data['soft_file_limit']
667.356 +
667.357 + obj = self.get_obj()
667.358 + if self.cleaned_data['model'] == 'user':
667.359 + obj.set_quota(s1, s2, 0,0)
667.360 + else:
667.361 + obj.set_members_quota(s1, s2, 0,0 )
667.362 + return obj
668.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
668.2 +++ b/web/users/views.py Mon Apr 26 11:16:23 2010 +0200
668.3 @@ -0,0 +1,295 @@
668.4 +# -*- coding: utf-8 -*-
668.5 +
668.6 +# Copyright (C) 2010, Sandro Dentella <[email protected]>
668.7 +#
668.8 +# This program is free software: you can redistribute it and/or modify
668.9 +# it under the terms of the GNU General Public License as published by
668.10 +# the Free Software Foundation, either version 3 of the License, or
668.11 +# (at your option) any later version.
668.12 +#
668.13 +# This program is distributed in the hope that it will be useful,
668.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
668.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
668.16 +# GNU General Public License for more details.
668.17 +#
668.18 +# You should have received a copy of the GNU General Public License
668.19 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
668.20 +
668.21 +
668.22 +from vov.template import mako_loader
668.23 +from vov.template.mako_loader import render_to_response
668.24 +from django.template import RequestContext
668.25 +from django.http import HttpResponseRedirect, HttpResponse
668.26 +from vov.views.decorators import login_required
668.27 +from django.views.decorators.csrf import csrf_protect
668.28 +from isi import srv, models, exc
668.29 +from django.contrib import messages
668.30 +from vov.views import mgeneric
668.31 +import user_forms
668.32 +import isi
668.33 +
668.34 +from pumpkin import filters
668.35 +
668.36 +l = isi.Manager(web=True)
668.37 +
668.38 +@login_required
668.39 +def object_list(request, model, group_name=None):
668.40 +
668.41 + if model == 'group':
668.42 + groups = sorted(l.pumpkin_conn.search(models.PosixGroup), key=lambda x: x.name)
668.43 + template_name = "users/group_list.mako"
668.44 + context = {'groups' : groups}
668.45 +
668.46 + elif model == 'user':
668.47 +
668.48 + if group_name:
668.49 + group = l.get_group(group_name)
668.50 + users = group.members_as_users()
668.51 +
668.52 + else:
668.53 + users = l.pumpkin_conn.search(models.PosixUser)
668.54 + group = None
668.55 + template_name = "users/group_detail.mako"
668.56 + context = {'users' : users, 'group' : group, 'group_name' : group_name}
668.57 +
668.58 + return mako_loader.render_to_response(
668.59 + template_name, context,
668.60 + context_instance=RequestContext(request),)
668.61 +
668.62 +
668.63 +@login_required
668.64 +def object_detail(request, model, name):
668.65 +
668.66 + context = {}
668.67 + try:
668.68 + if model == 'group':
668.69 + group = l.get_group(name)
668.70 + template_name = "users/group_detail.mako"
668.71 + context = {'group' : group, 'group_name' : group.name, 'users' : group.members_as_users()}
668.72 +
668.73 + elif model == 'user':
668.74 + user = l.get_user(name)
668.75 + template_name = "users/user_detail.mako"
668.76 + context = {'u' : user}
668.77 +
668.78 + elif model == 'classe':
668.79 + classe = l.get_group(name)
668.80 + template_name = "users/classe_detail.mako"
668.81 + context = {'classe' : classe}
668.82 + except exc.MissingMatch, e:
668.83 + template_name = 'users/missing_object.mako'
668.84 + context = {'model' : model, 'name' : name}
668.85 +
668.86 + return mako_loader.render_to_response(
668.87 + template_name, context, context_instance=RequestContext(request),)
668.88 +
668.89 +
668.90 +def test_tab(request):
668.91 + return mako_loader.render_to_response(
668.92 + 'users/test.mako', {}, context_instance=RequestContext(request),)
668.93 +
668.94 +
668.95 +@login_required
668.96 +def start(request):
668.97 +
668.98 + if not request.user.is_staff:
668.99 + return HttpResponseRedirect('/navigazione/conf/')
668.100 + context = {
668.101 + 'classes' : sorted(srv.get_classes())
668.102 + }
668.103 +
668.104 + return mako_loader.render_to_response(
668.105 + 'users/start.mako', context, context_instance=RequestContext(request),)
668.106 +
668.107 +
668.108 +@login_required
668.109 +def change_password(request, username):
668.110 +
668.111 + class MyPasswordForm(user_forms.PasswordForm):
668.112 + username = request.user.username
668.113 +
668.114 + if request.method == 'POST': # If the form has been submitted...
668.115 + form = user_forms.PasswordForm(request.POST) # A form bound to the POST data
668.116 + form.admin_username = request.user.username
668.117 + if form.is_valid(): # All validation rules pass
668.118 + username = form.save()
668.119 + messages.success(request, "Password cambiata per utente %s" % username)
668.120 + return HttpResponseRedirect('/views/close_popup/?no_reload=1')
668.121 + else:
668.122 + form = user_forms.PasswordForm()
668.123 +
668.124 + context = {'form' : form,'username' : username}
668.125 +
668.126 + return mako_loader.render_to_response('users/change_password_form.mako', context,
668.127 + context_instance=RequestContext(request),)
668.128 +
668.129 +
668.130 +@login_required
668.131 +def edit_user(request, logname):
668.132 +
668.133 + try:
668.134 + user = l.get_samba_user(logname)
668.135 +
668.136 + if request.method == 'POST': # If the form has been submitted...
668.137 + form = user_forms.UserForm(request.POST) # A form bound to the POST data
668.138 + if form.is_valid(): # All validation rules pass
668.139 + user = form.save()
668.140 + messages.success(request, 'Modificato utente %s' % user )
668.141 + return HttpResponseRedirect('/users/user/detail/%s/?popup=1' % user.logname)
668.142 + else:
668.143 + form = user_forms.UserForm(initial=user.as_dict()) # An unbound form
668.144 +
668.145 + context = {'form' : form, 'obj' : user}
668.146 + except:
668.147 + context = {'name' : logname}
668.148 + return mako_loader.render_to_response('users/missing_object.mako',
668.149 + context, context_instance=RequestContext(request),)
668.150 +
668.151 +
668.152 + return mako_loader.render_to_response('users/user_form_update.mako', context,
668.153 + context_instance=RequestContext(request),)
668.154 +
668.155 +@login_required
668.156 +def add_user(request):
668.157 +
668.158 + if request.method == 'POST': # If the form has been submitted...
668.159 + form = user_forms.NewUserForm(request.POST) # A form bound to the POST data
668.160 + if form.is_valid(): # All validation rules pass
668.161 + user = form.save()
668.162 + messages.success(request, 'Aggiunto utente %s' % user )
668.163 + return HttpResponseRedirect('/users/user/detail/%s/?popup=1' % user.logname)
668.164 + else:
668.165 + form = user_forms.NewUserForm() # An unbound form
668.166 +
668.167 + context = {'form' : form, }
668.168 +
668.169 + return mako_loader.render_to_response('users/user_form.mako', context,
668.170 + context_instance=RequestContext(request),)
668.171 +
668.172 +@login_required
668.173 +def add_group(request):
668.174 +
668.175 + if request.method == 'POST': # If the form has been submitted...
668.176 + form = user_forms.NewGroupForm(request.POST) # A form bound to the POST data
668.177 + if form.is_valid(): # All validation rules pass
668.178 + group = form.save()
668.179 + messages.success(request, 'Aggiunto gruppo %s' % group )
668.180 + return HttpResponseRedirect('/users/group/detail/%s/?popup=1' % group.name)
668.181 + else:
668.182 + form = user_forms.NewGroupForm() # An unbound form
668.183 +
668.184 + context = {'form' : form, }
668.185 +
668.186 + return mako_loader.render_to_response('users/group_form.mako', context,
668.187 + context_instance=RequestContext(request),)
668.188 +
668.189 +@login_required
668.190 +def add_bulk_user(request):
668.191 +
668.192 + if request.method == 'POST': # If the form has been submitted...
668.193 + form = user_forms.BulkUserForm(request.POST, request.FILES) # A form bound to the POST data
668.194 + if form.is_valid(): # All validation rules pass
668.195 + n_users = form.save()
668.196 + messages.success(request, 'Aggiunti %s utenti' % n_users )
668.197 + return HttpResponseRedirect('/views/close_popup/')
668.198 + else:
668.199 + form = user_forms.BulkUserForm() # An unbound form
668.200 +
668.201 + context = {'form' : form, }
668.202 +
668.203 + return mako_loader.render_to_response('users/user_bulk_form.mako', context,
668.204 + context_instance=RequestContext(request),)
668.205 +
668.206 +@login_required
668.207 +def convert(request):
668.208 +
668.209 + if request.method == 'POST': # If the form has been submitted...
668.210 + form = user_forms.ConvertUserForm(request.POST, request.FILES) # A form bound to the POST data
668.211 + if form.is_valid(): # All validation rules pass
668.212 + bulk = form.save()
668.213 +
668.214 + context = {'form' : form, 'bulk': bulk}
668.215 + return mako_loader.render_to_response('users/user_convert.mako', context,
668.216 + context_instance=RequestContext(request),)
668.217 +
668.218 + else:
668.219 + form = user_forms.ConvertUserForm() # An unbound form
668.220 +
668.221 + context = {'form' : form}
668.222 + return mako_loader.render_to_response('users/user_convert_form.mako', context,
668.223 + context_instance=RequestContext(request),)
668.224 +
668.225 +class DelUser(mgeneric.Obj):
668.226 +
668.227 + def __init__(self, request, logname):
668.228 +
668.229 + self.post_delete_redirect = '/views/close_popup/?no_reload=1'
668.230 + self.user = l.get_user(logname)
668.231 + self.request = request
668.232 + self.value = u'%s (%s %s)' % (self.user.logname, self.user.first_name, self.user.last_name)
668.233 + self.extra_form = '<input type="hidden" name="home_mode" value="%s">' % self.request.GET['home_mode']
668.234 +
668.235 + def delete(self):
668.236 + self.user.delete(home_mode=self.request.POST['home_mode'])
668.237 + self.message = 'Eliminato utente: %s' % self.user.logname
668.238 + l.logger.debug('Eliminato host %s' % self.user.logname)
668.239 +
668.240 +
668.241 +@login_required
668.242 +def del_user(request, logname):
668.243 +
668.244 + obj = DelUser(request, logname)
668.245 + return mgeneric.delete_non_model(request, obj=obj, )
668.246 +
668.247 +@login_required
668.248 +def create_links(request, name):
668.249 +
668.250 + if request.method == 'POST': # If the form has been submitted...
668.251 + form = user_forms.CreateLinks(request.POST, request.FILES) # A form bound to the POST data
668.252 + if form.is_valid(): # All validation rules pass
668.253 + classe = form.save()
668.254 + messages.success(request, 'Rigenerati link per classe %s' % classe )
668.255 + return HttpResponseRedirect('/views/close_popup/?no_reload=1')
668.256 + else:
668.257 + form = user_forms.CreateLinks() # An unbound form
668.258 +
668.259 + context = {'form' : form, 'name' : name}
668.260 +
668.261 + return mako_loader.render_to_response('users/create_links.mako', context,
668.262 + context_instance=RequestContext(request),)
668.263 +
668.264 +
668.265 +@login_required
668.266 +def expire_password(request, model, name):
668.267 +
668.268 + if request.method == 'POST': # If the form has been submitted...
668.269 + form = user_forms.ExpirePassword(request.POST, request.FILES) # A form bound to the POST data
668.270 + if form.is_valid(): # All validation rules pass
668.271 + classe = form.save()
668.272 + messages.success(request, 'Forzata scadenza password %s' % classe )
668.273 + return HttpResponseRedirect('/views/close_popup/?no_reload=1')
668.274 + else:
668.275 + form = user_forms.ExpirePassword() # An unbound form
668.276 +
668.277 + context = {'form' : form, 'name' : name, 'model' : model}
668.278 +
668.279 + return mako_loader.render_to_response('users/expire_password.mako', context,
668.280 + context_instance=RequestContext(request),)
668.281 +
668.282 +@login_required
668.283 +def set_quota(request, model, name):
668.284 +
668.285 + if request.method == 'POST': # If the form has been submitted...
668.286 + form = user_forms.QuotaSet(request.POST, request.FILES) # A form bound to the POST data
668.287 + if form.is_valid(): # All validation rules pass
668.288 + classe = form.save()
668.289 + messages.success(request, 'Impostata quota')
668.290 + return HttpResponseRedirect('/views/close_popup/?no_reload=1')
668.291 + else:
668.292 + form = user_forms.QuotaSet() # An unbound form
668.293 +
668.294 + context = {'form' : form, 'name' : name, 'model' : model}
668.295 +
668.296 + return mako_loader.render_to_response('users/quota_set.mako', context,
668.297 + context_instance=RequestContext(request),)
668.298 +