Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch 4_0 Excluding Merge-Ins
This is equivalent to a diff from 16399ebdeb to ffc189660f
2015-05-14
| ||
10:31 | Converted the last of the lassign-brent calls to straight-up lassign Adapted the http::compat to be user selectable as far as how far back we intend to support Adding a qwiki object called MAIN to the default httpd thread Fixed the examples of Taourl so far to now employ the "puts" to buffer architecture. Merging in upsteam changes from tao Broke out the base security system and urls into layers Leaf check-in: ffc189660f user: hypnotoad tags: 4_0 | |
2015-04-03
| ||
07:35 | Added more documentation Renamed the cookieSet method to httpdCookieSet, and moved it to httpd.meta Moved httpdHostName it to httpd.meta Implemented logins using encrypted password hashes Added a module to store javascript password hashing routines. Added a "cat" command to dump files Added the pageHeader and pageFooter methods to httpd.meta Community and its decendents now render pages in bootstrap/jquery. Added jquery to our bootstrap distribution check-in: 80751cdeac user: hypnotoad tags: 4_0 | |
2015-04-02
| ||
10:07 | Bumped the version to 3.5.3 to fold in all of the fixes thusfar, and to account for the incomplete way that 3.5.2 was rolled out. Updated the version numbers in all distribution files The 3.5 series is now in pure bug fix mode, new development is along the 4.0 branch Leaf check-in: e7e4dbf86a user: hypnotoad tags: 3_5_3 | |
2015-03-28
| ||
08:26 | Creating a "branch" to maintain our feature set as released in 3.5.1 Leaf check-in: d2a3620b0e user: hypnotoad tags: 3_5_1 | |
08:25 | Starting the branch to tclhttpd 4.0 check-in: de06e800ad user: hypnotoad tags: 4_0 | |
08:17 | Merged with trunk Closed-Leaf check-in: d5c61ebd08 user: hypnotoad tags: Supports8.6 | |
2014-09-10
| ||
12:45 | Added support for "-dispatch" option to Url_PrefixInstall. This allows for custom thread dispatchers and per-session threading. Leaf check-in: 16399ebdeb user: clif tags: trunk | |
2014-08-17
| ||
16:06 | Added support for config::cget MailServer. That's what's defined in tclhttpd.rc. I think Config(mail) was a previous incarnation of Config. I left that for consistency with older (much older?) systems. check-in: 973cd248ed user: clif tags: trunk | |
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2005-04-26 Michael Thomas <[email protected]> * bin/httpd.tcl: Don't [fork] if we're in a threaded interpreter since [fork] doesn't play well with threads. 2005-04-09 Colin McCormack <[email protected]> * bin/httpd.tcl: changed version number to reflect actual version (3.5.2) | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 2015-03-28 Sean Woods <[email protected]> * Started work on v4 * Tclhttpd now targets 8.6+ * Many evals replaced with the expansion operator {*} * "lib" directory restructured into a tcllib style "modules" directory * NOTE: Changes are now maintained in the fossil repo 2005-04-26 Michael Thomas <[email protected]> * bin/httpd.tcl: Don't [fork] if we're in a threaded interpreter since [fork] doesn't play well with threads. 2005-04-09 Colin McCormack <[email protected]> * bin/httpd.tcl: changed version number to reflect actual version (3.5.2) |
︙ | ︙ |
Changes to DIST_build/DIST.
1 2 3 4 | #!/bin/sh # # Create a super distribution of TclHttpd, Tcl, Tcllib, and Thread | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/bin/sh # # Create a super distribution of TclHttpd, Tcl, Tcllib, and Thread WELCH=/opt/odie/sandbox/tclhttpd HTTPD_VERSION=4.0.0 HTTPD_TAG=tclhttpd-4-0 HTTPD_TAG=4_0 WIN_VERSION=351 DISTDIR=${WELCH}/dist SUPER_DIR=${DISTDIR}/tclhttpd${HTTPD_VERSION}-dist TCL_VERSION=8.6.4 TCL_DIST=${DISTDIR}/tcl${TCL_VERSION}-src.tar.gz TCLLIB_VERSION=1.6 TCLLIB_DIST=${DISTDIR}/tcllib-${TCLLIB_VERSION}.tar.gz # There is a configure error in CVS right now #THREAD_VERSION=2.6 |
︙ | ︙ | |||
32 33 34 35 36 37 38 | SCRATCH=${WELCH}/scratch mkdir -p ${SCRATCH} cd ${SCRATCH} echo "*** Checkout tclhttpd ${HTTPD_VERSION} ***" rm -rf ${SCRATCH}/tclhttpd${HTTPD_VERSION} | | > | > | > | > > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | SCRATCH=${WELCH}/scratch mkdir -p ${SCRATCH} cd ${SCRATCH} echo "*** Checkout tclhttpd ${HTTPD_VERSION} ***" rm -rf ${SCRATCH}/tclhttpd${HTTPD_VERSION} mkdir -p ${SCRATCH}/tclhttpd${HTTPD_VERSION} chmod -R a+r ${SCRATCH}/tclhttpd${HTTPD_VERSION} fossil clone http://core.tcl.tk/tclhttpd /opt/odie/download/tclhttpd.fos cd ${SCRATCH}/tclhttpd${HTTPD_VERSION} fossil open /opt/odie/download/tclhttpd.fos ${HTTPD_TAG} cd ${SCRATCH} chmod a+x tclhttpd${HTTPD_VERSION}/bin/httpd.tcl chmod a-x tclhttpd${HTTPD_VERSION}/bin/httpdthread.tcl chmod a+x tclhttpd${HTTPD_VERSION}/htdocs/cgi-bin/junk* chmod a+x tclhttpd${HTTPD_VERSION}/htdocs/cgi-bin/env find tclhttpd${HTTPD_VERSION}/htdocs -name "*.cgi" -exec chmod a+x {} \; cp tclhttpd${HTTPD_VERSION}/license.terms tclhttpd${HTTPD_VERSION}/htdocs mkdir tclhttpd${HTTPD_VERSION}/htdocs/links |
︙ | ︙ |
Changes to DIST_build/DIST.exp.
1 2 | # Expect script to drive DIST, and handle the CVS password prompting. | | | | 1 2 3 4 5 6 7 8 9 10 11 | # Expect script to drive DIST, and handle the CVS password prompting. set v 4.0.0 set vv 400 stty -echo send_user "CVS Password: " expect_user { -re "(.*)\n" { set Password $expect_out(1,string) } timeout { return -code error "You must enter a password!"} } |
︙ | ︙ |
Changes to DIST_build/README.
1 2 3 4 5 6 | This is a bundled distribution of TclHttpd, Tcl, the Standard Tcl Library, and the Thread extension. If you already have tcl 8.4 or 8.3 installed, then you can probably run the Tcl Web Server directly from this distribtuion without doing any installation steps (The directory will really be | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | This is a bundled distribution of TclHttpd, Tcl, the Standard Tcl Library, and the Thread extension. If you already have tcl 8.4 or 8.3 installed, then you can probably run the Tcl Web Server directly from this distribtuion without doing any installation steps (The directory will really be named something like tclhttpd4.0.1) : cd tclhttpd4.0/bin tclsh httpd.tcl -port 8001 -debug 1 If you get complaints about missing the Standard Tcl Library, then you can install just that by running the install.sh script in the tcllib1.6 directory. If you want a clean install of everything, including a Tcl 8.4.5 that has thread enabled, then use the Makefile in the top-level directory. This will compile things under the build directory, segregating by platform into different subdirectories. More Docs There are a few more README-like files you should read: tclhttpd4.0/INSTALL tclhttpd4.0/README tclhttpd4.0/WHATSNEW tclhttpd4.0/ChangeLog tclhttpd4.0/certs/README.ssl Information about TclHttpd is at http://www.tcl.tk/software/tclhttpd The mailing list is mailto:[email protected] |
︙ | ︙ |
Changes to INSTALL.
︙ | ︙ | |||
107 108 109 110 111 112 113 | blocks. Without threads, you are forced to put your blocking operations into CGI scripts so that the external CGI process blocks. The server continues to service requests until the pipe connected to the CGI process produces data. 5. Starkit Distribution | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | blocks. Without threads, you are forced to put your blocking operations into CGI scripts so that the external CGI process blocks. The server continues to service requests until the pipe connected to the CGI process produces data. 5. Starkit Distribution The tclhttpd4.0.0.kit file is a starkit that is used with the tclkit Tcl interpreter. There is more information about Tclkit at http://wiki.tcl.tk/tclkit/ but the basic idea is simple. All you need is a tclkit binary installed for your platform, and the platform-independent tclhttpd.kit. Start the server like this: tclkit tclhttpd.kit -port 8001 -docRoot /your/htdocs -library /your/code If you don't supply a docRoot or library, then you get the sample |
︙ | ︙ |
Changes to Makefile.in.
︙ | ︙ | |||
114 115 116 117 118 119 120 | includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@@VERSION@ pkglibdir = $(libdir)/@PACKAGE@@VERSION@ | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@@VERSION@ pkglibdir = $(libdir)/@PACKAGE@@VERSION@ cryptlibdir = $(libdir)/@PACKAGE@@VERSION@/@CRYPT_PACKAGE@ limitlibdir = $(libdir)/@PACKAGE@@VERSION@/@LIMIT_PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@@VERSION@ SERVER_ROOT = @SERVER_ROOT@ htdocsdir = $(SERVER_ROOT)/htdocs customdir = $(SERVER_ROOT)/custom top_builddir = . |
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 | $(INSTALL_PROGRAM) $$i $(DESTDIR)$(prefix)/bin ; \ done; @for i in $(srcdir)/bin/*.rc ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(prefix)/bin ; \ done; @echo "Installing sample boot script" $(INSTALL_DATA) $(srcdir)/bin/tclhttpd.etc.init $(DESTDIR)$(SERVER_ROOT) install-libraries: install-custom installdirs @echo "Installing script files in $(DESTDIR)$(pkglibdir)" | > < | < | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | $(INSTALL_PROGRAM) $$i $(DESTDIR)$(prefix)/bin ; \ done; @for i in $(srcdir)/bin/*.rc ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(prefix)/bin ; \ done; @echo "Installing sample boot script" $(INSTALL_DATA) $(srcdir)/bin/tclhttpd.etc.init $(DESTDIR)$(SERVER_ROOT) install-libraries: install-custom installdirs @echo "Installing script files in $(DESTDIR)$(pkglibdir)" $(TCLSH_PROG) autosetup/install.tcl $(srcdir)/modules $(DESTDIR)$(pkglibdir) $(INSTALL_SCRIPT) $(srcdir)/modules/httpd/mime.types $(DESTDIR)$(pkglibdir) install-htdocs: @echo "Creating htdocs tree in $(htdocsdir)" -chmod 755 `@CYGPATH@ $(srcdir)/htdocs/cgi-bin/*.cgi` $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/bin/CopyDist` `@CYGPATH@ $(srcdir)/htdocs` `@CYGPATH@ $(DESTDIR)$(htdocsdir)` -$(mkinstalldirs) $(DESTDIR)$(htdocsdir)/links @echo "Copying some READMEs into $(htdocsdir)/links" |
︙ | ︙ | |||
374 375 376 377 378 379 380 | if test -f $$p; then \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ | | | | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | if test -f $$p; then \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_PROGRAM) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ $(INSTALL_PROGRAM) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ fi; \ else \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \ fi; \ else :; fi; \ done @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ |
︙ | ︙ |
Deleted README.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added README.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | This HTTPD is written in Tcl and Tk. Originally written by Stephen Uhler and Brent Welch of Sun Microsystems Laboratory. Brent is now at Panasas, Inc. Version 4 is maintained by Sean Woods of Test & Evaluation Solutions. See the file "license.terms" for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. Version: 4.0.0 Sat Mar 28 04:44:11 EDT 2015 STARKIT QUICK START tclkit tclhttpd4.0.0.kit -port 80 -docRoot htmldir -library tcldir The server loads all the tcl sources in the library. Try also tclkit tclhttpd4.0.0.kit -help STANDARD QUICK START It requires Tcl 8.6 (or higher) and the Standard Tcl Library. This uses the cmdline, base64, ncgi, html, sha1, and counter modules of the Standard Tcl Library. If you must, you can probably get by with Tcl 8.5 or later if you install the Standard Tcl Library and the TclOO extension. The Web server runs under either tclsh or wish. With wish you get a simple GUI that shows some counters. For a quick test that runs a server on port 8015, do UNIX: 1) Test preconditions Tcl interpreter: tclsh8.5, tclsh8.6, tclkit (or wish) tcllib 1.6 or higher Try tclsh (whatever version) package require counter 2) If you can do the above, then you should be able to run the server directly from this distribution directory without bothering to configure, make, and install it. e.g., tclsh8.6 bin/httpd.tcl -debug 1 Windows and Macintosh: Run wish or tclsh and source bin/httpd.tcl 3) For more detailed installation instructions, see the INSTALL file. For a complete set of command line options, do httpd.tcl -help This lets you set basic parameters like port number and server name. VERSION SUMMARY Version 4.0 adds support for Tcl 8.6, and integrates TclOO. The /lib directory has been moved to /modules, and the layout of modules now mirrors that of Tcllib. DirectOO adds the ability to implement dynamic content with TclOO objects. This version adds bootstrap and markdown support. Version 3.5 has various bug fixes, improvements to the docs, and some sample applications. 3.5.1 adds a mail client module. Version 3.4.3 fixes loading code from the custom code directory, which broke in 3.4.2 Version 3.4.2 has bug fixes in the directory listing code (dirlist.tcl). Prevent listing of directory trees outside the URL tree, and get them to work at all. Added a fix in upload.tcl so that extra post data is cleaned up correctly - fixes bugs that occur when GET and POST uploads are mixed. Minor cleanup to the sample htdocs tree. Version 3.4.1 fixes CGI POST forms on Windows, a typo in upload.tcl and the lib/pkgIndex.tcl. It also disallows the ability to retrieve .tml, .tclaccess, and .htaccess files. These simple new APIs crept in: Url_AccessInstallPrepend, Url_AccessUnInstall Mtype_Add, Mtype_Reset Direct_UrlRemove Version 3.4 has several updates to the Doc, Upload, and Thread modules done by Melissa Chawla of Panasas. Please see the ChangeLog for details. There is also a small modification to support If-Modified-Since optimization in Httpd_ReturnFile contributed by Brian Meagher. Don Porter contributed virtual host support, so you can support several sites with one server. Please see README.virthost for details Version 3.3.1 was just a cleanup of the installation files and configure scripts. (acruz) Version 3.3 fixes more bugs in CGI handling and adds a simple file upload domain handler. Version 3.2.1 fixes bugs in CGI handling related to the changes in 3.2 in the way POST data is handled. Version 3.2 changes the way you customize a TclHttpd installation with the goal of not having to modify the bin/httpd.tcl and bin/httpdthread.tcl scripts, although in some cases this will still be necessary. A new "custom code" directory is supported and the server will load all the code from that directory during startup. Specify this with the -library command line option or the "library" Config specification in your .rc file. Version 3.1.0 renames all the packages to be httpd::foo instead of just foo, so that the package namespace is a bit more organized when TclHttpd is installed along with the rest of Tcl and Tk. Other that that, it is essentially identical with 3.0.4. Version 3.0.4 fixes yet-another bug with Doc_AddRoot. Version 3.0.3 fixes another bug with Doc_AddRoot, and fixes the bundled distribution so you can use the Thread extension again. Version 3.0.2 fixes a serious SECURITY BUG that let 3.0.0 and 3.0.1 serve up any old file on your system. That bug was not present in earlier versions of the server. Version 3.0.1 has minor bug fixes and (hopefully) some improvements in the bundled distribution. Version 3.0.0 has three major changes: * Use of Standard Tcl Library modules. The server looks around for the tcllib distribution and automatically uses it. One goal of this conversion is to eliminate the use of the page global array and replace that with calls to the ncgi module. * Support for threads. If you configure and build Tclsh with --enable-threads and you have the Thread extension available, the the server can use threads to service requests. * Support for SSL. If you have the "tls" extension installed, then you can start an SSL server by giving the -https_port command line argument. Version 2.3.6 is the last in the 2.3 series. It has a few minor bug fixes. The next release, 3.0, will support threading using the Thread extension and SSL using the TLS extension. Version 2.3 changes the way post data is handled. The various point releases (e.g., 2.3.4) fix important bugs in cookie handling and the new post data handler. Version 2.1.6 introduces a configuration file, tclhttpd.rc You can edit this to tune the set of modules used by the server, or to hardwire the port, etc. If you have Scotty installed, then you can try out the SNMP demo. You'll need to arrange to have the Tnm*.so library on the auto_path for your shell. I have found that 2.1.5 works with 8.0a2, but not with 8.0b1 because Tcl_GetFile has gone. MAILING LISTS There is a mailing list for users of the Tcl web server at SourceForge as part of the tclhttpd project. Please sign up via the web site at www.sourceforge.net/projects/tclhttpd. If that is dead, send email to [email protected] to find out the current location of the mailing list Send messages for the list to [email protected] Bugs and comments to the mailing list, or to <[email protected]> Put "httpd" in the subject of the mail so I can sort it automatically. WWW The current URL for the distribution can be found in http://core.tcl.tk/tclhttpd This site contains the fossil source repository, as well as the most up to date documentation. |
Changes to VERSION.
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Current version is 4.0.0 This is reflected in the following files (sigh) README For informational purposes configure.in The patchlevel is either "" or ".1" etc. *re-run* autoconf to update configure bin/httpd.tcl set v 4.0.0 So it can look for the right tclhttpd library lib/version.tcl To set the right version string. This does package provide major.minor only, but the string has the date and patchlevel. The actual value of the httpd::version package number isn't used. lib/pkgIndex.tcl |
︙ | ︙ |
Changes to WHATSNEW.
1 2 3 4 5 6 7 8 9 | What's new in TclHttpd 3.5 Mostly this is a cleanup of the code and web pages to cleanly separate out the core server from various sample applications and demo code. The default web site is defined by the htdocs and custom subdirectories, and all the other stuff is organized under sampleapp. There are some new security controls over the debug URL so you can | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | What's new in TclHttpd 4.0 This version targets the new TclOO features backed into 8.6, as well as utilizing sqlite as a database backend. 3.5 Mostly this is a cleanup of the code and web pages to cleanly separate out the core server from various sample applications and demo code. The default web site is defined by the htdocs and custom subdirectories, and all the other stuff is organized under sampleapp. There are some new security controls over the debug URL so you can |
︙ | ︙ |
Added auto.def.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | # Created by migrate-autoconf - fix items marked XXX use cc cc-shared odie options { with-serverroot:DIR => {} } array set ::project { name tclhttpd major_version 4 minor_version 0 patchlevel .alpha fedora_release 0.fdr.1 } foreach {field value} [array get ::project] { define PKG_[string toupper $field] $value } #-------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. The NODOT_VERSION is # required for constructing the library name on systems that don't like # dots in library names (Windows). The VERSION variable is used on the # other systems. #-------------------------------------------------------------------- # XXX PACKAGE=tclhttpd # XXX MAJOR_VERSION=4 # XXX MINOR_VERSION=0 # XXX PATCHLEVEL=".0" # XXX RELEASE=`grep Release: ${srcdir}/${PACKAGE}.spec | sed -e 's/Release: *//'` # XXX VERSION=${MAJOR_VERSION}.${MINOR_VERSION}${PATCHLEVEL} # XXX NODOT_VERSION=${MAJOR_VERSION}${MINOR_VERSION} # XXX WIN_VERSION=`echo ${VERSION} | sed -e 's/\.//g'` # XXX TCL_VERSION=8.6.4 # XXX TCLLIB_VERSION=1.6 # XXX THREAD_VERSION=2.6 # We build two minor packages for the crypt and limit C extensions # XXX CRYPT_PACKAGE=crypt # XXX CRYPT_VERSION="1.0" # XXX WIN_CRYPT_VERSION=`echo ${CRYPT_VERSION} | sed -e 's/\.//g'` # XXX LIMIT_PACKAGE=limit # XXX LIMIT_VERSION="1.0" # XXX WIN_LIMIT_VERSION=`echo ${LIMIT_VERSION} | sed -e 's/\.//g'` if {[opt-val with-serverroot] ne {}} { set withval [opt-val with-serverroot] # XXX SERVER_ROOT=${withval} } else { # XXX SERVER_ROOT='$(prefix)/$(PACKAGE)' } # XXX AC_SUBST PACKAGE # XXX AC_SUBST SERVER_ROOT # XXX AC_SUBST VERSION # XXX AC_SUBST RELEASE # XXX AC_SUBST WIN_VERSION # XXX AC_SUBST CRYPT_PACKAGE # XXX AC_SUBST CRYPT_VERSION # XXX AC_SUBST WIN_CRYPT_VERSION # XXX AC_SUBST LIMIT_PACKAGE # XXX AC_SUBST LIMIT_VERSION # XXX AC_SUBST WIN_LIMIT_VERSION # XXX AC_SUBST TCL_VERSION # XXX AC_SUBST TCLLIB_VERSION # XXX AC_SUBST THREAD_VERSION #-------------------------------------------------------------------- # We put this here so that you can compile with -DVERSION="1.2" to # encode the package version directly into the source files. #-------------------------------------------------------------------- # XXX eval AC_DEFINE_UNQUOTED(VERSION, "${VERSION}") #-------------------------------------------------------------------- # Check whether --enable-gcc or --disable-gcc was given. Do this # before AC_CYGWIN is called so the compiler can # be fully tested by built-in autoconf tools. # This macro also calls AC_PROG_CC to set the compiler if --enable-gcc # was not used. #-------------------------------------------------------------------- # XXX SC_ENABLE_GCC cc-check-progs install #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- cc-check-tools ranlib #-------------------------------------------------------------------- # This macro performs additional compiler tests. #-------------------------------------------------------------------- # XXX AC_CYGWIN #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- # XXX AC_OBJEXT #-------------------------------------------------------------------- # "cygpath" is used on windows to generate native path names for include # files. # These variables should only be used with the compiler and linker since # they generate native path names. # # Unix tclConfig.sh points SRC_DIR at the top-level directory of # the Tcl sources, while the Windows tclConfig.sh points SRC_DIR at # the win subdirectory. Hence the different usages of SRC_DIR below. # # This must be done before calling SC_PUBLIC_TCL_HEADERS #-------------------------------------------------------------------- # XXX case "`uname -s`" in # XXX *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95*) # XXX CYGPATH="cygpath -w" # XXX RELPATH=".. .. bin" # XXX ;; # XXX *) # XXX CYGPATH=echo # XXX RELPATH=.. # XXX ;; # XXX esac # XXX AC_SUBST CYGPATH # XXX AC_SUBST RELPATH #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # XXX SC_PATH_TCLCONFIG # XXX SC_LOAD_TCLCONFIG #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after SC_PATH_TCLCONFIG/SC_LOAD_TCLCONFIG #-------------------------------------------------------------------- # XXX SC_PUBLIC_TCL_HEADERS #SC_PRIVATE_TCL_HEADERS #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_exampleA in this case) so # that we create the export library with the dll. See sha1.h on how # to use this. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # Define any extra compiler flags in the PACKAGE_CFLAGS variable. # These will be appended to the current set of compiler flags for # your system. #-------------------------------------------------------------------- # XXX case "`uname -s`" in # XXX *win32* | *WIN32* | *CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*) # XXX AC_DEFINE_UNQUOTED BUILD_${PACKAGE} # XXX CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc50.pch" # XXX AC_SUBST CLEANFILES # XXX ;; # XXX *) # XXX CLEANFILES= # XXX ;; # XXX esac #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # So far only Tcl responds to this one. #-------------------------------------------------------------------- # XXX SC_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- # XXX SC_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # is all taken from the tclConfig.sh file. #-------------------------------------------------------------------- # XXX CFLAGS_DEBUG=${TCL_CFLAGS_DEBUG} # XXX CFLAGS_OPTIMIZE=${TCL_CFLAGS_OPTIMIZE} # XXX LDFLAGS_DEBUG=${TCL_LDFLAGS_DEBUG} # XXX LDFLAGS_OPTIMIZE=${TCL_LDFLAGS_OPTIMIZE} # XXX SHLIB_LD=${TCL_SHLIB_LD} # XXX STLIB_LD=${TCL_STLIB_LD} # XXX SHLIB_CFLAGS=${TCL_SHLIB_CFLAGS} # XXX AC_SUBST CFLAGS_DEBUG # XXX AC_SUBST CFLAGS_OPTIMIZE # XXX AC_SUBST STLIB_LD # XXX AC_SUBST SHLIB_LD # XXX AC_SUBST SHLIB_CFLAGS # XXX AC_SUBST SHLIB_LDFLAGS #-------------------------------------------------------------------- # Find out where we should get the crypt() function #-------------------------------------------------------------------- if {![cc-check-functions crypt]} { } # XXX AC_SUBST CRYPT_OBJS #-------------------------------------------------------------------- # Find out if we have the sys/resource.h header file for building # the limit extension #-------------------------------------------------------------------- if {[cc-check-includes sys/resource.h]} { # XXX BUILD_LIMIT=1 } else { # XXX BUILD_LIMIT=0 } # XXX if test "${BUILD_LIMIT}" = 1 ; then # XXX LIMIT_EXTENSION='$(limit_LIB_FILE)' # XXX else # XXX LIMIT_EXTENSION='' # XXX fi # XXX AC_SUBST LIMIT_EXTENSION # XXX AC_SUBST BUILD_LIMIT #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols # option. #-------------------------------------------------------------------- # XXX SC_ENABLE_SYMBOLS # XXX if test "${SHARED_BUILD}" = "1" ; then # XXX CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}' # XXX else # XXX CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}' # XXX fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. #-------------------------------------------------------------------- define USE_TCL_STUBS #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the SC_ENABLE_SHARED, SC_ENABLE_SYMBOLS, # and SC_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- # XXX SC_MAKE_LIB #-------------------------------------------------------------------- # eval these two values to dereference the ${DBGX} variable. #-------------------------------------------------------------------- # XXX eval "SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}" # XXX eval "UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}" #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. #-------------------------------------------------------------------- # XXX case "`uname -s`" in # XXX *win32* | *WIN32* | *CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*) # XXX if test "${SHARED_BUILD}" = "1" ; then # XXX SHLIB_LD_LIBS="\"`cygpath -w ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\" ${TCL_SHLIB_LD_LIBS}" # XXX eval "${PACKAGE}_LIB_FILE=${PACKAGE}${SHARED_LIB_SUFFIX}" # XXX eval "${CRYPT_PACKAGE}_LIB_FILE=${CRYPT_PACKAGE}${SHARED_LIB_SUFFIX}" # XXX eval "${LIMIT_PACKAGE}_LIB_FILE=${LIMIT_PACKAGE}${SHARED_LIB_SUFFIX}" # XXX RANLIB=: # XXX else # XXX eval "${PACKAGE}_LIB_FILE=${PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX eval "${CRYPT_PACKAGE}_LIB_FILE=${CRYPT_PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX eval "${LIMIT_PACKAGE}_LIB_FILE=${LIMIT_PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX fi # XXX ;; # XXX *) # XXX if test "${SHARED_BUILD}" = "1" ; then # XXX SHLIB_LD_LIBS="${TCL_STUB_LIB_SPEC} ${CRYPT_LIB}" # XXX eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${SHARED_LIB_SUFFIX}" # XXX eval "${CRYPT_PACKAGE}_LIB_FILE=lib${CRYPT_PACKAGE}${SHARED_LIB_SUFFIX}" # XXX eval "${LIMIT_PACKAGE}_LIB_FILE=lib${LIMIT_PACKAGE}${SHARED_LIB_SUFFIX}" # XXX RANLIB=: # XXX else # XXX eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX eval "${CRYPT_PACKAGE}_LIB_FILE=lib${CRYPT_PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX eval "${LIMIT_PACKAGE}_LIB_FILE=lib${LIMIT_PACKAGE}${UNSHARED_LIB_SUFFIX}" # XXX fi # XXX ;; # XXX esac # XXX AC_SUBST SHARED_BUILD #-------------------------------------------------------------------- # __CHANGE__ # Change the name from exampeA_LIB_FILE to match your package name. #-------------------------------------------------------------------- # Hack to map from the TclHttpd version number that got automatically # sucked up by the SHARED_LIB_SUFFIX macro # XXX crypt_LIB_FILE=`echo $crypt_LIB_FILE | sed -e "s/$VERSION/$CRYPT_VERSION/" | sed -e "s/$NODOT_VERSION/$WIN_CRYPT_VERSION/"` # XXX limit_LIB_FILE=`echo $limit_LIB_FILE | sed -e "s/$VERSION/$LIMIT_VERSION/" | sed -e "s/$NODOT_VERSION/$WIN_LIMIT_VERSION/"` # XXX AC_SUBST limit_LIB_FILE # XXX AC_SUBST crypt_LIB_FILE # XXX AC_SUBST SHLIB_LD_LIBS #-------------------------------------------------------------------- # Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl # file during the install process. Don't run the TCLSH_PROG through # ${CYGPATH} because it's being used directly by make. # Require that we use a tclsh shell version 8.2 or later since earlier # versions have bugs in the pkg_mkIndex routine. #-------------------------------------------------------------------- # XXX SC_PROG_TCLSH #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. #-------------------------------------------------------------------- make-template Makefile.in make-template crypt_pkgIndex.tcl.in make-template limit_pkgIndex.tcl.in make-template $::project(name).spec.in |
Added autosetup/LICENSE.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | Unless explicitly stated, all files which form part of autosetup are released under the following license: --------------------------------------------------------------------- autosetup - A build environment "autoconfigurator" Copyright (c) 2010-2011, WorkWare Systems <http://workware.net.au/> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE WORKWARE SYSTEMS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WORKWARE SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of WorkWare Systems. |
Added autosetup/README.autosetup.
> | 1 | This is autosetup v0.6.6. See http://msteveb.github.com/autosetup/ |
Added autosetup/autosetup.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 | #!/bin/sh # Copyright (c) 2006-2011 WorkWare Systems http://www.workware.net.au/ # All rights reserved # vim:se syntax=tcl: # \ dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@" set autosetup(version) 0.6.6 # Can be set to 1 to debug early-init problems set autosetup(debug) 0 ################################################################## # # Main flow of control, option handling # proc main {argv} { global autosetup define # There are 3 potential directories involved: # 1. The directory containing autosetup (this script) # 2. The directory containing auto.def # 3. The current directory # From this we need to determine: # a. The path to this script (and related support files) # b. The path to auto.def # c. The build directory, where output files are created # This is also complicated by the fact that autosetup may # have been run via the configure wrapper ([getenv WRAPPER] is set) # Here are the rules. # a. This script is $::argv0 # => dir, prog, exe, libdir # b. auto.def is in the directory containing the configure wrapper, # otherwise it is in the current directory. # => srcdir, autodef # c. The build directory is the current directory # => builddir, [pwd] # 'misc' is needed before we can do anything, so set a temporary libdir # in case this is the development version set autosetup(libdir) [file dirname $::argv0]/lib use misc # (a) set autosetup(dir) [realdir [file dirname [realpath $::argv0]]] set autosetup(prog) [file join $autosetup(dir) [file tail $::argv0]] set autosetup(exe) [getenv WRAPPER $autosetup(prog)] if {$autosetup(installed)} { set autosetup(libdir) $autosetup(dir) } else { set autosetup(libdir) [file join $autosetup(dir) lib] } autosetup_add_dep $autosetup(prog) # (b) if {[getenv WRAPPER ""] eq ""} { # Invoked directly set autosetup(srcdir) [pwd] } else { # Invoked via the configure wrapper set autosetup(srcdir) [file dirname $autosetup(exe)] } set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def] # (c) set autosetup(builddir) [pwd] set autosetup(argv) $argv set autosetup(cmdline) {} set autosetup(options) {} set autosetup(optionhelp) {} set autosetup(showhelp) 0 # Parse options use getopt array set ::useropts [getopt argv] #"=Core Options:" options-add { help:=local => "display help and options. Optionally specify a module name, such as --help=system" version => "display the version of autosetup" ref:=text manual:=text reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" debug => "display debugging output as autosetup runs" install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)" force init:=help => "create initial auto.def, etc. Use --init=help for known types" # Undocumented options option-checking=1 nopager quiet timing conf: } #parray ::useropts if {[opt-bool version]} { puts $autosetup(version) exit 0 } # autosetup --conf=alternate-auto.def if {[opt-val conf] ne ""} { set autosetup(autodef) [opt-val conf] } # Debugging output (set this early) incr autosetup(debug) [opt-bool debug] incr autosetup(force) [opt-bool force] incr autosetup(msg-quiet) [opt-bool quiet] incr autosetup(msg-timing) [opt-bool timing] # If the local module exists, source it now to allow for # project-local customisations if {[file exists $autosetup(libdir)/local.tcl]} { use local } # Now any auto-load modules foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { automf_load source $file } if {[opt-val help] ne ""} { incr autosetup(showhelp) use help autosetup_help [opt-val help] } if {[opt-val {manual ref reference}] ne ""} { use help autosetup_reference [opt-val {manual ref reference}] } if {[opt-val init] ne ""} { use init autosetup_init [opt-val init] } if {[opt-val install] ne ""} { use install autosetup_install [opt-val install] } if {![file exists $autosetup(autodef)]} { # Check for invalid option first options {} user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)" } # Parse extra arguments into autosetup(cmdline) foreach arg $argv { if {[regexp {([^=]*)=(.*)} $arg -> n v]} { dict set autosetup(cmdline) $n $v define $n $v } else { user-error "Unexpected parameter: $arg" } } autosetup_add_dep $autosetup(autodef) set cmd [file-normalize $autosetup(exe)] foreach arg $autosetup(argv) { append cmd " [quote-if-needed $arg]" } define AUTOREMAKE $cmd # Log how we were invoked configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]" # Note that auto.def is *not* loaded in the global scope source $autosetup(autodef) # Could warn here if options {} was not specified show-notices if {$autosetup(debug)} { msg-result "Writing all defines to config.log" configlog "================ defines ======================" foreach n [lsort [array names define]] { configlog "define $n $define($n)" } } exit 0 } # Initial settings set autosetup(exe) $::argv0 set autosetup(istcl) 1 set autosetup(start) [clock millis] set autosetup(installed) 0 set autosetup(msg-checking) 0 set autosetup(msg-quiet) 0 # Embedded modules are inserted below here set autosetup(installed) 1 # @opt-bool option ... # # Check each of the named, boolean options and return 1 if any of them have # been set by the user. # proc opt-bool {args} { option-check-names {*}$args opt_bool ::useropts {*}$args } # @opt-val option-list ?default=""? # # Returns a list containing all the values given for the non-boolean options in 'option-list'. # There will be one entry in the list for each option given by the user, including if the # same option was used multiple times. # If only a single value is required, use something like: # ## lindex [opt-val $names] end # # If no options were set, $default is returned (exactly, not as a list). # proc opt-val {names {default ""}} { option-check-names {*}$names join [opt_val ::useropts $names $default] } proc option-check-names {args} { foreach o $args { if {$o ni $::autosetup(options)} { autosetup-error "Request for undeclared option --$o" } } } # Parse the option definition in $opts and update # ::useropts() and ::autosetup(optionhelp) appropriately # proc options-add {opts {header ""}} { global useropts autosetup # First weed out comment lines set realopts {} foreach line [split $opts \n] { if {![string match "#*" [string trimleft $line]]} { append realopts $line \n } } set opts $realopts for {set i 0} {$i < [llength $opts]} {incr i} { set opt [lindex $opts $i] if {[string match =* $opt]} { # This is a special heading lappend autosetup(optionhelp) $opt "" set header {} continue } #puts "i=$i, opt=$opt" regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value if {$name in $autosetup(options)} { autosetup-error "Option $name already specified" } #puts "$opt => $name $colon $equal $value" # Find the corresponding value in the user options # and set the default if necessary if {[string match "-*" $opt]} { # This is a documentation-only option, like "-C <dir>" set opthelp $opt } elseif {$colon eq ""} { # Boolean option lappend autosetup(options) $name if {![info exists useropts($name)]} { set useropts($name) $value } if {$value eq "1"} { set opthelp "--disable-$name" } else { set opthelp "--$name" } } else { # String option. lappend autosetup(options) $name if {$equal eq "="} { if {[info exists useropts($name)]} { # If the user specified the option with no value, the value will be "1" # Replace with the default if {$useropts($name) eq "1"} { set useropts($name) $value } } set opthelp "--$name?=$value?" } else { set opthelp "--$name=$value" } } # Now create the help for this option if appropriate if {[lindex $opts $i+1] eq "=>"} { set desc [lindex $opts $i+2] #string match \n* $desc if {$header ne ""} { lappend autosetup(optionhelp) $header "" set header "" } # A multi-line description lappend autosetup(optionhelp) $opthelp $desc incr i 2 } } } # @module-options optionlist # # Like 'options', but used within a module. proc module-options {opts} { set header "" if {$::autosetup(showhelp) > 1 && [llength $opts]} { set header "Module Options:" } options-add $opts $header if {$::autosetup(showhelp)} { # Ensure that the module isn't executed on --help # We are running under eval or source, so use break # to prevent further execution #return -code break -level 2 return -code break } } proc max {a b} { expr {$a > $b ? $a : $b} } proc options-wrap-desc {text length firstprefix nextprefix initial} { set len $initial set space $firstprefix foreach word [split $text] { set word [string trim $word] if {$word == ""} { continue } if {$len && [string length $space$word] + $len >= $length} { puts "" set len 0 set space $nextprefix } incr len [string length $space$word] puts -nonewline $space$word set space " " } if {$len} { puts "" } } proc options-show {} { # Determine the max option width set max 0 foreach {opt desc} $::autosetup(optionhelp) { if {[string match =* $opt] || [string match \n* $desc]} { continue } set max [max $max [string length $opt]] } set indent [string repeat " " [expr $max+4]] set cols [getenv COLUMNS 80] catch { lassign [exec stty size] rows cols } incr cols -1 # Now output foreach {opt desc} $::autosetup(optionhelp) { if {[string match =* $opt]} { puts [string range $opt 1 end] continue } puts -nonewline " [format %-${max}s $opt]" if {[string match \n* $desc]} { puts $desc } else { options-wrap-desc [string trim $desc] $cols " " $indent [expr $max + 2] } } } # @options options-spec # # Specifies configuration-time options which may be selected by the user # and checked with opt-val and opt-bool. The format of options-spec follows. # # A boolean option is of the form: # ## name[=0|1] => "Description of this boolean option" # # The default is name=0, meaning that the option is disabled by default. # If name=1 is used to make the option enabled by default, the description should reflect # that with text like "Disable support for ...". # # An argument option (one which takes a parameter) is of the form: # ## name:[=]value => "Description of this option" # # If the name:value form is used, the value must be provided with the option (as --name=myvalue). # If the name:=value form is used, the value is optional and the given value is used as the default # if is not provided. # # Undocumented options are also supported by omitting the "=> description. # These options are not displayed with --help and can be useful for internal options or as aliases. # # For example, --disable-lfs is an alias for --disable=largefile: # ## lfs=1 largefile=1 => "Disable large file support" # proc options {optlist} { # Allow options as a list or args options-add $optlist "Local Options:" if {$::autosetup(showhelp)} { options-show exit 0 } # Check for invalid options if {[opt-bool option-checking]} { foreach o [array names ::useropts] { if {$o ni $::autosetup(options)} { user-error "Unknown option --$o" } } } } proc config_guess {} { if {[file-isexec $::autosetup(dir)/config.guess]} { exec-with-stderr sh $::autosetup(dir)/config.guess if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} { user-error $alias } return $alias } else { configlog "No config.guess, so using uname" string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r] } } proc config_sub {alias} { if {[file-isexec $::autosetup(dir)/config.sub]} { if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} { user-error $alias } } return $alias } # @define name ?value=1? # # Defines the named variable to the given value. # These (name, value) pairs represent the results of the configuration check # and are available to be checked, modified and substituted. # proc define {name {value 1}} { set ::define($name) $value #dputs "$name <= $value" } # @define-append name value ... # # Appends the given value(s) to the given 'defined' variable. # If the variable is not defined or empty, it is set to $value. # Otherwise the value is appended, separated by a space. # Any extra values are similarly appended. # If any value is already contained in the variable (as a substring) it is omitted. # proc define-append {name args} { if {[get-define $name ""] ne ""} { # Make a token attempt to avoid duplicates foreach arg $args { if {[string first $arg $::define($name)] == -1} { append ::define($name) " " $arg } } } else { set ::define($name) [join $args] } #dputs "$name += [join $args] => $::define($name)" } # @get-define name ?default=0? # # Returns the current value of the 'defined' variable, or $default # if not set. # proc get-define {name {default 0}} { if {[info exists ::define($name)]} { #dputs "$name => $::define($name)" return $::define($name) } #dputs "$name => $default" return $default } # @is-defined name # # Returns 1 if the given variable is defined. # proc is-defined {name} { info exists ::define($name) } # @all-defines # # Returns a dictionary (name value list) of all defined variables. # # This is suitable for use with 'dict', 'array set' or 'foreach' # and allows for arbitrary processing of the defined variables. # proc all-defines {} { array get ::define } # @get-env name default # # If $name was specified on the command line, return it. # If $name was set in the environment, return it. # Otherwise return $default. # proc get-env {name default} { if {[dict exists $::autosetup(cmdline) $name]} { return [dict get $::autosetup(cmdline) $name] } getenv $name $default } # @env-is-set name # # Returns 1 if the $name was specified on the command line or in the environment. # Note that an empty environment variable is not considered to be set. # proc env-is-set {name} { if {[dict exists $::autosetup(cmdline) $name]} { return 1 } if {[getenv $name ""] ne ""} { return 1 } return 0 } # @readfile filename ?default=""? # # Return the contents of the file, without the trailing newline. # If the doesn't exist or can't be read, returns $default. # proc readfile {filename {default_value ""}} { set result $default_value catch { set f [open $filename] set result [read -nonewline $f] close $f } return $result } # @writefile filename value # # Creates the given file containing $value. # Does not add an extra newline. # proc writefile {filename value} { set f [open $filename w] puts -nonewline $f $value close $f } proc quote-if-needed {str} { if {[string match {*[\" ]*} $str]} { return \"[string map [list \" \\" \\ \\\\] $str]\" } return $str } proc quote-argv {argv} { set args {} foreach arg $argv { lappend args [quote-if-needed $arg] } join $args } # @suffix suf list # # Takes a list and returns a new list with $suf appended # to each element # ## suffix .c {a b c} => {a.c b.c c.c} # proc suffix {suf list} { set result {} foreach p $list { lappend result $p$suf } return $result } # @prefix pre list # # Takes a list and returns a new list with $pre prepended # to each element # ## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} # proc prefix {pre list} { set result {} foreach p $list { lappend result $pre$p } return $result } # @find-executable name # # Searches the path for an executable with the given name. # Note that the name may include some parameters, e.g. "cc -mbig-endian", # in which case the parameters are ignored. # Returns 1 if found, or 0 if not. # proc find-executable {name} { # Ignore any parameters set name [lindex $name 0] if {$name eq ""} { # The empty string is never a valid executable return 0 } foreach p [split-path] { dputs "Looking for $name in $p" set exec [file join $p $name] if {[file-isexec $exec]} { dputs "Found $name -> $exec" return 1 } } return 0 } # @find-an-executable ?-required? name ... # # Given a list of possible executable names, # searches for one of these on the path. # # Returns the name found, or "" if none found. # If the first parameter is '-required', an error is generated # if no executable is found. # proc find-an-executable {args} { set required 0 if {[lindex $args 0] eq "-required"} { set args [lrange $args 1 end] incr required } foreach name $args { if {[find-executable $name]} { return $name } } if {$required} { if {[llength $args] == 1} { user-error "failed to find: [join $args]" } else { user-error "failed to find one of: [join $args]" } } return "" } # @configlog msg # # Writes the given message to the configuration log, config.log # proc configlog {msg} { if {![info exists ::autosetup(logfh)]} { set ::autosetup(logfh) [open config.log w] } puts $::autosetup(logfh) $msg } # @msg-checking msg # # Writes the message with no newline to stdout. # proc msg-checking {msg} { if {$::autosetup(msg-quiet) == 0} { maybe-show-timestamp puts -nonewline $msg set ::autosetup(msg-checking) 1 } } # @msg-result msg # # Writes the message to stdout. # proc msg-result {msg} { if {$::autosetup(msg-quiet) == 0} { maybe-show-timestamp puts $msg set ::autosetup(msg-checking) 0 show-notices } } # @msg-quiet command ... # # msg-quiet evaluates it's arguments as a command with output # from msg-checking and msg-result suppressed. # # This is useful if a check needs to run a subcheck which isn't # of interest to the user. proc msg-quiet {args} { incr ::autosetup(msg-quiet) set rc [uplevel 1 $args] incr ::autosetup(msg-quiet) -1 return $rc } # Will be overridden by 'use misc' proc error-stacktrace {msg} { return $msg } proc error-location {msg} { return $msg } ################################################################## # # Debugging output # proc dputs {msg} { if {$::autosetup(debug)} { puts $msg } } ################################################################## # # User and system warnings and errors # # Usage errors such as wrong command line options # @user-error msg # # Indicate incorrect usage to the user, including if required components # or features are not found. # autosetup exits with a non-zero return code. # proc user-error {msg} { show-notices puts stderr "Error: $msg" puts stderr "Try: '[file tail $::autosetup(exe)] --help' for options" exit 1 } # @user-notice msg # # Output the given message to stderr. # proc user-notice {msg} { lappend ::autosetup(notices) $msg } # Incorrect usage in the auto.def file. Identify the location. proc autosetup-error {msg} { autosetup-full-error [error-location $msg] } # Like autosetup-error, except $msg is the full error message. proc autosetup-full-error {msg} { show-notices puts stderr $msg exit 1 } proc show-notices {} { if {$::autosetup(msg-checking)} { puts "" set ::autosetup(msg-checking) 0 } flush stdout if {[info exists ::autosetup(notices)]} { puts stderr [join $::autosetup(notices) \n] unset ::autosetup(notices) } } proc maybe-show-timestamp {} { if {$::autosetup(msg-timing) && $::autosetup(msg-checking) == 0} { puts -nonewline [format {[%6.2f] } [expr {([clock millis] - $::autosetup(start)) % 10000 / 1000.0}]] } } proc autosetup_version {} { return "autosetup v$::autosetup(version)" } ################################################################## # # Directory/path handling # proc realdir {dir} { set oldpwd [pwd] cd $dir set pwd [pwd] cd $oldpwd return $pwd } # Follow symlinks until we get to something which is not a symlink proc realpath {path} { while {1} { if {[catch { set path [file readlink $path] }]} { # Not a link break } } return $path } # Convert absolute path, $path into a path relative # to the given directory (or the current dir, if not given). # proc relative-path {path {pwd {}}} { set diff 0 set same 0 set newf {} set prefix {} set path [file-normalize $path] if {$pwd eq ""} { set pwd [pwd] } else { set pwd [file-normalize $pwd] } if {$path eq $pwd} { return . } # Try to make the filename relative to the current dir foreach p [split $pwd /] f [split $path /] { if {$p ne $f} { incr diff } elseif {!$diff} { incr same } if {$diff} { if {$p ne ""} { # Add .. for sibling or parent dir lappend prefix .. } if {$f ne ""} { lappend newf $f } } } if {$same == 1 || [llength $prefix] > 3} { return $path } file join [join $prefix /] [join $newf /] } # Add filename as a dependency to rerun autosetup # The name will be normalised (converted to a full path) # proc autosetup_add_dep {filename} { lappend ::autosetup(deps) [file-normalize $filename] } ################################################################## # # Library module support # # @use module ... # # Load the given library modules. # e.g. 'use cc cc-shared' # # Note that module 'X' is implemented in either 'autosetup/X.tcl' # or 'autosetup/X/init.tcl' # # The latter form is useful for a complex module which requires additional # support file. In this form, '$::usedir' is set to the module directory # when it is loaded. # proc use {args} { foreach m $args { if {[info exists ::libmodule($m)]} { continue } set ::libmodule($m) 1 if {[info exists ::modsource($m)]} { automf_load eval $::modsource($m) } else { set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl] set found 0 foreach source $sources { if {[file exists $source]} { incr found break } } if {$found} { # For the convenience of the "use" source, point to the directory # it is being loaded from set ::usedir [file dirname $source] automf_load source $source autosetup_add_dep $source } else { autosetup-error "use: No such module: $m" } } } } # Load module source in the global scope by executing the given command proc automf_load {args} { if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] } } # ----- module core ----- set modsource(core) { } # ----- module asciidoc-formatting ----- set modsource(asciidoc-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # asciidoc format use formatting proc para {text} { regsub -all "\[ \t\n\]+" [string trim $text] " " } proc title {text} { underline [para $text] = nl } proc p {text} { puts [para $text] nl } proc code {text} { foreach line [parse_code_block $text] { puts " $line" } nl } proc codelines {lines} { foreach line $lines { puts " $line" } nl } proc nl {} { puts "" } proc underline {text char} { regexp "^(\[ \t\]*)(.*)" $text -> indent words puts $text puts $indent[string repeat $char [string length $words]] } proc section {text} { underline "[para $text]" - nl } proc subsection {text} { underline "$text" ~ nl } proc bullet {text} { puts "* [para $text]" } proc indent {text} { puts " :: " puts [para $text] } proc defn {first args} { set sep "" if {$first ne ""} { puts "${first}::" } else { puts " :: " } set defn [string trim [join $args \n]] regsub -all "\n\n" $defn "\n ::\n" defn puts $defn } } # ----- module formatting ----- set modsource(formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides common text formatting # This is designed for documenation which looks like: # code {...} # or # code { # ... # ... # } # In the second case, we need to work out the indenting # and strip it from all lines but preserve the remaining indenting. # Note that all lines need to be indented with the same initial # spaces/tabs. # # Returns a list of lines with the indenting removed. # proc parse_code_block {text} { # If the text begins with newline, take the following text, # otherwise just return the original if {![regexp "^\n(.*)" $text -> text]} { return [list [string trim $text]] } # And trip spaces off the end set text [string trimright $text] set min 100 # Examine each line to determine the minimum indent foreach line [split $text \n] { if {$line eq ""} { # Ignore empty lines for the indent calculation continue } regexp "^(\[ \t\]*)" $line -> indent set len [string length $indent] if {$len < $min} { set min $len } } # Now make a list of lines with this indent removed set lines {} foreach line [split $text \n] { lappend lines [string range $line $min end] } # Return the result return $lines } } # ----- module getopt ----- set modsource(getopt) { # Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Simple getopt module # Parse everything out of the argv list which looks like an option # Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1 # Everything which doesn't look like an option, or is after --, is left unchanged proc getopt {argvname} { upvar $argvname argv set nargv {} for {set i 0} {$i < [llength $argv]} {incr i} { set arg [lindex $argv $i] #dputs arg=$arg if {$arg eq "--"} { # End of options incr i lappend nargv {*}[lrange $argv $i end] break } if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} { lappend opts($name) $value } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} { if {$prefix eq "disable-"} { set value 0 } else { set value 1 } lappend opts($name) $value } else { lappend nargv $arg } } #puts "getopt: argv=[join $argv] => [join $nargv]" #parray opts set argv $nargv return [array get opts] } proc opt_val {optarrayname options {default {}}} { upvar $optarrayname opts set result {} foreach o $options { if {[info exists opts($o)]} { lappend result {*}$opts($o) } } if {[llength $result] == 0} { return $default } return $result } proc opt_bool {optarrayname args} { upvar $optarrayname opts # Support the args being passed as a list if {[llength $args] == 1} { set args [lindex $args 0] } foreach o $args { if {[info exists opts($o)]} { if {"1" in $opts($o) || "yes" in $opts($o)} { return 1 } } } return 0 } } # ----- module help ----- set modsource(help) { # Copyright (c) 2010 WorkWare Systems http://workware.net.au/ # All rights reserved # Module which provides usage, help and the command reference proc autosetup_help {what} { use_pager puts "Usage: [file tail $::autosetup(exe)] \[options\] \[settings\]\n" puts "This is [autosetup_version], a build environment \"autoconfigurator\"" puts "See the documentation online at http://msteveb.github.com/autosetup/\n" if {$what eq "local"} { if {[file exists $::autosetup(autodef)]} { # This relies on auto.def having a call to 'options' # which will display options and quit source $::autosetup(autodef) } else { options-show } } else { incr ::autosetup(showhelp) if {[catch {use $what}]} { user-error "Unknown module: $what" } else { options-show } } exit 0 } # If not already paged and stdout is a tty, pipe the output through the pager # This is done by reinvoking autosetup with --nopager added proc use_pager {} { if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} { if {[catch { exec [info nameofexecutable] $::argv0 --nopager {*}$::argv |& {*}[getenv PAGER] >@stdout <@stdin 2>@stderr } msg opts] == 1} { if {[dict get $opts -errorcode] eq "NONE"} { # an internal/exec error puts stderr $msg exit 1 } } exit 0 } } # Outputs the autosetup references in one of several formats proc autosetup_reference {{type text}} { use_pager switch -glob -- $type { wiki {use wiki-formatting} ascii* {use asciidoc-formatting} md - markdown {use markdown-formatting} default {use text-formatting} } title "[autosetup_version] -- Command Reference" section {Introduction} p { See http://msteveb.github.com/autosetup/ for the online documentation for 'autosetup' } p { 'autosetup' provides a number of built-in commands which are documented below. These may be used from 'auto.def' to test for features, define variables, create files from templates and other similar actions. } automf_command_reference exit 0 } proc autosetup_output_block {type lines} { if {[llength $lines]} { switch $type { code { codelines $lines } p { p [join $lines] } list { foreach line $lines { bullet $line } nl } } } } # Generate a command reference from inline documentation proc automf_command_reference {} { lappend files $::autosetup(prog) lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]] section "Core Commands" set type p set lines {} set cmd {} foreach file $files { set f [open $file] while {![eof $f]} { set line [gets $f] # Find lines starting with "# @*" and continuing through the remaining comment lines if {![regexp {^# @(.*)} $line -> cmd]} { continue } # Synopsis or command? if {$cmd eq "synopsis:"} { section "Module: [file rootname [file tail $file]]" } else { subsection $cmd } set lines {} set type p # Now the description while {![eof $f]} { set line [gets $f] if {![regexp {^#(#)? ?(.*)} $line -> hash cmd]} { break } if {$hash eq "#"} { set t code } elseif {[regexp {^- (.*)} $cmd -> cmd]} { set t list } else { set t p } #puts "hash=$hash, oldhash=$oldhash, lines=[llength $lines], cmd=$cmd" if {$t ne $type || $cmd eq ""} { # Finish the current block autosetup_output_block $type $lines set lines {} set type $t } if {$cmd ne ""} { lappend lines $cmd } } autosetup_output_block $type $lines } close $f } } } # ----- module init ----- set modsource(init) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module to help create auto.def and configure proc autosetup_init {type} { set help 0 if {$type in {? help}} { incr help } elseif {![dict exists $::autosetup(inittypes) $type]} { puts "Unknown type, --init=$type" incr help } if {$help} { puts "Use one of the following types (e.g. --init=make)\n" foreach type [lsort [dict keys $::autosetup(inittypes)]] { lassign [dict get $::autosetup(inittypes) $type] desc # XXX: Use the options-show code to wrap the description puts [format "%-10s %s" $type $desc] } exit 0 } lassign [dict get $::autosetup(inittypes) $type] desc script puts "Initialising $type: $desc\n" # All initialisations happens in the top level srcdir cd $::autosetup(srcdir) uplevel #0 $script exit 0 } proc autosetup_add_init_type {type desc script} { dict set ::autosetup(inittypes) $type [list $desc $script] } # This is for in creating build-system init scripts # # If the file doesn't exist, create it containing $contents # If the file does exist, only overwrite if --force is specified. # proc autosetup_check_create {filename contents} { if {[file exists $filename]} { if {!$::autosetup(force)} { puts "I see $filename already exists." return } else { puts "I will overwrite the existing $filename because you used --force." } } else { puts "I don't see $filename, so I will create it." } writefile $filename $contents } } # ----- module install ----- set modsource(install) { # Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which can install autosetup proc autosetup_install {dir} { if {[catch { cd $dir file mkdir autosetup set f [open autosetup/autosetup w] set publicmodules $::autosetup(libdir)/default.auto # First the main script, but only up until "CUT HERE" set in [open $::autosetup(dir)/autosetup] while {[gets $in buf] >= 0} { if {$buf ne "##-- CUT HERE --##"} { puts $f $buf continue } # Insert the static modules here # i.e. those which don't contain @synopsis: puts $f "set autosetup(installed) 1" set buf [readfile $::autosetup(libdir)/core.tcl] set modname core puts $f $buf puts $f "# ----- module $modname -----" puts $f "\nset modsource($modname) \{" puts $f "\}\n" foreach file [lsort [glob $::autosetup(libdir)/*.tcl]] { if {[file tail $file] eq "core.tcl"} continue set buf [readfile $file] if {[string match "*\n# @synopsis:*" $buf]} { lappend publicmodules $file continue } set modname [file rootname [file tail $file]] puts $f "# ----- module $modname -----" puts $f "\nset modsource($modname) \{" puts $f $buf puts $f "\}\n" } } close $in close $f exec chmod 755 autosetup/autosetup # Install public modules foreach file $publicmodules { autosetup_install_file $file autosetup } # Install support files foreach file {config.guess config.sub jimsh0.c find-tclsh test-tclsh LICENSE} { autosetup_install_file $::autosetup(dir)/$file autosetup } foreach file [glob -nocomplain $::autosetup(dir)/scripts/*] { autosetup_install_file $::autosetup(dir)/scripts/[file tail $file] autosetup } exec chmod 755 autosetup/config.sub autosetup/config.guess autosetup/find-tclsh writefile autosetup/README.autosetup \ "This is [autosetup_version]. See http://msteveb.github.com/autosetup/\n" } error]} { user-error "Failed to install autosetup: $error" } puts "Installed [autosetup_version] to autosetup/" # Now create 'configure' if necessary autosetup_create_configure exit 0 } proc autosetup_create_configure {} { if {[file exists configure]} { if {!$::autosetup(force)} { # Could this be an autosetup configure? if {![string match "*\nWRAPPER=*" [readfile configure]]} { puts "I see configure, but not created by autosetup, so I won't overwrite it." puts "Remove it or use --force to overwrite." return } } else { puts "I will overwrite the existing configure because you used --force." } } else { puts "I don't see configure, so I will create it." } writefile configure \ {#!/bin/sh dir="`dirname "$0"`/autosetup" WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@" } catch {exec chmod 755 configure} } # Append the contents of $file to filehandle $f proc autosetup_install_append {f file} { set in [open $file] puts $f [read $in] close $in } proc autosetup_install_file {file dir} { if {![file exists $file]} { error "Missing installation file '$file'" } writefile [file join $dir [file tail $file]] [readfile $file]\n } if {$::autosetup(installed)} { user-error "autosetup can only be installed from development source, not from installed copy" } } # ----- module markdown-formatting ----- set modsource(markdown-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # markdown format (kramdown syntax) use formatting proc para {text} { regsub -all "\[ \t\n\]+" [string trim $text] " " text regsub -all {([^a-zA-Z])'([^']*)'} $text {\1**`\2`**} text regsub -all {^'([^']*)'} $text {**`\1`**} text regsub -all {(http[^ \t\n]*)} $text {[\1](\1)} text return $text } proc title {text} { underline [para $text] = nl } proc p {text} { puts [para $text] nl } proc codelines {lines} { puts "~~~~~~~~~~~~" foreach line $lines { puts $line } puts "~~~~~~~~~~~~" nl } proc code {text} { puts "~~~~~~~~~~~~" foreach line [parse_code_block $text] { puts $line } puts "~~~~~~~~~~~~" nl } proc nl {} { puts "" } proc underline {text char} { regexp "^(\[ \t\]*)(.*)" $text -> indent words puts $text puts $indent[string repeat $char [string length $words]] } proc section {text} { underline "[para $text]" - nl } proc subsection {text} { puts "### `$text`" nl } proc bullet {text} { puts "* [para $text]" } proc defn {first args} { puts "^" set defn [string trim [join $args \n]] if {$first ne ""} { puts "**${first}**" puts -nonewline ": " regsub -all "\n\n" $defn "\n: " defn } puts "$defn" } } # ----- module misc ----- set modsource(misc) { # Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module containing misc procs useful to modules # Largely for platform compatibility set autosetup(istcl) [info exists ::tcl_library] set autosetup(iswin) [string equal windows $tcl_platform(platform)] if {$autosetup(iswin)} { # mingw/windows separates $PATH with semicolons # and doesn't have an executable bit proc split-path {} { split [getenv PATH .] {;} } proc file-isexec {exec} { # Basic test for windows. We ignore .bat if {[file isfile $exec] || [file isfile $exec.exe]} { return 1 } return 0 } } else { # unix separates $PATH with colons and has and executable bit proc split-path {} { split [getenv PATH .] : } proc file-isexec {exec} { file executable $exec } } # Assume that exec can return stdout and stderr proc exec-with-stderr {args} { exec {*}$args 2>@1 } if {$autosetup(istcl)} { # Tcl doesn't have the env command proc getenv {name args} { if {[info exists ::env($name)]} { return $::env($name) } if {[llength $args]} { return [lindex $args 0] } return -code error "environment variable \"$name\" does not exist" } proc isatty? {channel} { dict exists [fconfigure $channel] -xchar } } else { if {$autosetup(iswin)} { # On Windows, backslash convert all environment variables # (Assume that Tcl does this for us) proc getenv {name args} { string map {\\ /} [env $name {*}$args] } } else { # Jim on unix is simple alias getenv env } proc isatty? {channel} { set tty 0 catch { # isatty is a recent addition to Jim Tcl set tty [$channel isatty] } return $tty } } # In case 'file normalize' doesn't exist # proc file-normalize {path} { if {[catch {file normalize $path} result]} { if {$path eq ""} { return "" } set oldpwd [pwd] if {[file isdir $path]} { cd $path set result [pwd] } else { cd [file dirname $path] set result [file join [pwd] [file tail $path]] } cd $oldpwd } return $result } # If everything is working properly, the only errors which occur # should be generated in user code (e.g. auto.def). # By default, we only want to show the error location in user code. # We use [info frame] to achieve this, but it works differently on Tcl and Jim. # # This is designed to be called for incorrect usage in auto.def, via autosetup-error # proc error-location {msg} { if {$::autosetup(debug)} { return -code error $msg } # Search back through the stack trace for the first error in a .def file for {set i 1} {$i < [info level]} {incr i} { if {$::autosetup(istcl)} { array set info [info frame -$i] } else { lassign [info frame -$i] info(caller) info(file) info(line) } if {[string match *.def $info(file)]} { return "[relative-path $info(file)]:$info(line): Error: $msg" } #puts "Skipping $info(file):$info(line)" } return $msg } # If everything is working properly, the only errors which occur # should be generated in user code (e.g. auto.def). # By default, we only want to show the error location in user code. # We use [info frame] to achieve this, but it works differently on Tcl and Jim. # # This is designed to be called for incorrect usage in auto.def, via autosetup-error # proc error-stacktrace {msg} { if {$::autosetup(debug)} { return -code error $msg } # Search back through the stack trace for the first error in a .def file for {set i 1} {$i < [info level]} {incr i} { if {$::autosetup(istcl)} { array set info [info frame -$i] } else { lassign [info frame -$i] info(caller) info(file) info(line) } if {[string match *.def $info(file)]} { return "[relative-path $info(file)]:$info(line): Error: $msg" } #puts "Skipping $info(file):$info(line)" } return $msg } # Given the return from [catch {...} msg opts], returns an appropriate # error message. A nice one for Jim and a less-nice one for Tcl. # If 'fulltrace' is set, a full stack trace is provided. # Otherwise a simple message is provided. # # This is designed for developer errors, e.g. in module code or auto.def code # # proc error-dump {msg opts fulltrace} { if {$::autosetup(istcl)} { if {$fulltrace} { return "Error: [dict get $opts -errorinfo]" } else { return "Error: $msg" } } else { lassign $opts(-errorinfo) p f l if {$f ne ""} { set result "$f:$l: Error: " } append result "$msg\n" if {$fulltrace} { append result [stackdump $opts(-errorinfo)] } # Remove the trailing newline string trim $result } } } # ----- module odie ----- set modsource(odie) { # @synopsis: # # ODIE modules adds teacup platform data and integration with # sherpa # use system codebale # Build procs for this modules options { nodots => "Suppress dots in version numbers in lib names" pkgdir: => "Where to install the package (default $prefix/lib)" shlibver:=0.0 => "Shared lib version" debugbld => "Debug build: symbols, asserts, etc." nothreads => "Turn off threads" static => "Build a static library (default off)" } proc odie_tea_init conflist { array set project $conflist set nodots [lindex [opt-val nodots] end] if {$nodots eq {}} { if {$::odie(windows)} { set nodots 1 } } elseif {[string is true -strict $nodots]} { set nodots 1 } else { set nodots 0 } set libver $::project(pkgvers) lassign [regsub {^(\d)\.(\d)\.\d+$} [package provide Tcl] {\1.\2}] tclver if {[string is true -strict $nodots]} { set libver [string map {. ""} $libver] set tclver [string map {. ""} $tclver] } set prefix [get-define prefix] set pkgdir [lindex [opt-val pkgdir] end] if { $pkgdir eq {}} { set pkgdir [file join $prefix lib] } define pkgdir $pkgdir define docdir [file join $prefix share doc] define exadir [file join $prefix share examples] define datarootdir [file join $prefix share] if {[file exists [file join $project(srcdir) .. odie odieConfig.tcl]]} { source [file join $project(srcdir) .. odie odieConfig.tcl] } else { set prefix [get-define prefix] if {$prefix eq {}} { foreach path { /odie ~/odie c:/odie /opt/local /opt/odie /opt/local/odie /usr/local/odie } { set cffile [file join $path sandbox odie odieConfig.tcl] if {[file exists $cffile]} { set prefix [file normalize $path] source $cffile break } } } if {$prefix eq {} } { error "No Odie detected" } if {![file exists [file join $prefix sandbox odie odieConfig.tcl]]} { error "odieConfig.tcl not found" } } foreach {field} [lsort -dictionary [array names package]] { define PACKAGE_[string toupper $field] $package($field) define PKG_[string toupper $field] $package($field) } define PKG_NAME $::project(name) define PKG_VER $::project(pkgvers) set shlibver [lindex [opt-val shlibver 0.0] end] define SHLIB_VER $shlibver if {$shlibver ni {0.0 {}}} { append shlibspec [format [get-define SH_SOEXTVER] $shlibver] } else { set shlibspec [get-define SH_SOEXT] } define SHLIB_SPEC $shlibspec define EXT_INC_SPEC "" define EXT_LIB_DIR_SPEC "" define EXT_LIB_SPEC "" define TCL_INC_SPEC $::odie_tcl(include_spec) if {"tk" in $project(libs)} { define TCL_LIB_SPEC "$::odie_tcl(build_stub_lib_spec) $::odie_tk(build_stub_lib_spec)" } else { define TCL_LIB_SPEC $::odie_tcl(build_stub_lib_spec) } set ::odie_package(name) $::project(pkgname) set ::odie_package(version) $::project(pkgvers) set ::odie_package(ver) $::project(pkgvers) set ::odie_package(libfile) lib${::project(name)}$libver[get-define SHLIB_SPEC] set ::odie_package(lib_file) $::odie_package(libfile) if {"tk" in $project(libs)} { set ::odie_package(libs) $::odie_tk(libs) } else { set ::odie_package(libs) $::odie_tcl(libs) } foreach lib $project(libs) { if { $lib in {tcl tk} } continue if { "-l$lib" ni $::odie_package(libs) } { lappend ::odie_package(libs) "-l$lib" } } set idx 0 set start 0 set end 0 if {"tk" in $project(libs)} { set str $::odie_tk(defs) } else { set str $::odie_tcl(defs) } set len [string length $str] set token {} set next {} set item {} set opts {} while {$idx < $len} { ### # Seek start of opt ### if {[string range [string trim $item] end-1 end] != "-D"} { append item [string index $str $idx] incr idx } else { set end [expr {$idx-3}] set token [string trim [string range $str $start $end]] lappend opts $token set item {} set start $idx incr idx } } set token [string trim [string range $str $start end]] lappend opts $token set defs "-DPACKAGE_NAME=\"$::project(pkgname)\" -DPACKAGE_TARNAME=\"$::project(name)\" -DPACKAGE_VERSION=\"$::project(pkgvers)\" -DPACKAGE_STRING=\"$::project(pkgname) $::project(pkgvers)\"" foreach opt [lrange $opts 4 end] { append defs " -D$opt" } set ::odie_package(defs) $defs set ::odie_package(cflags) {} define DEFS $::odie_package(defs) set cflags { -pipe } if {[opt-bool debugbld]} { append cflags {${CFLAGS_DEBUG} ${CFLAGS_WARNING}} } else { append cflags {${CFLAGS_DEFAULT} ${CFLAGS_WARNING}} } if {[opt-bool static]} { } else { append cflags { ${SHLIB_CFLAGS}} } define CCFLAGS $cflags if {[lindex [opt-val nothreads] end] eq "1"} { define TH_CFLAGS "" define TH_LIBS "" define TH_DEFS "" } else { define TH_CFLAGS -pthread define TH_LIBS "" define TH_DEFS "-DTCL_THREADS=1 -DUSE_THREAD_ALLOC=1" } set tdefs {} lappend tdefs -DUSE_TCL_STUBS=1 if {"tk" in $project(libs)} { lappend tdefs -DUSE_TK_STUBS=1 } if {[lindex [opt-val debugbld] end] eq "1"} { define DEBUG "" define NDEBUG "#" lappend tdefs -DTCL_MEM_DEBUG=1 } else { define DEBUG "#" define NDEBUG "" } define TDEFS [join $tdefs] set opt_defs {} define OPT_DEFS [join $opt_defs] define CCFLAGS $::odie_tcl(extra_cflags) define CFLAGS_WARN $::odie_tcl(cflags_warning) define CFLAGS_OPT $::odie_tcl(cflags_optimize) define CFLAGS_DEBUG $::odie_tcl(cflags_debug) foreach path $::project(include_paths) { append ::odie_package(includes) " " -I$path } set ::odie_package(headers) $::project(h_file) foreach {var val} [array get ::odie_package] { define PACKAGE_[string toupper $var] $val define PKG_[string toupper $var] $val } define LIB lib${::project(name)}$libver[get-define SHLIB_SPEC] define PKG_LIB lib${::project(name)}$libver[get-define SHLIB_SPEC] define PKG_TCL_MODULES_ROOT [file join $::project(srcdir) modules] define PKG_TCL_SOURCES "" set modules {} foreach path [glob -nocomplain [file join $::project(srcdir) modules *]] { if {[file isdirectory $path]} { lappend modules [file tail $path] } } define PKG_TCL_MODULES $modules define PKG_LIB_INIT $::project(name) } proc odie_mkhdr {} { ### # Build mkhdr if we don't have it ### if {![file exists [::realpath $::odie(mkhdr)]]} { cd [::realpath $::odie(src_dir)] doexec $::odie(cc) -o mkhdr.o -c scripts/mkhdr.c doexec $::odie(cc) mkhdr.o -o mkhdr$::odie(exe_suffix) file copy -force mkhdr$::odie(exe_suffix) [::realpath $::odie(mkhdr)] } } ### # Initialize our picture of the world ### array set odie_tcl { config_flags {} version 8.6 major_version 8 minor_version 6 patch_level .4 fossil_branch release } array set odie_tk { config_flags {} version 8.6 major_version 8 minor_version 6 patch_level .4 fossil_branch release } array set odie { exe_suffix {} platform unix tea_platform_dir unix tcl_platform_dir unix tcl_config_flags {} tk_config_flags {} 64bit {} windows 0 system generic target generic os generic os_version {} teacup_os generic cpu {} window_system {} fossil_checkout .fslckout teacup_profile {} tk_binary_platform {} mirror_url http://fossil.etoyoc.com/fossil } # Make sure srcdir is fully qualified! set ::odie(cpu) [exec uname -m] set ::odie(os) [exec uname -s] set ::odie(system) ${::odie(os)}-${::odie(cpu)} set vfscp {cp -a} set ::odie(windows) 0 set ::odie(64bit) [expr {$::odie(cpu) in {amd64 x64 x86_64}}] ### # Sort out some slight differences between Visual studio # based builds and mingw/cygwin ### switch -glob -- [get-define build] { *-*-ming* - *-*-cygwin - *-*-msys { ### # Under mingw, 64 bit is not possible ### set odie(windows) 1 set odie(os) cygwin set ::odie(64bit) 0 } *win32* - *WIN32* { ### # With visual studio, 64 bit should be assumed # but is otherwise to taste ### set odie(windows) 1 set ::odie(os) windows } } ### # Build information about the local tools ### switch -glob -- [string tolower [get-define build]] { *-*-darwin* { # Use a native tool set verdat [exec sw_vers] foreach line [split $verdat \n] { if {[lindex $line 0] eq "ProductVersion:"} { set ::odie(os_version) [lindex $line 1] } } set ::odie(os) macosx set ::odie(teacup_os) macosx ### # Detect universal or x86_64 ### set major [lindex [split $::odie(os_version) .] 1] if { $major < 4 || $::odie(cpu) != "x86_64"} { set ::odie(teacup_os) macosx set ::odie(teacup_profile) macosx-universal set ::odie(cpu) universal } else { set ::odie(teacup_os) macosx10.5 set ::odie(teacup_profile) macosx10.5-i386-x86_64 set ::odie(cpu) x86_64 } set ::odie(tea_platform_dir) macosx } *-*-ming* - *-*-cygwin - *-*-msys - *win32* { ### # With visual studio, 64 bit should be assumed # but is otherwise to taste ### set ::odie(platform) windows set ::odie(system) windows set ::odie(teacup_os) win32 set vfscp {cp -a --no-preserve=links} set ::odie(windows) 1 set ::odie(fossil_checkout) _FOSSIL_ set ::odie(tclsrc_dir) win set ::odie(platform_dir) win set ::odie(tea_platform_dir) win set ::odie(tcl_platform_dir) win if {$::odie(64bit)} { set ::odie(teacup_profile) win32-ix86 set ::odie(cpu) ix86 } else { set ::odie(teacup_profile) win32-x86_64 set ::odie(cpu) x86_64 } set ::odie(exe_suffix) .exe } *-*-linux* { set glibcver [exec ldd --version] set major [lindex [split $glibcver .] 0] set minor [lindex [split $glibcver .] 1] set ::odie(teacup_os) linux-glibc$major.$minor set ::odie(system) linux-$::odie(cpu) set ::odie(os) linux } } if {[get-define build] ne [get-define host]} { set ::odie(windows) 0 ### # Build information about the target ### switch [get-define host] { darwin - macosx - macosx10.5-i386-x86_64 { set ::odie(os) macosx set ::odie(teacup_os) macosx10.5 set ::odie(teacup_profile) macosx10.5-i386-x86_64 set ::odie(cpu) x86_64 set ::odie(tea_platform_dir) macosx set ::odie(64bit) 1 } macosx-universal { set ::odie(os) macosx set ::odie(teacup_os) macosx set ::odie(teacup_profile) macosx-universal set ::odie(cpu) universal set ::odie(tea_platform_dir) macosx } windows - windows-x86_64 - win32-x86_64 { set ::odie(platform) windows set ::odie(system) windows set ::odie(teacup_os) win32 set ::odie(windows) 1 set ::odie(tclsrc_dir) win set ::odie(platform_dir) win set ::odie(64bit) 1 set ::odie(teacup_profile) win32-x86_64 set ::odie(cpu) x86_64 set ::odie(exe_suffix) .exe } windows-ix86 - win32-ix86 { set ::odie(platform) windows set ::odie(system) windows set ::odie(teacup_os) win32 set ::odie(windows) 1 set ::odie(tclsrc_dir) win set ::odie(platform_dir) win set ::odie(64bit) 0 set ::odie(teacup_profile) win32-ix86 set ::odie(cpu) ix86 set ::odie(exe_suffix) .exe } default { switch -glob -nocase -- [get-define target] { *macosx* - *-*-darwin* { # We don't know the version, so punt to # modern 64bit ix86 set ::odie(os) macosx set ::odie(teacup_os) macosx10.5 set ::odie(teacup_profile) macosx10.5-i386-x86_64 set ::odie(cpu) x86_64 set ::odie(tea_platform_dir) macosx } *-*-ming* - *-*-cygwin - *-*-msys - *win32* { set ::odie(platform) windows set ::odie(system) windows set ::odie(teacup_os) win32 set ::odie(windows) 1 set ::odie(tclsrc_dir) win set ::odie(platform_dir) win if {$::odie(64bit)} { set ::odie(teacup_profile) win32-x86_64 set ::odie(cpu) x86_64 } else { set ::odie(teacup_profile) win32-ix86 set ::odie(cpu) ix86 } set ::odie(exe_suffix) .exe } *-*-linux* { # Assume a modern linux found in teacup profiles set ::odie(teacup_os) linux-glibc2.3 set ::odie(system) linux-$::odie(cpu) set ::odie(os) linux } } } } } if {$::odie(teacup_profile) eq {}} { set ::odie(teacup_profile) $::odie(teacup_os)-$::odie(cpu) } define VFS_CP $vfscp if {[opt-val prefix] ne {} || ![info exists ::odie(prefix)]} { #------------------------------------------------------------------------ # Handle the --prefix=... option #------------------------------------------------------------------------ set prefix [opt-val prefix] if { $prefix eq {} } { if { $::odie(windows) } { set prefix c:/odie } else { set prefix $::env(HOME)/odie } } set ::odie_config(prefix) $prefix set exec_prefix $prefix } set ::odie(prefix) $prefix define prefix $prefix define exec_prefix $prefix ### # Read in tclConfig.sh ### set pathlist [list ../tcl/$::odie(tcl_platform_dir) ../tk/$::odie(tcl_platform_dir) [file join $prefix lib] /usr/local/lib /opt/local/lib c:/tcl c:/tcl/lib] foreach {file pre array} { tclConfig.sh tcl ::odie_tcl tkConfig.sh tk ::odie_tk } { set ${array}(config_found) 0 set l [expr {[string length $pre]+1}] foreach path $pathlist { set ffile [file join $path $file] if {[file exists $ffile]} break } if {![file exists $ffile]} continue set ${array}(config_found) 1 foreach {field dat} [read_Config.sh $ffile] { set field [string tolower $field] if {[string match ${pre}_* $field]} { set field [string range $field $l end] } set ${array}($field) $dat } } ### # Figure out Tcl ### if {$::odie(windows)} { set ::odie(tcl_shell) [file join $prefix bin tclsh${::odie_tcl(major_version)}${::odie_tcl(minor_version)}.exe] set ::odie(wish_shell) [file join $prefix bin wish${::odie_tk(major_version)}${::odie_tk(minor_version)}.exe] set ::odie(tclkit) [file join $prefix bin tclkit${::odie_tcl(major_version)}${::odie_tcl(minor_version)}.exe] set ::odie(wishkit) [file join $prefix bin tclkit${::odie_tcl(major_version)}${::odie_tcl(minor_version)}.exe] set ::odie(toadkit) [file join $prefix bin toadkit${::odie_tcl(major_version)}${::odie_tcl(minor_version)}.exe] } else { set ::odie(tcl_shell) [file join $prefix bin tclsh${::odie_tcl(major_version)}.${::odie_tcl(minor_version)}] set ::odie(wish_shell) [file join $prefix bin wish${::odie_tk(major_version)}.${::odie_tk(minor_version)}] set ::odie(tclkit) [file join $prefix bin tclkit${::odie_tcl(major_version)}.${::odie_tcl(minor_version)}] set ::odie(wishkit) [file join $prefix bin wishkit${::odie_tcl(major_version)}.${::odie_tcl(minor_version)}] set ::odie(toadkit) [file join $prefix bin toadkit${::odie_tcl(major_version)}.${::odie_tcl(minor_version)}] } define TCL_SHELL $::odie(tcl_shell) define WISH_SHELL $::odie(wish_shell) define TCLSH_PROG [info nameofexecutable] define BUILD_TCLSH [info nameofexecutable] set ::force_check 0 ### # Under MSYS/Cygwin transform the Cygwinized paths # pack into proper names for Windows ### foreach path { sandbox download src_dir tcl_shell wish_shell build_tclsh fossil git zip unzip sherpa lib local_repo } { if {[info exists ::odie($path)]} { set ::odie_build($path) [::realpath $::odie($path)] } } } # ----- module text-formatting ----- set modsource(text-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting use formatting proc wordwrap {text length {firstprefix ""} {nextprefix ""}} { set len 0 set space $firstprefix foreach word [split $text] { set word [string trim $word] if {$word == ""} { continue } if {$len && [string length $space$word] + $len >= $length} { puts "" set len 0 set space $nextprefix } incr len [string length $space$word] # Use man-page conventions for highlighting 'quoted' and *quoted* # single words. # Use x^Hx for *bold* and _^Hx for 'underline'. # # less and more will both understand this. # Pipe through 'col -b' to remove them. if {[regexp {^'(.*)'([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { regsub -all . $bareword "_\b&" word append word $dot } elseif {[regexp {^[*](.*)[*]([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { regsub -all . $bareword "&\b&" word append word $dot } puts -nonewline $space$word set space " " } if {$len} { puts "" } } proc title {text} { underline [string trim $text] = nl } proc p {text} { wordwrap $text 80 nl } proc codelines {lines} { foreach line $lines { puts " $line" } nl } proc nl {} { puts "" } proc underline {text char} { regexp "^(\[ \t\]*)(.*)" $text -> indent words puts $text puts $indent[string repeat $char [string length $words]] } proc section {text} { underline "[string trim $text]" - nl } proc subsection {text} { underline "$text" ~ nl } proc bullet {text} { wordwrap $text 76 " * " " " } proc indent {text} { wordwrap $text 76 " " " " } proc defn {first args} { if {$first ne ""} { underline " $first" ~ } foreach p $args { if {$p ne ""} { indent $p } } } } # ----- module wiki-formatting ----- set modsource(wiki-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # wiki.tcl.tk format output use formatting proc joinlines {text} { set lines {} foreach l [split [string trim $text] \n] { lappend lines [string trim $l] } join $lines } proc p {text} { puts [joinlines $text] puts "" } proc title {text} { puts "*** [joinlines $text] ***" puts "" } proc codelines {lines} { puts "======" foreach line $lines { puts " $line" } puts "======" } proc code {text} { puts "======" foreach line [parse_code_block $text] { puts " $line" } puts "======" } proc nl {} { } proc section {text} { puts "'''$text'''" puts "" } proc subsection {text} { puts "''$text''" puts "" } proc bullet {text} { puts " * [joinlines $text]" } proc indent {text} { puts " : [joinlines $text]" } proc defn {first args} { if {$first ne ""} { indent '''$first''' } foreach p $args { p $p } } } set corefile [file join [file dirname $::argv0] lib core.tcl] if {[file exist $corefile]} { source $corefile } ################################################################## # # Entry/Exit # if {$autosetup(debug)} { main $argv } if {[catch {main $argv} msg opts] == 1} { show-notices autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] if {!$autosetup(debug)} { puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" } exit 1 } |
Added autosetup/cc-db.tcl.
> > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # # The 'cc-db' module provides a knowledge based of system idiosyncracies # In general, this module can always be included use cc module-options {} # openbsd needs sys/types.h to detect some system headers cc-include-needs sys/socket.h sys/types.h cc-include-needs netinet/in.h sys/types.h |
Added autosetup/cc-lib.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # # Provides a library of common tests on top of the 'cc' module. use cc module-options {} # @cc-check-lfs # # The equivalent of the AC_SYS_LARGEFILE macro # # defines 'HAVE_LFS' if LFS is available, # and defines '_FILE_OFFSET_BITS=64' if necessary # # Returns 1 if 'LFS' is available or 0 otherwise # proc cc-check-lfs {} { cc-check-includes sys/types.h msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..." set lfs 1 if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} { msg-result no } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} { define _FILE_OFFSET_BITS 64 msg-result yes } else { set lfs 0 msg-result none } define-feature lfs $lfs return $lfs } # @cc-check-endian # # The equivalent of the AC_C_BIGENDIAN macro # # defines 'HAVE_BIG_ENDIAN' if endian is known to be big, # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. # # Returns 1 if determined, or 0 if not. # proc cc-check-endian {} { cc-check-includes sys/types.h sys/param.h set rc 0 msg-checking "Checking endian..." cc-with {-includes {sys/types.h sys/param.h}} { if {[cctest -code { #if !defined(BIG_ENDIAN) || !defined(BYTE_ORDER) #error unknown #elif BYTE_ORDER != BIG_ENDIAN #error little #endif }]} { define-feature big-endian msg-result "big" set rc 1 } elseif {[cctest -code { #if !defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER) #error unknown #elif BYTE_ORDER != LITTLE_ENDIAN #error big #endif }]} { define-feature little-endian msg-result "little" set rc 1 } else { msg-result "unknown" } } return $rc } # @cc-check-flags flag ?...? # # Checks whether the given C/C++ compiler flags can be used. Defines feature # names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and # appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'. proc cc-check-flags {args} { set result 1 array set opts [cc-get-settings] switch -exact -- $opts(-lang) { c++ { set lang C++ set prefix CXXFLAG } c { set lang C set prefix CFLAG } default { autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" } } foreach flag $args { msg-checking "Checking whether the $lang compiler accepts $flag..." if {[cctest -cflags $flag]} { msg-result yes define-feature $prefix$flag cc-with [list -cflags [list $flag]] define-append ${prefix}S $flag } else { msg-result no set result 0 } } return $result } # @cc-check-standards ver ?...? # # Checks whether the C/C++ compiler accepts one of the specified '-std=$ver' # options, and appends the first working one to '-cflags' and 'CFLAGS' or # 'CXXFLAGS'. proc cc-check-standards {args} { array set opts [cc-get-settings] foreach std $args { if {[cc-check-flags -std=$std]} { return $std } } return "" } # Checks whether $keyword is usable as alignof proc cctest_alignof {keyword} { msg-checking "Checking for $keyword..." if {[cctest -code [subst -nobackslashes { printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x')); }]]} then { msg-result ok define-feature $keyword } else { msg-result "not found" } } # @cc-check-c11 # # Checks for several C11/C++11 extensions and their alternatives. Currently # checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'. proc cc-check-c11 {} { msg-checking "Checking for _Static_assert..." if {[cctest -code { _Static_assert(1, "static assertions are available"); }]} then { msg-result ok define-feature _Static_assert } else { msg-result "not found" } cctest_alignof _Alignof cctest_alignof __alignof__ cctest_alignof __alignof } |
Added autosetup/cc-shared.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # # The 'cc-shared' module provides support for shared libraries and shared objects. # It defines the following variables: # ## SH_CFLAGS Flags to use compiling sources destined for a shared library ## SH_LDFLAGS Flags to use linking (creating) a shared library ## SH_SOPREFIX Prefix to use to set the soname when creating a shared library ## SH_SOEXT Extension for shared libs ## SH_SOEXTVER Format for versioned shared libs - %s = version ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object ## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed ## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects ## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries ## STRIPLIBFLAGS Arguments to strip to strip a dynamic library module-options {} # Defaults: gcc on unix define SHOBJ_CFLAGS -fpic define SHOBJ_LDFLAGS -shared define SH_CFLAGS -fpic define SH_LDFLAGS -shared define SH_LINKFLAGS -rdynamic define SH_SOEXT .so define SH_SOEXTVER .so.%s define SH_SOPREFIX -Wl,-soname, define LD_LIBRARY_PATH LD_LIBRARY_PATH define STRIPLIBFLAGS --strip-unneeded # Note: This is a helpful reference for identifying the toolchain # http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers switch -glob -- [get-define host] { *-*-darwin* { define SHOBJ_CFLAGS "-dynamic -fno-common" define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup" define SHOBJ_LDFLAGS_R -bundle define SH_CFLAGS -dynamic define SH_LDFLAGS -dynamiclib define SH_LINKFLAGS "" define SH_SOEXT .dylib define SH_SOEXTVER .%s.dylib define SH_SOPREFIX -Wl,-install_name, define LD_LIBRARY_PATH DYLD_LIBRARY_PATH define STRIPLIBFLAGS -x } *-*-ming* - *-*-cygwin - *-*-msys { define SHOBJ_CFLAGS "" define SHOBJ_LDFLAGS -shared define SH_CFLAGS "" define SH_LDFLAGS -shared define SH_LINKFLAGS "" define SH_SOEXT .dll define SH_SOEXTVER .dll define SH_SOPREFIX "" define LD_LIBRARY_PATH PATH } sparc* { if {[msg-quiet cc-check-decls __SUNPRO_C]} { msg-result "Found sun stdio compiler" # sun stdio compiler # XXX: These haven't been fully tested. define SHOBJ_CFLAGS -KPIC define SHOBJ_LDFLAGS "-G" define SH_CFLAGS -KPIC define SH_LINKFLAGS -Wl,-export-dynamic define SH_SOPREFIX -Wl,-h, } else { # sparc has a very small GOT table limit, so use -fPIC define SH_CFLAGS -fPIC define SHOBJ_CFLAGS -fPIC } } *-*-solaris* { if {[msg-quiet cc-check-decls __SUNPRO_C]} { msg-result "Found sun stdio compiler" # sun stdio compiler # XXX: These haven't been fully tested. define SHOBJ_CFLAGS -KPIC define SHOBJ_LDFLAGS "-G" define SH_CFLAGS -KPIC define SH_LINKFLAGS -Wl,-export-dynamic define SH_SOPREFIX -Wl,-h, } } *-*-hpux { # XXX: These haven't been tested define SHOBJ_CFLAGS "+O3 +z" define SHOBJ_LDFLAGS -b define SH_CFLAGS +z define SH_LINKFLAGS -Wl,+s define LD_LIBRARY_PATH SHLIB_PATH } *-*-haiku { define SHOBJ_CFLAGS "" define SHOBJ_LDFLAGS -shared define SH_CFLAGS "" define SH_LDFLAGS -shared define SH_LINKFLAGS "" define SH_SOPREFIX "" define LD_LIBRARY_PATH LIBRARY_PATH } } if {![is-defined SHOBJ_LDFLAGS_R]} { define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS] } |
Added autosetup/cc.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # # The 'cc' module supports checking various 'features' of the C or C++ # compiler/linker environment. Common commands are cc-check-includes, # cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template. # # The following environment variables are used if set: # ## CC - C compiler ## CXX - C++ compiler ## CCACHE - Set to "none" to disable automatic use of ccache ## CFLAGS - Additional C compiler flags ## CXXFLAGS - Additional C++ compiler flags ## LDFLAGS - Additional compiler flags during linking ## LIBS - Additional libraries to use (for all tests) ## CROSS - Tool prefix for cross compilation # # The following variables are defined from the corresponding # environment variables if set. # ## CPPFLAGS ## LINKFLAGS ## CC_FOR_BUILD ## LD use system module-options {} # Note that the return code is not meaningful proc cc-check-something {name code} { uplevel 1 $code } # Checks for the existence of the given function by linking # proc cctest_function {function} { cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" } # Checks for the existence of the given type by compiling proc cctest_type {type} { cctest -code "$type _x;" } # Checks for the existence of the given type/structure member. # e.g. "struct stat.st_mtime" proc cctest_member {struct_member} { lassign [split $struct_member .] struct member cctest -code "static $struct _s; return sizeof(_s.$member);" } # Checks for the existence of the given define by compiling # proc cctest_define {name} { cctest -code "#ifndef $name\n#error not defined\n#endif" } # Checks for the existence of the given name either as # a macro (#define) or an rvalue (such as an enum) # proc cctest_decl {name} { cctest -code "#ifndef $name\n(void)$name;\n#endif" } # @cc-check-sizeof type ... # # Checks the size of the given types (between 1 and 32, inclusive). # Defines a variable with the size determined, or "unknown" otherwise. # e.g. for type 'long long', defines SIZEOF_LONG_LONG. # Returns the size of the last type. # proc cc-check-sizeof {args} { foreach type $args { msg-checking "Checking for sizeof $type..." set size unknown # Try the most common sizes first foreach i {4 8 1 2 16 32} { if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { set size $i break } } msg-result $size set define [feature-define-name $type SIZEOF_] define $define $size } # Return the last result get-define $define } # Checks for each feature in $list by using the given script. # # When the script is evaluated, $each is set to the feature # being checked, and $extra is set to any additional cctest args. # # Returns 1 if all features were found, or 0 otherwise. proc cc-check-some-feature {list script} { set ret 1 foreach each $list { if {![check-feature $each $script]} { set ret 0 } } return $ret } # @cc-check-includes includes ... # # Checks that the given include files can be used proc cc-check-includes {args} { cc-check-some-feature $args { set with {} if {[dict exists $::autosetup(cc-include-deps) $each]} { set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] msg-quiet cc-check-includes {*}$deps foreach i $deps { if {[have-feature $i]} { lappend with $i } } } if {[llength $with]} { cc-with [list -includes $with] { cctest -includes $each } } else { cctest -includes $each } } } # @cc-include-needs include required ... # # Ensures that when checking for 'include', a check is first # made for each 'required' file, and if found, it is #included proc cc-include-needs {file args} { foreach depfile $args { dict set ::autosetup(cc-include-deps) $file $depfile 1 } } # @cc-check-types type ... # # Checks that the types exist. proc cc-check-types {args} { cc-check-some-feature $args { cctest_type $each } } # @cc-check-defines define ... # # Checks that the given preprocessor symbol is defined proc cc-check-defines {args} { cc-check-some-feature $args { cctest_define $each } } # @cc-check-decls name ... # # Checks that each given name is either a preprocessor symbol or rvalue # such as an enum. Note that the define used for a decl is HAVE_DECL_xxx # rather than HAVE_xxx proc cc-check-decls {args} { set ret 1 foreach name $args { msg-checking "Checking for $name..." set r [cctest_decl $name] define-feature "decl $name" $r if {$r} { msg-result "ok" } else { msg-result "not found" set ret 0 } } return $ret } # @cc-check-functions function ... # # Checks that the given functions exist (can be linked) proc cc-check-functions {args} { cc-check-some-feature $args { cctest_function $each } } # @cc-check-members type.member ... # # Checks that the given type/structure members exist. # A structure member is of the form "struct stat.st_mtime" proc cc-check-members {args} { cc-check-some-feature $args { cctest_member $each } } # @cc-check-function-in-lib function libs ?otherlibs? # # Checks that the given given function can be found in one of the libs. # # First checks for no library required, then checks each of the libraries # in turn. # # If the function is found, the feature is defined and lib_$function is defined # to -l$lib where the function was found, or "" if no library required. # In addition, -l$lib is added to the LIBS define. # # If additional libraries may be needed for linking, they should be specified # as $extralibs as "-lotherlib1 -lotherlib2". # These libraries are not automatically added to LIBS. # # Returns 1 if found or 0 if not. # proc cc-check-function-in-lib {function libs {otherlibs {}}} { msg-checking "Checking libs for $function..." set found 0 cc-with [list -libs $otherlibs] { if {[cctest_function $function]} { msg-result "none needed" define lib_$function "" incr found } else { foreach lib $libs { cc-with [list -libs -l$lib] { if {[cctest_function $function]} { msg-result -l$lib define lib_$function -l$lib define-append LIBS -l$lib incr found break } } } } } if {$found} { define [feature-define-name $function] } else { msg-result "no" } return $found } # @cc-check-tools tool ... # # Checks for existence of the given compiler tools, taking # into account any cross compilation prefix. # # For example, when checking for "ar", first AR is checked on the command # line and then in the environment. If not found, "${host}-ar" or # simply "ar" is assumed depending upon whether cross compiling. # The path is searched for this executable, and if found AR is defined # to the executable name. # Note that even when cross compiling, the simple "ar" is used as a fallback, # but a warning is generated. This is necessary for some toolchains. # # It is an error if the executable is not found. # proc cc-check-tools {args} { foreach tool $args { set TOOL [string toupper $tool] set exe [get-env $TOOL [get-define cross]$tool] if {[find-executable {*}$exe]} { define $TOOL $exe continue } if {[find-executable {*}$tool]} { msg-result "Warning: Failed to find $exe, falling back to $tool which may be incorrect" define $TOOL $tool continue } user-error "Failed to find $exe" } } # @cc-check-progs prog ... # # Checks for existence of the given executables on the path. # # For example, when checking for "grep", the path is searched for # the executable, 'grep', and if found GREP is defined as "grep". # # It the executable is not found, the variable is defined as false. # Returns 1 if all programs were found, or 0 otherwise. # proc cc-check-progs {args} { set failed 0 foreach prog $args { set PROG [string toupper $prog] msg-checking "Checking for $prog..." if {![find-executable $prog]} { msg-result no define $PROG false incr failed } else { msg-result ok define $PROG $prog } } expr {!$failed} } # Adds the given settings to $::autosetup(ccsettings) and # returns the old settings. # proc cc-add-settings {settings} { if {[llength $settings] % 2} { autosetup-error "settings list is missing a value: $settings" } set prev [cc-get-settings] # workaround a bug in some versions of jimsh by forcing # conversion of $prev to a list llength $prev array set new $prev foreach {name value} $settings { switch -exact -- $name { -cflags - -includes { # These are given as lists lappend new($name) {*}$value } -declare { lappend new($name) $value } -libs { # Note that new libraries are added before previous libraries set new($name) [list {*}$value {*}$new($name)] } -link - -lang - -nooutput { set new($name) $value } -source - -sourcefile - -code { # XXX: These probably are only valid directly from cctest set new($name) $value } default { autosetup-error "unknown cctest setting: $name" } } } cc-store-settings [array get new] return $prev } proc cc-store-settings {new} { set ::autosetup(ccsettings) $new } proc cc-get-settings {} { return $::autosetup(ccsettings) } # Similar to cc-add-settings, but each given setting # simply replaces the existing value. # # Returns the previous settings proc cc-update-settings {args} { set prev [cc-get-settings] cc-store-settings [dict merge $prev $args] return $prev } # @cc-with settings ?{ script }? # # Sets the given 'cctest' settings and then runs the tests in 'script'. # Note that settings such as -lang replace the current setting, while # those such as -includes are appended to the existing setting. # # If no script is given, the settings become the default for the remainder # of the auto.def file. # ## cc-with {-lang c++} { ## # This will check with the C++ compiler ## cc-check-types bool ## cc-with {-includes signal.h} { ## # This will check with the C++ compiler, signal.h and any existing includes. ## ... ## } ## # back to just the C++ compiler ## } # # The -libs setting is special in that newer values are added *before* earlier ones. # ## cc-with {-libs {-lc -lm}} { ## cc-with {-libs -ldl} { ## cctest -libs -lsocket ... ## # libs will be in this order: -lsocket -ldl -lc -lm ## } ## } proc cc-with {settings args} { if {[llength $args] == 0} { cc-add-settings $settings } elseif {[llength $args] > 1} { autosetup-error "usage: cc-with settings ?script?" } else { set save [cc-add-settings $settings] set rc [catch {uplevel 1 [lindex $args 0]} result info] cc-store-settings $save if {$rc != 0} { return -code [dict get $info -code] $result } return $result } } # @cctest ?settings? # # Low level C compiler checker. Compiles and or links a small C program # according to the arguments and returns 1 if OK, or 0 if not. # # Supported settings are: # ## -cflags cflags A list of flags to pass to the compiler ## -includes list A list of includes, e.g. {stdlib.h stdio.h} ## -declare code Code to declare before main() ## -link 1 Don't just compile, link too ## -lang c|c++ Use the C (default) or C++ compiler ## -libs liblist List of libraries to link, e.g. {-ldl -lm} ## -code code Code to compile in the body of main() ## -source code Compile a complete program. Ignore -includes, -declare and -code ## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file] ## -nooutput 1 Treat any compiler output (e.g. a warning) as an error # # Unless -source or -sourcefile is specified, the C program looks like: # ## #include <firstinclude> /* same for remaining includes in the list */ ## ## declare-code /* any code in -declare, verbatim */ ## ## int main(void) { ## code /* any code in -code, verbatim */ ## return 0; ## } # # Any failures are recorded in 'config.log' # proc cctest {args} { set src conftest__.c set tmp conftest__ # Easiest way to merge in the settings cc-with $args { array set opts [cc-get-settings] } if {[info exists opts(-sourcefile)]} { set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"] } if {[info exists opts(-source)]} { set lines $opts(-source) } else { foreach i $opts(-includes) { if {$opts(-code) ne "" && ![feature-checked $i]} { # Compiling real code with an unchecked header file # Quickly (and silently) check for it now # Remove all -includes from settings before checking set saveopts [cc-update-settings -includes {}] msg-quiet cc-check-includes $i cc-store-settings $saveopts } if {$opts(-code) eq "" || [have-feature $i]} { lappend source "#include <$i>" } } lappend source {*}$opts(-declare) lappend source "int main(void) {" lappend source $opts(-code) lappend source "return 0;" lappend source "}" set lines [join $source \n] } # Build the command line set cmdline {} lappend cmdline {*}[get-define CCACHE] switch -exact -- $opts(-lang) { c++ { lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS] } c { lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS] } default { autosetup-error "cctest called with unknown language: $opts(-lang)" } } if {!$opts(-link)} { set tmp conftest__.o lappend cmdline -c } lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""] lappend cmdline $src -o $tmp {*}$opts(-libs) # At this point we have the complete command line and the # complete source to be compiled. Get the result from cache if # we can if {[info exists ::cc_cache($cmdline,$lines)]} { msg-checking "(cached) " set ok $::cc_cache($cmdline,$lines) if {$::autosetup(debug)} { configlog "From cache (ok=$ok): [join $cmdline]" configlog "============" configlog $lines configlog "============" } return $ok } writefile $src $lines\n set ok 1 set err [catch {exec-with-stderr {*}$cmdline} result errinfo] if {$err || ($opts(-nooutput) && [string length $result])} { configlog "Failed: [join $cmdline]" configlog $result configlog "============" configlog "The failed code was:" configlog $lines configlog "============" set ok 0 } elseif {$::autosetup(debug)} { configlog "Compiled OK: [join $cmdline]" configlog "============" configlog $lines configlog "============" } file delete $src file delete $tmp # cache it set ::cc_cache($cmdline,$lines) $ok return $ok } # @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*? # # Deprecated - see make-config-header proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} { user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead" make-config-header $file -auto $autopatterns -bare $barepatterns } # @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ... # # Examines all defined variables which match the given patterns # and writes an include file, $file, which defines each of these. # Variables which match '-auto' are output as follows: # - defines which have the value "0" are ignored. # - defines which have integer values are defined as the integer value. # - any other value is defined as a string, e.g. "value" # Variables which match '-bare' are defined as-is. # Variables which match '-str' are defined as a string, e.g. "value" # Variables which match '-none' are omitted. # # Note that order is important. The first pattern which matches is selected # Default behaviour is: # # -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * # # If the file would be unchanged, it is not written. proc make-config-header {file args} { set guard _[string toupper [regsub -all {[^a-zA-Z0-9]} [file tail $file] _]] file mkdir [file dirname $file] set lines {} lappend lines "#ifndef $guard" lappend lines "#define $guard" # Add some defaults lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* foreach n [lsort [dict keys [all-defines]]] { set value [get-define $n] set type [calc-define-output-type $n $args] switch -exact -- $type { -bare { # Just output the value unchanged } -none { continue } -str { set value \"[string map [list \\ \\\\ \" \\\"] $value]\" } -auto { # Automatically determine the type if {$value eq "0"} { lappend lines "/* #undef $n */" continue } if {![string is integer -strict $value]} { set value \"[string map [list \\ \\\\ \" \\\"] $value]\" } } "" { continue } default { autosetup-error "Unknown type in make-config-header: $type" } } lappend lines "#define $n $value" } lappend lines "#endif" set buf [join $lines \n] write-if-changed $file $buf { msg-result "Created $file" } } proc calc-define-output-type {name spec} { foreach {type patterns} $spec { foreach pattern $patterns { if {[string match $pattern $name]} { return $type } } } return "" } # Initialise some values from the environment or commandline or default settings foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS {CFLAGS "-g -O2"}} { lassign $i var default define $var [get-env $var $default] } if {[env-is-set CC]} { # Set by the user, so don't try anything else set try [list [get-env CC ""]] } else { # Try some reasonable options set try [list [get-define cross]cc [get-define cross]gcc] } define CC [find-an-executable {*}$try] if {[get-define CC] eq ""} { user-error "Could not find a C compiler. Tried: [join $try ", "]" } define CPP [get-env CPP "[get-define CC] -E"] # XXX: Could avoid looking for a C++ compiler until requested # Note that if CXX isn't found, we just set it to "false". It might not be needed. if {[env-is-set CXX]} { define CXX [find-an-executable -required [get-env CXX ""]] } else { define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++ false] } # CXXFLAGS default to CFLAGS if not specified define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] # May need a CC_FOR_BUILD, so look for one define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] if {[get-define CC] eq ""} { user-error "Could not find a C compiler. Tried: [join $try ", "]" } define CCACHE [find-an-executable [get-env CCACHE ccache]] # Initial cctest settings cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} set autosetup(cc-include-deps) {} msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]" if {[get-define CXX] ne "false"} { msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS]" } msg-result "Build C compiler...[get-define CC_FOR_BUILD]" # On Darwin, we prefer to use -g0 to avoid creating .dSYM directories # but some compilers may not support it, so test here. switch -glob -- [get-define host] { *-*-darwin* { if {[cctest -cflags {-g0}]} { define cc-default-debug -g0 } } } if {![cc-check-includes stdlib.h]} { user-error "Compiler does not work. See config.log" } |
Added autosetup/codebale.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | ### # codebale.tcl # # This file defines routines used to bundle and manage Tcl and C # code repositories # # Copyright (c) 2014 Sean Woods # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. ### #::namespace eval ::codebale {} # @synopsis: # # CODEBALE modules adds autobuild utilities # set col 0 use fileutil ### # topic: e1d75c45e58cc525a0a70ce6f767717c ### proc codebale_isdirectory name { return [file isdirectory $name] } ### # topic: d0663852b31759ce78f33cbc63379d84 ### proc codebale_istcl name { return [string match *.tcl $name] } ### # topic: ea4ac0a84ae990dafee965b995f48e63 ### proc codebale_istm name { return [string match *.tm $name] } ### # topic: ec0fd469c986351ea0d5a287d6f040d8 ### proc codebale_cases_finalize f { global col if {$col>0} {puts $f {}} set col 0 } ### # topic: 78728b1f05577d4bc1276e7294ff2cc7 ### proc codebale_cases_generate {prefix cases} { global col set col 0 set f [open [file join $::project(path) build [string tolower ${prefix}_cases].h] w] fconfigure $f -translation crlf puts $f $::project(standard_header) puts $f " const static char *${prefix}_strs\[\] = \173" set lx [lsort $cases] foreach item $lx { cases_put $f \"[string tolower $item]\", } cases_put $f 0 cases_finalize $f puts $f " \175;" puts $f " enum ${prefix}_enum \173" foreach name $lx { regsub -all {@} $name {} name cases_put $f ${prefix}_[string toupper $name], } cases_finalize $f puts $f " \175;" puts $f "\ int index; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, \"METHOD ?ARG ...?\"); return TCL_ERROR; } if( Tcl_GetIndexFromObj(interp, objv\[1\], ${prefix}_strs,\ \"option\", 0, &index)){ return TCL_ERROR; } switch( (enum ${prefix}_enum)index )" close $f } ### # topic: 545596e62faedfeda638c8bb703882b1 ### proc codebale_cases_put {f x} { global col if {$col==0} {puts -nonewline $f " "} if {$col<2} { puts -nonewline $f [format " %-21s" $x] incr col } else { puts $f $x set col 0 } } ### # topic: 9dd91e4b98b001260e30671883da494b # description: Generate function declarations ### proc codebale_headers_csourcefile file { ### # Skip huge files ### if {[file size $file] > 500000} {return {}} set fin [open $file r] set dat [read $fin] close $fin set result [digest_csource $dat] set functions {} if [catch { foreach {funcname info} [lsort -stride 2 [dictGetnull $result function]] { dict with info { if { "static" in $keywords } continue append functions "$keywords $funcname\([join $arglist ", "]\)\x3b" \n } } } err] { puts "ERROR Parsing $file: $err" return "/* ** $file ** Process cancelled because of errors ** $err ** Line number: $::readinglinenumber ** Line: $::readingline */ " } return $functions } ### # topic: c0304a049be6f31206a02d15813720ce ### proc codebale_meta_output outfile { set fout [open $outfile w] puts "SAVING TO $outfile" #puts $fout "array set filemd5 \x7b" #array set temp [array get ::filemd5] #foreach {file md5} [lsort [array names temp]] { # set md5 $temp($file) # puts $fout " [list $file $md5]" #} #array unset temp #puts $fout "\x7d" puts $fout "helpdoc eval {begin transaction}" helpdoc eval { select handle,localpath from repository } { puts $fout [list ::helpdoc repository_restore $handle [list localpath $localpath]] } helpdoc eval { select hash,fileid from file } { puts $fout [helpdoc file_serialize $fileid] } puts $fout [helpdoc node_serialize 0] helpdoc eval { select entryid from entry where class='section' order by name } { puts $fout [helpdoc node_serialize $entryid] } helpdoc eval { select entryid from entry where class!='section' order by parent,class,name } { puts $fout [helpdoc node_serialize $entryid] } puts $fout "helpdoc eval {commit}" close $fout } ### # topic: cd6e815c2e68b751656a4c9bbe8918dd # description: Filters extranous fields from meta data ### proc codebale_meta_scrub {aliases info} { foreach {c alist} $aliases { foreach a $alist { set canonical($a) $c } } set outfo {} foreach {field val} $info { if {[info exists canonical($field)]} { set cname $canonical($field) } else { set cname $field } if {$cname eq {}} continue if {[string length [string trim $val]]} { dict set outfo $cname $val } } return $outfo } ### # topic: 51380132b6f872ed01830e34431931d4 ### proc codebale_pkg_mkIndex base { set stack {} if {[file exists [file join $base pkgIndex.tcl]]} { return #file delete [file join $base pkgIndex.tcl] } set fout [open [file join $base pkgIndex.tcl.new] w] fconfigure $fout -translation crlf set result [::codebale_sniffPath $base stack] puts $fout {# Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. } while {[llength $stack]} { set stackpath [lindex $stack 0] set stack [lrange $stack 1 end] foreach {type file} [::codebale_sniffPath $stackpath stack] { lappend result $type $file } } set i [string length $base] foreach {type file} $result { switch $type { module { set fname [file rootname [file tail $file]] set package [lindex [split $fname -] 0] set version [lindex [split $fname -] 1] set dir [string trimleft [string range [file dirname $file] $i end] /] puts $fout "package ifneeded $package $version \[list source \[file join \$dir $dir [file tail $file]\]\]" #::codebale_read_tclsourcefile $file } source { if { $file == "$base/pkgIndex.tcl" } continue if { $file == "$base/packages.tcl" } continue if { $file == "$base/main.tcl" } continue if { [file tail $file] == "version_info.tcl" } continue set fin [open $file r] set dat [read $fin] close $fin if {[regexp "package provide" $dat]} { set fname [file rootname [file tail $file]] set dir [string trimleft [string range [file dirname $file] $i end] /] foreach line [split $dat \n] { set line [string trim $line] if { [string range $line 0 14] != "package provide" } continue set package [lindex $line 2] set version [lindex $line 3] if { $dir eq {} } { puts $fout "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" } else { puts $fout "package ifneeded $package $version \[list source \[file join \$dir $dir [file tail $file]\]\]" } break } } #::codebale_read_tclsourcefile $file } } } close $fout file rename -force [file join $base pkgIndex.tcl.new] [file join $base pkgIndex.tcl] } ### # topic: 924caf1f68529d8dbc329b85e391a1c1 ### proc codebale_pkgindex_manifest base { set stack {} set output {} set base [file-normalize $base] set i [string length $base] foreach {file} [fileutil_find $base codebale_istm] { set file [file-normalize $file] set fname [file rootname [file tail $file]] ### # Assume the package is correct in the filename ### set package [lindex [split $fname -] 0] set version [lindex [split $fname -] 1] set path [string trimleft [string range [file dirname $file] $i end] /] ### # Read the file, and override assumptions as needed ### set fin [open $file r] set dat [read $fin] close $fin foreach line [split $dat \n] { set line [string trim $line] if { [string range $line 0 9] != "# Package " } continue set package [lindex $line 2] set version [lindex $line 3] break } lappend output $package $version } foreach {file} [fileutil_find $base codebale_istcl] { set file [file-normalize $file] set fin [open $file r] set dat [read $fin] close $fin if {![regexp "package provide" $dat]} continue set fname [file rootname [file tail $file]] set dir [string trimleft [string range [file dirname $file] $i end] /] foreach line [split $dat \n] { set line [string trim $line] if { [string range $line 0 14] != "package provide" } continue set package [lindex $line 2] set version [lindex $line 3] lappend output $package $version break } } return $output } ### # topic: 929629f0ebaa554710f66410dfa51f8a ### proc codebale_pkgindex_path base { set stack {} set buffer { lappend ::PATHSTACK $dir } set base [file-normalize $base] set i [string length $base] # Build a list of all of the paths set paths [fileutil_find $base codebale_isdirectory] foreach path $paths { if {$path eq $base} continue set path_indexed($path) 0 foreach idxname {pkgIndex.tcl} { if {[file exists [file join $path $idxname]]} { incr path_indexed($path) set dir [string trimleft [string range $path $i end] /] append buffer " set dir \[file join \[lindex \$::PATHSTACK end\] $dir\] \; source \[file join \[lindex \$::PATHSTACK end\] $dir $idxname\] " append buffer \n } } } foreach path $paths { if {$path_indexed($path)} continue foreach file [glob -nocomplain $path/*.tm] { set file [file-normalize $file] set fname [file rootname [file tail $file]] ### # Assume the package is correct in the filename ### set package [lindex [split $fname -] 0] set version [lindex [split $fname -] 1] set path [string trimleft [string range [file dirname $file] $i end] /] ### # Read the file, and override assumptions as needed ### set fin [open $file r] set dat [read $fin] close $fin foreach line [split $dat \n] { set line [string trim $line] if { [string range $line 0 9] != "# Package " } continue set package [lindex $line 2] set version [lindex $line 3] break } append buffer "package ifneeded $package $version \[list source \[file join \[lindex \$::PATHSTACK end\] $path [file tail $file]\]\]" append buffer \n } foreach file [glob -nocomplain $path/*.tcl] { set file [file-normalize $file] if { $file == [file join $base tcl8.6 package.tcl] } continue if { $file == [file join $base packages.tcl] } continue if { $file == [file join $base main.tcl] } continue if { [file tail $file] == "version_info.tcl" } continue set fin [open $file r] set dat [read $fin] close $fin if {![regexp "package provide" $dat]} continue set fname [file rootname [file tail $file]] set dir [string trimleft [string range [file dirname $file] $i end] /] foreach line [split $dat \n] { set line [string trim $line] if { [string range $line 0 14] != "package provide" } continue set package [lindex $line 2] set version [lindex $line 3] append buffer "package ifneeded $package $version \[list source \[file join \[lindex \$::PATHSTACK end\] $dir [file tail $file]\]\]" append buffer \n break } } } append buffer { set dir [lindex $::PATHSTACK end] set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] } return $buffer } ### # topic: 3a00781665184d1efb9e292dbdd1b35c # title: Read the contents of an rc conf file # description: # This style of conf file is assumed to contain lines formatted # set VARNAME VALUE ### proc codebale_read_rc_file fname { if {![file exists $fname]} { return {} } if {![catch {source $fname} err]} { # Could read as a Tcl file # Fill the result with the contents of # all of the local variables defined by # that file set vars [info vars] ldelete vars fname foreach var $vars { dict set result $var [set $var] } return $result } # Parse the file the hard way... set fin [open $fname r] set thisline {} while {[gets $fin line] >= 0} { set line [string trim $line] if {[string index $line 0] eq "#"} continue append thisline \n $line if {![info complete $thisline]} continue # Remove leading \n set thisline [string trimleft $thisline] if {[string range $line 0 2] == "set"} { dict set result [lindex $line 1] [lindex $line 2] } else { if {[llength $line] eq 2} { dict set result [lindex $line 0] [lindex $line 1] } } } return $result } ### # topic: cbb00d37108708e5968c8a38f73ec38a ### proc codebale_read_sh_file {filename {localdat {}}} { set fin [open $filename r] set result {} if {$localdat eq {}} { set top 1 set local [array get ::env] dict set local EXE {} } else { set top 0 set local $localdat } while {[gets $fin line] >= 0} { set line [string trim $line] if {[string index $line 0] eq "#"} continue if {$line eq {}} continue catch { if {[string range $line 0 6] eq "export "} { set eq [string first "=" $line] set field [string trim [string range $line 6 [expr {$eq - 1}]]] set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] dict set result $field [read_sh_subst $value $local] dict set local $field $value } elseif {[string range $line 0 7] eq "include "} { set subfile [read_sh_subst [string range $line 7 end] $local] foreach {field value} [read_sh_file $subfile $local] { dict set result $field $value } } else { set eq [string first "=" $line] if {$eq > 0} { set field [read_sh_subst [string range $line 0 [expr {$eq - 1}]] $local] set value [string trim [string range $line [expr {$eq+1}] end] '] #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] dict set local $field $value dict set result $field $value } } } err opts if {[dict get $opts -code] != 0} { #puts $opts puts "Error reading line:\n$line\nerr: $err\n***" return $err {*}$opts } } return $result } ### # topic: 22c2e7ae33fbe0d87784ca9b16df0de4 # description: Converts a XXX.sh file into a series of Tcl variables ### proc codebale_read_sh_subst {line info} { regsub -all {\x28} $line \x7B line regsub -all {\x29} $line \x7D line #set line [string map $key [string trim $line]] foreach {field value} $info { catch {set $field $value} } if [catch {subst $line} result] { return {} } set result [string trim $result] return [string trim $result '] } ### # topic: 45a5b1e3f8a8372363f1670642972c62 ### proc codebale_shlib_fname {os pkgname pkgvers} { if { $os eq "windows" } { return lib${pkgname}[string map {. {}} ${pkgvers}].dll } else { switch $os { macosx { set suffix .dylib } default { set suffix .so } } return lib${pkgname}${pkgvers}$suffix } } proc realpath path { if { !$::odie(windows) } { return $path } if {[string index $path 0] eq "/" && [string index $path 2] eq "/"} { return [string index $path 1]:[string range $path 2 end] } return $path } proc cygpath path { if { !$::odie(windows) } { return $path } if {[string index $path 1] != ":" } { return $path } set path [file-normalize $path] return /[string tolower [string index $path 0]][string range $path 2 end] } proc cygrelative {base filename} { set base [::cygpath $base] set filename [::cygpath $filename] return [::fileutil_relative $base $filename] } ### # topic: a5992c7f8340ba02d40e386aac95b1b8 # description: Records an alias for a Tcl keyword ### proc codebale_alias {alias cname} { global cnames set cnames($alias) $cname } ### # topic: 0e883f3583c0ccd3eddc6b297ac2ea77 ### proc codebale_buffer_append {varname args} { upvar 1 $varname result if {![info exists result]} { set result {} } if {[string length $result]} { set result [string trimright $result \n] append result \n } set priorarg {} foreach arg $args { if {[string length [string trim $arg]]==0} continue #if {[string match $arg $priorarg]} continue set priorarg $arg append result \n [string trim $arg \n] \n } set result [string trim $result \n] append result \n return $result } ### # topic: 926c564aa67884986f7489f37da3fb32 ### proc codebale_buffer_merge args { set result {} set priorarg {} foreach arg $args { if {[string length [string trim $arg]]==0} continue if {[string match $arg $priorarg]} continue set priorarg $arg append result [string trim $arg \n] \n } set result [string trim $result \n] return $result } ### # topic: c1e66f4a20e397a5d2541714575c165f ### proc codebale_buffer_puts {varname args} { upvar 1 $varname result if {![info exists result]} { set result {} } set result [string trimright $result \n] #if {[string length $result]} { # set result [string trimright $result \n] #} set priorarg {} foreach arg $args { #if {[string length [string trim $arg]]==0} continue #if {[string match $arg $priorarg]} continue #set priorarg $arg append result \n $arg #[string trim $arg \n] } #set result [string trim $result \n] #append result \n return $result } ### # topic: 951f31f2cb24992f34d97e3deb16b43f # description: Reports back the canonical name of a tcl keyword ### proc codebale_canonical alias { global cnames if {[info exists cnames($alias)]} { return $cnames($alias) } return $alias } proc codebale_detect_cases_put_item {f x} { upvar 1 col col if {$col==0} {puts -nonewline $f " "} if {$col<2} { puts -nonewline $f [format " %-21s" $x] incr col } else { puts $f $x set col 0 } } proc codebale_detect_cases_finalize {f} { upvar 1 col col if {$col>0} {puts $f {}} set col 0 } ### # topic: aacfe07625f74f93dada2159f53fca32 ### proc codebale_detect_cases cfile { set dirname [file dirname $cfile] set fin [open $cfile r] while {[gets $fin line] >= 0} { if {[regexp {^ *case *([A-Z]+)_([A-Z0-9_]+):} $line all prefix label]} { lappend cases($prefix) $label } } close $fin set col 0 foreach prefix [array names cases] { set hfile [file join $dirname [string tolower $prefix]_cases.h] if {[file exists $hfile] && [file mtime $hfile]>[file mtime $cfile]} continue set f [open $hfile w] fconfigure $f -translation crlf puts $f "/*** Automatically Generated Header File - Do Not Edit ***/" puts $f " const static char *${prefix}_strs\[\] = \173" set lx [lsort $cases($prefix)] foreach item $lx { codebale_detect_cases_put_item $f \"[string tolower $item]\", } codebale_detect_cases_put_item $f 0 codebale_detect_cases_finalize $f puts $f " \175;" puts $f " enum ${prefix}_enum \173" foreach name $lx { regsub -all {@} $name {} name codebale_detect_cases_put_item $f ${prefix}_[string toupper $name], } codebale_detect_cases_finalize $f puts $f " \175;" puts $f "\ int index; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, \"METHOD ?ARG ...?\"); return TCL_ERROR; } if( Tcl_GetIndexFromObj(interp, objv\[1\], ${prefix}_strs,\ \"option\", 0, &index)){ return TCL_ERROR; } switch( (enum ${prefix}_enum)index )" close $f } set result {} foreach item [array names cases] { lappend result [string tolower ${item}_cases.h] } return $result } ### # topic: 003ce0c0d69b74076e8433492deac920 # description: # Descends into a directory structure, returning # a list of items found in the form of: # type object # where type is one of: csource source parent_name # and object is the full path to the file ### proc codebale_sniffPath {spath stackvar} { upvar 1 $stackvar stack set result {} if { ![file isdirectory $spath] } { switch [file extension $spath] { .tm { return [list parent_name $spath] } .tcl { return [list source $spath] } .h { return [list cheader $spath] } .c { return [list csource $spath] } } return } foreach f [glob -nocomplain $spath/*] { if {[file isdirectory $f]} { if {[file tail $f] in {CVS build} } continue if {[file extension $f] eq ".vfs" } continue set stack [linsert $stack 0 $f] } } set idx 0 foreach idxtype { pkgIndex.tcl tclIndex } { if {[file exists [file join $spath $idxtype]]} { lappend result index [file join $spath $idxtype] } } if {[llength $result]} { return $result } foreach f [glob -nocomplain $spath/*] { if {![file isdirectory $f]} { set stack [linsert $stack 0 $f] } } return {} } # [dictGetnull] is like [dict get] but returns empty string for missing keys. proc dictGetnull {dictionary args} { if {[dict exists $dictionary {*}$args]} { dict get $dictionary {*}$args } } #namespace ensemble configure dict -map [dict replace\ # [namespace ensemble configure dict -map] getnull ::tcl::dict::getnull] if {[info command ::ldelete] eq {}} { proc ldelete {varname args} { upvar 1 $varname var if ![info exists var] { return } foreach item [lsort -unique $args] { while {[set i [lsearch $var $item]]>=0} { set var [lreplace $var $i $i] } } return $var } } ### # topic: 5b6897b1d60450332ff9f389b5ca952d ### proc doexec args { exec {*}$args >&@ stdout } # Simpler version without the substitution proc read_Config.sh {filename} { set fin [open $filename r] set result {} while {[gets $fin line] >= 0} { set line [string trim $line] if {[string index $line 0] eq "#"} continue if {$line eq {}} continue catch { set eq [string first "=" $line] if {$eq > 0} { set field [string range $line 0 [expr {$eq - 1}]] set value [string trim [string range $line [expr {$eq+1}] end] '] #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] dict set result $field $value } } err opts if {[dict get $opts -code] != 0} { #puts $opts puts "Error reading line:\n$line\nerr: $err\n***" return $err {*}$opts } } return $result } |
Added autosetup/config.guess.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 | #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2010-09-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to <[email protected]> and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <[email protected]>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' HUP INT TERM # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # ([email protected] 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # [email protected] (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include <stdlib.h> #include <unistd.h> int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-tilera-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` echo ${UNAME_MACHINE}-pc-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says <[email protected]> echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <[email protected]>. # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From [email protected]. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From [email protected]. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From [email protected]. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include <sys/param.h> printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include <sys/param.h> # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 <<EOF $0: unable to guess system type This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be pertinent to <[email protected]> in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: |
Added autosetup/config.sub.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 | #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2010-09-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to <[email protected]>. Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <[email protected]>." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; msys) basic_machine=i386-pc os=-msys ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: |
Added autosetup/cthulhu.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | ### # Utilities for automating the build process of C extensions ### use codebale # @synopsis: # # CTHULHU modules adds autobuild utilities # #::namespace eval ::cthulhu {} ### # title: define which modules the source we are adding contributes to ### proc cthulhu_config args { set ::cthulhu_config [dict merge $::cthulhu_config $args] } ### # topic: 9c0c2d73c1afa8ef83a739c5d01309d0 # title: Signal for a C header to be read with mkhdr ### proc cthulhu_add_cheader {filename {trace 0}} { set hfilename [::cygrelative $::project(srcdir) $filename] if {$hfilename in $::project(headers_verbatim)} { return } if {$hfilename ni $::project(headers)} { lappend ::project(headers) $hfilename #::cthulhu_read_csourcefile $file } } ### # topic: c52ea7e1ff44f11f960d99a55e4ab998 # title: Add the contents of a header file verbatim to the internal headers and public headers ### proc cthulhu_add_cheader_verbatim {filename {trace 0}} { set hfilename [::cygrelative $::project(srcdir) $filename] ldelete ::project(headers) $hfilename if {$hfilename ni $::project(headers_verbatim)} { lappend ::project(headers_verbatim) $hfilename } } ### # topic: 91e4d7da8dd82d78af41561360deab10 # title: Signal for a C source to be read with mkhdr ### proc cthulhu_add_csource {filename {cmdconfig {}}} { set config [dict merge $::cthulhu_config $cmdconfig] set cfilename [::cygrelative $::project(srcdir) $filename] dict set ::thesources $cfilename $config if {$cfilename ni $::project(sources)} { lappend ::project(sources) $cfilename } if {[string is true [dictGetnull $config scan]]} { if {$cfilename ni $::project(scanlist)} { lappend ::project(scanlist) $cfilename } } } ### # topic: f11da5f705442524715e8f8fe9af5276 # title: Add a path containing C code ### proc cthulhu_add_directory {here {cmdconfig {}}} { set config [dict merge { cthulhu-ignore-hfiles {} cthulhu-ignore-cfiles {} build-ignore-cfiles {} cthulhu-trace-cfiles {} } $::cthulhu_config $cmdconfig] dict with config {} set here [::realpath $here] ### # Execute any .tcl scripts in the generic directory ### foreach file [lsort [glob -nocomplain [file join $here *.tcl]]] { if {[file tail $file] eq "pkgIndex.tcl"} continue cd $here uplevel #0 [list source $file] } ### # Build a list of all public header files that # need to be amalgamated into the publicly exported # version ### foreach file [lsort [glob -nocomplain [file join $here *.h]]] { cthulhu_include_directory $here set fname [file tail $file] if {${cthulhu-ignore-hfiles} eq "*"} continue if { $fname in ${cthulhu-ignore-hfiles} } continue if {[string match *_cases.h $fname]} continue cthulhu_add_cheader $file } foreach file [lsort [glob -nocomplain [file join $here *.c]]] { if {[file tail $file] in ${build-ignore-cfiles} } continue cthulhu_add_csource $file } } proc cthulhu_include_directory {here} { if { $here ni $::project(include_paths) } { lappend ::project(include_paths) $here } } ### # topic: 1d3a911fd58337df92205759a6d092c3 # title: Add a source file in Tcl that produces a C file ### proc cthulhu_add_dynamic {csource tclscript} { set cfilename [::cygrelative $::project(srcdir) $csource] set tclfilename [::cygrelative $::project(srcdir) $tclscript] dict set ::thesources $cfilename tclscript $tclfilename } ### # topic: d10665e8da4dd0781bb0a9ced5486e40 # title: Add a pure-tcl library ### proc cthulhu_add_library {here {cmdconfig {}}} { set config [dict merge { cthulhu-ignore-tclfiles {} } $::cthulhu_config $cmdconfig] dict with config {} set here [::realpath $here] foreach file [lsort [glob -nocomplain $here/*.tcl]] { if {[file tail $file] in ${cthulhu-ignore-tclfiles}} continue set libfilename [::cygrelative $::project(srcdir) $libfilename] } } ### # topic: ccfe65b26705afc498e08d3004031066 # title: Detect where we need to produce a _cases.h file to automate a C source ### proc cthulhu_detect_cases filename { set cfilename [::cygrelative $::project(srcdir) $filename] set cases [codebale_detect_cases $filename] if {![llength $cases]} return set dirname [file dirname $cfilename] foreach case $cases { lappend result [file join $dirname $case] } dict set ::thesources $cfilename cases $result } ### # topic: 41d95037e5a1cab76939150efdef8939 # title: Declare an end to modifications of ::project # description: # This directive is placed after the last set ::project(X) Y # but before the first ::cthulhu_add_* ### proc cthulhu_init args { set ::cthulhu_config [dict merge { target pkg } $args] set ::project(strlen) [string length $::project(path)/] set ::project(cases) {} set ::project(sources) {} set ::project(headers) {} set ::project(scanlist) {} set ::project(headers_verbatim) {} } ### # topic: 17c9931c3ec5ba115efafaaaa3cf61ed ### proc cthulhu_mk_lib_init.c outfile { global project cout set cout [open $outfile w] fconfigure $cout -translation crlf puts $cout $::project(standard_header) puts $cout "#include \"$::project(h_file_int)\"" puts $cout " extern int DLLEXPORT ${project(init_funct)}( Tcl_Interp *interp ) \{ Tcl_Namespace *modPtr\; " puts $cout { /* Initialise the stubs tables. */ #ifdef USE_TCL_STUBS if ( !Tcl_InitStubs(interp, "8.3", 0) ) { return TCL_ERROR; } #endif } foreach module $::project(modules) { puts $cout " if(${module}(interp)) return TCL_ERROR\;" } foreach {nspace cmds} [lsort -stride 2 -dictionary [array get namespace_commands]] { puts $cout " modPtr=Tcl_FindNamespace(interp,\"$nspace\",NULL,TCL_NAMESPACE_ONLY)\; if(!modPtr) { modPtr = Tcl_CreateNamespace(interp, \"$nspace\", NULL, NULL); } " foreach {command cfunct} [lsort -stride 2 -dictionary $cmds] { puts $cout " Tcl_CreateObjCommand(interp,\"::${nspace}::${command}\",(Tcl_ObjCmdProc *)$cfunct,NULL,NULL);" } puts $cout { Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); Tcl_Export(interp, modPtr, "[a-z]*", 1); } } puts $cout { /* Register the package. */} puts $cout " if (Tcl_PkgProvide(interp, \"${project(pkgname)}\", \"${project(pkgvers)}\")) return TCL_ERROR\;" puts $cout " return TCL_OK\;\n\}" close $cout } ### # topic: 17c9931c3ec5ba115efafaaaa3cf61ed ### proc cthulhu_mk_app_init.c outfile { global project cout set cout [open $outfile w] fconfigure $cout -translation crlf puts $cout $::project(standard_header) puts $cout "#include \"$::project(h_file_int)\"" puts $cout " int ${project(init_funct)}_static( Tcl_Interp *interp ) \{ Tcl_Namespace *modPtr\; " foreach module $::project(modules) { puts $cout " if(${module}(interp)) \{ return TCL_ERROR\; \} " } foreach {nspace cmds} [lsort -stride 2 -dictionary [array get namespace_commands]] { puts $cout " modPtr=Tcl_FindNamespace(interp,\"$nspace\",NULL,TCL_NAMESPACE_ONLY)\; if(!modPtr) { modPtr = Tcl_CreateNamespace(interp, \"$nspace\", NULL, NULL); } " foreach {command cfunct} [lsort -stride 2 -dictionary $cmds] { puts $cout " Tcl_CreateObjCommand(interp,\"::${nspace}::${command}\",(Tcl_ObjCmdProc *)$cfunct,NULL,NULL);" } puts $cout { Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); Tcl_Export(interp, modPtr, "[a-z]*", 1); } } puts $cout { /* Register the package. */} puts $cout " if (Tcl_PkgProvide(interp, \"${project(pkgname)}\", \"${project(pkgvers)}\")) return TCL_ERROR\;" puts $cout " return TCL_OK\;\n\}" close $cout } ### # topic: 06bca7e2bddebdca69537fc3a9a0735f ### proc cthulhu_mk_sources {bldpath outfile} { global project file mkdir $bldpath set fout [open $outfile w] fconfigure $fout -translation crlf set pkg_sources {} set pkg_objects {} foreach {csource} $::project(sources) { set ofile [file join $bldpath [string trimleft [string map {/ _ .c .o .. {}} $csource] _]] lappend pkg_sources $csource lappend pkg_objects $ofile dict set ::thesources $csource ofile $ofile } set ILINE "MYINCLUDES=" foreach ipath $::project(include_paths) { append ILINE \\\n" -I[::cygrelative $::project(srcdir) $ipath]" } puts $fout $ILINE puts $fout {} define PKG_OBJECTS [lsort $pkg_objects] define PKG_SOURCES [lsort $pkg_sources] #puts $fout "build/$project(c_file):" #puts $fout "\t\${TCLSH} scripts/cthulhu.tcl\n" foreach {csource cinfo} $::thesources { if {[dict exists $cinfo ofile]} { set ofile [dict get $cinfo ofile] } else { set ofile {} } set hfiles {} if {[dict exists $cinfo cases]} { foreach hfile [dict get $cinfo cases] { puts $fout "$hfile:" puts $fout "\t\$(TCLSH_PROG) scripts/mktclopts.tcl $csource\n" lappend hfiles $hfile } } if {[dict exists $cinfo tclscript]} { puts $fout "$csource:" puts $fout "\t\$(TCLSH_PROG) [dict get $cinfo tclscript] $csource\n" if {$ofile != {}} { puts $fout "$ofile: $hfiles" puts $fout "\t\$(COMPILE) [dictGetnull $cinfo extra] \$(MYINCLUDES) -c $csource -o \$@\n" } } else { if {$ofile != {}} { puts $fout "$ofile: $hfiles" puts $fout "\t\$(COMPILE) [dictGetnull $cinfo extra] \$(MYINCLUDES) -c $csource -o \$@\n" } } } close $fout } ### # topic: f7eec240dada25d73c1f68a877fa40be # title: Produce the PROJECT.decls file # description: Tools for automating the process of building stubs libraries ### proc cthulhu_mk_stub_decls {pkgname mkhdrfile path} { set outfile [file join $path/$pkgname.decls] ### # Build the decls file ### set fout [open $outfile w] puts $fout [subst {### # $outfile # # This file was generated by [info script] ### library $pkgname interface $pkgname }] set fin [open $mkhdrfile r] set thisline {} set functcount 0 while {[gets $fin line]>=0} { append thisline \n $line if {![info complete $thisline]} continue set readline $thisline set thisline {} set type [lindex $readline 1] if { $type ne "f" } continue set infodict [lindex $readline end] if {![dict exists $infodict definition]} continue set def [dict get $infodict definition] set def [string trim $def] set def [string trimright $def \;] if {![string match "*STUB_EXPORT*" $def]} continue puts $fout [list declare [incr functcount] $def] } close $fin close $fout ### # Build [package]Decls.h ### set hout [open [file join $path ${pkgname}Decls.h] w] close $hout set cout [open [file join $path ${pkgname}StubInit.c] w] puts $cout [string map [list %pkgname% $pkgname %PkgName% [string totitle $pkgname]] { #ifndef USE_TCL_STUBS #define USE_TCL_STUBS #endif #undef USE_TCL_STUB_PROCS #include "tcl.h" #include "%pkgname%.h" /* ** Ensure that Tdom_InitStubs is built as an exported symbol. The other stub ** functions should be built as non-exported symbols. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT %PkgName%Stubs *%pkgname%StubsPtr; /* **---------------------------------------------------------------------- ** ** %PkgName%_InitStubs -- ** ** Checks that the correct version of %PkgName% is loaded and that it ** supports stubs. It then initialises the stub table pointers. ** ** Results: ** The actual version of %PkgName% that satisfies the request, or ** NULL to indicate that an error occurred. ** ** Side effects: ** Sets the stub table pointers. ** **---------------------------------------------------------------------- */ char * %PkgName%_InitStubs (Tcl_Interp *interp, char *version, int exact) { char *actualVersion; actualVersion = Tcl_PkgRequireEx(interp, "%pkgname%", version, exact, (ClientData *) &%pkgname%StubsPtr); if (!actualVersion) { return NULL; } if (!%pkgname%StubsPtr) { Tcl_SetResult(interp, "This implementation of %PkgName% does not support stubs", TCL_STATIC); return NULL; } return actualVersion; } }] close $cout } ### # topic: ba1d2c7e8eab96029e434d54f917ef5a ### proc cthulhu_mkhdr_index {hout docfileout} { global project set scanlist {} foreach file $::project(headers) { lappend scanlist [::realpath [file join $::project(srcdir) $file]] } foreach file $::project(scanlist) { lappend scanlist [::realpath [file join $::project(srcdir) $file]] } ldelete scanlist [::realpath $::project(srcdir)/generic/$::project(h_file_int)] ldelete scanlist [::realpath $::project(srcdir)/generic/$::project(c_file)] puts "WRITING INTERNAL HEADERS TO $hout" set fout [open $hout w] puts $fout "/* ** DO NOT EDIT THIS FILE ** It is automagically generated by scripts/cthulhu.tcl */" fconfigure $fout -translation crlf foreach file $::project(headers_verbatim) { puts $fout "/* Verbatim headers */" set fullname [file join $::project(srcdir) $file] set type [file type $fullname] if {$type ne "file"} continue puts $fout "/*\n *$file \n*/" set fin [open $fullname r] puts $fout [read $fin] close $fin } puts $fout "/* FUNCTION DECLARATIONS */" ### # Do get around platform line breaks, we output to a tmp file # and concat in Tcl ### set crscanlist {} foreach file $scanlist { set crfile $file.cr[file extension $file] set rawfin [open $file r] set rawfout [open $crfile w] fconfigure $rawfout -translation lf puts $rawfout [read $rawfin] close $rawfout close $rawfin lappend crscanlist $crfile } ::cthulhu_mkhdr -h -- {*}$crscanlist > $hout.cr set rawfin [open $hout.cr r] puts $fout [read $rawfin] close $rawfin file delete $hout.cr close $fout ::cthulhu_mkhdr -doc -- {*}$scanlist > $docfileout foreach file $crscanlist { file delete $file } foreach {prefix cases} $::project(cases) { ::codebale_cases_generate $prefix $cases } set fin [open $hout r] while {[gets $fin line]>=0} { if {[regexp TCL_MODULE $line] || [regexp DLLEXPORT $line]} { foreach regexp { {(.*) ([a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} {(.*) (\x2a[a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} } { if {[regexp $regexp $line all keywords funcname arglist]} { lappend ::project(modules) $funcname break } } } } } proc cthulhu_find_mkhdr {} { set exename [lindex [find-an-executable mkhdr] 0] if {$exename ne {}} { return [list exec [::realpath $exename]] } if {[info exists ::odie(mkhdr)]} { if {[file exists [::realpath $::odie(mkhdr)]]} { return [list exec [::realpath $::odie(mkhdr)]] } } doexec $::odie(cc) -o mkhdr.o -c $::odie(src_dir)/scripts/mkhdr.c doexec $::odie(cc) mkhdr.o -o mkhdr$::odie(exe_suffix) file copy -force mkhdr$::odie(exe_suffix) [::realpath $::odie(mkhdr)] return [list exec [::realpath $::odie(mkhdr)]] error {mkhdr not available} } proc cthulhu_mkhdr args { set cmd [cthulhu_find_mkhdr] {*}${cmd} {*}$args } array set ::project { include_paths {} sources {} tcl_sources {} modules {} } |
Added autosetup/default.auto.
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Auto-load module for 'make' build system integration use init autosetup_add_init_type make {Simple "make" build system} { autosetup_check_create auto.def \ {# Initial auto.def created by 'autosetup --init=make' use cc # Add any user options here options { } make-config-header config.h make-template Makefile.in } if {![file exists Makefile.in]} { puts "Note: I don't see Makefile.in. You will probably need to create one." } } |
Added autosetup/fileutil.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 | # fileutil.tcl -- # # Tcl implementations of standard UNIX utilities. # # Copyright (c) 1998-2000 by Ajuba Solutions. # Copyright (c) 2002 by Phil Ehrens <[email protected]> (fileType) # Copyright (c) 2005-2013 by Andreas Kupries <[email protected]> # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: fileutil.tcl,v 1.78 2010/06/17 04:46:19 andreas_kupries Exp $ # @synopsis: # # CODEBALE modules adds a jimtcl compadible version of the fileutil package from tcllib # package provide cthulhu-fileutil 1.14.8 #namespace eval ::fileutil { # namespace export \ # find findByPattern cat touch foreachLine \ # jail stripPwd stripN stripPath tempdir tempfile \ # install fileType writeFile appendToFile \ # insertIntoFile removeFromFile replaceInFile \ # updateInPlace test tempdirReset #} # ::fileutil_grep -- # # Implementation of grep. Adapted from the Tcler's Wiki. # # Arguments: # pattern pattern to search for. # files list of files to search; if NULL, uses stdin. # # Results: # results list of matches proc fileutil_grep {pattern {files {}}} { set result [list] if {[llength $files] == 0} { # read from stdin set lnum 0 while {[gets stdin line] >= 0} { incr lnum if {[regexp -- $pattern $line]} { lappend result "${lnum}:${line}" } } } else { foreach filename $files { set file [open $filename r] set lnum 0 while {[gets $file line] >= 0} { incr lnum if {[regexp -- $pattern $line]} { lappend result "${filename}:${lnum}:${line}" } } close $file } } return $result } # ::fileutil_find == # Below is the core command, which is portable across Tcl versions and # platforms. Functionality which is common or platform and/or Tcl # version dependent, has been factored out/ encapsulated into separate # (small) commands. Only these commands may have multiple variant # implementations per the available features of the Tcl core / # platform. # # These commands are # # FADD - Add path result, performs filtering. Portable! # GLOBF - Return files in a directory. Tcl version/platform dependent. # GLOBD - Return dirs in a directory. Tcl version/platform dependent. # ACCESS - Check directory for accessibility. Tcl version/platform dependent. proc fileutil_find {{basedir .} {filtercmd {}}} { set result {} set filt [string length $filtercmd] if {[file isfile $basedir]} { # The base is a file, and therefore only possible result, # modulo filtering. fileutil_FADD $basedir } elseif {[file isdirectory $basedir]} { # For a directory as base we do an iterative recursion through # the directory hierarchy starting at the base. We use a queue # (Tcl list) of directories we have to check. We access it by # index, and stop when we have reached beyond the end of the # list. This is faster than removing elements from the be- # ginning of the list, as that entails copying down a possibly # large list of directories, making it O(n*n). The index is # faster, O(n), at the expense of memory. Nothing is deleted # from the list until we have processed all directories in the # hierarchy. # # We scan each directory at least twice. First for files, then # for directories. The scans may internally make several # passes (normal vs hidden files). # # Looped directory structures due to symbolic links are # handled by _fully_ normalizing directory paths and checking # if we encountered the normalized form before. The array # 'known' is our cache where we record the known normalized # paths. set pending [list $basedir] set at 0 array set known {} while {$at < [llength $pending]} { # Get next directory not yet processed. set current [lindex $pending $at] incr at # Is the directory accessible? Continue if not. fileutil_ACCESS $current # Files first, then the sub-directories ... foreach f [fileutil_GLOBF $current] { fileutil_FADD $f } foreach f [fileutil_GLOBD $current] { # Ignore current and parent directory, this needs # explicit filtering outside of the filter command. if { [string equal [file tail $f] "."] || [string equal [file tail $f] ".."] } continue # Extend result, modulo filtering. fileutil_FADD $f # Detection of symlink loops via a portable path # normalization computing a canonical form of the path # followed by a check if that canonical form was # encountered before. If ok, record directory for # expansion in future iterations. set norm [fileutil_fullnormalize $f] if {[info exists known($norm)]} continue set known($norm) . lappend pending $f } } } else { return -code error "$basedir does not exist" } return $result } # Helper command for fileutil_find. Performs the filtering of the # result per a filter command for the candidates found by the # traversal core, see above. This is portable. proc fileutil_FADD {filename} { upvar 1 result result filt filt filtercmd filtercmd if {!$filt} { lappend result $filename return } set here [pwd] cd [file dirname $filename] if {[uplevel 2 [linsert $filtercmd end [file tail $filename]]]} { lappend result $filename } cd $here return } # The next three helper commands for fileutil_find depend strongly on # the version of Tcl, and partially on the platform. # 1. The -directory and -types switches were added to glob in Tcl # 8.3. This means that we have to emulate them for Tcl 8.2. # # 2. In Tcl 8.3 using -types f will return only true files, but not # links to files. This changed in 8.4+ where links to files are # returned as well. So for 8.3 we have to handle the links # separately (-types l) and also filter on our own. # Note that Windows file links are hard links which are reported by # -types f, but not -types l, so we can optimize that for the two # platforms. # # Note further that we have to handle broken links on our own. They # are not returned by glob yet we want them in the output. # # 3. In Tcl 8.3 we also have a crashing bug in glob (SIGABRT, "stat on # a known file") when trying to perform 'glob -types {hidden f}' on # a directory without e'x'ecute permissions. We code around by # testing if we can cd into the directory (stat might return enough # information too (mode), but possibly also not portable). # # For Tcl 8.2 and 8.4+ glob simply delivers an empty result # (-nocomplain), without crashing. For them this command is defined # so that the bytecode compiler removes it from the bytecode. # # This bug made the ACCESS helper necessary. # We code around the problem by testing if we can cd into the # directory (stat might return enough information too (mode), but # possibly also not portable). set tclver [package present Tcl] puts [list TCL VERSION $tclver] if {$tclver eq {}} { # jimTcl emulates a pre-namespace tcl set tclver 7.8 } puts [list TCL VERSION $tclver] ### # Assume an austere environment # circa 8.2. # (Ad 1,2,3) We do not have -directory, nor -types. Full emulation required. ### proc fileutil_ACCESS {args} {} if {[string equal $::tcl_platform(platform) windows]} { # Hidden files cannot be handled by Tcl 8.2 in glob. We have # to punt. proc fileutil_GLOBF {current} { set current \\[join [split $current {}] \\] set res {} foreach x [glob -nocomplain -- [file join $current *]] { if {[file isdirectory $x]} continue if {[catch {file type $x}]} continue # We have now accepted files, links to files, and # broken links. We may also have accepted a directory # as well, if the current path was inaccessible. This # however will cause 'file type' to throw an error, # hence the second check. lappend res $x } return $res } proc fileutil_GLOBD {current} { set current \\[join [split $current {}] \\] set res {} foreach x [glob -nocomplain -- [file join $current *]] { if {![file isdirectory $x]} continue lappend res $x } return $res } } else { # Hidden files on Unix are dot-files. We emulate the switch # '-types hidden' by using an explicit pattern. proc fileutil_GLOBF {current} { set current \\[join [split $current {}] \\] set res {} foreach x [glob -nocomplain -- [file join $current *] [file join $current .*]] { if {[file isdirectory $x]} continue if {[catch {file type $x}]} continue # We have now accepted files, links to files, and # broken links. We may also have accepted a directory # as well, if the current path was inaccessible. This # however will cause 'file type' to throw an error, # hence the second check. lappend res $x } return $res } proc fileutil_GLOBD {current} { set current \\[join [split $current {}] \\] set res {} foreach x [glob -nocomplain -- $current/* [file join $current .*]] { if {![file isdirectory $x]} continue lappend res $x } return $res } } # ::fileutil_findByPattern -- # # Specialization of find. Finds files based on their names, # which have to match the specified patterns. Options are used # to specify which type of patterns (regexp-, glob-style) is # used. # # Arguments: # basedir Directory to start searching from. # args Options (-glob, -regexp, --) followed by a # list of patterns to search for. # # Results: # files a list of interesting files. proc fileutil_findByPattern {basedir args} { set pos 0 set cmd ::fileutil_FindGlob foreach a $args { incr pos switch -glob -- $a { -- {break} -regexp {set cmd ::fileutil_FindRegexp} -glob {set cmd ::fileutil_FindGlob} -* {return -code error "Unknown option $a"} default {incr pos -1 ; break} } } set args [lrange $args $pos end] if {[llength $args] != 1} { set pname [lindex [info level 0] 0] return -code error \ "wrong#args for \"$pname\", should be\ \"$pname basedir ?-regexp|-glob? ?--? patterns\"" } set patterns [lindex $args 0] return [find $basedir [list $cmd $patterns]] } # ::fileutil_FindRegexp -- # # Internal helper. Filter command used by 'findByPattern' # to match files based on regular expressions. # # Arguments: # patterns List of regular expressions to match against. # filename Name of the file to match against the patterns. # Results: # interesting A boolean flag. Set to true if the file # matches at least one of the patterns. proc fileutil_FindRegexp {patterns filename} { foreach p $patterns { if {[regexp -- $p $filename]} { return 1 } } return 0 } # ::fileutil_FindGlob -- # # Internal helper. Filter command used by 'findByPattern' # to match files based on glob expressions. # # Arguments: # patterns List of glob expressions to match against. # filename Name of the file to match against the patterns. # Results: # interesting A boolean flag. Set to true if the file # matches at least one of the patterns. proc fileutil_FindGlob {patterns filename} { foreach p $patterns { if {[string match $p $filename]} { return 1 } } return 0 } # ::fileutil_stripPwd -- # # If the specified path references is a path in [pwd] (or [pwd] itself) it # is made relative to [pwd]. Otherwise it is left unchanged. # In the case of [pwd] itself the result is the string '.'. # # Arguments: # path path to modify # # Results: # path The (possibly) modified path. proc fileutil_stripPwd {path} { # [file split] is used to generate a canonical form for both # paths, for easy comparison, and also one which is easy to modify # using list commands. set pwd [pwd] if {[string equal $pwd $path]} { return "." } set pwd [file split $pwd] set npath [file split $path] if {[string match ${pwd}* $npath]} { set path [eval [linsert [lrange $npath [llength $pwd] end] 0 file join ]] } return $path } # ::fileutil_stripN -- # # Removes N elements from the beginning of the path. # # Arguments: # path path to modify # n number of elements to strip # # Results: # path The modified path proc fileutil_stripN {path n} { set path [file split $path] if {$n >= [llength $path]} { return {} } else { return [eval [linsert [lrange $path $n end] 0 file join]] } } # ::fileutil_stripPath -- # # If the specified path references/is a path in prefix (or prefix itself) it # is made relative to prefix. Otherwise it is left unchanged. # In the case of it being prefix itself the result is the string '.'. # # Arguments: # prefix prefix to strip from the path. # path path to modify # # Results: # path The (possibly) modified path. if {[string equal $::tcl_platform(platform) windows]} { # Windows. While paths are stored with letter-case preserved al # comparisons have to be done case-insensitive. For reference see # SF Tcllib Bug 2499641. proc fileutil_stripPath {prefix path} { # [file split] is used to generate a canonical form for both # paths, for easy comparison, and also one which is easy to modify # using list commands. set prefix [file split $prefix] set npath [file split $path] if {[string equal -nocase $prefix $npath]} { return "." } if {[string match -nocase "${prefix} *" $npath]} { set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] } return $path } } else { proc fileutil_stripPath {prefix path} { # [file split] is used to generate a canonical form for both # paths, for easy comparison, and also one which is easy to modify # using list commands. set prefix [file split $prefix] set npath [file split $path] if {[string equal $prefix $npath]} { return "." } if {[string match "${prefix} *" $npath]} { set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] } return $path } } # ::fileutil_jail -- # # Ensures that the input path 'filename' stays within the the # directory 'jail'. In this way it preventsuser-supplied paths # from escaping the jail. # # Arguments: # jail The path to the directory the other must # not escape from. # filename The path to prevent from escaping. # # Results: # path The (possibly) modified path surely within # the confines of the jail. proc fileutil_jail {jail filename} { if {![string equal [file pathtype $filename] "relative"]} { # Although the path to check is absolute (or volumerelative on # windows) we cannot perform a simple prefix check to see if # the path is inside the jail or not. We have to normalize # both path and jail and then we can check. If the path is # outside we make the original path relative and prefix it # with the original jail. We do make the jail pseudo-absolute # by prefixing it with the current working directory for that. # Normalized jail. Fully resolved sym links, if any. Our main # complication is that normalize does not resolve symlinks in the # last component of the path given to it, so we add a bogus # component, resolve, and then strip it off again. That is why the # code is so large and long. set njail [eval [list file join] [lrange [file split \ [fileutil_Normalize [file join $jail __dummy__]]] 0 end-1]] # Normalize filename. Fully resolved sym links, if # any. S.a. for an explanation of the complication. set nfile [eval [list file join] [lrange [file split \ [fileutil_Normalize [file join $filename __dummy__]]] 0 end-1]] if {[string match ${njail}* $nfile]} { return $filename } # Outside the jail, put it inside. ... We normalize the input # path lexically for this, to prevent escapes still lurking in # the original path. (We cannot use the normalized path, # symlinks may have bent it out of shape in unrecognizable ways. return [eval [linsert [lrange [file split \ [fileutil_lexnormalize $filename]] 1 end] 0 file join [pwd] $jail]] } else { # The path is relative, consider it as outside # implicitly. Normalize it lexically! to prevent escapes, then # put the jail in front, use PWD to ensure absoluteness. return [eval [linsert [file split [fileutil_lexnormalize $filename]] 0 \ file join [pwd] $jail]] } } # ::fileutil_test -- # # Simple API to testing various properties of # a path (read, write, file/dir, existence) # # Arguments: # path path to test # codes names of the properties to test # msgvar Name of variable to leave an error # message in. Optional. # label Label for error message, optional # # Results: # ok boolean flag, set if the path passes # all tests. global test array set test { read {readable {Read access is denied}} write {writable {Write access is denied}} exec {executable {Is not executable}} exists {exists {Does not exist}} file {isfile {Is not a file}} dir {isdirectory {Is not a directory}} } proc fileutil_test {path codes {msgvar {}} {label {}}} { global test if {[string equal $msgvar ""]} { set msg "" } else { upvar 1 $msgvar msg } if {![string equal $label ""]} {append label { }} if {![regexp {^(read|write|exec|exists|file|dir)} $codes]} { # Translate single characters into proper codes set codes [string map { r read w write e exists x exec f file d dir } [split $codes {}]] } foreach c $codes { foreach {cmd text} $test($c) break if {![file $cmd $path]} { set msg "$label\"$path\": $text" return 0 } } return 1 } # ::fileutil_cat -- # # Tcl implementation of the UNIX "cat" command. Returns the contents # of the specified files. # # Arguments: # args names of the files to read, interspersed with options # to set encodings, translations, or eofchar. # # Results: # data data read from the file. proc fileutil_cat {args} { # Syntax: (?options? file)+ # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- if {![llength $args]} { # Argument processing stopped with arguments missing. return -code error \ "wrong#args: should be\ [lindex [info level 0] 0] ?-eofchar|-translation|-encoding arg?+ file ..." } # We go through the arguments using foreach and keeping track of # the index we are at. We do not shift the arguments out to the # left. That is inherently quadratic, copying everything down. set opts {} set mode maybeopt set channels {} foreach a $args { if {[string equal $mode optarg]} { lappend opts $a set mode maybeopt continue } elseif {[string equal $mode maybeopt]} { if {[string match -* $a]} { switch -exact -- $a { -encoding - -translation - -eofchar { lappend opts $a set mode optarg continue } -- { set mode file continue } default { return -code error \ "Bad option \"$a\",\ expected one of\ -encoding, -eofchar,\ or -translation" } } } # Not an option, but a file. Change mode and fall through. set mode file } # Process file arguments if {[string equal $a -]} { # Stdin reference is special. # Test that the current options are all ok. # For stdin we have to avoid closing it. set old [fconfigure stdin] set fail [catch { SetOptions stdin $opts } msg] ; # {} SetOptions stdin $old if {$fail} { return -code error $msg } lappend channels [list $a $opts 0] } else { if {![file exists $a]} { return -code error "Cannot read file \"$a\", does not exist" } elseif {![file isfile $a]} { return -code error "Cannot read file \"$a\", is not a file" } elseif {![file readable $a]} { return -code error "Cannot read file \"$a\", read access is denied" } # Test that the current options are all ok. set c [open $a r] set fail [catch { SetOptions $c $opts } msg] ; # {} close $c if {$fail} { return -code error $msg } lappend channels [list $a $opts [file size $a]] } # We may have more options and files coming after. set mode maybeopt } if {![string equal $mode maybeopt]} { # Argument processing stopped with arguments missing. return -code error \ "wrong#args: should be\ [lindex [info level 0] 0] ?-eofchar|-translation|-encoding arg?+ file ..." } set data "" foreach c $channels { foreach {fname opts size} $c break if {[string equal $fname -]} { set old [fconfigure stdin] SetOptions stdin $opts append data [read stdin] SetOptions stdin $old continue } set c [open $fname r] SetOptions $c $opts if {$size > 0} { # Used the [file size] command to get the size, which # preallocates memory, rather than trying to grow it as # the read progresses. append data [read $c $size] } else { # if the file has zero bytes it is either empty, or # something where [file size] reports 0 but the file # actually has data (like the files in the /proc # filesystem on Linux). append data [read $c] } close $c } return $data } # ::fileutil_writeFile -- # # Write the specified data into the named file, # creating it if necessary. # # Arguments: # options... Options and arguments. # filename Path to the file to write. # data The data to write into the file # # Results: # None. proc fileutil_writeFile {args} { # Syntax: ?options? file data # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec Writable $args opts fname data # Now perform the requested operation. file mkdir [file dirname $fname] set c [open $fname w] SetOptions $c $opts puts -nonewline $c $data close $c return } # ::fileutil_appendToFile -- # # Append the specified data at the end of the named file, # creating it if necessary. # # Arguments: # options... Options and arguments. # filename Path to the file to extend. # data The data to extend the file with. # # Results: # None. proc fileutil_appendToFile {args} { # Syntax: ?options? file data # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec Writable $args opts fname data # Now perform the requested operation. file mkdir [file dirname $fname] set c [open $fname a] SetOptions $c $opts set at [tell $c] puts -nonewline $c $data close $c return $at } # ::fileutil_insertIntoFile -- # # Insert the specified data into the named file, # creating it if necessary, at the given locaton. # # Arguments: # options... Options and arguments. # filename Path to the file to extend. # data The data to extend the file with. # # Results: # None. proc fileutil_insertIntoFile {args} { # Syntax: ?options? file at data # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec ReadWritable $args opts fname at data set max [file size $fname] CheckLocation $at $max insertion if {[string length $data] == 0} { # Another degenerate case, inserting nothing. # Leave the file well enough alone. return } foreach {c o t} [Open2 $fname $opts] break # The degenerate cases of both appending and insertion at the # beginning of the file allow more optimized implementations of # the operation. if {$at == 0} { puts -nonewline $o $data fcopy $c $o } elseif {$at == $max} { fcopy $c $o puts -nonewline $o $data } else { fcopy $c $o -size $at puts -nonewline $o $data fcopy $c $o } Close2 $fname $t $c $o return } # ::fileutil_removeFromFile -- # # Remove n characters from the named file, # starting at the given locaton. # # Arguments: # options... Options and arguments. # filename Path to the file to extend. # at Location to start the removal from. # n Number of characters to remove. # # Results: # None. proc fileutil_removeFromFile {args} { # Syntax: ?options? file at n # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec ReadWritable $args opts fname at n set max [file size $fname] CheckLocation $at $max removal CheckLength $n $at $max removal if {$n == 0} { # Another degenerate case, removing nothing. # Leave the file well enough alone. return } foreach {c o t} [Open2 $fname $opts] break # The degenerate cases of both removal from the beginning or end # of the file allow more optimized implementations of the # operation. if {$at == 0} { seek $c $n current fcopy $c $o } elseif {($at + $n) == $max} { fcopy $c $o -size $at # Nothing further to copy. } else { fcopy $c $o -size $at seek $c $n current fcopy $c $o } Close2 $fname $t $c $o return } # ::fileutil_replaceInFile -- # # Remove n characters from the named file, # starting at the given locaton, and replace # it with the given data. # # Arguments: # options... Options and arguments. # filename Path to the file to extend. # at Location to start the removal from. # n Number of characters to remove. # data The replacement data. # # Results: # None. proc fileutil_replaceInFile {args} { # Syntax: ?options? file at n data # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec ReadWritable $args opts fname at n data set max [file size $fname] CheckLocation $at $max replacement CheckLength $n $at $max replacement if { ($n == 0) && ([string length $data] == 0) } { # Another degenerate case, replacing nothing with # nothing. Leave the file well enough alone. return } foreach {c o t} [Open2 $fname $opts] break # Check for degenerate cases and handle them separately, # i.e. strip the no-op parts out of the general implementation. if {$at == 0} { if {$n == 0} { # Insertion instead of replacement. puts -nonewline $o $data fcopy $c $o } elseif {[string length $data] == 0} { # Removal instead of replacement. seek $c $n current fcopy $c $o } else { # General replacement at front. seek $c $n current puts -nonewline $o $data fcopy $c $o } } elseif {($at + $n) == $max} { if {$n == 0} { # Appending instead of replacement fcopy $c $o puts -nonewline $o $data } elseif {[string length $data] == 0} { # Truncating instead of replacement fcopy $c $o -size $at # Nothing further to copy. } else { # General replacement at end fcopy $c $o -size $at puts -nonewline $o $data } } else { if {$n == 0} { # General insertion. fcopy $c $o -size $at puts -nonewline $o $data fcopy $c $o } elseif {[string length $data] == 0} { # General removal. fcopy $c $o -size $at seek $c $n current fcopy $c $o } else { # General replacement. fcopy $c $o -size $at seek $c $n current puts -nonewline $o $data fcopy $c $o } } Close2 $fname $t $c $o return } # ::fileutil_updateInPlace -- # # Run command prefix on the contents of the # file and replace them with the result of # the command. # # Arguments: # options... Options and arguments. # filename Path to the file to extend. # cmd Command prefix to run. # # Results: # None. proc fileutil_updateInPlace {args} { # Syntax: ?options? file cmd # options = -encoding ENC # | -translation TRA # | -eofchar ECH # | -- Spec ReadWritable $args opts fname cmd # readFile/cat inlined ... set c [open $fname r] SetOptions $c $opts set data [read $c] close $c # Transformation. Abort and do not modify the target file if an # error was raised during this step. lappend cmd $data set code [catch {uplevel 1 $cmd} res] if {$code} { return -code $code $res } # writeFile inlined, with careful preservation of old contents # until we are sure that the write was ok. if {[catch { file rename -force $fname ${fname}.bak set o [open $fname w] SetOptions $o $opts puts -nonewline $o $res close $o file delete -force ${fname}.bak } msg]} { if {[file exists ${fname}.bak]} { catch { file rename -force ${fname}.bak $fname } return -code error $msg } } return } proc fileutil_Writable {fname mv} { upvar 1 $mv msg if {[file exists $fname]} { if {![file isfile $fname]} { set msg "Cannot use file \"$fname\", is not a file" return 0 } elseif {![file writable $fname]} { set msg "Cannot use file \"$fname\", write access is denied" return 0 } } return 1 } proc fileutil_ReadWritable {fname mv} { upvar 1 $mv msg if {![file exists $fname]} { set msg "Cannot use file \"$fname\", does not exist" return 0 } elseif {![file isfile $fname]} { set msg "Cannot use file \"$fname\", is not a file" return 0 } elseif {![file writable $fname]} { set msg "Cannot use file \"$fname\", write access is denied" return 0 } elseif {![file readable $fname]} { set msg "Cannot use file \"$fname\", read access is denied" return 0 } return 1 } proc fileutil_Spec {check alist ov fv args} { upvar 1 $ov opts $fv fname set n [llength $args] ; # Num more args incr n ; # Count path as well set opts {} set mode maybeopt set at 0 foreach a $alist { if {[string equal $mode optarg]} { lappend opts $a set mode maybeopt incr at continue } elseif {[string equal $mode maybeopt]} { if {[string match -* $a]} { switch -exact -- $a { -encoding - -translation - -eofchar { lappend opts $a set mode optarg incr at continue } -- { # Stop processing. incr at break } default { return -code error \ "Bad option \"$a\",\ expected one of\ -encoding, -eofchar,\ or -translation" } } } # Not an option, but a file. # Stop processing. break } } if {([llength $alist] - $at) != $n} { # Argument processing stopped with arguments missing, or too # many return -code error \ "wrong#args: should be\ [lindex [info level 1] 0] ?-eofchar|-translation|-encoding arg? file $args" } set fname [lindex $alist $at] incr at foreach \ var $args \ val [lrange $alist $at end] { upvar 1 $var A set A $val } # Check given path ... if {![eval [linsert $check end $a msg]]} { return -code error $msg } return } proc fileutil_Open2 {fname opts} { set c [open $fname r] set t [tempfile] set o [open $t w] SetOptions $c $opts SetOptions $o $opts return [list $c $o $t] } proc fileutil_Close2 {f temp in out} { close $in close $out file copy -force $f ${f}.bak file rename -force $temp $f file delete -force ${f}.bak return } proc fileutil_SetOptions {c opts} { if {![llength $opts]} return eval [linsert $opts 0 fconfigure $c] return } proc fileutil_CheckLocation {at max label} { if {![string is integer -strict $at]} { return -code error \ "Expected integer but got \"$at\"" } elseif {$at < 0} { return -code error \ "Bad $label point $at, before start of data" } elseif {$at > $max} { return -code error \ "Bad $label point $at, behind end of data" } } proc fileutil_CheckLength {n at max label} { if {![string is integer -strict $n]} { return -code error \ "Expected integer but got \"$n\"" } elseif {$n < 0} { return -code error \ "Bad $label size $n" } elseif {($at + $n) > $max} { return -code error \ "Bad $label size $n, going behind end of data" } } # ::fileutil_foreachLine -- # # Executes a script for every line in a file. # # Arguments: # var name of the variable to contain the lines # filename name of the file to read. # cmd The script to execute. # # Results: # None. proc fileutil_foreachLine {var filename cmd} { upvar 1 $var line set fp [open $filename r] # -future- Use try/eval from tcllib/control catch { set code 0 set result {} while {[gets $fp line] >= 0} { set code [catch {uplevel 1 $cmd} result] if {($code != 0) && ($code != 4)} {break} } } close $fp if {($code == 0) || ($code == 3) || ($code == 4)} { return $result } if {$code == 1} { global errorCode errorInfo return \ -code $code \ -errorcode $errorCode \ -errorinfo $errorInfo \ $result } return -code $code $result } # ::fileutil_fileType -- # # Do some simple heuristics to determine file type. # # # Arguments: # filename Name of the file to test. # # Results # type Type of the file. May be a list if multiple tests # are positive (eg, a file could be both a directory # and a link). In general, the list proceeds from most # general (eg, binary) to most specific (eg, gif), so # the full type for a GIF file would be # "binary graphic gif" # # At present, the following types can be detected: # # directory # empty # binary # text # script <interpreter> # executable [elf, dos, ne, pe] # binary graphic [gif, jpeg, png, tiff, bitmap, icns] # ps, eps, pdf # html # xml <doctype> # message pgp # compressed [bzip, gzip, zip, tar] # audio [mpeg, wave] # gravity_wave_data_frame # link # doctools, doctoc, and docidx documentation files. # proc fileutil_fileType {filename} { ;## existence test if { ! [ file exists $filename ] } { set err "file not found: '$filename'" return -code error $err } ;## directory test if { [ file isdirectory $filename ] } { set type directory if { ! [ catch {file readlink $filename} ] } { lappend type link } return $type } ;## empty file test if { ! [ file size $filename ] } { set type empty if { ! [ catch {file readlink $filename} ] } { lappend type link } return $type } set bin_rx {[\x00-\x08\x0b\x0e-\x1f]} if { [ catch { set fid [ open $filename r ] fconfigure $fid -translation binary fconfigure $fid -buffersize 1024 fconfigure $fid -buffering full set test [ read $fid 1024 ] ::close $fid } err ] } { catch { ::close $fid } return -code error "::fileutil_fileType: $err" } if { [ regexp $bin_rx $test ] } { set type binary set binary 1 } else { set type text set binary 0 } # SF Tcllib bug [795585]. Allowing whitespace between #! # and path of script interpreter set metakit 0 if { [ regexp {^\#\!\s*(\S+)} $test -> terp ] } { lappend type script $terp } elseif {([regexp "\\\[manpage_begin " $test] && !([regexp -- {--- !doctools ---} $test] || [regexp -- "!tcl\.tk//DSL doctools//EN//" $test])) || ([regexp -- {--- doctools ---} $test] || [regexp -- "tcl\.tk//DSL doctools//EN//" $test])} { lappend type doctools } elseif {([regexp "\\\[toc_begin " $test] && !([regexp -- {--- !doctoc ---} $test] || [regexp -- "!tcl\.tk//DSL doctoc//EN//" $test])) || ([regexp -- {--- doctoc ---} $test] || [regexp -- "tcl\.tk//DSL doctoc//EN//" $test])} { lappend type doctoc } elseif {([regexp "\\\[index_begin " $test] && !([regexp -- {--- !docidx ---} $test] || [regexp -- "!tcl\.tk//DSL docidx//EN//" $test])) || ([regexp -- {--- docidx ---} $test] || [regexp -- "tcl\.tk//DSL docidx//EN//" $test])} { lappend type docidx } elseif {[regexp -- "tcl\\.tk//DSL diagram//EN//" $test]} { lappend type tkdiagram } elseif { $binary && [ regexp {^[\x7F]ELF} $test ] } { lappend type executable elf } elseif { $binary && [string match "MZ*" $test] } { if { [scan [string index $test 24] %c] < 64 } { lappend type executable dos } else { binary scan [string range $test 60 61] s next set sig [string range $test $next [expr {$next + 1}]] if { $sig == "NE" || $sig == "PE" } { lappend type executable [string tolower $sig] } else { lappend type executable dos } } } elseif { $binary && [string match "BZh91AY\&SY*" $test] } { lappend type compressed bzip } elseif { $binary && [string match "\x1f\x8b*" $test] } { lappend type compressed gzip } elseif { $binary && [string range $test 257 262] == "ustar\x00" } { lappend type compressed tar } elseif { $binary && [string match "\x50\x4b\x03\x04*" $test] } { lappend type compressed zip } elseif { $binary && [string match "GIF*" $test] } { lappend type graphic gif } elseif { $binary && [string match "icns*" $test] } { lappend type graphic icns bigendian } elseif { $binary && [string match "snci*" $test] } { lappend type graphic icns smallendian } elseif { $binary && [string match "\x89PNG*" $test] } { lappend type graphic png } elseif { $binary && [string match "\xFF\xD8\xFF*" $test] } { binary scan $test x3H2x2a5 marker txt if { $marker == "e0" && $txt == "JFIF\x00" } { lappend type graphic jpeg jfif } elseif { $marker == "e1" && $txt == "Exif\x00" } { lappend type graphic jpeg exif } } elseif { $binary && [string match "MM\x00\**" $test] } { lappend type graphic tiff } elseif { $binary && [string match "BM*" $test] && [string range $test 6 9] == "\x00\x00\x00\x00" } { lappend type graphic bitmap } elseif { $binary && [string match "\%PDF\-*" $test] } { lappend type pdf } elseif { ! $binary && [string match -nocase "*\<html\>*" $test] } { lappend type html } elseif { [string match "\%\!PS\-*" $test] } { lappend type ps if { [string match "* EPSF\-*" $test] } { lappend type eps } } elseif { [string match -nocase "*\<\?xml*" $test] } { lappend type xml if { [ regexp -nocase {\<\!DOCTYPE\s+(\S+)} $test -> doctype ] } { lappend type $doctype } } elseif { [string match {*BEGIN PGP MESSAGE*} $test] } { lappend type message pgp } elseif { $binary && [string match {IGWD*} $test] } { lappend type gravity_wave_data_frame } elseif {[string match "JL\x1a\x00*" $test] && ([file size $filename] >= 27)} { lappend type metakit smallendian set metakit 1 } elseif {[string match "LJ\x1a\x00*" $test] && ([file size $filename] >= 27)} { lappend type metakit bigendian set metakit 1 } elseif { $binary && [string match "RIFF*" $test] && [string range $test 8 11] == "WAVE" } { lappend type audio wave } elseif { $binary && [string match "ID3*" $test] } { lappend type audio mpeg } elseif { $binary && [binary scan $test S tmp] && [expr {$tmp & 0xFFE0}] == 65504 } { lappend type audio mpeg } # Additional checks of file contents at the end of the file, # possibly pointing into the middle too (attached metakit, # attached zip). ## Metakit File format: http://www.equi4.com/metakit/metakit-ff.html ## Metakit database attached ? ## if {!$metakit && ([file size $filename] >= 27)} { # The offsets in the footer are in always bigendian format if { [ catch { set fid [ open $filename r ] fconfigure $fid -translation binary fconfigure $fid -buffersize 1024 fconfigure $fid -buffering full seek $fid -16 end set test [ read $fid 16 ] ::close $fid } err ] } { catch { ::close $fid } return -code error "::fileutil_fileType: $err" } binary scan $test IIII __ hdroffset __ __ set hdroffset [expr {[file size $filename] - 16 - $hdroffset}] # Further checks iff the offset is actually inside the file. if {($hdroffset >= 0) && ($hdroffset < [file size $filename])} { # Seek to the specified location and try to match a metakit header # at this location. if { [ catch { set fid [ open $filename r ] fconfigure $fid -translation binary fconfigure $fid -buffersize 1024 fconfigure $fid -buffering full seek $fid $hdroffset start set test [ read $fid 16 ] ::close $fid } err ] } { catch { ::close $fid } return -code error "::fileutil_fileType: $err" } if {[string match "JL\x1a\x00*" $test]} { lappend type attached metakit smallendian set metakit 1 } elseif {[string match "LJ\x1a\x00*" $test]} { lappend type attached metakit bigendian set metakit 1 } } } ## Zip File Format: http://zziplib.sourceforge.net/zzip-parse.html ## http://www.pkware.com/products/enterprise/white_papers/appnote.html ;## lastly, is it a link? if { ! [ catch {file readlink $filename} ] } { lappend type link } return $type } # ::fileutil_tempdir -- # # Return the correct directory to use for temporary files. # Python attempts this sequence, which seems logical: # # 1. The directory named by the `TMPDIR' environment variable. # # 2. The directory named by the `TEMP' environment variable. # # 3. The directory named by the `TMP' environment variable. # # 4. A platform-specific location: # * On Macintosh, the `Temporary Items' folder. # # * On Windows, the directories `C:\\TEMP', `C:\\TMP', # `\\TEMP', and `\\TMP', in that order. # # * On all other platforms, the directories `/tmp', # `/var/tmp', and `/usr/tmp', in that order. # # 5. As a last resort, the current working directory. # # The code here also does # # 0. The directory set by invoking tempdir with an argument. # If this is present it is used exclusively. # # Arguments: # None. # # Side Effects: # None. # # Results: # The directory for temporary files. proc fileutil_tempdir {args} { if {[llength $args] > 1} { return -code error {wrong#args: should be "::fileutil_tempdir ?path?"} } elseif {[llength $args] == 1} { global tempdir set tempdir [lindex $args 0] global tempdirSet set tempdirSet 1 return } return [fileutil_Normalize [TempDir]] } proc fileutil_tempdirReset {} { global tempdir set tempdir {} global tempdirSet set tempdirSet 0 return } proc fileutil_TempDir {} { global tcl_platform env tempdir tempdirSet set attempdirs [list] set problems {} if {$tempdirSet} { lappend attempdirs $tempdir lappend problems {User/Application specified tempdir} } else { foreach tmp {TMPDIR TEMP TMP} { if { [info exists env($tmp)] } { lappend attempdirs $env($tmp) } else { lappend problems "No environment variable $tmp" } } switch $tcl_platform(platform) { windows { lappend attempdirs "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP" } macintosh { lappend attempdirs $env(TRASH_FOLDER) ;# a better place? } default { lappend attempdirs \ [file join / tmp] \ [file join / var tmp] \ [file join / usr tmp] } } lappend attempdirs [pwd] } foreach tmp $attempdirs { if { [file isdirectory $tmp] && [file writable $tmp] } { return $tmp } elseif { ![file isdirectory $tmp] } { lappend problems "Not a directory: $tmp" } else { lappend problems "Not writable: $tmp" } } # Fail if nothing worked. return -code error "Unable to determine a proper directory for temporary files\n[join $problems \n]" } set tempdir {} set tempdirSet 0 # ::fileutil_tempfile -- # # generate a temporary file name suitable for writing to # the file name will be unique, writable and will be in the # appropriate system specific temp directory # Code taken from http://mini.net/tcl/772 attributed to # Igor Volobouev and anon. # # Arguments: # prefix - a prefix for the filename, p # Results: # returns a file name # proc fileutil_tempfile {{prefix {}}} { return [fileutil_Normalize [TempFile $prefix]] } proc fileutil_TempFile {prefix} { set tmpdir [tempdir] set chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" set nrand_chars 10 set maxtries 10 set access [list RDWR CREAT EXCL] set permission 0600 set channel "" set checked_dir_writable 0 for {set i 0} {$i < $maxtries} {incr i} { set newname $prefix for {set j 0} {$j < $nrand_chars} {incr j} { append newname [string index $chars \ [expr {int(rand()*62)}]] } set newname [file join $tmpdir $newname] if {[catch {open $newname $access $permission} channel]} { if {!$checked_dir_writable} { set dirname [file dirname $newname] if {![file writable $dirname]} { return -code error "Directory $dirname is not writable" } set checked_dir_writable 1 } } else { # Success close $channel return $newname } } if {[string compare $channel ""]} { return -code error "Failed to open a temporary file: $channel" } else { return -code error "Failed to find an unused temporary file name" } } # ::fileutil_install -- # # Tcl version of the 'install' command, which copies files from # one places to another and also optionally sets some attributes # such as group, owner, and permissions. # # Arguments: # -m Change the file permissions to the specified # value. Valid arguments are those accepted by # file attributes -permissions # # Results: # None. # TODO - add options for group/owner manipulation. proc fileutil_install {args} { set options { {m.arg "" "Set permission mode"} } set usage ": [lindex [info level 0] 0]\ \[options] source destination \noptions:" array set params [::cmdline::getoptions args $options $usage] # Args should now just be the source and destination. if { [llength $args] < 2 } { return -code error $usage } set src [lindex $args 0] set dst [lindex $args 1] file copy -force $src $dst if { $params(m) != "" } { set targets [::fileutil_find $dst] foreach fl $targets { file attributes $fl -permissions $params(m) } } } # ### ### ### ######### ######### ######### proc fileutil_lexnormalize {sp} { set spx [file split $sp] # Resolution of embedded relative modifiers (., and ..). if { ([lsearch -exact $spx . ] < 0) && ([lsearch -exact $spx ..] < 0) } { # Quick path out if there are no relative modifiers return $sp } set absolute [expr {![string equal [file pathtype $sp] relative]}] # A volumerelative path counts as absolute for our purposes. set sp $spx set np {} set noskip 1 while {[llength $sp]} { set ele [lindex $sp 0] set sp [lrange $sp 1 end] set islast [expr {[llength $sp] == 0}] if {[string equal $ele ".."]} { if { ($absolute && ([llength $np] > 1)) || (!$absolute && ([llength $np] >= 1)) } { # .. : Remove the previous element added to the # new path, if there actually is enough to remove. set np [lrange $np 0 end-1] } } elseif {[string equal $ele "."]} { # Ignore .'s, they stay at the current location continue } else { # A regular element. lappend np $ele } } if {[llength $np] > 0} { return [eval [linsert $np 0 file join]] # 8.5: return [file join {*}$np] } return {} } # ### ### ### ######### ######### ######### ## Forward compatibility. Some routines require path normalization, ## something we have supported by the builtin 'file' only since Tcl ## 8.4. For versions of Tcl before that, to be supported by the ## module, we implement a normalizer in Tcl itself. Slow, but working. if {[package vcompare [package provide Tcl] 8.4] < 0} { # Pre 8.4. We do not have 'file-normalize'. We create an # approximation for it based on earlier commands. # ... Hm. This is lexical normalization. It does not resolve # symlinks in the path to their origin. proc fileutil_Normalize {sp} { set sp [file split $sp] # Conversion of the incoming path to absolute. if {[string equal [file pathtype [lindex $sp 0]] "relative"]} { set sp [file split [eval [list file join [pwd]] $sp]] } # Resolution of symlink components, and embedded relative # modifiers (., and ..). set np {} set noskip 1 while {[llength $sp]} { set ele [lindex $sp 0] set sp [lrange $sp 1 end] set islast [expr {[llength $sp] == 0}] if {[string equal $ele ".."]} { if {[llength $np] > 1} { # .. : Remove the previous element added to the # new path, if there actually is enough to remove. set np [lrange $np 0 end-1] } } elseif {[string equal $ele "."]} { # Ignore .'s, they stay at the current location continue } else { # A regular element. If it is not the last component # then check if the combination is a symlink, and if # yes, resolve it. lappend np $ele if {!$islast && $noskip} { # The flag 'noskip' is technically not required, # just 'file exists'. However if a path P does not # exist, then all longer paths starting with P can # not exist either, and using the flag to store # this knowledge then saves us a number of # unnecessary stat calls. IOW this a performance # optimization. set p [eval file join $np] set noskip [file exists $p] if {$noskip} { if {[string equal link [file type $p]]} { set dst [file readlink $p] # We always push the destination in front of # the source path (in expanded form). So that # we handle .., .'s, and symlinks inside of # this path as well. An absolute path clears # the result, a relative one just removes the # last, now resolved component. set sp [eval [linsert [file split $dst] 0 linsert $sp 0]] if {![string equal relative [file pathtype $dst]]} { # Absolute|volrelative destination, clear # result, we have to start over. set np {} } else { # Relative link, just remove the resolved # component again. set np [lrange $np 0 end-1] } } } } } } if {[llength $np] > 0} { return [eval file join $np] } return {} } } else { proc fileutil_Normalize {sp} { file-normalize $sp } } # ::fileutil_relative -- # # Taking two _directory_ paths, a base and a destination, computes the path # of the destination relative to the base. # # Arguments: # base The path to make the destination relative to. # dst The destination path # # Results: # The path of the destination, relative to the base. proc fileutil_relative {base dst} { # Ensure that the link to directory 'dst' is properly done relative to # the directory 'base'. if {![string equal [file pathtype $base] [file pathtype $dst]]} { return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" } set base [fileutil_lexnormalize [file join [pwd] $base]] set dst [fileutil_lexnormalize [file join [pwd] $dst]] set save $dst set base [file split $base] set dst [file split $dst] while {[string equal [lindex $dst 0] [lindex $base 0]]} { set dst [lrange $dst 1 end] set base [lrange $base 1 end] if {![llength $dst]} {break} } set dstlen [llength $dst] set baselen [llength $base] if {($dstlen == 0) && ($baselen == 0)} { # Cases: # (a) base == dst set dst . } else { # Cases: # (b) base is: base/sub = sub # dst is: base = {} # (c) base is: base = {} # dst is: base/sub = sub while {$baselen > 0} { set dst [linsert $dst 0 ..] incr baselen -1 } # 8.5: set dst [file join {*}$dst] set dst [eval [linsert $dst 0 file join]] } return $dst } # ::fileutil_relativeUrl -- # # Taking two _file_ paths, a base and a destination, computes the path # of the destination relative to the base, from the inside of the base. # # This is how a browser resolves relative links in a file, hence the # url in the command name. # # Arguments: # base The file path to make the destination relative to. # dst The destination file path # # Results: # The path of the destination file, relative to the base file. proc fileutil_relativeUrl {base dst} { # Like 'relative', but for links from _inside_ a file to a # different file. if {![string equal [file pathtype $base] [file pathtype $dst]]} { return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" } set base [fileutil_lexnormalize [file join [pwd] $base]] set dst [fileutil_lexnormalize [file join [pwd] $dst]] set basedir [file dirname $base] set dstdir [file dirname $dst] set dstdir [relative $basedir $dstdir] # dstdir == '.' on input => dstdir output has trailing './'. Strip # this superfluous segment off. if {[string equal $dstdir "."]} { return [file tail $dst] } elseif {[string equal [file tail $dstdir] "."]} { return [file join [file dirname $dstdir] [file tail $dst]] } else { return [file join $dstdir [file tail $dst]] } } # ::fileutil_fullnormalize -- # # Normalizes a path completely. I.e. a symlink in the last # element is resolved as well, not only symlinks in the higher # elements. # # Arguments: # path The path to normalize # # Results: # The input path with all symlinks resolved. proc fileutil_fullnormalize {path} { # When encountering symlinks in a file copy operation Tcl copies # the link, not the contents of the file it references. There are # situations there this is not acceptable. For these this command # resolves all symbolic links in the path, including in the last # element of the path. A "file copy" using the return value of # this command copies an actual file, it will not encounter # symlinks. # BUG / WORKAROUND. Using the / instead of the join seems to work # around a bug in the path handling on windows which can break the # core 'file-normalize' for symbolic links. This was exposed by # the find testsuite which could not reproduced outside. I believe # that there is some deep path bug in the core triggered under # special circumstances. Use of / likely forces a refresh through # the string rep and so avoids the problem with the path intrep. return [file dirname [fileutil_Normalize $path/__dummy__]] #return [file dirname [fileutil_Normalize [file join $path __dummy__]]] } set tclver [package present Tcl] if {$tclver ne {} && [package vsatisfies [package present Tcl] 8.5]} { # Tcl 8.5+. # We have to check readability of "current" on our own, glob # changed to error out instead of returning nothing. proc fileutil_ACCESS {args} {} proc fileutil_GLOBF {current} { if {![file readable $current]} { return {} } if {([file type $current] eq "link") && !([file exists [file readlink $current]] && [file readable [file readlink $current]])} { return {} } set res [lsort -unique [concat \ [glob -nocomplain -directory $current -types f -- *] \ [glob -nocomplain -directory $current -types {hidden f} -- *]]] # Look for broken links (They are reported as neither file nor directory). foreach l [lsort -unique [concat \ [glob -nocomplain -directory $current -types l -- *] \ [glob -nocomplain -directory $current -types {hidden l} -- *]]] { if {[file isfile $l]} continue if {[file isdirectory $l]} continue lappend res $l } return [lsort -unique $res] } proc fileutil_GLOBD {current} { if {![file readable $current]} { return {} } if {([file type $current] eq "link") && !([file exists [file readlink $current]] && [file readable [file readlink $current]])} { return {} } lsort -unique [concat \ [glob -nocomplain -directory $current -types d -- *] \ [glob -nocomplain -directory $current -types {hidden d} -- *]] } } |
Added autosetup/find-tclsh.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/bin/sh # Looks for a suitable tclsh or jimsh in the PATH # If not found, builds a bootstrap jimsh from source d=`dirname "$0"` { "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0 PATH="$PATH:$d/../../../bin:$d"; export PATH for tclsh in tclsh8.6 tclsh86.exe tclsh8.5 tclsh85.exe tclsh tclsh.exe jimsh ; do { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue "$d/jimsh0" "$d/test-tclsh" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." echo false |
Added autosetup/install.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # @synopsis: # # Helper script for Makefiles # proc use args { foreach pkg $args { if {[file exists $::here/${pkg}.tcl]} { source $::here/${pkg}.tcl } elseif {[file exists $::here/../lib/${pkg}.tcl]} { source $::here/../lib/${pkg}.tcl } else { error "Could not find package $args" } } } set ::here [file dirname [file normalize [info script]]] use fileutil proc file-normalize args { return [file normalize {*}$args] } proc _istcl name { return [string match *.tcl $name] } ### # topic: ea4ac0a84ae990dafee965b995f48e63 ### proc _istm name { return [string match *.tm $name] } proc _isdirectory name { return [file isdirectory $name] } foreach {src dest} $argv { set src [file normalize $src] set dest [file normalize $dest] file mkdir $dest foreach {file} [fileutil_find $src _istcl] { set relname [fileutil_relative $src $file] set destfile [file join $dest $relname] file mkdir [file dirname $destfile] file copy -force $file [file join $dest $relname] } } |
Added autosetup/system.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # # This module supports common system interrogation and options # such as --host, --build, --prefix, and setting srcdir, builddir, and EXEXT. # # It also support the 'feature' naming convention, where searching # for a feature such as sys/type.h defines HAVE_SYS_TYPES_H # module-options { host:host-alias => {a complete or partial cpu-vendor-opsys for the system where the application will run (defaults to the same value as --build)} build:build-alias => {a complete or partial cpu-vendor-opsys for the system where the application will be built (defaults to the result of running config.guess)} prefix:dir => {the target directory for the build (defaults to /usr/local)} # These (hidden) options are supported for autoconf/automake compatibility exec-prefix: bindir: sbindir: includedir: mandir: infodir: libexecdir: datadir: libdir: sysconfdir: sharedstatedir: localstatedir: maintainer-mode=0 dependency-tracking=0 } # Returns 1 if exists, or 0 if not # proc check-feature {name code} { msg-checking "Checking for $name..." set r [uplevel 1 $code] define-feature $name $r if {$r} { msg-result "ok" } else { msg-result "not found" } return $r } # @have-feature name ?default=0? # # Returns the value of the feature if defined, or $default if not. # See 'feature-define-name' for how the feature name # is translated into the define name. # proc have-feature {name {default 0}} { get-define [feature-define-name $name] $default } # @define-feature name ?value=1? # # Sets the feature 'define' to the given value. # See 'feature-define-name' for how the feature name # is translated into the define name. # proc define-feature {name {value 1}} { define [feature-define-name $name] $value } # @feature-checked name # # Returns 1 if the feature has been checked, whether true or not # proc feature-checked {name} { is-defined [feature-define-name $name] } # @feature-define-name name ?prefix=HAVE_? # # Converts a name to the corresponding define, # e.g. sys/stat.h becomes HAVE_SYS_STAT_H. # # Converts * to P and all non-alphanumeric to underscore. # proc feature-define-name {name {prefix HAVE_}} { string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] } # If $file doesn't exist, or it's contents are different than $buf, # the file is written and $script is executed. # Otherwise a "file is unchanged" message is displayed. proc write-if-changed {file buf {script {}}} { set old [readfile $file ""] if {$old eq $buf && [file exists $file]} { msg-result "$file is unchanged" } else { writefile $file $buf\n uplevel 1 $script } } # @make-template template ?outfile? # # Reads the input file <srcdir>/$template and writes the output file $outfile. # If $outfile is blank/omitted, $template should end with ".in" which # is removed to create the output file name. # # Each pattern of the form @define@ is replaced the the corresponding # define, if it exists, or left unchanged if not. # # The special value @srcdir@ is substituted with the relative # path to the source directory from the directory where the output # file is created, while the special value @top_srcdir@ is substituted # with the relative path to the top level source directory. # # Conditional sections may be specified as follows: ## @if name == value ## lines ## @else ## lines ## @endif # # Where 'name' is a defined variable name and @else is optional. # If the expression does not match, all lines through '@endif' are ignored. # # The alternative forms may also be used: ## @if name ## @if name != value # # Where the first form is true if the variable is defined, but not empty or 0 # # Currently these expressions can't be nested. # proc make-template {template {out {}}} { set infile [file join $::autosetup(srcdir) $template] if {![file exists $infile]} { user-error "Template $template is missing" } # Define this as late as possible define AUTODEPS $::autosetup(deps) if {$out eq ""} { if {[file ext $template] ne ".in"} { autosetup-error "make_template $template has no target file and can't guess" } set out [file rootname $template] } set outdir [file dirname $out] # Make sure the directory exists file mkdir $outdir # Set up srcdir and top_srcdir to be relative to the target dir define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] define top_srcdir [relative-path $::autosetup(srcdir) $outdir] set mapping {} foreach {n v} [array get ::define] { lappend mapping @$n@ $v } set result {} foreach line [split [readfile $infile] \n] { if {[info exists cond]} { set l [string trimright $line] if {$l eq "@endif"} { unset cond continue } if {$l eq "@else"} { set cond [expr {!$cond}] continue } if {$cond} { lappend result $line } continue } if {[regexp {^@if\s+(\w+)(.*)} $line -> name expression]} { lassign $expression equal value set varval [get-define $name ""] if {$equal eq ""} { set cond [expr {$varval ni {"" 0}}] } else { set cond [expr {$varval eq $value}] if {$equal ne "=="} { set cond [expr {!$cond}] } } continue } lappend result $line } writefile $out [string map $mapping [join $result \n]]\n msg-result "Created [relative-path $out] from [relative-path $template]" } # build/host tuples and cross-compilation prefix set build [opt-val build] define build_alias $build if {$build eq ""} { define build [config_guess] } else { define build [config_sub $build] } set host [opt-val host] define host_alias $host if {$host eq ""} { define host [get-define build] set cross "" } else { define host [config_sub $host] set cross $host- } define cross [get-env CROSS $cross] # Do "define defaultprefix myvalue" to set the default prefix *before* the first "use" set prefix [opt-val prefix [get-define defaultprefix /usr/local]] # These are for compatibility with autoconf define target [get-define host] define prefix $prefix define builddir $autosetup(builddir) define srcdir $autosetup(srcdir) # Allow this to come from the environment define top_srcdir [get-env top_srcdir [get-define srcdir]] # autoconf supports all of these set exec_prefix [opt-val exec-prefix $prefix] define exec_prefix $exec_prefix foreach {name defpath} { bindir /bin sbindir /sbin libexecdir /libexec libdir /lib } { define $name [opt-val $name $exec_prefix$defpath] } foreach {name defpath} { datadir /share sysconfdir /etc sharedstatedir /com localstatedir /var infodir /share/info mandir /share/man includedir /include } { define $name [opt-val $name $prefix$defpath] } define SHELL [get-env SHELL [find-an-executable sh bash ksh]] # Windows vs. non-Windows switch -glob -- [get-define host] { *-*-ming* - *-*-cygwin - *-*-msys { define-feature windows define EXEEXT .exe } default { define EXEEXT "" } } # Display msg-result "Host System...[get-define host]" msg-result "Build System...[get-define build]" |
Added autosetup/test-tclsh.
> > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # A small Tcl script to verify that the chosen # interpreter works. Sometimes we might e.g. pick up # an interpreter for a different arch. # Outputs the full path to the interpreter if {[catch {info version} version] == 0} { # This is Jim Tcl if {$version >= 0.72} { # Ensure that regexp works regexp (a.*?) a puts [info nameofexecutable] exit 0 } } elseif {[catch {info tclversion} version] == 0} { if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { puts [info nameofexecutable] exit 0 } } exit 1 |
Changes to bin/README.
1 2 3 4 5 6 7 8 9 10 | httpd.tcl Sample startup script. To run a server on port 8015, just do: wish httpd.tcl -debug 1 This should work with any Tcl 8.0 or later wish or tclsh. To run on a different port and in the background, try: tclsh httpd.tcl -port 80 & To try out threads, run with a thread-enabled tclsh and do: tclsh httpd.tcl -threads 5 where this means use up to 5 worker threads. httpd.tcl depends on both tclhttpd.rc and httpdthread.tcl, | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | httpd.tcl Sample startup script. To run a server on port 8015, just do: wish httpd.tcl -debug 1 This should work with any Tcl 8.0 or later wish or tclsh. To run on a different port and in the background, try: tclsh httpd.tcl -port 80 & To try out threads, run with a thread-enabled tclsh and do: tclsh httpd.tcl -threads 5 where this means use up to 5 worker threads. httpd.tcl depends on both tclhttpd.rc and httpdthread.tcl, as well as the packages in ../modules/tclhttpd tclhttpd.rc Configuration file with default port, etc. httpdthread.tcl Per-thread initialization. tclhttpd.etc.init This is a Solaris startup script: /etc/init.d/tclhttpd |
︙ | ︙ |
Changes to bin/httpd.tcl.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # tclhttpd.rc This has configuration settings like port and host. # It is sourced one time by the server during start up # before command line arguments are processed. # httpdthread.tcl This has the bulk of the initialization code. It is # split out into its own file because it is loaded by # by each thread: the main thread and any worker threads # created by the "-threads N" command line argument. | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # tclhttpd.rc This has configuration settings like port and host. # It is sourced one time by the server during start up # before command line arguments are processed. # httpdthread.tcl This has the bulk of the initialization code. It is # split out into its own file because it is loaded by # by each thread: the main thread and any worker threads # created by the "-threads N" command line argument. # ../modules/tclhttpd The script library that contains most of the TclHttpd # implementation # ../tcllib The Standard Tcl Library. TclHttpd ships with a copy # of this library because it depends on it. If you already # have copy installed TclHttpd will attempt to find it. # # TclHttpd now requires Tcl 8.0 or higher because it depends on some # modules in the Standard Tcl Library (tcllib) that use namespaces. |
︙ | ︙ | |||
59 60 61 62 63 64 65 | set home [file join [pwd] $home] # Auto-detect the configuration # 1. Development - look for $home/../lib and $home/../../tcllib/modules # 2. Standalone install - look for $home/../lib/tclhttpd $home/tcllib # 3. Tcl package install - look for $tcl_library/../tclhttpd | | | | < | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | set home [file join [pwd] $home] # Auto-detect the configuration # 1. Development - look for $home/../lib and $home/../../tcllib/modules # 2. Standalone install - look for $home/../lib/tclhttpd $home/tcllib # 3. Tcl package install - look for $tcl_library/../tclhttpd set v 4.0.0 if {[file exist [file join $home ../modules/httpd/httpd.tcl]]} { # Cases 1 and 2 set Config(lib) [file join $home ../modules] } elseif {[file exist [file join $home ../lib/tclhttpd$v]]} { # Standard package install (e.g., TclPro) # By going one level up, we make all Tcl packages available. set Config(lib) [file join $home ../lib] } else { # Hmm - see if Tcl can find it for us. tcl_findLibrary tclhttpd $v $v version.tcl TCL_HTTPD_LIBRARY Config(lib) } if {![info exist Config(lib)]} { error "Cannot find TclHttpd library in auto_path:\n[join $auto_path \n]" } # Put the library in front in case there is both the development # library and an installed library set auto_path [concat [list $Config(lib)] $auto_path] # Search around for the Standard Tcl Library # We used to require "tcllib", but that now causes complaints # Tcllib 1.6 has inconsistencies with md5 1.4.3 and 2.0.0, # and requiring 1.0 cures later conflicts with 2.0 if {![catch {package require md5 2}]} { # Already available in environment } elseif {[file exist [file join $home ../tcllib]]} { lappend auto_path [file join $home ../tcllib] } else { # Look for the CVS development sources set cvs [lindex [lsort -decreasing \ [glob -nocomplain [file join $home ../../tcllib*]]] 0] |
︙ | ︙ | |||
206 207 208 209 210 211 212 | if {[catch {package require httpd::stdin}]} { puts "No command loop available" set Config(debug) 0 } } if {$Config(compat)} { | > | > > > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | if {[catch {package require httpd::stdin}]} { puts "No command loop available" set Config(debug) 0 } } if {$Config(compat)} { if {[catch { package require httpd::compat httpd::compat_level $Config(compat) }]} { puts stderr "tclhttpd$Config(compat) compatibility mode failed." } else { # Messages here just confuse people } } ################### |
︙ | ︙ |
Changes to bin/httpdthread.tcl.
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 | } # Core modules package require httpd ;# Protocol stack package require httpd::version ;# Version number package require httpd::url ;# URL dispatching package require httpd::mtype ;# Mime types # Search for mime.types either right in Config(lib), or down # one level in the installed tclhttpd subdirectory | > < > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | } # Core modules package require httpd ;# Protocol stack package require httpd::version ;# Version number package require httpd::url ;# URL dispatching package require httpd::mtype ;# Mime types package require httpd::bootstrap ;# Mime types # Search for mime.types either right in Config(lib), or down # one level in the installed tclhttpd subdirectory foreach path [list \ [file join $Config(lib) mime.types] \ [file join $Config(lib) httpd mime.types] \ [glob -nocomplain [file join $Config(lib) tclhttpd* mime.types]] \ ] { if {[llength $path] > 0} { set path [lindex $path 0] } if {[file exists $path]} { Mtype_ReadTypes $path break } } package require httpd::counter ;# Statistics Counter_Init $Config(secs) package require httpd::utils ;# handy stuff like "lassign" package require httpd::redirect ;# URL redirection package require httpd::auth ;# Basic authentication package require httpd::log ;# Standard logging |
︙ | ︙ | |||
72 73 74 75 76 77 78 79 80 81 82 83 84 85 | } # These packages are required for "normal" web servers # doc # provides access to files on the local file systems. package require httpd::doc # Doc_Root defines the top-level directory, or folder, for # your web-visible file structure. Doc_Root $Config(docRoot) # Merge in a second file system into the URL tree. | > > > > > > > > > > > > > > > > > > > > > > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | } # These packages are required for "normal" web servers # doc # provides access to files on the local file systems. package require httpd::doc package require httpd::qwiki set mainconfig {} dict set mainconfig filename $Config(MainDatabaseFile) foreach {f v} [array get Config] { dict set mainconfig $f $v } tao::class mainclass { superclass httpd.qwiki option docRoot {} ### # The main page reads from the docroot ### method /html resultObj { ### # By default, act as a conduit to DocRoot ### ::DocDomain [my cget virtual] [my cget docRoot] [$resultObj sock] [$resultObj cget suffix] } } mainclass create MAIN / $mainconfig # Doc_Root defines the top-level directory, or folder, for # your web-visible file structure. Doc_Root $Config(docRoot) # Merge in a second file system into the URL tree. |
︙ | ︙ | |||
168 169 170 171 172 173 174 | if {[catch { Auth_InitCrypt ;# Probe for crypt module } err]} { catch {puts "No .htaccess support: $err"} } | < < < < | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | if {[catch { Auth_InitCrypt ;# Probe for crypt module } err]} { catch {puts "No .htaccess support: $err"} } ####################################### # Load Custom Code ####################################### if {[info exist Config(library)] && [string length $Config(library)]} { if {![file isdirectory $Config(library)]} { |
︙ | ︙ |
Changes to bin/tclhttpd.rc.
︙ | ︙ | |||
221 222 223 224 225 226 227 | # Default group file - used if .htaccess doesn't specify AuthGroupFile # this defaults to the authentication array authdefault() #Config AuthGroupFile {} # Default mail servers - the smtp servers to use when sending mail Config MailServer {} | > > > | 221 222 223 224 225 226 227 228 229 230 | # Default group file - used if .htaccess doesn't specify AuthGroupFile # this defaults to the authentication array authdefault() #Config AuthGroupFile {} # Default mail servers - the smtp servers to use when sending mail Config MailServer {} # Default master index file location Config MainDatabaseFile [file join [Config home] httpd.sqlite] |
Added bin/test/common.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | # # Tcl HTTPD # # This is the main script for an HTTP server. # To test out of the box, do # tclsh httpd.tcl -debug 1 # or # wish httpd.tcl -debug 1 # # For a quick spin, just pass the appropriate settings via the command line. # For fully custom operation, see the notes in README_custom. # # A note about the code structure: # ../lib The script library that contains most of the TclHttpd # implementation # ../tcllib The Standard Tcl Library. TclHttpd ships with a copy # of this library because it depends on it. If you already # have copy installed TclHttpd will attempt to find it. # # TclHttpd now requires Tcl 8.0 or higher because it depends on some # modules in the Standard Tcl Library (tcllib) that use namespaces. # In practice, some of the modules in tcllib may depend on # new string commands introduced in Tcl 8.2 and 8.3. However, # the server core only depends on the base64 and ncgi packages # that may/should be/are compatible with Tcl 8.0 # # Copyright (c) 1997 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Scriptics Corporation # Copyright (c) 2001-2002 Panasas # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: httpd.tcl,v 1.61 2006/04/27 00:24:51 wart Exp $ # # Auto-detect the configuration # 1. Development - look for $home/../lib and $home/../../tcllib/modules # 2. Standalone install - look for $home/../lib/tclhttpd $home/tcllib # 3. Tcl package install - look for $tcl_library/../tclhttpd set v 4.0.0 # Put the library in front in case there is both the development # library and an installed library set auto_path [concat [list $Config(lib)] $auto_path] # Search around for the Standard Tcl Library # We used to require "tcllib", but that now causes complaints # Tcllib 1.6 has inconsistencies with md5 1.4.3 and 2.0.0, # and requiring 1.0 cures later conflicts with 2.0 if {![catch {package require md5 2}]} { # Already available in environment } elseif {[file exist [file join $home ../tcllib]]} { lappend auto_path [file join $home ../tcllib] } else { # Look for the CVS development sources set cvs [lindex [lsort -decreasing \ [glob -nocomplain [file join $home ../../tcllib*]]] 0] if {[file exist [file join $cvs modules]]} { lappend auto_path [file join $cvs modules] } elseif {[file exist [file join $cvs pkgIndex.tcl]]} { lappend auto_path $cvs } else { error "Cannot find Standard Tcl Library in auto_path:\n[join $auto_path \n]" } } set Config(home) $home unset home # Add operating-specific directories to the auto_path for # the binary extensions regsub -all { } $tcl_platform(os) {} tmp foreach dir [list \ [file join $Config(lib) Binaries $tmp] \ [file join $Config(lib) Binaries $tmp $tcl_platform(osVersion)] \ ] { if {[file isdirectory $dir]} { lappend auto_path $dir } } unset tmp dir proc ::Config {field args} { switch {[llength $args]>1} { error "Usage: Config field ?value?" } global Config if {[llength $args]} { set Config($field) [lindex $args 0] } if {[info exists Config($field)]} { return $Config($field) } } ############## # Config file ############## # Load the configuration file into the Config array # First, we preload a couple of defaults set Config(docRoot) [file join [file dirname [Config home]] htdocs] set Config(library) [file join [file dirname [Config home]] custom] set Config(main) [file join [Config home] httpdthread.tcl] set Config(debug) 0 set Config(compat) 3.3 # The configuration bootstrap goes like this: # 1) Look on the command line for a -config rcfile name argument # 2) Load this configuration file via the config module # 3) Process the rest of the command line arguments so the user # can override the settings in the rc file with them. set ix [lsearch $argv -config] if {$ix >= 0} { incr ix set Config(config) [lindex $argv $ix] } else { set Config(config) [file join [Config home] tclhttpd.rc] } package require httpd 1.6 package require httpd::version ;# For Version proc package require httpd::utils ;# For Stderr package require httpd::counter ;# For Count package require fileutil ;# For tempdir support: needed on Windows package require httpd::config ;# for config::init proc ::cget {field} { global Config if {[info exists Config($field)]} { return $Config($field) } } proc ::DebugCheckRandomPassword input { return 1 } array set Config { debug 1 port 8015 https_port 8016 uid 50 gid 50 ipaddr {} https_ipaddr {} secsPerMinute 60 threads 0 gui 1 LogFlushMinutes 0 LogDebug 0 CompressProg gzip MaxFileDescriptors 256 SSL_REQUEST 0 SSL_REQUIRE 0 SSL_CAFILE "" } Config docroot [file join [Config home] .. htdocs] Config library [file join [Config home] .. custom] Config main [file join [Config home] httpdthread.tcl] Config host [info hostname] Config https_host [info hostname] Config webmaster webmaster@[info hostname] Config LogFile [file join [::fileutil::tempdir] log] Config SSL_CADIR [file join [file dirname [Config home]] certs]) Config SSL_CERTFILE [file join [Config SSL_CADIR] server.pem] Config MailServer {} # The Config array now reflects the info in the configuration file ######################### # command line arguments ######################### # Override config file settings with command line arguments. # The CommandLineOptions global is known to some of the # web pages that document the server. package require cmdline set CommandLineOptions [list \ [list virtual.arg [cget virtual] {Virtual host config list}] \ [list config.arg [cget config] {Configuration File}] \ [list main.arg [cget main] {Per-Thread Tcl script}] \ [list docRoot.arg [cget docRoot] {Root directory for documents}] \ [list port.arg [cget port] {Port number server is to listen on}] \ [list host.arg [cget host] {Server name, should be fully qualified}] \ [list ipaddr.arg [cget ipaddr] {Interface server should bind to}] \ [list https_port.arg [cget https_port] {SSL Port number}] \ [list https_host.arg [cget https_host] {SSL Server name, should be fully qualified}] \ [list https_ipaddr.arg [cget https_ipaddr] {Interface SSL server should bind to}] \ [list webmaster.arg [cget webmaster] {E-mail address for errors}] \ [list uid.arg [cget uid] {User Id that server runs under}] \ [list gid.arg [cget gid] {Group Id for caching templates}] \ [list secs.arg [cget secsPerMinute] {Seconds per "minute" for time-based histograms}] \ [list threads.arg [cget threads] {Number of worker threads (zero for non-threaded)}] \ [list library.arg [cget library] {Directory list where custom packages and auto loads are}] \ [list debug.arg 0 {If true, start interactive command loop}] \ [list compat.arg 3.3 {version compatibility to maintain}] \ [list gui.arg [cget gui] {flag for launching the user interface}] \ [list mail.arg [cget MailServer] {Mail Servers for sending email from tclhttpd}] \ [list daemon.arg 0 {Run in the background as a daemon process. Requires the 'Expect' package.}] \ ] array set Config [cmdline::getoptions argv $CommandLineOptions \ "usage: httpd.tcl options:"] if {[string length $Config(library)]} { lappend auto_path $Config(library) } if {$Config(debug)} { puts stderr "auto_path:\n[join $auto_path \n]" if {[catch {package require httpd::stdin}]} { puts "No command loop available" set Config(debug) 0 } } if {$Config(compat)} { if {[catch { package require httpd::compat httpd::compat_level $Config(compat) } err]} { puts stderr "tclhttpd$Config(compat) compatibility mode failed: $err \n $::errorInfo" } else { # Messages here just confuse people } } ################### # Start the server ################### Httpd_Init #Counter_Init $Config(secs) # Open the listening sockets Httpd_Server $Config(port) $Config(host) $Config(ipaddr) append startup "httpd started on port $Config(port)\n" if {[catch {source $Config(main)} message]} then { global errorInfo set error "Error processing main startup script \"[file nativename $Config(main)]\"." append error "\n$errorInfo" error $error } # The main thread owns the log Log_CompressProg [cget CompressProg] Log_SetFile [cget LogFile]$Config(port)_ Log_FlushMinutes [cget LogFlushMinutes] Log_Flush |
Added bin/test/directoo.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #!/bin/sh # \ exec tclsh "$0" ${1+"$@"} ############ # auto_path ############ # Configure the auto_path so we can find the script library. # home is the directory containing this script set home [string trimright [file dirname [info script]] ./] set home [file normalize [file join [pwd] $home ..]] set Config(lib) [file join $home .. modules] source $home/test/common.tcl ### # Test for DirectOO ### package require httpd::directoo oo::class create ootest { superclass httpd.url ### # title: Implement html content at a toplevel ### method /html resultObj { $resultObj configure title {Welcome!} $resultObj puts [my pageHeader] $resultObj puts { Hello World! <p> Try the following links: <ul> } set prefix [$resultObj cget url_prefix] foreach {url comment} { errorurl {Throw an internal error from Tcl} deadurl {Page that generates a 505 error} suburl {Valid Suburl} missing {Non-existent url} } { $resultObj puts "<li><a href=$prefix/$url>$url</a> - $comment</li>" } $resultObj puts {</ul>} $resultObj puts [my pageFooter] } method /html/errorurl resultObj { error "Die Yuppie Scum!" } method /html/deadurl resultObj { $resultObj configure title {Page Error!} $resultObj configure code 501 $resultObj puts [my pageHeader] $resultObj puts { I threw an error this way } $resultObj puts [my pageFooter] } ### # title: Implement html content at a toplevel ### method /html/suburl resultObj { $resultObj configure title {Sub Url!} $resultObj puts [my pageHeader] $resultObj puts {Sub Url} $resultObj puts "<p><a href=\"[my cget virtual]\">Back</a>" $resultObj puts [my pageFooter] } ### # title: Implement html content at a toplevel ### method /html/default resultObj { $resultObj configure title {Not Found} $resultObj configure code 404 $resultObj puts [my pageHeader] $resultObj puts "The page: [$resultObj cgi get REQUEST_URI] coult not be cound} $resultObj puts "<p><a href=\"[my cget virtual]\">Back</a>" $resultObj puts [my pageFooter] } } ootest create OOTEST /ootest {} vwait forever if 0 { # Start up the user interface and event loop. package require Tk package require httpd::srvui package require httpd::stdin SrvUI_Init "Tcl HTTPD $Httpd(version)" Stderr $startup if {[info commands "console"] == "console"} { console show } else { Stdin_Start "httpd % " Httpd_Shutdown } } |
Added bin/test/qwiki.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #!/bin/sh # \ exec tclsh "$0" ${1+"$@"} ############ # auto_path ############ # Configure the auto_path so we can find the script library. # home is the directory containing this script set home [string trimright [file dirname [info script]] ./] set home [file normalize [file join [pwd] $home ..]] set Config(lib) [file join $home .. modules] set Config(MainDatabaseFile) [file join $home test qwiki.sqlite] source $home/test/common.tcl ### # Begin the test ### package require httpd::qwiki tao::class qwikitest { superclass httpd.qwiki ### # title: Implement html content at a toplevel ### method /html resultObj { $resultObj configure title {Welcome to Qwiki!} $resultObj puts [my pageHeader] $resultObj puts { Hello World! <p> } $resultObj puts "Logged in as user: [$resultObj session get username]<br>" $resultObj puts "Logged with session: [$resultObj cget sessionid]<br>" $resultObj puts { Try the following links: <ul> } set prefix [my cget virtual] foreach {url comment} { errorurl {Throw an internal error from Tcl} deadurl {Page that generates a 505 error} suburl {Valid Suburl} missing {Non-existent url} login {Log In} logout {Log Out} } { $resultObj puts "<li><a href=$prefix/$url>$url</a> - $comment</li>" } $resultObj puts {</ul>} $resultObj puts [my pageFooter] } method /html/errorurl resultObj { error "Die Yuppie Scum!" } method /html/deadurl resultObj { $resultObj configure title {Page Error!} $resultObj configure code 501 $resultObj puts [my pageHeader] $resultObj puts { I threw an error this way } $resultObj puts [my pageFooter] } ### # title: Implement html content at a toplevel ### method /html/suburl resultObj { $resultObj configure title {Sub Url!} $resultObj puts [my pageHeader] $resultObj puts {Sub Url} $resultObj puts "<p><a href=\"[my cget virtual]\">Back</a>" $resultObj puts [my pageFooter] } ### # title: Implement html content at a toplevel ### method /html/default resultObj { $resultObj configure title {Not Found} $resultObj configure code 404 $resultObj puts [my pageHeader] $resultObj puts "The page: [$resultObj cgi get REQUEST_URI] coult not be cound" $resultObj puts "<p><a href=\"[my cget virtual]\">Back</a>" $resultObj puts [my pageFooter] } } qwikitest create HOME /home [list filename [Config MainDatabaseFile]] HOME task_daily vwait forever if 0 { # Start up the user interface and event loop. package require Tk package require httpd::srvui package require httpd::stdin SrvUI_Init "Tcl HTTPD $Httpd(version)" Stderr $startup if {[info commands "console"] == "console"} { console show } else { Stdin_Start "httpd % " Httpd_Shutdown } } |
Changes to bin/util/crypt.tcl.
1 2 3 4 5 6 7 8 9 | #!/bin/sh # htpass.tcl # Crude interface to generate encrypted passwords for htaccess files # # \ exec expect "$0" ${1+"$@"} # Obviously, edit this to reference the appropriate crypt .so file #load /home/welch/cvs/tclhttpd/lib/Binaries/SunOS/5.6/crypt.so | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/bin/sh # htpass.tcl # Crude interface to generate encrypted passwords for htaccess files # # \ exec expect "$0" ${1+"$@"} # Obviously, edit this to reference the appropriate crypt .so file #load /home/welch/cvs/tclhttpd/lib/Binaries/SunOS/5.6/crypt.so load /usr/lib/tclhttpd4.0.0/libcrypt1.0.so stty -echo send_user "Enter a word to crypt: " expect_user { -re "(\[^\n]+)\n" { set pass1 $expect_out(1,string) ; send_user \r\n} timeout { send_user timeout\n ; exit 1} } |
︙ | ︙ |
Changes to certs/README.ssl.
︙ | ︙ | |||
96 97 98 99 100 101 102 | It's signed by your own CA. You can make any number of certs by repeating steps two through four again with different file names. To set up tclhttpd, copy the key and the cert into the tclhttpd/certs subdirectory. E.g., | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | It's signed by your own CA. You can make any number of certs by repeating steps two through four again with different file names. To set up tclhttpd, copy the key and the cert into the tclhttpd/certs subdirectory. E.g., cd /usr/local/tclhttpd-4.0.0/ mkdir certs cp /usr/local/ssl/key1.pem certs/skey.pem cp /usr/local/ssl/demoCA/newcerts/02.pem certs/server.pem It appears that the default location for the certs directory is a "bin/certs", a subdirectory of the bin directory. If you want to change that, edit bin/tclhttpd.rc and fix |
︙ | ︙ |
Changes to configure.
1 | #! /bin/sh | < | > > | > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > > > > > > | > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > | > > | < > > | > > > | > > > > > > > > | > > > > < | < < < > > > > > > > | > < > | | | | | | | | < > < | | | | > | > > | | | | > > > | | > > > | > > > | | < > | > > > > > > > > > > | > > > | | > > > > | | | | | | > > | > | | | | < | < < < < < | < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | > > > > > > | | | | | > > > > > | < | < | | | | | | | | > > > > > > > > > > | | | | | | | | | < | < > | < > | | > > | > | | | < > | < > | > > | > > > > > | | | > > > > > > > > > > > > > | | < < < < | | > < | < < | > | < < < < < < > | < < < < < < | < < < | > > > > > | < < < < < > > | > > | > > > | | | | | > | > | | > | > > > > > | | | < > > > | > > | < | | | | > > > > > > > > > > > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > > | | > | | > | < | > > | > | > | > > > > > > > > | | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | | < | < < < < < < < < < < < < < | | | > > > > | | > > > > > | > | | | | | | | > | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell [email protected] about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 </dev/null exec 6>&1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="bin/httpd.tcl" # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef STDC_HEADERS # include <stdlib.h> # include <stddef.h> #else # ifdef HAVE_STDLIB_H # include <stdlib.h> # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include <memory.h> # endif # include <string.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif" ac_subst_vars='LTLIBOBJS LIBOBJS TCLSH_PROG SHLIB_LD_LIBS crypt_LIB_FILE limit_LIB_FILE SHARED_BUILD MAKE_STATIC_LIB MAKE_SHARED_LIB MAKE_LIB LDFLAGS_DEFAULT CFLAGS_DEFAULT BUILD_LIMIT LIMIT_EXTENSION EGREP GREP CPP CRYPT_OBJS SHLIB_LDFLAGS SHLIB_CFLAGS SHLIB_LD STLIB_LD CFLAGS_OPTIMIZE CFLAGS_DEBUG CLEANFILES TCL_INCLUDES TCL_BUILD_STUB_LIB_SPEC TCL_STUB_LIB_SPEC TCL_BUILD_LIB_SPEC TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_LD_FLAGS TCL_EXTRA_CFLAGS TCL_SHLIB_LD_LIBS TCL_DEFS TCL_LIBS TCL_LIB_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX RELPATH CYGPATH host_os host_vendor host_cpu host build_os build_vendor build_cpu build RANLIB SET_MAKE INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC THREAD_VERSION TCLLIB_VERSION TCL_VERSION WIN_LIMIT_VERSION LIMIT_VERSION LIMIT_PACKAGE WIN_CRYPT_VERSION CRYPT_VERSION CRYPT_PACKAGE WIN_VERSION RELEASE VERSION SERVER_ROOT PACKAGE CONFIGDIR target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_serverroot enable_gcc with_tcl with_tclinclude enable_threads enable_shared enable_symbols ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-gcc allow use of gcc if available --disable-gcc --enable-threads build with threads --enable-shared build and link with shared libraries --enable-shared --enable-symbols build with debugging symbols --disable-symbols Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-serverroot=DIR Location of where to install the server document tree --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tclinclude directory containing the public Tcl header files. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case <limits.h> declares $2. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. CONFIGDIR=${srcdir}/config #-------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. The NODOT_VERSION is # required for constructing the library name on systems that don't like # dots in library names (Windows). The VERSION variable is used on the # other systems. #-------------------------------------------------------------------- PACKAGE=tclhttpd MAJOR_VERSION=4 MINOR_VERSION=0 PATCHLEVEL=".0" RELEASE=`grep Release: ${srcdir}/${PACKAGE}.spec | sed -e 's/Release: *//'` VERSION=${MAJOR_VERSION}.${MINOR_VERSION}${PATCHLEVEL} NODOT_VERSION=${MAJOR_VERSION}${MINOR_VERSION} WIN_VERSION=`echo ${VERSION} | sed -e 's/\.//g'` TCL_VERSION=8.6.4 TCLLIB_VERSION=1.6 THREAD_VERSION=2.6 # We build two minor packages for the crypt and limit C extensions CRYPT_PACKAGE=crypt CRYPT_VERSION="1.0" WIN_CRYPT_VERSION=`echo ${CRYPT_VERSION} | sed -e 's/\.//g'` LIMIT_PACKAGE=limit LIMIT_VERSION="1.0" WIN_LIMIT_VERSION=`echo ${LIMIT_VERSION} | sed -e 's/\.//g'` # Check whether --with-serverroot was given. if test "${with_serverroot+set}" = set; then : withval=$with_serverroot; SERVER_ROOT=${withval} else SERVER_ROOT='$(prefix)/$(PACKAGE)' fi |
︙ | ︙ | |||
619 620 621 622 623 624 625 | #-------------------------------------------------------------------- # We put this here so that you can compile with -DVERSION="1.2" to # encode the package version directly into the source files. #-------------------------------------------------------------------- | | | | | | | < | > > > > > > | | | | | | | | > > > > > > > > > > > > | > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > | > | | | > | > | | > | > | > > > > > > > > > > > > > > > > | | | | | | > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > < | | > > | > | | | | | | > | | | > | > | < < | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | < | | > | < | > | | | | | | > | > > > | > > > | | > > | | > > > > > > > > > > > > > > > | > > | > > > > > > > > > | > > > > | > | > > > > > > > > > > > > | > | > > > | > > > > | > > > > > > > > > > > | > > | < < | | < < < < < | | > > > | > > | | < < < > > > > | | | > > > > > > > > > > > | > > > > > > > > > > > > > > > | < > > > > | > > > | < | | < < | | | | | | | < | > | < > | < < < | > > > > | | > > > > > > > > | > > | > > > > > > > > > > > > | | < | < < < < | > > | > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > | > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > | | < | | | | > > > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | > > > | | > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | > > > | > > > | | | | | | > | | > > > > > > > > > > > > > | | | | < < < < < < | > > > > > > > > > > > | | | | | > | | | | | > | | | > | | | | < > | < > | < > | | > | > | > | | | | | | < | | > > | > | | > | | | > | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > | > > | > > | | > | | > > > > | > > > > > > > > > > > > > > > > > > > | | | | > | < < < < | | < < < | > | < > > > > > > > > > > > > > > > > > > | > > > | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 | #-------------------------------------------------------------------- # We put this here so that you can compile with -DVERSION="1.2" to # encode the package version directly into the source files. #-------------------------------------------------------------------- eval cat >>confdefs.h <<_ACEOF #define VERSION "${VERSION}" _ACEOF #-------------------------------------------------------------------- # Check whether --enable-gcc or --disable-gcc was given. Do this # before AC_CYGWIN is called so the compiler can # be fully tested by built-in autoconf tools. # This macro also calls AC_PROG_CC to set the compiler if --enable-gcc # was not used. #-------------------------------------------------------------------- # Check whether --enable-gcc was given. if test "${enable_gcc+set}" = set; then : enableval=$enable_gcc; ok=$enableval else ok=no fi if test "$ok" = "yes"; then CC=gcc else case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95*) CC=cl ;; *) CC=${CC-cc} ;; esac fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdio.h> int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # This macro performs additional compiler tests. #-------------------------------------------------------------------- # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host_os in *cygwin* ) CYGWIN=yes;; * ) CYGWIN=no;; esac #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- #-------------------------------------------------------------------- # "cygpath" is used on windows to generate native path names for include # files. # These variables should only be used with the compiler and linker since # they generate native path names. |
︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 | # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true | > | | < | | | | | | | | 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 | # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then : withval=$with_tcl; with_tclconfig=${withval} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 $as_echo_n "checking for Tcl configuration... " >&6; } if ${ac_cv_c_tclconfig+:} false; then : $as_echo_n "(cached) " >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ |
︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 | break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then | > | | > | > | | | > | > | | | | | | | | | | | | | | | | > | | | | < | | | | | | | > | | | 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 | break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5 $as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 $as_echo "found $TCL_BIN_DIR/tclConfig.sh" >&6; } fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 $as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; } if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 $as_echo "loading" >&6; } . $TCL_BIN_DIR/tclConfig.sh else { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5 $as_echo "file not found" >&6; } fi # # The eval is required to do the TCL_DBGX substitution in the # TCL_LIB_FILE variable # eval TCL_LIB_FILE=${TCL_LIB_FILE} eval TCL_LIB_FLAG=${TCL_LIB_FLAG} #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after SC_PATH_TCLCONFIG/SC_LOAD_TCLCONFIG #-------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5 $as_echo_n "checking for Tcl public headers... " >&6; } # Check whether --with-tclinclude was given. if test "${with_tclinclude+set}" = set; then : withval=$with_tclinclude; with_tclinclude=${withval} fi if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else as_fn_error $? "${with_tclinclude} directory does not contain Tcl public header file tcl.h" "$LINENO" 5 fi else if ${ac_cv_c_tclh+:} false; then : $as_echo_n "(cached) " >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then ac_cv_c_tclh=${with_tclinclude} else # Check in the includedir, if --prefix was specified eval "temp_includedir=${includedir}" for i in \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null` \ /usr/local/include /usr/include ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then as_fn_error $? "tcl.h not found. Please specify its location with --with-tclinclude" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5 $as_echo "${ac_cv_c_tclh}" >&6; } fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" #SC_PRIVATE_TCL_HEADERS #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # |
︙ | ︙ | |||
1382 1383 1384 1385 1386 1387 1388 | # Define any extra compiler flags in the PACKAGE_CFLAGS variable. # These will be appended to the current set of compiler flags for # your system. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*) | | | | > | | | | < | < | < < | < > | | | | < | | | | | | | | > > > | > > | < | > | > | < < > | < < < | | | | < > | > < | > | > | > | > | | | | | < | > | > | < | < | 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 | # Define any extra compiler flags in the PACKAGE_CFLAGS variable. # These will be appended to the current set of compiler flags for # your system. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*) cat >>confdefs.h <<_ACEOF #define BUILD_${PACKAGE} 1 _ACEOF CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc50.pch" ;; *) CLEANFILES= ;; esac #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # So far only Tcl responds to this one. #-------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5 $as_echo_n "checking for building with threads... " >&6; } # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; tcl_ok=$enableval else tcl_ok=no fi if test "$tcl_ok" = "yes"; then TCL_THREADS=1 $as_echo "#define TCL_THREADS 1" >>confdefs.h $as_echo "#define _REENTRANT 1" >>confdefs.h case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else TCL_THREADS=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"Don t know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...\"" >&5 $as_echo "$as_me: WARNING: \"Don t know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...\"" >&2;} fi ;; esac else TCL_THREADS=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (default)" >&5 $as_echo "no (default)" >&6; } fi #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5 $as_echo_n "checking how to build libraries... " >&6; } # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; tcl_ok=$enableval else tcl_ok=yes fi if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5 $as_echo "shared" >&6; } SHARED_BUILD=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5 $as_echo "static" >&6; } SHARED_BUILD=0 $as_echo "#define STATIC_BUILD 1" >>confdefs.h fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information |
︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 | #-------------------------------------------------------------------- # Find out where we should get the crypt() function #-------------------------------------------------------------------- | > | | > | > > > | | > | | | < < | | | < | < | < < < < < < < | < < < < < < < < < < | < | | | < < < < | < < < < < < < < < < < < | < < | < < < | < < > | < < < | | | | < > | > < | > > > > > | | | | | | < > > > > > > > > | > > > > > > > > > > > > > > > | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | < < < | | < | | > | | > > | > > > > | | > | | > > > | > > | > | > > > > > > | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > | | > > | | < | | > | < > > > > > > > > | < | > | < > > > > > | > > > > > | > > > > > > > > > > > > > | > > > > > > > | | > | > > > > > > > > | < | > > > | > > > > > > > > | > > > | > | > | > > > | > | < > > | | > > | > | > | > > > > > > > > > | > > > | > > > > > | > > | | > > > | | > | | < < | | > | > > | > | > > > > > | > | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > < | > | | | | | < | > | > | | | | < | < | | | | | | | | 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 | #-------------------------------------------------------------------- # Find out where we should get the crypt() function #-------------------------------------------------------------------- ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" if test "x$ac_cv_func_crypt" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_crypt=yes else ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 $as_echo "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes; then : CRYPT_LIB=-lcrypt else CRYPT_OBJS=cryptLib.${OBJEXT} fi fi #-------------------------------------------------------------------- # Find out if we have the sys/resource.h header file for building # the limit extension #-------------------------------------------------------------------- ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <string.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ctype.h> #include <stdlib.h> #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default" if test "x$ac_cv_header_sys_resource_h" = xyes; then : BUILD_LIMIT=1 else BUILD_LIMIT=0 fi if test "${BUILD_LIMIT}" = 1 ; then LIMIT_EXTENSION='$(limit_LIB_FILE)' else LIMIT_EXTENSION='' fi #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols # option. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95*) tcl_dbgx=d ;; *) tcl_dbgx=g ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5 $as_echo_n "checking for build with symbols... " >&6; } # Check whether --enable-symbols was given. if test "${enable_symbols+set}" = set; then : enableval=$enable_symbols; tcl_ok=$enableval else tcl_ok=no fi if test "$tcl_ok" = "yes"; then CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" DBGX=${tcl_dbgx} TCL_DBGX=${tcl_dbgx} { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" DBGX="" TCL_DBGX="" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "${SHARED_BUILD}" = "1" ; then CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}' else CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}' fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. #-------------------------------------------------------------------- $as_echo "#define USE_TCL_STUBS 1" >>confdefs.h #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the SC_ENABLE_SHARED, SC_ENABLE_SYMBOLS, # and SC_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* |*CYGWIN_98*|*CYGWIN_95*) if test "${CC-cc}" = "cl"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(\$@_OBJECTS) " MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS} \$(LDFLAGS) -out:\$@ \$(\$@_OBJECTS) " fi ;; *) MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(\$@_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(\$@_OBJECTS) \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS}" ;; esac if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB=${MAKE_SHARED_LIB} else MAKE_LIB=${MAKE_STATIC_LIB} fi #-------------------------------------------------------------------- # eval these two values to dereference the ${DBGX} variable. #-------------------------------------------------------------------- eval "SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}" |
︙ | ︙ | |||
1928 1929 1930 1931 1932 1933 1934 | # file during the install process. Don't run the TCLSH_PROG through # ${CYGPATH} because it's being used directly by make. # Require that we use a tclsh shell version 8.2 or later since earlier # versions have bugs in the pkg_mkIndex routine. #-------------------------------------------------------------------- | | | | | | | > | | | > | | > | | < < < < < < | | > > > > | > | > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | > > > > > > > > > > | > > > > > > | < | | > | > > | > > > > | < < < < < < < < < < < > > > > > > > > > > > | > > > | > > > | | | | > > > > > > > > > > | | > > > > > > > > > > > > > | > | | > > > > > > > > > > > > > > > | | > > | > | > | > > > | > > | > > > | > > > > > > | < | < > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > | > | < < < < | < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > | | > > > > | > > | > > > | > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | < | < > | | < > | > > | | > > > > > > | > > | > > | > > | > | | > > > > > > > > > > > > > > > > > > | > > > > > > | > > > > > > > > > > > > | | | | > | | > > > > > > > > > > > > > > > > > > > | | | > < > > | > | < < | | | | | > > > > > > > > > > > > > > > > > > > > > > > > < > | > > > > > > > | | > > > > > > > | | > > > > > > > > > | > > | < > > | | > > > > | > | > > > > > > > | > > > > > | > > | > | > > > | < | | > > > | > | > > > > > | > | > > > > > > > > > | > > | > | > > | | | | | | > > > | > > | > > | < > > > > > > > > > > > > > > > > > > | | > | | < | | < > | | > > > > > > > > > > > > > > > > > > | > > > | > > | > > > | > | > > > > | > > > > > > > > > > | > > > > > > > > > > | > > | > > > > > > > | > > > | | > > > > > > > | > > > > > | > > | > | > > > > > | > > | > > | > > > | > > > > | | > > > > | | | | | | | | | | > > | | > > > > > > > > > > > > > > > > > > > > | > | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | > > | < > | | | < > > | < | > > | > > > > > > > | > > > > > > > | > > > > > > | > > | > > > > > > > > > > > > > > > > > > | > | > > > | | > | > > > > | | | > > > > > > > | > > > > > | > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | | | | | > | > | > > > | > > > > | > | > > > | | > > > > > > > | | > > > > | | > | > > | > > > > > > > > > > > > > > > | > > > > > > > > > > > > | > < > > > > | > > > > > | > > | > | > > > > | > > | > | | > > > > > > > > > > > > > > | | > | > | | | > | > > | | > > > > > > > > > > > > > > > > > > > > > > > > | 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 | # file during the install process. Don't run the TCLSH_PROG through # ${CYGPATH} because it's being used directly by make. # Require that we use a tclsh shell version 8.2 or later since earlier # versions have bugs in the pkg_mkIndex routine. #-------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5 $as_echo_n "checking for tclsh... " >&6; } if ${ac_cv_path_tclsh+:} false; then : $as_echo_n "(cached) " >&6 else search_path=`echo ${exec_prefix}/bin:${prefix}/bin:${TCL_BIN_DIR}:${TCL_BIN_DIR}/../bin:${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/tclsh[8-9]*${EXEEXT} 2> /dev/null` \ `ls -r $dir/tclsh*${EXEEXT} 2> /dev/null` ; do if test x"$ac_cv_path_tclsh" = x ; then if test -f "$j" ; then ac_cv_path_tclsh=$j break fi fi done done fi if test -f "$ac_cv_path_tclsh" ; then TCLSH_PROG=$ac_cv_path_tclsh { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5 $as_echo "$TCLSH_PROG" >&6; } else as_fn_error $? "No tclsh found in PATH: $search_path" "$LINENO" 5 fi #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile crypt_pkgIndex.tcl limit_pkgIndex.tcl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "crypt_pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES crypt_pkgIndex.tcl" ;; "limit_pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES limit_pkgIndex.tcl" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' <conf$$subs.awk | sed ' /^[^""]/{ N s/\n// } ' >>$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi |
Changes to configure.in.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # required for constructing the library name on systems that don't like # dots in library names (Windows). The VERSION variable is used on the # other systems. #-------------------------------------------------------------------- PACKAGE=tclhttpd | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # required for constructing the library name on systems that don't like # dots in library names (Windows). The VERSION variable is used on the # other systems. #-------------------------------------------------------------------- PACKAGE=tclhttpd MAJOR_VERSION=4 MINOR_VERSION=0 PATCHLEVEL=".0" RELEASE=`grep Release: ${srcdir}/${PACKAGE}.spec | sed -e 's/Release: *//'` VERSION=${MAJOR_VERSION}.${MINOR_VERSION}${PATCHLEVEL} NODOT_VERSION=${MAJOR_VERSION}${MINOR_VERSION} WIN_VERSION=`echo ${VERSION} | sed -e 's/\.//g'` TCL_VERSION=8.6.4 TCLLIB_VERSION=1.6 THREAD_VERSION=2.6 # We build two minor packages for the crypt and limit C extensions CRYPT_PACKAGE=crypt CRYPT_VERSION="1.0" WIN_CRYPT_VERSION=`echo ${CRYPT_VERSION} | sed -e 's/\.//g'` |
︙ | ︙ |
Changes to debian/changelog.
1 2 3 4 5 6 7 | tclhttpd (3.5.1-1) unstable; urgency=low * change version for release -- Colin McCormack <[email protected]> Thu, 27 May 2004 10:06:02 +1000 tclhttpd (3.5.0-2) unstable; urgency=low | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | tclhttpd (4.0.0) unstable; urgency=low * Change version for release -- Sean Woods <[email protected]> Sat, Mar 28 2015 04:44:11 EDT tclhttpd (3.5.1-1) unstable; urgency=low * change version for release -- Colin McCormack <[email protected]> Thu, 27 May 2004 10:06:02 +1000 tclhttpd (3.5.0-2) unstable; urgency=low |
︙ | ︙ |
Changes to debian/rules.
1 2 3 4 | #!/usr/bin/make -f # -*- makefile -*- # debian/rules with debhelper for tclhttpd | | | 1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/make -f # -*- makefile -*- # debian/rules with debhelper for tclhttpd export VERSION=4.0.0 export BUILD=$(CURDIR)/debian/tclhttpd/ # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 # This has to be exported to make some magic below work. export DH_OPTIONS |
︙ | ︙ |
Added htdocs/bootdemo/index.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 | <!DOCTYPE html> <html lang="en"> <head> <!-- Meta, title, CSS, favicons, etc. --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content="Bootstrap, a sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development."> <meta name="keywords" content="HTML, CSS, JS, JavaScript, framework, bootstrap, front-end, frontend, web development"> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <title> Components · Bootstrap </title> <!-- Bootstrap core CSS --> <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Optional Bootstrap Theme --> <link href="data:text/css;charset=utf-8," data-href="/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet" id="bs-theme-stylesheet"> <!-- Documentation extras --> <link href="../assets/css/docs.min.css" rel="stylesheet"> <!--[if lt IE 9]><script src="../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> <script src="../assets/js/ie-emulation-modes-warning.js"></script> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> <!-- Favicons --> <link rel="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="icon" href="/favicon.ico"> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-146052-10', 'getbootstrap.com'); ga('send', 'pageview'); </script> </head> <body> <a id="skippy" class="sr-only sr-only-focusable" href="#content"><div class="container"><span class="skiplink-text">Skip to main content</span></div></a> <!-- Docs master nav --> <header class="navbar navbar-static-top bs-docs-nav" id="top" role="banner"> <div class="container"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="../" class="navbar-brand">Bootstrap</a> </div> <nav class="collapse navbar-collapse bs-navbar-collapse"> <ul class="nav navbar-nav"> <li> <a href="../getting-started/">Getting started</a> </li> <li> <a href="../css/">CSS</a> </li> <li class="active"> <a href="../components/">Components</a> </li> <li> <a href="../javascript/">JavaScript</a> </li> <li> <a href="../customize/">Customize</a> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="http://expo.getbootstrap.com" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Expo');">Expo</a></li> <li><a href="http://blog.getbootstrap.com" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');">Blog</a></li> </ul> </nav> </div> </header> <!-- Docs page layout --> <div class="bs-docs-header" id="content" tabindex="-1"> <div class="container"> <h1>Components</h1> <p>Over a dozen reusable components built to provide iconography, dropdowns, input groups, navigation, alerts, and much more.</p> <div id="carbonads-container"><div class="carbonad"><div id="azcarbon"></div><script>var z = document.createElement("script"); z.async = true; z.src = "http://engine.carbonads.com/z/32341/azcarbon_2_1_0_HORIZ"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(z, s);</script></div></div> </div> </div> <div class="container bs-docs-container"> <div class="row"> <div class="col-md-9" role="main"> <div class="bs-docs-section"> <h1 id="glyphicons" class="page-header">Glyphicons</h1> <h2 id="glyphicons-glyphs">Available glyphs</h2> <p>Includes over 250 glyphs in font format from the Glyphicon Halflings set. <a href="http://glyphicons.com/">Glyphicons</a> Halflings are normally not available for free, but their creator has made them available for Bootstrap free of cost. As a thank you, we only ask that you include a link back to <a href="http://glyphicons.com/">Glyphicons</a> whenever possible.</p> <div class="bs-glyphicons"> <ul class="bs-glyphicons-list"> <li> <span class="glyphicon glyphicon-asterisk" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-asterisk</span> </li> <li> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-plus</span> </li> <li> <span class="glyphicon glyphicon-euro" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-euro</span> </li> <li> <span class="glyphicon glyphicon-eur" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-eur</span> </li> <li> <span class="glyphicon glyphicon-minus" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-minus</span> </li> <li> <span class="glyphicon glyphicon-cloud" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cloud</span> </li> <li> <span class="glyphicon glyphicon-envelope" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-envelope</span> </li> <li> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-pencil</span> </li> <li> <span class="glyphicon glyphicon-glass" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-glass</span> </li> <li> <span class="glyphicon glyphicon-music" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-music</span> </li> <li> <span class="glyphicon glyphicon-search" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-search</span> </li> <li> <span class="glyphicon glyphicon-heart" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-heart</span> </li> <li> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-star</span> </li> <li> <span class="glyphicon glyphicon-star-empty" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-star-empty</span> </li> <li> <span class="glyphicon glyphicon-user" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-user</span> </li> <li> <span class="glyphicon glyphicon-film" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-film</span> </li> <li> <span class="glyphicon glyphicon-th-large" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-th-large</span> </li> <li> <span class="glyphicon glyphicon-th" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-th</span> </li> <li> <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-th-list</span> </li> <li> <span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ok</span> </li> <li> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-remove</span> </li> <li> <span class="glyphicon glyphicon-zoom-in" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-zoom-in</span> </li> <li> <span class="glyphicon glyphicon-zoom-out" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-zoom-out</span> </li> <li> <span class="glyphicon glyphicon-off" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-off</span> </li> <li> <span class="glyphicon glyphicon-signal" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-signal</span> </li> <li> <span class="glyphicon glyphicon-cog" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cog</span> </li> <li> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-trash</span> </li> <li> <span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-home</span> </li> <li> <span class="glyphicon glyphicon-file" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-file</span> </li> <li> <span class="glyphicon glyphicon-time" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-time</span> </li> <li> <span class="glyphicon glyphicon-road" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-road</span> </li> <li> <span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-download-alt</span> </li> <li> <span class="glyphicon glyphicon-download" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-download</span> </li> <li> <span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-upload</span> </li> <li> <span class="glyphicon glyphicon-inbox" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-inbox</span> </li> <li> <span class="glyphicon glyphicon-play-circle" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-play-circle</span> </li> <li> <span class="glyphicon glyphicon-repeat" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-repeat</span> </li> <li> <span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-refresh</span> </li> <li> <span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-list-alt</span> </li> <li> <span class="glyphicon glyphicon-lock" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-lock</span> </li> <li> <span class="glyphicon glyphicon-flag" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-flag</span> </li> <li> <span class="glyphicon glyphicon-headphones" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-headphones</span> </li> <li> <span class="glyphicon glyphicon-volume-off" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-volume-off</span> </li> <li> <span class="glyphicon glyphicon-volume-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-volume-down</span> </li> <li> <span class="glyphicon glyphicon-volume-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-volume-up</span> </li> <li> <span class="glyphicon glyphicon-qrcode" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-qrcode</span> </li> <li> <span class="glyphicon glyphicon-barcode" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-barcode</span> </li> <li> <span class="glyphicon glyphicon-tag" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tag</span> </li> <li> <span class="glyphicon glyphicon-tags" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tags</span> </li> <li> <span class="glyphicon glyphicon-book" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-book</span> </li> <li> <span class="glyphicon glyphicon-bookmark" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bookmark</span> </li> <li> <span class="glyphicon glyphicon-print" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-print</span> </li> <li> <span class="glyphicon glyphicon-camera" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-camera</span> </li> <li> <span class="glyphicon glyphicon-font" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-font</span> </li> <li> <span class="glyphicon glyphicon-bold" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bold</span> </li> <li> <span class="glyphicon glyphicon-italic" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-italic</span> </li> <li> <span class="glyphicon glyphicon-text-height" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-text-height</span> </li> <li> <span class="glyphicon glyphicon-text-width" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-text-width</span> </li> <li> <span class="glyphicon glyphicon-align-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-align-left</span> </li> <li> <span class="glyphicon glyphicon-align-center" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-align-center</span> </li> <li> <span class="glyphicon glyphicon-align-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-align-right</span> </li> <li> <span class="glyphicon glyphicon-align-justify" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-align-justify</span> </li> <li> <span class="glyphicon glyphicon-list" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-list</span> </li> <li> <span class="glyphicon glyphicon-indent-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-indent-left</span> </li> <li> <span class="glyphicon glyphicon-indent-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-indent-right</span> </li> <li> <span class="glyphicon glyphicon-facetime-video" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-facetime-video</span> </li> <li> <span class="glyphicon glyphicon-picture" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-picture</span> </li> <li> <span class="glyphicon glyphicon-map-marker" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-map-marker</span> </li> <li> <span class="glyphicon glyphicon-adjust" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-adjust</span> </li> <li> <span class="glyphicon glyphicon-tint" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tint</span> </li> <li> <span class="glyphicon glyphicon-edit" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-edit</span> </li> <li> <span class="glyphicon glyphicon-share" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-share</span> </li> <li> <span class="glyphicon glyphicon-check" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-check</span> </li> <li> <span class="glyphicon glyphicon-move" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-move</span> </li> <li> <span class="glyphicon glyphicon-step-backward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-step-backward</span> </li> <li> <span class="glyphicon glyphicon-fast-backward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-fast-backward</span> </li> <li> <span class="glyphicon glyphicon-backward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-backward</span> </li> <li> <span class="glyphicon glyphicon-play" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-play</span> </li> <li> <span class="glyphicon glyphicon-pause" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-pause</span> </li> <li> <span class="glyphicon glyphicon-stop" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-stop</span> </li> <li> <span class="glyphicon glyphicon-forward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-forward</span> </li> <li> <span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-fast-forward</span> </li> <li> <span class="glyphicon glyphicon-step-forward" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-step-forward</span> </li> <li> <span class="glyphicon glyphicon-eject" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-eject</span> </li> <li> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-chevron-left</span> </li> <li> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-chevron-right</span> </li> <li> <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-plus-sign</span> </li> <li> <span class="glyphicon glyphicon-minus-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-minus-sign</span> </li> <li> <span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-remove-sign</span> </li> <li> <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ok-sign</span> </li> <li> <span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-question-sign</span> </li> <li> <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-info-sign</span> </li> <li> <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-screenshot</span> </li> <li> <span class="glyphicon glyphicon-remove-circle" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-remove-circle</span> </li> <li> <span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ok-circle</span> </li> <li> <span class="glyphicon glyphicon-ban-circle" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ban-circle</span> </li> <li> <span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-arrow-left</span> </li> <li> <span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-arrow-right</span> </li> <li> <span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-arrow-up</span> </li> <li> <span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-arrow-down</span> </li> <li> <span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-share-alt</span> </li> <li> <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-resize-full</span> </li> <li> <span class="glyphicon glyphicon-resize-small" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-resize-small</span> </li> <li> <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-exclamation-sign</span> </li> <li> <span class="glyphicon glyphicon-gift" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-gift</span> </li> <li> <span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-leaf</span> </li> <li> <span class="glyphicon glyphicon-fire" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-fire</span> </li> <li> <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-eye-open</span> </li> <li> <span class="glyphicon glyphicon-eye-close" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-eye-close</span> </li> <li> <span class="glyphicon glyphicon-warning-sign" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-warning-sign</span> </li> <li> <span class="glyphicon glyphicon-plane" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-plane</span> </li> <li> <span class="glyphicon glyphicon-calendar" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-calendar</span> </li> <li> <span class="glyphicon glyphicon-random" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-random</span> </li> <li> <span class="glyphicon glyphicon-comment" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-comment</span> </li> <li> <span class="glyphicon glyphicon-magnet" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-magnet</span> </li> <li> <span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-chevron-up</span> </li> <li> <span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-chevron-down</span> </li> <li> <span class="glyphicon glyphicon-retweet" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-retweet</span> </li> <li> <span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-shopping-cart</span> </li> <li> <span class="glyphicon glyphicon-folder-close" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-folder-close</span> </li> <li> <span class="glyphicon glyphicon-folder-open" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-folder-open</span> </li> <li> <span class="glyphicon glyphicon-resize-vertical" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-resize-vertical</span> </li> <li> <span class="glyphicon glyphicon-resize-horizontal" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-resize-horizontal</span> </li> <li> <span class="glyphicon glyphicon-hdd" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hdd</span> </li> <li> <span class="glyphicon glyphicon-bullhorn" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bullhorn</span> </li> <li> <span class="glyphicon glyphicon-bell" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bell</span> </li> <li> <span class="glyphicon glyphicon-certificate" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-certificate</span> </li> <li> <span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-thumbs-up</span> </li> <li> <span class="glyphicon glyphicon-thumbs-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-thumbs-down</span> </li> <li> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hand-right</span> </li> <li> <span class="glyphicon glyphicon-hand-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hand-left</span> </li> <li> <span class="glyphicon glyphicon-hand-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hand-up</span> </li> <li> <span class="glyphicon glyphicon-hand-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hand-down</span> </li> <li> <span class="glyphicon glyphicon-circle-arrow-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-circle-arrow-right</span> </li> <li> <span class="glyphicon glyphicon-circle-arrow-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-circle-arrow-left</span> </li> <li> <span class="glyphicon glyphicon-circle-arrow-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-circle-arrow-up</span> </li> <li> <span class="glyphicon glyphicon-circle-arrow-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-circle-arrow-down</span> </li> <li> <span class="glyphicon glyphicon-globe" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-globe</span> </li> <li> <span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-wrench</span> </li> <li> <span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tasks</span> </li> <li> <span class="glyphicon glyphicon-filter" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-filter</span> </li> <li> <span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-briefcase</span> </li> <li> <span class="glyphicon glyphicon-fullscreen" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-fullscreen</span> </li> <li> <span class="glyphicon glyphicon-dashboard" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-dashboard</span> </li> <li> <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-paperclip</span> </li> <li> <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-heart-empty</span> </li> <li> <span class="glyphicon glyphicon-link" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-link</span> </li> <li> <span class="glyphicon glyphicon-phone" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-phone</span> </li> <li> <span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-pushpin</span> </li> <li> <span class="glyphicon glyphicon-usd" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-usd</span> </li> <li> <span class="glyphicon glyphicon-gbp" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-gbp</span> </li> <li> <span class="glyphicon glyphicon-sort" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort</span> </li> <li> <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-alphabet</span> </li> <li> <span class="glyphicon glyphicon-sort-by-alphabet-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-alphabet-alt</span> </li> <li> <span class="glyphicon glyphicon-sort-by-order" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-order</span> </li> <li> <span class="glyphicon glyphicon-sort-by-order-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-order-alt</span> </li> <li> <span class="glyphicon glyphicon-sort-by-attributes" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-attributes</span> </li> <li> <span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sort-by-attributes-alt</span> </li> <li> <span class="glyphicon glyphicon-unchecked" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-unchecked</span> </li> <li> <span class="glyphicon glyphicon-expand" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-expand</span> </li> <li> <span class="glyphicon glyphicon-collapse-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-collapse-down</span> </li> <li> <span class="glyphicon glyphicon-collapse-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-collapse-up</span> </li> <li> <span class="glyphicon glyphicon-log-in" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-log-in</span> </li> <li> <span class="glyphicon glyphicon-flash" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-flash</span> </li> <li> <span class="glyphicon glyphicon-log-out" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-log-out</span> </li> <li> <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-new-window</span> </li> <li> <span class="glyphicon glyphicon-record" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-record</span> </li> <li> <span class="glyphicon glyphicon-save" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-save</span> </li> <li> <span class="glyphicon glyphicon-open" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-open</span> </li> <li> <span class="glyphicon glyphicon-saved" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-saved</span> </li> <li> <span class="glyphicon glyphicon-import" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-import</span> </li> <li> <span class="glyphicon glyphicon-export" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-export</span> </li> <li> <span class="glyphicon glyphicon-send" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-send</span> </li> <li> <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-floppy-disk</span> </li> <li> <span class="glyphicon glyphicon-floppy-saved" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-floppy-saved</span> </li> <li> <span class="glyphicon glyphicon-floppy-remove" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-floppy-remove</span> </li> <li> <span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-floppy-save</span> </li> <li> <span class="glyphicon glyphicon-floppy-open" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-floppy-open</span> </li> <li> <span class="glyphicon glyphicon-credit-card" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-credit-card</span> </li> <li> <span class="glyphicon glyphicon-transfer" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-transfer</span> </li> <li> <span class="glyphicon glyphicon-cutlery" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cutlery</span> </li> <li> <span class="glyphicon glyphicon-header" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-header</span> </li> <li> <span class="glyphicon glyphicon-compressed" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-compressed</span> </li> <li> <span class="glyphicon glyphicon-earphone" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-earphone</span> </li> <li> <span class="glyphicon glyphicon-phone-alt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-phone-alt</span> </li> <li> <span class="glyphicon glyphicon-tower" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tower</span> </li> <li> <span class="glyphicon glyphicon-stats" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-stats</span> </li> <li> <span class="glyphicon glyphicon-sd-video" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sd-video</span> </li> <li> <span class="glyphicon glyphicon-hd-video" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hd-video</span> </li> <li> <span class="glyphicon glyphicon-subtitles" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-subtitles</span> </li> <li> <span class="glyphicon glyphicon-sound-stereo" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sound-stereo</span> </li> <li> <span class="glyphicon glyphicon-sound-dolby" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sound-dolby</span> </li> <li> <span class="glyphicon glyphicon-sound-5-1" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sound-5-1</span> </li> <li> <span class="glyphicon glyphicon-sound-6-1" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sound-6-1</span> </li> <li> <span class="glyphicon glyphicon-sound-7-1" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sound-7-1</span> </li> <li> <span class="glyphicon glyphicon-copyright-mark" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-copyright-mark</span> </li> <li> <span class="glyphicon glyphicon-registration-mark" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-registration-mark</span> </li> <li> <span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cloud-download</span> </li> <li> <span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cloud-upload</span> </li> <li> <span class="glyphicon glyphicon-tree-conifer" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tree-conifer</span> </li> <li> <span class="glyphicon glyphicon-tree-deciduous" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tree-deciduous</span> </li> <li> <span class="glyphicon glyphicon-cd" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-cd</span> </li> <li> <span class="glyphicon glyphicon-save-file" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-save-file</span> </li> <li> <span class="glyphicon glyphicon-open-file" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-open-file</span> </li> <li> <span class="glyphicon glyphicon-level-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-level-up</span> </li> <li> <span class="glyphicon glyphicon-copy" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-copy</span> </li> <li> <span class="glyphicon glyphicon-paste" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-paste</span> </li> <li> <span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-alert</span> </li> <li> <span class="glyphicon glyphicon-equalizer" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-equalizer</span> </li> <li> <span class="glyphicon glyphicon-king" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-king</span> </li> <li> <span class="glyphicon glyphicon-queen" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-queen</span> </li> <li> <span class="glyphicon glyphicon-pawn" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-pawn</span> </li> <li> <span class="glyphicon glyphicon-bishop" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bishop</span> </li> <li> <span class="glyphicon glyphicon-knight" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-knight</span> </li> <li> <span class="glyphicon glyphicon-baby-formula" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-baby-formula</span> </li> <li> <span class="glyphicon glyphicon-tent" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-tent</span> </li> <li> <span class="glyphicon glyphicon-blackboard" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-blackboard</span> </li> <li> <span class="glyphicon glyphicon-bed" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bed</span> </li> <li> <span class="glyphicon glyphicon-apple" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-apple</span> </li> <li> <span class="glyphicon glyphicon-erase" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-erase</span> </li> <li> <span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-hourglass</span> </li> <li> <span class="glyphicon glyphicon-lamp" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-lamp</span> </li> <li> <span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-duplicate</span> </li> <li> <span class="glyphicon glyphicon-piggy-bank" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-piggy-bank</span> </li> <li> <span class="glyphicon glyphicon-scissors" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-scissors</span> </li> <li> <span class="glyphicon glyphicon-bitcoin" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-bitcoin</span> </li> <li> <span class="glyphicon glyphicon-btc" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-btc</span> </li> <li> <span class="glyphicon glyphicon-xbt" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-xbt</span> </li> <li> <span class="glyphicon glyphicon-yen" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-yen</span> </li> <li> <span class="glyphicon glyphicon-jpy" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-jpy</span> </li> <li> <span class="glyphicon glyphicon-ruble" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ruble</span> </li> <li> <span class="glyphicon glyphicon-rub" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-rub</span> </li> <li> <span class="glyphicon glyphicon-scale" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-scale</span> </li> <li> <span class="glyphicon glyphicon-ice-lolly" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ice-lolly</span> </li> <li> <span class="glyphicon glyphicon-ice-lolly-tasted" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-ice-lolly-tasted</span> </li> <li> <span class="glyphicon glyphicon-education" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-education</span> </li> <li> <span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-option-horizontal</span> </li> <li> <span class="glyphicon glyphicon-option-vertical" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-option-vertical</span> </li> <li> <span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-menu-hamburger</span> </li> <li> <span class="glyphicon glyphicon-modal-window" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-modal-window</span> </li> <li> <span class="glyphicon glyphicon-oil" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-oil</span> </li> <li> <span class="glyphicon glyphicon-grain" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-grain</span> </li> <li> <span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-sunglasses</span> </li> <li> <span class="glyphicon glyphicon-text-size" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-text-size</span> </li> <li> <span class="glyphicon glyphicon-text-color" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-text-color</span> </li> <li> <span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-text-background</span> </li> <li> <span class="glyphicon glyphicon-object-align-top" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-top</span> </li> <li> <span class="glyphicon glyphicon-object-align-bottom" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-bottom</span> </li> <li> <span class="glyphicon glyphicon-object-align-horizontal" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-horizontal</span> </li> <li> <span class="glyphicon glyphicon-object-align-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-left</span> </li> <li> <span class="glyphicon glyphicon-object-align-vertical" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-vertical</span> </li> <li> <span class="glyphicon glyphicon-object-align-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-object-align-right</span> </li> <li> <span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-triangle-right</span> </li> <li> <span class="glyphicon glyphicon-triangle-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-triangle-left</span> </li> <li> <span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-triangle-bottom</span> </li> <li> <span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-triangle-top</span> </li> <li> <span class="glyphicon glyphicon-console" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-console</span> </li> <li> <span class="glyphicon glyphicon-superscript" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-superscript</span> </li> <li> <span class="glyphicon glyphicon-subscript" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-subscript</span> </li> <li> <span class="glyphicon glyphicon-menu-left" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-menu-left</span> </li> <li> <span class="glyphicon glyphicon-menu-right" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-menu-right</span> </li> <li> <span class="glyphicon glyphicon-menu-down" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-menu-down</span> </li> <li> <span class="glyphicon glyphicon-menu-up" aria-hidden="true"></span> <span class="glyphicon-class">glyphicon glyphicon-menu-up</span> </li> </ul> </div> <h2 id="glyphicons-how-to-use">How to use</h2> <p>For performance reasons, all icons require a base class and individual icon class. To use, place the following code just about anywhere. Be sure to leave a space between the icon and text for proper padding.</p> <div class="bs-callout bs-callout-danger" id="callout-glyphicons-dont-mix"> <h4>Don't mix with other components</h4> <p>Icon classes cannot be directly combined with other components. They should not be used along with other classes on the same element. Instead, add a nested <code><span></code> and apply the icon classes to the <code><span></code>.</p> </div> <div class="bs-callout bs-callout-danger" id="callout-glyphicons-empty-only"> <h4>Only for use on empty elements</h4> <p>Icon classes should only be used on elements that contain no text content and have no child elements.</p> </div> <div class="bs-callout bs-callout-info" id="callout-glyphicons-location"> <h4>Changing the icon font location</h4> <p>Bootstrap assumes icon font files will be located in the <code>../fonts/</code> directory, relative to the compiled CSS files. Moving or renaming those font files means updating the CSS in one of three ways:</p> <ul> <li>Change the <code>@icon-font-path</code> and/or <code>@icon-font-name</code> variables in the source Less files.</li> <li>Utilize the <a href="http://lesscss.org/usage/#command-line-usage-relative-urls">relative URLs option</a> provided by the Less compiler.</li> <li>Change the <code>url()</code> paths in the compiled CSS.</li> </ul> <p>Use whatever option best suits your specific development setup.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-glyphicons-accessibility"> <h4>Accessible icons</h4> <p>Modern versions of assistive technologies will announce CSS generated content, as well as specific Unicode characters. To avoid unintended and confusing output in screen readers (particularly when icons are used purely for decoration), we hide them with the <code>aria-hidden="true"</code> attribute.</p> <p>If you're using an icon to convey meaning (rather than only as a decorative element), ensure that this meaning is also conveyed to assistive technologies � for instance, include additional content, visually hidden with the <code>.sr-only</code> class.</p> <p>If you're creating controls with no other text (such as a <code><button></code> that only contains an icon), you should always provide alternative content to identify the purpose of the control, so that it will make sense to users of assistive technologies. In this case, you could add an <code>aria-label</code> attribute on the control itself.</p> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-search"</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span></span></code></pre></div> <h2 id="glyphicons-examples">Examples</h2> <p>Use them in buttons, button groups for a toolbar, navigation, or prepended form inputs.</p> <div class="bs-example" data-example-id="glyphicons-general"> <div class="btn-toolbar" role="toolbar"> <div class="btn-group"> <button type="button" class="btn btn-default" aria-label="Left Align"><span class="glyphicon glyphicon-align-left" aria-hidden="true"></span></button> <button type="button" class="btn btn-default" aria-label="Center Align"><span class="glyphicon glyphicon-align-center" aria-hidden="true"></span></button> <button type="button" class="btn btn-default" aria-label="Right Align"><span class="glyphicon glyphicon-align-right" aria-hidden="true"></span></button> <button type="button" class="btn btn-default" aria-label="Justify"><span class="glyphicon glyphicon-align-justify" aria-hidden="true"></span></button> </div> </div> <div class="btn-toolbar" role="toolbar"> <button type="button" class="btn btn-default btn-lg"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Star</button> <button type="button" class="btn btn-default"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Star</button> <button type="button" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Star</button> <button type="button" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-star" aria-hidden="true"></span> Star</button> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span> <span class="na">aria-label=</span><span class="s">"Left Align"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-align-left"</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default btn-lg"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-star"</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span></span> Star <span class="nt"></button></span></code></pre></div> <p>An icon used in an <a href="#alerts">alert</a> to convey that it's an error message, with additional <code>.sr-only</code> text to convey this hint to users of assistive technologies.</p> <div class="bs-example" data-example-id="glyphicons-accessibility"> <div class="alert alert-danger" role="alert"> <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <span class="sr-only">Error:</span> Enter a valid email address </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-danger"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"glyphicon glyphicon-exclamation-sign"</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>Error:<span class="nt"></span></span> Enter a valid email address <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="dropdowns" class="page-header">Dropdowns</h1> <p class="lead">Toggleable, contextual menu for displaying lists of links. Made interactive with the <a href="../javascript/#dropdowns">dropdown JavaScript plugin</a>.</p> <h2 id="dropdowns-example">Example</h2> <p>Wrap the dropdown's trigger and the dropdown menu within <code>.dropdown</code>, or another element that declares <code>position: relative;</code>. Then add the menu's HTML. Dropdown menus can be changed to expand upwards (instead of downwards) by adding <code>.dropup</code> to the parent.</p> <div class="bs-example" data-example-id="static-dropdown"> <div class="dropdown clearfix"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li> </ul> </div> <div class="dropup clearfix"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu2"> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li> </ul> </div> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"dropdown"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"dropdownMenu1"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"true"</span><span class="nt">></span> Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dropdownMenu1"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"dropup"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"dropdownMenu2"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"true"</span><span class="nt">></span> Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dropdownMenu2"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> <h2 id="dropdowns-alignment">Alignment</h2> <p>By default, a dropdown menu is automatically positioned 100% from the top and along the left side of its parent. Add <code>.dropdown-menu-right</code> to a <code>.dropdown-menu</code> to right align the dropdown menu.</p> <div class="bs-callout bs-callout-warning" id="callout-dropdown-positioning"> <h4>May require additional positioning</h4> <p>Dropdowns are automatically positioned via CSS within the normal flow of the document. This means dropdowns may be cropped by parents with certain <code>overflow</code> properties or appear out of bounds of the viewport. Address these issues on your own as they arise.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-dropdown-pull-right"> <h4>Deprecated <code>.pull-right</code> alignment</h4> <p>As of v3.1.0, we've deprecated <code>.pull-right</code> on dropdown menus. To right-align a menu, use <code>.dropdown-menu-right</code>. Right-aligned nav components in the navbar use a mixin version of this class to automatically align the menu. To override it, use <code>.dropdown-menu-left</code>.</p> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu dropdown-menu-right"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dLabel"</span><span class="nt">></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="dropdowns-headers">Headers</h2> <p>Add a header to label sections of actions in any dropdown menu.</p> <div class="bs-example"> <div class="dropdown clearfix"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu3" data-toggle="dropdown" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu3"> <li role="presentation" class="dropdown-header">Dropdown header</li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li> <li role="presentation" class="dropdown-header">Dropdown header</li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li> </ul> </div> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dropdownMenu3"</span><span class="nt">></span> ... <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"dropdown-header"</span><span class="nt">></span>Dropdown header<span class="nt"></li></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="dropdowns-divider">Divider</h2> <p>Add a divider to separate series of links in a dropdown menu.</p> <div class="bs-example"> <div class="dropdown clearfix"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenuDivider" data-toggle="dropdown" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuDivider"> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li> <li role="presentation" class="divider"></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li> </ul> </div> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dropdownMenuDivider"</span><span class="nt">></span> ... <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="dropdowns-disabled">Disabled menu items</h2> <p>Add <code>.disabled</code> to a <code><li></code> in the dropdown to disable the link.</p> <div class="bs-example"> <div class="dropdown clearfix"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu4" data-toggle="dropdown" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu4"> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Regular link</a></li> <li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Disabled link</a></li> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another link</a></li> </ul> </div> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span> <span class="na">aria-labelledby=</span><span class="s">"dropdownMenu4"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Regular link<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"disabled"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Disabled link<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">role=</span><span class="s">"menuitem"</span> <span class="na">tabindex=</span><span class="s">"-1"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another link<span class="nt"></a></li></span> <span class="nt"></ul></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="btn-groups" class="page-header">Button groups</h1> <p class="lead">Group a series of buttons together on a single line with the button group. Add on optional JavaScript radio and checkbox style behavior with <a href="../javascript/#buttons">our buttons plugin</a>.</p> <div class="bs-callout bs-callout-warning" id="callout-btn-group-tooltips"> <h4>Tooltips & popovers in button groups require special setting</h4> <p>When using tooltips or popovers on elements within a <code>.btn-group</code>, you'll have to specify the option <code>container: 'body'</code> to avoid unwanted side effects (such as the element growing wider and/or losing its rounded corners when the tooltip or popover is triggered).</p> </div> <div class="bs-callout bs-callout-warning" id="callout-btn-group-accessibility"> <h4>Ensure correct <code>role</code> and provide a label</h4> <p>In order for assistive technologies � such as screen readers � to convey that a series of buttons is grouped, an appropriate <code>role</code> attribute needs to be provided. For button groups, this would be <code>role="group"</code>, while toolbars should have a <code>role="toolbar"</code>.</p> <p>One exception are groups which only contain a single control (for instance the <a href="#btn-groups-justified">justified button groups</a> with <code><button></code> elements) or a dropdown.</p> <p>In addition, groups and toolbars should be given an explicit label, as most assistive technologies will otherwise not announce them, despite the presence of the correct <code>role</code> attribute. In the examples provided here, we use <code>aria-label</code>, but alternatives such as <code>aria-labelledby</code> can also be used.</p> </div> <h2 id="btn-groups-single">Basic example</h2> <p>Wrap a series of buttons with <code>.btn</code> in <code>.btn-group</code>.</p> <div class="bs-example" data-example-id="simple-button-group"> <div class="btn-group" role="group" aria-label="Basic example"> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Left<span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Middle<span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Right<span class="nt"></button></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-groups-toolbar">Button toolbar</h2> <p>Combine sets of <code><div class="btn-group"></code> into a <code><div class="btn-toolbar"></code> for more complex components.</p> <div class="bs-example" data-example-id="simple-button-toolbar"> <div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups"> <div class="btn-group" role="group" aria-label="First group"> <button type="button" class="btn btn-default">1</button> <button type="button" class="btn btn-default">2</button> <button type="button" class="btn btn-default">3</button> <button type="button" class="btn btn-default">4</button> </div> <div class="btn-group" role="group" aria-label="Second group"> <button type="button" class="btn btn-default">5</button> <button type="button" class="btn btn-default">6</button> <button type="button" class="btn btn-default">7</button> </div> <div class="btn-group" role="group" aria-label="Third group"> <button type="button" class="btn btn-default">8</button> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-toolbar"</span> <span class="na">role=</span><span class="s">"toolbar"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-groups-sizing">Sizing</h2> <p>Instead of applying button sizing classes to every button in a group, just add <code>.btn-group-*</code> to each <code>.btn-group</code>, including when nesting multiple groups.</p> <div class="bs-example" data-example-id="button-group-sizing"> <div class="btn-group btn-group-lg" role="group" aria-label="Large button group"> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> <br> <div class="btn-group" role="group" aria-label="Default button group"> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> <br> <div class="btn-group btn-group-sm" role="group" aria-label="Small button group"> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> <br> <div class="btn-group btn-group-xs" role="group" aria-label="Extra-small button group"> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group btn-group-lg"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group btn-group-sm"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group btn-group-xs"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> <h2 id="btn-groups-nested">Nesting</h2> <p>Place a <code>.btn-group</code> within another <code>.btn-group</code> when you want dropdown menus mixed with a series of buttons.</p> <div class="bs-example" data-example-id="button-group-nesting"> <div class="btn-group" role="group" aria-label="Button group with nested dropdown"> <button type="button" class="btn btn-default">1</button> <button type="button" class="btn btn-default">2</button> <div class="btn-group" role="group"> <button id="btnGroupDrop1" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="btnGroupDrop1"> <li><a href="#">Dropdown link</a></li> <li><a href="#">Dropdown link</a></li> </ul> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>1<span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>2<span class="nt"></button></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Dropdown link<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Dropdown link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-groups-vertical">Vertical variation</h2> <p>Make a set of buttons appear vertically stacked rather than horizontally. <strong class="text-danger">Split button dropdowns are not supported here.</strong></p> <div class="bs-example" data-example-id="vertical-button-group"> <div class="btn-group-vertical" role="group" aria-label="Vertical button group"> <button type="button" class="btn btn-default">Button</button> <button type="button" class="btn btn-default">Button</button> <div class="btn-group" role="group"> <button id="btnGroupVerticalDrop1" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="btnGroupVerticalDrop1"> <li><a href="#">Dropdown link</a></li> <li><a href="#">Dropdown link</a></li> </ul> </div> <button type="button" class="btn btn-default">Button</button> <button type="button" class="btn btn-default">Button</button> <div class="btn-group" role="group"> <button id="btnGroupVerticalDrop2" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="btnGroupVerticalDrop2"> <li><a href="#">Dropdown link</a></li> <li><a href="#">Dropdown link</a></li> </ul> </div> <div class="btn-group" role="group"> <button id="btnGroupVerticalDrop3" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="btnGroupVerticalDrop3"> <li><a href="#">Dropdown link</a></li> <li><a href="#">Dropdown link</a></li> </ul> </div> <div class="btn-group" role="group"> <button id="btnGroupVerticalDrop4" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="btnGroupVerticalDrop4"> <li><a href="#">Dropdown link</a></li> <li><a href="#">Dropdown link</a></li> </ul> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group-vertical"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> ... <span class="nt"></div></span></code></pre></div> <h2 id="btn-groups-justified">Justified button groups</h2> <p>Make a group of buttons stretch at equal sizes to span the entire width of its parent. Also works with button dropdowns within the button group.</p> <div class="bs-callout bs-callout-warning" id="callout-btn-group-justified-dbl-border"> <h4>Handling borders</h4> <p>Due to the specific HTML and CSS used to justify buttons (namely <code>display: table-cell</code>), the borders between them are doubled. In regular button groups, <code>margin-left: -1px</code> is used to stack the borders instead of removing them. However, <code>margin</code> doesn't work with <code>display: table-cell</code>. As a result, depending on your customizations to Bootstrap, you may wish to remove or re-color the borders.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-btn-group-ie8-border"> <h4>IE8 and borders</h4> <p>Internet Explorer 8 doesn't render borders on buttons in a justified button group, whether it's on <code><a></code> or <code><button></code> elements. To get around that, wrap each button in another <code>.btn-group</code>.</p> <p>See <a href="https://github.com/twbs/bootstrap/issues/12476">#12476</a> for more information.</p> </div> <h4>With <code><a></code> elements</h4> <p>Just wrap a series of <code>.btn</code>s in <code>.btn-group.btn-group-justified</code>.</p> <div class="bs-example" data-example-id="simple-justified-button-group"> <div class="btn-group btn-group-justified" role="group" aria-label="Justified button group"> <a href="#" class="btn btn-default" role="button">Left</a> <a href="#" class="btn btn-default" role="button">Middle</a> <a href="#" class="btn btn-default" role="button">Right</a> </div> <br> <div class="btn-group btn-group-justified" role="group" aria-label="Justified button group with nested dropdown"> <a href="#" class="btn btn-default" role="button">Left</a> <a href="#" class="btn btn-default" role="button">Middle</a> <div class="btn-group" role="group"> <a href="#" class="btn btn-default dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> Dropdown <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group btn-group-justified"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> ... <span class="nt"></div></span></code></pre></div> <div class="bs-callout bs-callout-warning" id="callout-btn-group-anchor-btn"> <h4>Links acting as buttons</h4> <p>If the <code><a></code> elements are used to act as buttons � triggering in-page functionality, rather than navigating to another document or section within the current page � they should also be given an appropriate <code>role="button"</code>.</p> </div> <h4>With <code><button></code> elements</h4> <p>To use justified button groups with <code><button></code> elements, <strong class="text-danger">you must wrap each button in a button group</strong>. Most browsers don't properly apply our CSS for justification to <code><button></code> elements, but since we support button dropdowns, we can work around that.</p> <div class="bs-example" data-example-id="button-tag-button-group-justified"> <div class="btn-group btn-group-justified" role="group" aria-label="Justified button group"> <div class="btn-group" role="group"> <button type="button" class="btn btn-default">Left</button> </div> <div class="btn-group" role="group"> <button type="button" class="btn btn-default">Middle</button> </div> <div class="btn-group" role="group"> <button type="button" class="btn btn-default">Right</button> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group btn-group-justified"</span> <span class="na">role=</span><span class="s">"group"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Left<span class="nt"></button></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Middle<span class="nt"></button></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span> <span class="na">role=</span><span class="s">"group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Right<span class="nt"></button></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="btn-dropdowns" class="page-header">Button dropdowns</h1> <p class="lead">Use any button to trigger a dropdown menu by placing it within a <code>.btn-group</code> and providing the proper menu markup.</p> <div class="bs-callout bs-callout-danger" id="callout-btndropdown-dependency"> <h4>Plugin dependency</h4> <p>Button dropdowns require the <a href="../javascript/#dropdowns">dropdown plugin</a> to be included in your version of Bootstrap.</p> </div> <h2 id="btn-dropdowns-single">Single button dropdowns</h2> <p>Turn a button into a dropdown toggle with some basic markup changes.</p> <div class="bs-example" data-example-id="single-button-dropdown"> <div class="btn-group"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Default <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Primary <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Success <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Info <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Warning <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Danger <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- Single button --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Action <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-dropdowns-split">Split button dropdowns</h2> <p>Similarly, create split button dropdowns with the same markup changes, only with a separate button.</p> <div class="bs-example" data-example-id="split-button-dropdown"> <div class="btn-group"> <button type="button" class="btn btn-default">Default</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-primary">Primary</button> <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-success">Success</button> <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-info">Info</button> <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-warning">Warning</button> <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group"> <button type="button" class="btn btn-danger">Danger</button> <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- Split button --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-danger"</span><span class="nt">></span>Action<span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-danger dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>Toggle Dropdown<span class="nt"></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-dropdowns-sizing">Sizing</h2> <p>Button dropdowns work with buttons of all sizes.</p> <div class="bs-example" data-example-id="button-dropdown-sizing"> <div class="btn-toolbar" role="toolbar"> <div class="btn-group"> <button class="btn btn-default btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false"> Large button <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div><!-- /btn-toolbar --> <div class="btn-toolbar" role="toolbar"> <div class="btn-group"> <button class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false"> Small button <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div><!-- /btn-toolbar --> <div class="btn-toolbar" role="toolbar"> <div class="btn-group"> <button class="btn btn-default btn-xs dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false"> Extra small button <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div><!-- /btn-toolbar --> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- Large button group --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default btn-lg dropdown-toggle"</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Large button <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"></div></span> <span class="c"><!-- Small button group --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default btn-sm dropdown-toggle"</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Small button <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"></div></span> <span class="c"><!-- Extra small button group --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default btn-xs dropdown-toggle"</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Extra small button <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> <h2 id="btn-dropdowns-dropup">Dropup variation</h2> <p>Trigger dropdown menus above elements by adding <code>.dropup</code> to the parent.</p> <div class="bs-example" data-example-id="button-dropdown-dropup"> <div class="btn-toolbar" role="toolbar"> <div class="btn-group dropup"> <button type="button" class="btn btn-default">Dropup</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <div class="btn-group dropup"> <button type="button" class="btn btn-primary">Right dropup</button> <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu dropdown-menu-right" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"btn-group dropup"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Dropup<span class="nt"></button></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>Toggle Dropdown<span class="nt"></span></span> <span class="nt"></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="c"><!-- Dropdown menu links --></span> <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="input-groups" class="page-header">Input groups</h1> <p class="lead">Extend form controls by adding text or buttons before, after, or on both sides of any text-based <code><input></code>. Use <code>.input-group</code> with an <code>.input-group-addon</code> to prepend or append elements to a single <code>.form-control</code>.</p> <div class="bs-callout bs-callout-danger" id="callout-inputgroup-text-input-only"> <h4>Textual <code><input></code>s only</h4> <p>Avoid using <code><select></code> elements here as they cannot be fully styled in WebKit browsers.</p> <p>Avoid using <code><textarea></code> elements here as their <code>rows</code> attribute will not be respected in some cases.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-inputgroup-container-body"> <h4>Tooltips & popovers in input groups require special setting</h4> <p>When using tooltips or popovers on elements within an <code>.input-group</code>, you'll have to specify the option <code>container: 'body'</code> to avoid unwanted side effects (such as the element growing wider and/or losing its rounded corners when the tooltip or popover is triggered).</p> </div> <div class="bs-callout bs-callout-warning" id="callout-inputgroup-dont-mix"> <h4>Don't mix with other components</h4> <p>Do not mix form groups or grid column classes directly with input groups. Instead, nest the input group inside of the form group or grid-related element.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-inputgroup-form-labels"> <h4>Always add labels</h4> <p>Screen readers will have trouble with your forms if you don't include a label for every input. For these input groups, ensure that any additional label or functionality is conveyed to assistive technologies.</p> <p>The exact technique to be used (<code><label></code> elements hidden using the <code>.sr-only</code> class, or use of the <code>aria-label</code>, <code>aria-labelledby</code>, <code>aria-describedby</code>, <code>title</code> or <code>placeholder</code> attribute) and what additional information will need to be conveyed will vary depending on the exact type of interface widget you're implementing. The examples in this section provide a few suggested, case-specific approaches.</p> </div> <h2 id="input-groups-basic">Basic example</h2> <p>Place one add-on or button on either side of an input. You may also place one on both sides of an input.</p> <p><strong class="text-danger">We do not support multiple add-ons on a single side.</strong></p> <p><strong class="text-danger">We do not support multiple form-controls in a single input group.</strong></p> <form class="bs-example bs-example-form" data-example-id="simple-input-groups"> <div class="input-group"> <span class="input-group-addon" id="basic-addon1">@</span> <input type="text" class="form-control" placeholder="Username" aria-describedby="basic-addon1"> </div> <br> <div class="input-group"> <input type="text" class="form-control" placeholder="Recipient's username" aria-describedby="basic-addon2"> <span class="input-group-addon" id="basic-addon2">@example.com</span> </div> <br> <div class="input-group"> <span class="input-group-addon">$</span> <input type="text" class="form-control" aria-label="Amount (to the nearest dollar)"> <span class="input-group-addon">.00</span> </div> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span> <span class="na">id=</span><span class="s">"basic-addon1"</span><span class="nt">></span>@<span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Username"</span> <span class="na">aria-describedby=</span><span class="s">"basic-addon1"</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Recipient's username"</span> <span class="na">aria-describedby=</span><span class="s">"basic-addon2"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span> <span class="na">id=</span><span class="s">"basic-addon2"</span><span class="nt">></span>@example.com<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span><span class="nt">></span>$<span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"Amount (to the nearest dollar)"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span><span class="nt">></span>.00<span class="nt"></span></span> <span class="nt"></div></span></code></pre></div> <h2 id="input-groups-sizing">Sizing</h2> <p>Add the relative form sizing classes to the <code>.input-group</code> itself and contents within will automatically resize�no need for repeating the form control size classes on each element.</p> <form class="bs-example bs-example-form" data-example-id="input-group-sizing"> <div class="input-group input-group-lg"> <span class="input-group-addon" id="sizing-addon1">@</span> <input type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon1"> </div> <br> <div class="input-group"> <span class="input-group-addon" id="sizing-addon2">@</span> <input type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon2"> </div> <br> <div class="input-group input-group-sm"> <span class="input-group-addon" id="sizing-addon3">@</span> <input type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon3"> </div> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group input-group-lg"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span> <span class="na">id=</span><span class="s">"sizing-addon1"</span><span class="nt">></span>@<span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Username"</span> <span class="na">aria-describedby=</span><span class="s">"sizing-addon1"</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span> <span class="na">id=</span><span class="s">"sizing-addon2"</span><span class="nt">></span>@<span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Username"</span> <span class="na">aria-describedby=</span><span class="s">"sizing-addon2"</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group input-group-sm"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span> <span class="na">id=</span><span class="s">"sizing-addon3"</span><span class="nt">></span>@<span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Username"</span> <span class="na">aria-describedby=</span><span class="s">"sizing-addon3"</span><span class="nt">></span> <span class="nt"></div></span></code></pre></div> <h2 id="input-groups-checkboxes-radios">Checkboxes and radio addons</h2> <p>Place any checkbox or radio option within an input group's addon instead of text.</p> <form class="bs-example bs-example-form" data-example-id="input-group-with-checkbox-radio"> <div class="row"> <div class="col-lg-6"> <div class="input-group"> <span class="input-group-addon"> <input type="checkbox" aria-label="Checkbox for following text input"> </span> <input type="text" class="form-control" aria-label="Text input with checkbox"> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> <div class="col-lg-6"> <div class="input-group"> <span class="input-group-addon"> <input type="radio" aria-label="Radio button for following text input"> </span> <input type="text" class="form-control" aria-label="Text input with radio button"> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> </div><!-- /.row --> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-addon"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"radio"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"></div></span><span class="c"><!-- /.row --></span></code></pre></div> <h2 id="input-groups-buttons">Button addons</h2> <p>Buttons in input groups are a bit different and require one extra level of nesting. Instead of <code>.input-group-addon</code>, you'll need to use <code>.input-group-btn</code> to wrap the buttons. This is required due to default browser styles that cannot be overridden.</p> <form class="bs-example bs-example-form" data-example-id="input-group-with-button"> <div class="row"> <div class="col-lg-6"> <div class="input-group"> <span class="input-group-btn"> <button class="btn btn-default" type="button">Go!</button> </span> <input type="text" class="form-control" placeholder="Search for..."> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> <div class="col-lg-6"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-btn"> <button class="btn btn-default" type="button">Go!</button> </span> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> </div><!-- /.row --> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">></span>Go!<span class="nt"></button></span> <span class="nt"></span></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Search for..."</span><span class="nt">></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Search for..."</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-default"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">></span>Go!<span class="nt"></button></span> <span class="nt"></span></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"></div></span><span class="c"><!-- /.row --></span></code></pre></div> <h2 id="input-groups-buttons-dropdowns">Buttons with dropdowns</h2> <p></p> <form class="bs-example bs-example-form" data-example-id="input-group-dropdowns"> <div class="row"> <div class="col-lg-6"> <div class="input-group"> <div class="input-group-btn"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Action <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> <input type="text" class="form-control" aria-label="Text input with dropdown button"> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> <div class="col-lg-6"> <div class="input-group"> <input type="text" class="form-control" aria-label="Text input with dropdown button"> <div class="input-group-btn"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Action <span class="caret"></span></button> <ul class="dropdown-menu dropdown-menu-right" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> </div><!-- /.row --> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span>Action <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span><span class="c"><!-- /btn-group --></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-lg-6"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span>Action <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></button></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu dropdown-menu-right"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></div></span><span class="c"><!-- /btn-group --></span> <span class="nt"></div></span><span class="c"><!-- /input-group --></span> <span class="nt"></div></span><span class="c"><!-- /.col-lg-6 --></span> <span class="nt"></div></span><span class="c"><!-- /.row --></span></code></pre></div> <h2 id="input-groups-buttons-segmented">Segmented buttons</h2> <form class="bs-example bs-example-form" data-example-id="input-group-segmented-buttons"> <div class="row"> <div class="col-lg-6"> <div class="input-group"> <div class="input-group-btn"> <button type="button" class="btn btn-default">Action</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div> <input type="text" class="form-control" aria-label="Text input with segmented button dropdown"> </div><!-- /.input-group --> </div><!-- /.col-lg-6 --> <div class="col-lg-6"> <div class="input-group"> <input type="text" class="form-control" aria-label="Text input with segmented button dropdown"> <div class="input-group-btn"> <button type="button" class="btn btn-default">Action</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu dropdown-menu-right" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div> </div><!-- /.input-group --> </div><!-- /.col-lg-6 --> </div><!-- /.row --> </form> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="c"><!-- Button and dropdown menu --></span> <span class="nt"></div></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">aria-label=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"input-group-btn"</span><span class="nt">></span> <span class="c"><!-- Button and dropdown menu --></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="nav" class="page-header">Navs</h1> <p class="lead">Navs available in Bootstrap have shared markup, starting with the base <code>.nav</code> class, as well as shared states. Swap modifier classes to switch between each style.</p> <div class="bs-callout bs-callout-info" id="callout-navs-tabs-plugin"> <h4>Using navs for tab panels requires JavaScript tabs plugin</h4> <p>For tabs with tabbable areas, you must use the <a href="../javascript/#tabs">tabs JavaScript plugin</a>. The markup will also require additional <code>role</code> and ARIA attributes � see the plugin's <a href="../javascript/#tabs-usage">example markup</a> for further details.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-navs-accessibility"> <h4>Make navs used as navigation accessible</h4> <p>If you are using navs to provide a navigation bar, be sure to add a <code>role="navigation"</code> to the most logical parent container of the <code><ul></code>, or wrap a <code><nav></code> element around the whole navigation. Do not add the role to the <code><ul></code> itself, as this would prevent it from being announced as an actual list by assistive technologies.</p> </div> <h2 id="nav-tabs">Tabs</h2> <p>Note the <code>.nav-tabs</code> class requires the <code>.nav</code> base class.</p> <div class="bs-example" data-example-id="simple-nav-tabs"> <ul class="nav nav-tabs"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-tabs"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Home<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Profile<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Messages<span class="nt"></a></li></span> <span class="nt"></ul></span></code></pre></div> <h2 id="nav-pills">Pills</h2> <p>Take that same HTML, but use <code>.nav-pills</code> instead:</p> <div class="bs-example" data-example-id="simple-nav-pills"> <ul class="nav nav-pills"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Home<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Profile<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Messages<span class="nt"></a></li></span> <span class="nt"></ul></span></code></pre></div> <p>Pills are also vertically stackable. Just add <code>.nav-stacked</code>.</p> <div class="bs-example" data-example-id="simple-nav-stacked"> <ul class="nav nav-pills nav-stacked nav-pills-stacked-example"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills nav-stacked"</span><span class="nt">></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="nav-justified">Justified</h2> <p>Easily make tabs or pills equal widths of their parent at screens wider than 768px with <code>.nav-justified</code>. On smaller screens, the nav links are stacked.</p> <p><strong class="text-danger">Justified navbar nav links are currently not supported.</strong></p> <div class="bs-callout bs-callout-warning" id="callout-navs-justified-safari"> <h4>Safari and responsive justified navs</h4> <p>As of v8.0, Safari exhibits a bug in which resizing your browser horizontally causes rendering errors in the justified nav that are cleared upon refreshing. This bug is also shown in the <a href="../examples/justified-nav/">justified nav example</a>.</p> </div> <div class="bs-example" data-example-id="simple-nav-justified"> <ul class="nav nav-tabs nav-justified"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> </ul> <br> <ul class="nav nav-pills nav-justified"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-tabs nav-justified"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills nav-justified"</span><span class="nt">></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="nav-disabled-links">Disabled links</h2> <p>For any nav component (tabs or pills), add <code>.disabled</code> for <strong>gray links and no hover effects</strong>.</p> <div class="bs-callout bs-callout-warning" id="callout-navs-anchor-disabled"> <h4>Link functionality not impacted</h4> <p>This class will only change the <code><a></code>'s appearance, not its functionality. Use custom JavaScript to disable links here.</p> </div> <div class="bs-example" data-example-id="disabled-nav-link"> <ul class="nav nav-pills"> <li role="presentation"><a href="#">Clickable link</a></li> <li role="presentation"><a href="#">Clickable link</a></li> <li role="presentation" class="disabled"><a href="#">Disabled link</a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills"</span><span class="nt">></span> ... <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"disabled"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Disabled link<span class="nt"></a></li></span> ... <span class="nt"></ul></span></code></pre></div> <h2 id="nav-dropdowns">Using dropdowns</h2> <p>Add dropdown menus with a little extra HTML and the <a href="../javascript/#dropdowns">dropdowns JavaScript plugin</a>.</p> <h3>Tabs with dropdowns</h3> <div class="bs-example" data-example-id="nav-tabs-with-dropdown"> <ul class="nav nav-tabs"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Help</a></li> <li role="presentation" class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-expanded="false"> Dropdown <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-tabs"</span><span class="nt">></span> ... <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"dropdown"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">class=</span><span class="s">"dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">role=</span><span class="s">"button"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></a></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"></li></span> ... <span class="nt"></ul></span></code></pre></div> <h3>Pills with dropdowns</h3> <div class="bs-example" data-example-id="nav-pills-with-dropdown"> <ul class="nav nav-pills"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Help</a></li> <li role="presentation" class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-expanded="false"> Dropdown <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills"</span><span class="nt">></span> ... <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"dropdown"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">class=</span><span class="s">"dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">role=</span><span class="s">"button"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span> Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></span> <span class="nt"></a></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> ... <span class="nt"></ul></span> <span class="nt"></li></span> ... <span class="nt"></ul></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="navbar" class="page-header">Navbar</h1> <h2 id="navbar-default">Default navbar</h2> <p>Navbars are responsive meta components that serve as navigation headers for your application or site. They begin collapsed (and are toggleable) in mobile views and become horizontal as the available viewport width increases.</p> <p><strong class="text-danger">Justified navbar nav links are currently not supported.</strong></p> <div class="bs-callout bs-callout-warning" id="callout-navbar-overflow"> <h4>Overflowing content</h4> <p>Since Bootstrap doesn't know how much space the content in your navbar needs, you might run into issues with content wrapping into a second row. To resolve this, you can:</p> <ol type="a"> <li>Reduce the amount or width of navbar items.</li> <li>Hide certain navbar items at certain screen sizes using <a href="../css/#responsive-utilities">responsive utility classes</a>.</li> <li>Change the point at which your navbar switches between collapsed and horizontal mode. Customize the <code>@grid-float-breakpoint</code> variable or add your own media query.</li> </ol> </div> <div class="bs-callout bs-callout-danger" id="callout-navbar-js"> <h4>Requires JavaScript plugin</h4> <p>If JavaScript is disabled and the viewport is narrow enough that the navbar collapses, it will be impossible to expand the navbar and view the content within the <code>.navbar-collapse</code>.</p> <p>The responsive navbar requires the <a href="../javascript/#collapse">collapse plugin</a> to be included in your version of Bootstrap.</p> </div> <div class="bs-callout bs-callout-info" id="callout-navbar-breakpoint"> <h4>Changing the collapsed mobile navbar breakpoint</h4> <p>The navbar collapses into its vertical mobile view when the viewport is narrower than <code>@grid-float-breakpoint</code>, and expands into its horizontal non-mobile view when the viewport is at least <code>@grid-float-breakpoint</code> in width. Adjust this variable in the Less source to control when the navbar collapses/expands. The default value is <code>768px</code> (the smallest "small" or "tablet" screen).</p> </div> <div class="bs-callout bs-callout-warning" id="callout-navbar-role"> <h4>Make navbars accessible</h4> <p>Be sure to use a <code><nav></code> element or, if using a more generic element such as a <code><div></code>, add a <code>role="navigation"</code> to every navbar to explicitly identify it as a landmark region for users of assistive technologies.</p> </div> <div class="bs-example" data-example-id="default-navbar"> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> <li class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left" role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container-fluid"</span><span class="nt">></span> <span class="c"><!-- Brand and toggle get grouped for better mobile display --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-header"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"navbar-toggle collapsed"</span> <span class="na">data-toggle=</span><span class="s">"collapse"</span> <span class="na">data-target=</span><span class="s">"#bs-example-navbar-collapse-1"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>Toggle navigation<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"icon-bar"</span><span class="nt">></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"icon-bar"</span><span class="nt">></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"icon-bar"</span><span class="nt">></span></span> <span class="nt"></button></span> <span class="nt"><a</span> <span class="na">class=</span><span class="s">"navbar-brand"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Brand<span class="nt"></a></span> <span class="nt"></div></span> <span class="c"><!-- Collect the nav links, forms, and other content for toggling --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"collapse navbar-collapse"</span> <span class="na">id=</span><span class="s">"bs-example-navbar-collapse-1"</span><span class="nt">></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav navbar-nav"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Link <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>(current)<span class="nt"></span></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Link<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"dropdown"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">role=</span><span class="s">"button"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span>Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></a></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>One more separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></li></span> <span class="nt"></ul></span> <span class="nt"><form</span> <span class="na">class=</span><span class="s">"navbar-form navbar-left"</span> <span class="na">role=</span><span class="s">"search"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Search"</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Submit<span class="nt"></button></span> <span class="nt"></form></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav navbar-nav navbar-right"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Link<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"dropdown"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"dropdown-toggle"</span> <span class="na">data-toggle=</span><span class="s">"dropdown"</span> <span class="na">role=</span><span class="s">"button"</span> <span class="na">aria-expanded=</span><span class="s">"false"</span><span class="nt">></span>Dropdown <span class="nt"><span</span> <span class="na">class=</span><span class="s">"caret"</span><span class="nt">></span></a></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"dropdown-menu"</span> <span class="na">role=</span><span class="s">"menu"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Another action<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Something else here<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"divider"</span><span class="nt">></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Separated link<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></li></span> <span class="nt"></ul></span> <span class="nt"></div></span><span class="c"><!-- /.navbar-collapse --></span> <span class="nt"></div></span><span class="c"><!-- /.container-fluid --></span> <span class="nt"></nav></span></code></pre></div> <h2 id="navbar-brand-image">Brand image</h2> <p>Replace the navbar brand with your own image by swapping the text for an <code><img></code>. Since the <code>.navbar-brand</code> has its own padding and height, you may need to override some CSS depending on your image.</p> <div class="bs-example" data-example-id="navbar-with-image-brand"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#"> <img alt="Brand" width="20" height="20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAA81BMVEX///9VPnxWPXxWPXxWPXxWPXxWPXxWPXz///9hSYT6+vuFc6BXPn37+vz8+/z9/f2LeqWMe6aOfqiTg6uXiK5bQ4BZQX9iS4VdRYFdRYJfSINuWI5vWY9xXJF0YJR3Y5Z4ZZd5ZZd6Z5h9apq0qcW1qsW1q8a6sMqpnLyrn76tocCvpMGwpMJoUoprVYxeRoJjS4abjLGilLemmbrDutDFvdLPx9nX0eDa1OLb1uPd1+Td2OXe2eXh3Ofj3+nk4Orl4evp5u7u7PLv7fPx7/T08vb08/f19Pf29Pj39vn6+fuEcZ9YP35aQn/8/P1ZQH5fR4PINAOdAAAAB3RSTlMAIWWOw/P002ipnAAAAPhJREFUeF6NldWOhEAUBRvtRsfdfd3d3e3/v2ZPmGSWZNPDqScqqaSBSy4CGJbtSi2ubRkiwXRkBo6ZdJIApeEwoWMIS1JYwuZCW7hc6ApJkgrr+T/eW1V9uKXS5I5GXAjW2VAV9KFfSfgJpk+w4yXhwoqwl5AIGwp4RPgdK3XNHD2ETYiwe6nUa18f5jYSxle4vulw7/EtoCdzvqkPv3bn7M0eYbc7xFPXzqCrRCgH0Hsm/IjgTSb04W0i7EGjz+xw+wR6oZ1MnJ9TWrtToEx+4QfcZJ5X6tnhw+nhvqebdVhZUJX/oFcKvaTotUcvUnY188ue/n38AunzPPE8yg7bAAAAAElFTkSuQmCC"> </a> </div> </div> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container-fluid"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"navbar-header"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">class=</span><span class="s">"navbar-brand"</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">alt=</span><span class="s">"Brand"</span> <span class="na">src=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"></nav></span></code></pre></div> <h2 id="navbar-forms">Forms</h2> <p>Place form content within <code>.navbar-form</code> for proper vertical alignment and collapsed behavior in narrow viewports. Use the alignment options to decide where it resides within the navbar content.</p> <p>As a heads up, <code>.navbar-form</code> shares much of its code with <code>.form-inline</code> via mixin. <strong class="text-danger">Some form controls, like input groups, may require fixed widths to be show up properly within a navbar.</strong></p> <div class="bs-example" data-example-id="navbar-form"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-2"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-2"> <form class="navbar-form navbar-left" role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> </div> </div> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><form</span> <span class="na">class=</span><span class="s">"navbar-form navbar-left"</span> <span class="na">role=</span><span class="s">"search"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">class=</span><span class="s">"form-control"</span> <span class="na">placeholder=</span><span class="s">"Search"</span><span class="nt">></span> <span class="nt"></div></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span><span class="nt">></span>Submit<span class="nt"></button></span> <span class="nt"></form></span></code></pre></div> <div class="bs-callout bs-callout-warning" id="callout-navbar-mobile-caveats"> <h4>Mobile device caveats</h4> <p>There are some caveats regarding using form controls within fixed elements on mobile devices. <a href="../getting-started/#support-fixed-position-keyboards">See our browser support docs</a> for details.</p> </div> <div class="bs-callout bs-callout-warning" id="callout-navbar-form-labels"> <h4>Always add labels</h4> <p>Screen readers will have trouble with your forms if you don't include a label for every input. For these inline forms, you can hide the labels using the <code>.sr-only</code> class. There are further alternative methods of providing a label for assistive technologies, such as the <code>aria-label</code>, <code>aria-labelledby</code> or <code>title</code> attribute. If none of these is present, screen readers may resort to using the <code>placeholder</code> attribute, if present, but note that use of <code>placeholder</code> as a replacement for other labelling methods is not advised.</p> </div> <h2 id="navbar-buttons">Buttons</h2> <p>Add the <code>.navbar-btn</code> class to <code><button></code> elements not residing in a <code><form></code> to vertically center them in the navbar.</p> <div class="bs-example" data-example-id="navbar-button"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-3"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-3"> <button type="button" class="btn btn-default navbar-btn">Sign in</button> </div> </div> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"btn btn-default navbar-btn"</span><span class="nt">></span>Sign in<span class="nt"></button></span></code></pre></div> <div class="bs-callout bs-callout-warning" id="callout-navbar-btn-context"> <h4>Context-specific usage</h4> <p>Like the standard <a href="../css/#buttons">button classes</a>, <code>.navbar-btn</code> can be used on <code><a></code> and <code><input></code> elements. However, neither <code>.navbar-btn</code> nor the standard button classes should be used on <code><a></code> elements within <code>.navbar-nav</code>.</p> </div> <h2 id="navbar-text">Text</h2> <p>Wrap strings of text in an element with <code>.navbar-text</code>, usually on a <code><p></code> tag for proper leading and color.</p> <div class="bs-example" data-example-id="navbar-text"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-4"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-4"> <p class="navbar-text">Signed in as Mark Otto</p> </div> </div> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><p</span> <span class="na">class=</span><span class="s">"navbar-text"</span><span class="nt">></span>Signed in as Mark Otto<span class="nt"></p></span></code></pre></div> <h2 id="navbar-links">Non-nav links</h2> <p>For folks using standard links that are not within the regular navbar navigation component, use the <code>.navbar-link</code> class to add the proper colors for the default and inverse navbar options.</p> <div class="bs-example" data-example-id="navbar-link"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-5"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-5"> <p class="navbar-text navbar-right">Signed in as <a href="#" class="navbar-link">Mark Otto</a></p> </div> </div> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><p</span> <span class="na">class=</span><span class="s">"navbar-text navbar-right"</span><span class="nt">></span>Signed in as <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"navbar-link"</span><span class="nt">></span>Mark Otto<span class="nt"></a></p></span></code></pre></div> <h2 id="navbar-component-alignment">Component alignment</h2> <p>Align nav links, forms, buttons, or text, using the <code>.navbar-left</code> or <code>.navbar-right</code> utility classes. Both classes will add a CSS float in the specified direction. For example, to align nav links, put them in a separate <code><ul></code> with the respective utility class applied.</p> <p>These classes are mixin-ed versions of <code>.pull-left</code> and <code>.pull-right</code>, but they're scoped to media queries for easier handling of navbar components across device sizes.</p> <div class="bs-callout bs-callout-warning" id="callout-navbar-right-align"> <h4>Right aligning multiple components</h4> <p>Navbars currently have a limitation with multiple <code>.navbar-right</code> classes. To properly space content, we use negative margin on the last <code>.navbar-right</code> element. When there are multiple elements using that class, these margins don't work as intended.</p> <p>We'll revisit this when we can rewrite that component in v4.</p> </div> <h2 id="navbar-fixed-top">Fixed to top</h2> <p>Add <code>.navbar-fixed-top</code> and include a <code>.container</code> or <code>.container-fluid</code> to center and pad navbar content.</p> <div class="bs-example bs-navbar-top-example" data-example-id="navbar-fixed-to-top"> <nav class="navbar navbar-default navbar-fixed-top"> <!-- We use the fluid option here to avoid overriding the fixed width of a normal container within the narrow content columns. --> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-6"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> </div><!-- /.navbar-collapse --> </div> </nav> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-default navbar-fixed-top"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span> ... <span class="nt"></div></span> <span class="nt"></nav></span></code></pre></div> <div class="bs-callout bs-callout-danger" id="callout-navbar-fixed-top-padding"> <h4>Body padding required</h4> <p>The fixed navbar will overlay your other content, unless you add <code>padding</code> to the top of the <code><body></code>. Try out your own values or use our snippet below. Tip: By default, the navbar is 50px high.</p> <div class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="nt">body</span> <span class="p">{</span> <span class="nl">padding-top</span><span class="p">:</span> <span class="m">70px</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>Make sure to include this <strong>after</strong> the core Bootstrap CSS.</p> </div> <h2 id="navbar-fixed-bottom">Fixed to bottom</h2> <p>Add <code>.navbar-fixed-bottom</code> and include a <code>.container</code> or <code>.container-fluid</code> to center and pad navbar content.</p> <div class="bs-example bs-navbar-bottom-example" data-example-id="navbar-fixed-to-bottom"> <nav class="navbar navbar-default navbar-fixed-bottom"> <!-- We use the fluid option here to avoid overriding the fixed width of a normal container within the narrow content columns. --> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-7"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-7"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> </div><!-- /.navbar-collapse --> </div> </nav> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-default navbar-fixed-bottom"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span> ... <span class="nt"></div></span> <span class="nt"></nav></span></code></pre></div> <div class="bs-callout bs-callout-danger" id="callout-navbar-fixed-bottom-padding"> <h4>Body padding required</h4> <p>The fixed navbar will overlay your other content, unless you add <code>padding</code> to the bottom of the <code><body></code>. Try out your own values or use our snippet below. Tip: By default, the navbar is 50px high.</p> <div class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="nt">body</span> <span class="p">{</span> <span class="nl">padding-bottom</span><span class="p">:</span> <span class="m">70px</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>Make sure to include this <strong>after</strong> the core Bootstrap CSS.</p> </div> <h2 id="navbar-static-top">Static top</h2> <p>Create a full-width navbar that scrolls away with the page by adding <code>.navbar-static-top</code> and include a <code>.container</code> or <code>.container-fluid</code> to center and pad navbar content.</p> <p>Unlike the <code>.navbar-fixed-*</code> classes, you do not need to change any padding on the <code>body</code>.</p> <div class="bs-example bs-navbar-top-example" data-example-id="navbar-static-top"> <nav class="navbar navbar-default navbar-static-top"> <!-- We use the fluid option here to avoid overriding the fixed width of a normal container within the narrow content columns. --> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-8"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-8"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> </div><!-- /.navbar-collapse --> </div> </nav> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-default navbar-static-top"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span> ... <span class="nt"></div></span> <span class="nt"></nav></span></code></pre></div> <h2 id="navbar-inverted">Inverted navbar</h2> <p>Modify the look of the navbar by adding <code>.navbar-inverse</code>.</p> <div class="bs-example" data-example-id="inverted-navbar"> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-9"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-9"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </div><!-- /example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav</span> <span class="na">class=</span><span class="s">"navbar navbar-inverse"</span><span class="nt">></span> ... <span class="nt"></nav></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="breadcrumbs" class="page-header">Breadcrumbs</h1> <p class="lead">Indicate the current page's location within a navigational hierarchy.</p> <p>Separators are automatically added in CSS through <code>:before</code> and <code>content</code>.</p> <div class="bs-example" data-example-id="simple-breadcrumbs"> <ol class="breadcrumb"> <li class="active">Home</li> </ol> <ol class="breadcrumb"> <li><a href="#">Home</a></li> <li class="active">Library</li> </ol> <ol class="breadcrumb"> <li><a href="#">Home</a></li> <li><a href="#">Library</a></li> <li class="active">Data</li> </ol> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ol</span> <span class="na">class=</span><span class="s">"breadcrumb"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Home<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Library<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">></span>Data<span class="nt"></li></span> <span class="nt"></ol></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="pagination" class="page-header">Pagination</h1> <p class="lead">Provide pagination links for your site or app with the multi-page pagination component, or the simpler <a href="#pagination-pager">pager alternative</a>.</p> <h2 id="pagination-default">Default pagination</h2> <p>Simple pagination inspired by Rdio, great for apps and search results. The large block is hard to miss, easily scalable, and provides large click areas.</p> <div class="bs-example" data-example-id="simple-pagination"> <nav> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pagination"</span><span class="nt">></span> <span class="nt"><li></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">aria-label=</span><span class="s">"Previous"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&laquo;</span><span class="nt"></span></span> <span class="nt"></a></span> <span class="nt"></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>1<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>2<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>3<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>4<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>5<span class="nt"></a></li></span> <span class="nt"><li></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">aria-label=</span><span class="s">"Next"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&raquo;</span><span class="nt"></span></span> <span class="nt"></a></span> <span class="nt"></li></span> <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> <h3>Disabled and active states</h3> <p>Links are customizable for different circumstances. Use <code>.disabled</code> for unclickable links and <code>.active</code> to indicate the current page.</p> <div class="bs-example" data-example-id="disabled-active-pagination"> <nav> <ul class="pagination"> <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li> <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pagination"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"disabled"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">aria-label=</span><span class="s">"Previous"</span><span class="nt">><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&laquo;</span><span class="nt"></span></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>1 <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>(current)<span class="nt"></span></a></li></span> ... <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> <p>You can optionally swap out active or disabled anchors for <code><span></code>, or omit the anchor in the case of the previous/next arrows, to remove click functionality while retaining intended styles.</p> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pagination"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"disabled"</span><span class="nt">></span> <span class="nt"><span></span> <span class="nt"><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&laquo;</span><span class="nt"></span></span> <span class="nt"></span></span> <span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">></span> <span class="nt"><span></span>1 <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>(current)<span class="nt"></span></span></span> <span class="nt"></li></span> ... <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> <h3>Sizing</h3> <p>Fancy larger or smaller pagination? Add <code>.pagination-lg</code> or <code>.pagination-sm</code> for additional sizes.</p> <div class="bs-example" data-example-id="pagination-sizing"> <nav> <ul class="pagination pagination-lg"> <li><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li> </ul> </nav> <nav> <ul class="pagination"> <li><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li> </ul> </nav> <nav> <ul class="pagination pagination-sm"> <li><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav><ul</span> <span class="na">class=</span><span class="s">"pagination pagination-lg"</span><span class="nt">></span>...<span class="nt"></ul></nav></span> <span class="nt"><nav><ul</span> <span class="na">class=</span><span class="s">"pagination"</span><span class="nt">></span>...<span class="nt"></ul></nav></span> <span class="nt"><nav><ul</span> <span class="na">class=</span><span class="s">"pagination pagination-sm"</span><span class="nt">></span>...<span class="nt"></ul></nav></span></code></pre></div> <h2 id="pagination-pager">Pager</h2> <p>Quick previous and next links for simple pagination implementations with light markup and styles. It's great for simple sites like blogs or magazines.</p> <h3>Default example</h3> <p>By default, the pager centers links.</p> <div class="bs-example" data-example-id="simple-pager"> <nav> <ul class="pager"> <li><a href="#">Previous</a></li> <li><a href="#">Next</a></li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pager"</span><span class="nt">></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Previous<span class="nt"></a></li></span> <span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Next<span class="nt"></a></li></span> <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> <h3>Aligned links</h3> <p>Alternatively, you can align each link to the sides:</p> <div class="bs-example" data-example-id="aligned-pager-links"> <nav> <ul class="pager"> <li class="previous"><a href="#"><span aria-hidden="true">←</span> Older</a></li> <li class="next"><a href="#">Newer <span aria-hidden="true">→</span></a></li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pager"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"previous"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&larr;</span><span class="nt"></span></span> Older<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"next"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Newer <span class="nt"><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&rarr;</span><span class="nt"></span></a></li></span> <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> <h3>Optional disabled state</h3> <p>Pager links also use the general <code>.disabled</code> utility class from the pagination.</p> <div class="bs-example" data-example-id="disabled-pager"> <nav> <ul class="pager"> <li class="previous disabled"><a href="#"><span aria-hidden="true">←</span> Older</a></li> <li class="next"><a href="#">Newer <span aria-hidden="true">→</span></a></li> </ul> </nav> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><nav></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"pager"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"previous disabled"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&larr;</span><span class="nt"></span></span> Older<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"next"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Newer <span class="nt"><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&rarr;</span><span class="nt"></span></a></li></span> <span class="nt"></ul></span> <span class="nt"></nav></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="labels" class="page-header">Labels</h1> <h2>Example</h2> <div class="bs-example" data-example-id="labels-in-headings"> <h1>Example heading <span class="label label-default">New</span></h1> <h2>Example heading <span class="label label-default">New</span></h2> <h3>Example heading <span class="label label-default">New</span></h3> <h4>Example heading <span class="label label-default">New</span></h4> <h5>Example heading <span class="label label-default">New</span></h5> <h6>Example heading <span class="label label-default">New</span></h6> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><h3></span>Example heading <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-default"</span><span class="nt">></span>New<span class="nt"></span></h3></span></code></pre></div> <h2>Available variations</h2> <p>Add any of the below mentioned modifier classes to change the appearance of a label.</p> <div class="bs-example" data-example-id="label-variants"> <span class="label label-default">Default</span> <span class="label label-primary">Primary</span> <span class="label label-success">Success</span> <span class="label label-info">Info</span> <span class="label label-warning">Warning</span> <span class="label label-danger">Danger</span> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-default"</span><span class="nt">></span>Default<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-primary"</span><span class="nt">></span>Primary<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-success"</span><span class="nt">></span>Success<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-info"</span><span class="nt">></span>Info<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-warning"</span><span class="nt">></span>Warning<span class="nt"></span></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"label label-danger"</span><span class="nt">></span>Danger<span class="nt"></span></span></code></pre></div> <div class="bs-callout bs-callout-info" id="callout-labels-inline-block"> <h4>Have tons of labels?</h4> <p>Rendering problems can arise when you have dozens of inline labels within a narrow container, each containing its own <code>inline-block</code> element (like an icon). The way around this is setting <code>display: inline-block;</code>. For context and an example, <a href="https://github.com/twbs/bootstrap/issues/13219">see #13219</a>.</p> </div> </div> <div class="bs-docs-section"> <h1 id="badges" class="page-header">Badges</h1> <p class="lead">Easily highlight new or unread items by adding a <code><span class="badge"></code> to links, Bootstrap navs, and more.</p> <div class="bs-example" data-example-id="simple-badges"> <a href="#">Inbox <span class="badge">42</span></a> <br><br> <button class="btn btn-primary" type="button"> Messages <span class="badge">4</span> </button> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Inbox <span class="nt"><span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">></span>42<span class="nt"></span></a></span> <span class="nt"><button</span> <span class="na">class=</span><span class="s">"btn btn-primary"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">></span> Messages <span class="nt"><span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">></span>4<span class="nt"></span></span> <span class="nt"></button></span></code></pre></div> <h4>Self collapsing</h4> <p>When there are no new or unread items, badges will simply collapse (via CSS's <code>:empty</code> selector) provided no content exists within.</p> <div class="bs-callout bs-callout-danger" id="callout-badges-ie8-empty"> <h4>Cross-browser compatibility</h4> <p>Badges won't self collapse in Internet Explorer 8 because it lacks support for the <code>:empty</code> selector.</p> </div> <h4>Adapts to active nav states</h4> <p>Built-in styles are included for placing badges in active states in pill navigations.</p> <div class="bs-example" data-example-id="badges-in-pills"> <ul class="nav nav-pills" role="tablist"> <li role="presentation" class="active"><a href="#">Home <span class="badge">42</span></a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages <span class="badge">3</span></a></li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"nav nav-pills"</span> <span class="na">role=</span><span class="s">"tablist"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span> <span class="na">class=</span><span class="s">"active"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Home <span class="nt"><span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">></span>42<span class="nt"></span></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Profile<span class="nt"></a></li></span> <span class="nt"><li</span> <span class="na">role=</span><span class="s">"presentation"</span><span class="nt">><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Messages <span class="nt"><span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">></span>3<span class="nt"></span></a></li></span> <span class="nt"></ul></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="jumbotron" class="page-header">Jumbotron</h1> <p>A lightweight, flexible component that can optionally extend the entire viewport to showcase key content on your site.</p> <div class="bs-example" data-example-id="simple-jumbotron"> <div class="jumbotron"> <h1>Hello, world!</h1> <p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"jumbotron"</span><span class="nt">></span> <span class="nt"><h1></span>Hello, world!<span class="nt"></h1></span> <span class="nt"><p></span>...<span class="nt"></p></span> <span class="nt"><p><a</span> <span class="na">class=</span><span class="s">"btn btn-primary btn-lg"</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">role=</span><span class="s">"button"</span><span class="nt">></span>Learn more<span class="nt"></a></p></span> <span class="nt"></div></span></code></pre></div> <p>To make the jumbotron full width, and without rounded corners, place it outside all <code>.container</code>s and instead add a <code>.container</code> within.</p> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"jumbotron"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span> ... <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="page-header" class="page-header">Page header</h1> <p>A simple shell for an <code>h1</code> to appropriately space out and segment sections of content on a page. It can utilize the <code>h1</code>'s default <code>small</code> element, as well as most other components (with additional styles).</p> <div class="bs-example" data-example-id="simple-page-header"> <div class="page-header"> <h1>Example page header <small>Subtext for header</small></h1> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"page-header"</span><span class="nt">></span> <span class="nt"><h1></span>Example page header <span class="nt"><small></span>Subtext for header<span class="nt"></small></h1></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="thumbnails" class="page-header">Thumbnails</h1> <p class="lead">Extend Bootstrap's <a href="../css/#grid">grid system</a> with the thumbnail component to easily display grids of images, videos, text, and more.</p> <p>If you're looking for Pinterest-like presentation of thumbnails of varying heights and/or widths, you'll need to use a third-party plugin such as <a href="http://masonry.desandro.com">Masonry</a>, <a href="http://isotope.metafizzy.co">Isotope</a>, or <a href="http://salvattore.com">Salvattore</a>.</p> <h2 id="thumbnails-default">Default example</h2> <p>By default, Bootstrap's thumbnails are designed to showcase linked images with minimal required markup.</p> <div class="bs-example" data-example-id="simple-thumbnails"> <div class="row"> <div class="col-xs-6 col-md-3"> <a href="#" class="thumbnail"> <img data-src="holder.js/100%x180" alt="Generic placeholder thumbnail"> </a> </div> <div class="col-xs-6 col-md-3"> <a href="#" class="thumbnail"> <img data-src="holder.js/100%x180" alt="Generic placeholder thumbnail"> </a> </div> <div class="col-xs-6 col-md-3"> <a href="#" class="thumbnail"> <img data-src="holder.js/100%x180" alt="Generic placeholder thumbnail"> </a> </div> <div class="col-xs-6 col-md-3"> <a href="#" class="thumbnail"> <img data-src="holder.js/100%x180" alt="Generic placeholder thumbnail"> </a> </div> </div> </div><!-- /.bs-example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-xs-6 col-md-3"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"thumbnail"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">src=</span><span class="s">"..."</span> <span class="na">alt=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></a></span> <span class="nt"></div></span> ... <span class="nt"></div></span></code></pre></div> <h2 id="thumbnails-custom-content">Custom content</h2> <p>With a bit of extra markup, it's possible to add any kind of HTML content like headings, paragraphs, or buttons into thumbnails.</p> <div class="bs-example" data-example-id="thumbnails-with-custom-content"> <div class="row"> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img data-src="holder.js/100%x200" alt="Generic placeholder thumbnail"> <div class="caption"> <h3>Thumbnail label</h3> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> </div> </div> </div> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img data-src="holder.js/100%x200" alt="Generic placeholder thumbnail"> <div class="caption"> <h3>Thumbnail label</h3> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> </div> </div> </div> <div class="col-sm-6 col-md-4"> <div class="thumbnail"> <img data-src="holder.js/100%x200" alt="Generic placeholder thumbnail"> <div class="caption"> <h3>Thumbnail label</h3> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> </div> </div> </div> </div> </div><!-- /.bs-example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"col-sm-6 col-md-4"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"thumbnail"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">src=</span><span class="s">"..."</span> <span class="na">alt=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"caption"</span><span class="nt">></span> <span class="nt"><h3></span>Thumbnail label<span class="nt"></h3></span> <span class="nt"><p></span>...<span class="nt"></p></span> <span class="nt"><p><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"btn btn-primary"</span> <span class="na">role=</span><span class="s">"button"</span><span class="nt">></span>Button<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"btn btn-default"</span> <span class="na">role=</span><span class="s">"button"</span><span class="nt">></span>Button<span class="nt"></a></p></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="alerts" class="page-header">Alerts</h1> <p class="lead">Provide contextual feedback messages for typical user actions with the handful of available and flexible alert messages.</p> <h2 id="alerts-examples">Examples</h2> <p>Wrap any text and an optional dismiss button in <code>.alert</code> and one of the four contextual classes (e.g., <code>.alert-success</code>) for basic alert messages.</p> <div class="bs-callout bs-callout-info" id="callout-alerts-no-default"> <h4>No default class</h4> <p>Alerts don't have default classes, only base and modifier classes. A default gray alert doesn't make too much sense, so you're required to specify a type via contextual class. Choose from success, info, warning, or danger.</p> </div> <div class="bs-example" data-example-id="simple-alerts"> <div class="alert alert-success" role="alert"> <strong>Well done!</strong> You successfully read this important alert message. </div> <div class="alert alert-info" role="alert"> <strong>Heads up!</strong> This alert needs your attention, but it's not super important. </div> <div class="alert alert-warning" role="alert"> <strong>Warning!</strong> Better check yourself, you're not looking too good. </div> <div class="alert alert-danger" role="alert"> <strong>Oh snap!</strong> Change a few things up and try submitting again. </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-success"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-info"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-warning"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-danger"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> <h2 id="alerts-dismissible">Dismissible alerts</h2> <p>Build on any alert by adding an optional <code>.alert-dismissible</code> and close button.</p> <div class="bs-callout bs-callout-info" id="callout-alerts-dismiss-plugin"> <h4>Requires JavaScript alert plugin</h4> <p>For fully functioning, dismissible alerts, you must use the <a href="../javascript/#alerts">alerts JavaScript plugin</a>.</p> </div> <div class="bs-example" data-example-id="dismissible-alert-css"> <div class="alert alert-warning alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong>Warning!</strong> Better check yourself, you're not looking too good. </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-warning alert-dismissible"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">class=</span><span class="s">"close"</span> <span class="na">data-dismiss=</span><span class="s">"alert"</span> <span class="na">aria-label=</span><span class="s">"Close"</span><span class="nt">><span</span> <span class="na">aria-hidden=</span><span class="s">"true"</span><span class="nt">></span><span class="ni">&times;</span><span class="nt"></span></button></span> <span class="nt"><strong></span>Warning!<span class="nt"></strong></span> Better check yourself, you're not looking too good. <span class="nt"></div></span></code></pre></div> <div class="bs-callout bs-callout-warning" id="callout-alerts-dismiss-use-button"> <h4>Ensure proper behavior across all devices</h4> <p>Be sure to use the <code><button></code> element with the <code>data-dismiss="alert"</code> data attribute.</p> </div> <h2 id="alerts-links">Links in alerts</h2> <p>Use the <code>.alert-link</code> utility class to quickly provide matching colored links within any alert.</p> <div class="bs-example" data-example-id="alerts-with-links"> <div class="alert alert-success" role="alert"> <strong>Well done!</strong> You successfully read <a href="#" class="alert-link">this important alert message</a>. </div> <div class="alert alert-info" role="alert"> <strong>Heads up!</strong> This <a href="#" class="alert-link">alert needs your attention</a>, but it's not super important. </div> <div class="alert alert-warning" role="alert"> <strong>Warning!</strong> Better check yourself, you're <a href="#" class="alert-link">not looking too good</a>. </div> <div class="alert alert-danger" role="alert"> <strong>Oh snap!</strong> <a href="#" class="alert-link">Change a few things up</a> and try submitting again. </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-success"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"alert-link"</span><span class="nt">></span>...<span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-info"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"alert-link"</span><span class="nt">></span>...<span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-warning"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"alert-link"</span><span class="nt">></span>...<span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"alert alert-danger"</span> <span class="na">role=</span><span class="s">"alert"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"alert-link"</span><span class="nt">></span>...<span class="nt"></a></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="progress" class="page-header">Progress bars</h1> <p class="lead">Provide up-to-date feedback on the progress of a workflow or action with simple yet flexible progress bars.</p> <div class="bs-callout bs-callout-danger" id="callout-progress-animation-css3"> <h4>Cross-browser compatibility</h4> <p>Progress bars use CSS3 transitions and animations to achieve some of their effects. These features are not supported in Internet Explorer 9 and below or older versions of Firefox. Opera 12 does not support animations.</p> </div> <h2 id="progress-basic">Basic example</h2> <p>Default progress bar.</p> <div class="bs-example" data-example-id="simple-progress-bar"> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"> <span class="sr-only">60% Complete</span> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"60"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 60%;"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>60% Complete<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="progress-label">With label</h2> <p>Remove the <code><span></code> with <code>.sr-only</code> class from within the progress bar to show a visible percentage.</p> <div class="bs-example" data-example-id="progress-bar-with-label"> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"> 60% </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"60"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 60%;"</span><span class="nt">></span> 60% <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <p>To ensure that the label text remains legible even for low percentages, consider adding a <code>min-width</code> to the progress bar.</p> <div class="bs-example" data-example-id="progress-bar-at-low-percentage"> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em;"> 0% </div> </div> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="2" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em; width: 2%;"> 2% </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"0"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"min-width: 2em;"</span><span class="nt">></span> 0% <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"2"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"min-width: 2em; width: 2%;"</span><span class="nt">></span> 2% <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="progress-alternatives">Contextual alternatives</h2> <p>Progress bars use some of the same button and alert classes for consistent styles.</p> <div class="bs-example" data-example-id="contextual-progress-bar"> <div class="progress"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"> <span class="sr-only">40% Complete (success)</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"> <span class="sr-only">20% Complete</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"> <span class="sr-only">60% Complete (warning)</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"> <span class="sr-only">80% Complete (danger)</span> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-success"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"40"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 40%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>40% Complete (success)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-info"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"20"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 20%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>20% Complete<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-warning"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"60"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 60%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>60% Complete (warning)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-danger"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"80"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 80%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>80% Complete (danger)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="progress-striped">Striped</h2> <p>Uses a gradient to create a striped effect. Not available in IE9 and below.</p> <div class="bs-example" data-example-id="striped-progress-bar"> <div class="progress"> <div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"> <span class="sr-only">40% Complete (success)</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"> <span class="sr-only">20% Complete</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-warning progress-bar-striped" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"> <span class="sr-only">60% Complete (warning)</span> </div> </div> <div class="progress"> <div class="progress-bar progress-bar-danger progress-bar-striped" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"> <span class="sr-only">80% Complete (danger)</span> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-success progress-bar-striped"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"40"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 40%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>40% Complete (success)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-info progress-bar-striped"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"20"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 20%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>20% Complete<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-warning progress-bar-striped"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"60"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 60%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>60% Complete (warning)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-danger progress-bar-striped"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"80"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 80%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>80% Complete (danger)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="progress-animated">Animated</h2> <p>Add <code>.active</code> to <code>.progress-bar-striped</code> to animate the stripes right to left. Not available in IE9 and below.</p> <div class="bs-example" data-example-id="animated-progress-bar"> <div class="progress"> <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 45%"><span class="sr-only">45% Complete</span></div> </div> <button type="button" class="btn btn-default bs-docs-activate-animated-progressbar" data-toggle="button" aria-pressed="false" autocomplete="off">Toggle animation</button> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-striped active"</span> <span class="na">role=</span><span class="s">"progressbar"</span> <span class="na">aria-valuenow=</span><span class="s">"45"</span> <span class="na">aria-valuemin=</span><span class="s">"0"</span> <span class="na">aria-valuemax=</span><span class="s">"100"</span> <span class="na">style=</span><span class="s">"width: 45%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>45% Complete<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="progress-stacked">Stacked</h2> <p>Place multiple bars into the same <code>.progress</code> to stack them.</p> <div class="bs-example" data-example-id="stacked-progress-bar"> <div class="progress"> <div class="progress-bar progress-bar-success" style="width: 35%"> <span class="sr-only">35% Complete (success)</span> </div> <div class="progress-bar progress-bar-warning progress-bar-striped" style="width: 20%"> <span class="sr-only">20% Complete (warning)</span> </div> <div class="progress-bar progress-bar-danger" style="width: 10%"> <span class="sr-only">10% Complete (danger)</span> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-success"</span> <span class="na">style=</span><span class="s">"width: 35%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>35% Complete (success)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-warning progress-bar-striped"</span> <span class="na">style=</span><span class="s">"width: 20%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>20% Complete (warning)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"progress-bar progress-bar-danger"</span> <span class="na">style=</span><span class="s">"width: 10%"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"sr-only"</span><span class="nt">></span>10% Complete (danger)<span class="nt"></span></span> <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="media" class="page-header">Media object</h1> <p class="lead">Abstract object styles for building various types of components (like blog comments, Tweets, etc) that feature a left- or right-aligned image alongside textual content.</p> <h2 id="media-default">Default media</h2> <p>The default media displays a media object (images, video, audio) to the left or right of a content block.</p> <div class="bs-example" data-example-id="default-media"> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. </div> </div> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Nested media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. </div> </div> </div> </div> <div class="media"> <div class="media-body"> <h4 class="media-heading">Media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. </div> <div class="media-right"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> </div> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. </div> <div class="media-right"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> </div> </div><!-- /.bs-example --> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"media"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-left"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">class=</span><span class="s">"media-object"</span> <span class="na">src=</span><span class="s">"..."</span> <span class="na">alt=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-body"</span><span class="nt">></span> <span class="nt"><h4</span> <span class="na">class=</span><span class="s">"media-heading"</span><span class="nt">></span>Media heading<span class="nt"></h4></span> ... <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <p>The classes <code>.pull-left</code> and <code>.pull-right</code> also exist and were previously used as part of the media component, but are deprecated for that use as of v3.3.0. They are approximately equivalent to <code>.media-left</code> and <code>.media-right</code>, except that <code>.media-right</code> should be placed after the <code>.media-body</code> in the html.</p> <h2 id="media-alignment">Media alignment</h2> <p>The images or other media can be aligned top, middle, or bottom. The default is top aligned.</p> <div class="bs-example" data-example-id="media-alignment"> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Top aligned media</h4> <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.</p> <p>Donec sed odio dui. Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> </div> </div> <div class="media"> <div class="media-left media-middle"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Middle aligned media</h4> <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.</p> <p>Donec sed odio dui. Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> </div> </div> <div class="media"> <div class="media-left media-bottom"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Bottom aligned media</h4> <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.</p> <p>Donec sed odio dui. Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"media"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-left media-middle"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">class=</span><span class="s">"media-object"</span> <span class="na">src=</span><span class="s">"..."</span> <span class="na">alt=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-body"</span><span class="nt">></span> <span class="nt"><h4</span> <span class="na">class=</span><span class="s">"media-heading"</span><span class="nt">></span>Middle aligned media<span class="nt"></h4></span> ... <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="media-list">Media list</h2> <p>With a bit of extra markup, you can use media inside list (useful for comment threads or articles lists).</p> <div class="bs-example" data-example-id="media-list"> <ul class="media-list"> <li class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Media heading</h4> <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis.</p> <!-- Nested media object --> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Nested media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. <!-- Nested media object --> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Nested media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. </div> </div> </div> </div> <!-- Nested media object --> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" data-src="holder.js/64x64" alt="Generic placeholder image"> </a> </div> <div class="media-body"> <h4 class="media-heading">Nested media heading</h4> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. </div> </div> </div> </li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"media-list"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"media"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-left"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span> <span class="nt"><img</span> <span class="na">class=</span><span class="s">"media-object"</span> <span class="na">src=</span><span class="s">"..."</span> <span class="na">alt=</span><span class="s">"..."</span><span class="nt">></span> <span class="nt"></a></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"media-body"</span><span class="nt">></span> <span class="nt"><h4</span> <span class="na">class=</span><span class="s">"media-heading"</span><span class="nt">></span>Media heading<span class="nt"></h4></span> ... <span class="nt"></div></span> <span class="nt"></li></span> <span class="nt"></ul></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="list-group" class="page-header">List group</h1> <p class="lead">List groups are a flexible and powerful component for displaying not only simple lists of elements, but complex ones with custom content.</p> <h2 id="list-group-basic">Basic example</h2> <p>The most basic list group is simply an unordered list with list items, and the proper classes. Build upon it with the options that follow, or your own CSS as needed.</p> <div class="bs-example" data-example-id="simple-list-group"> <ul class="list-group"> <li class="list-group-item">Cras justo odio</li> <li class="list-group-item">Dapibus ac facilisis in</li> <li class="list-group-item">Morbi leo risus</li> <li class="list-group-item">Porta ac consectetur ac</li> <li class="list-group-item">Vestibulum at eros</li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Cras justo odio<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Morbi leo risus<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></li></span> <span class="nt"></ul></span></code></pre></div> <h2 id="list-group-badges">Badges</h2> <p>Add the badges component to any list group item and it will automatically be positioned on the right.</p> <div class="bs-example" data-example-id="list-group-badges"> <ul class="list-group"> <li class="list-group-item"> <span class="badge">14</span> Cras justo odio </li> <li class="list-group-item"> <span class="badge">2</span> Dapibus ac facilisis in </li> <li class="list-group-item"> <span class="badge">1</span> Morbi leo risus </li> </ul> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"badge"</span><span class="nt">></span>14<span class="nt"></span></span> Cras justo odio <span class="nt"></li></span> <span class="nt"></ul></span></code></pre></div> <h2 id="list-group-linked">Linked items</h2> <p>Linkify list group items by using anchor tags instead of list items (that also means a parent <code><div></code> instead of an <code><ul></code>). No need for individual parents around each element.</p> <div class="bs-example" data-example-id="list-group-anchors"> <div class="list-group"> <a href="#" class="list-group-item active"> Cras justo odio </a> <a href="#" class="list-group-item">Dapibus ac facilisis in</a> <a href="#" class="list-group-item">Morbi leo risus</a> <a href="#" class="list-group-item">Porta ac consectetur ac</a> <a href="#" class="list-group-item">Vestibulum at eros</a> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item active"</span><span class="nt">></span> Cras justo odio <span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Morbi leo risus<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></a></span> <span class="nt"></div></span></code></pre></div> <h2 id="list-group-disabled">Disabled items</h2> <p>Add <code>.disabled</code> to a <code>.list-group-item</code> to gray it out to appear disabled.</p> <div class="bs-example" data-example-id="list-group-disabled"> <div class="list-group"> <a href="#" class="list-group-item disabled"> Cras justo odio </a> <a href="#" class="list-group-item">Dapibus ac facilisis in</a> <a href="#" class="list-group-item">Morbi leo risus</a> <a href="#" class="list-group-item">Porta ac consectetur ac</a> <a href="#" class="list-group-item">Vestibulum at eros</a> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item disabled"</span><span class="nt">></span> Cras justo odio <span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Morbi leo risus<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></a></span> <span class="nt"></div></span></code></pre></div> <h2 id="list-group-contextual-classes">Contextual classes</h2> <p>Use contextual classes to style list items, default or linked. Also includes <code>.active</code> state.</p> <div class="bs-example" data-example-id="list-group-variants"> <div class="row"> <div class="col-sm-6"> <ul class="list-group"> <li class="list-group-item list-group-item-success">Dapibus ac facilisis in</li> <li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li> <li class="list-group-item list-group-item-warning">Porta ac consectetur ac</li> <li class="list-group-item list-group-item-danger">Vestibulum at eros</li> </ul> </div> <div class="col-sm-6"> <div class="list-group"> <a href="#" class="list-group-item list-group-item-success">Dapibus ac facilisis in</a> <a href="#" class="list-group-item list-group-item-info">Cras sit amet nibh libero</a> <a href="#" class="list-group-item list-group-item-warning">Porta ac consectetur ac</a> <a href="#" class="list-group-item list-group-item-danger">Vestibulum at eros</a> </div> </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><ul</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-success"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-info"</span><span class="nt">></span>Cras sit amet nibh libero<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-warning"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-danger"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></li></span> <span class="nt"></ul></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-success"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-info"</span><span class="nt">></span>Cras sit amet nibh libero<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-warning"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></a></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item list-group-item-danger"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></a></span> <span class="nt"></div></span></code></pre></div> <h2 id="list-group-custom-content">Custom content</h2> <p>Add nearly any HTML within, even for linked list groups like the one below.</p> <div class="bs-example" data-example-id="list-group-custom-content"> <div class="list-group"> <a href="#" class="list-group-item active"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"list-group-item active"</span><span class="nt">></span> <span class="nt"><h4</span> <span class="na">class=</span><span class="s">"list-group-item-heading"</span><span class="nt">></span>List group item heading<span class="nt"></h4></span> <span class="nt"><p</span> <span class="na">class=</span><span class="s">"list-group-item-text"</span><span class="nt">></span>...<span class="nt"></p></span> <span class="nt"></a></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="panels" class="page-header">Panels</h1> <p class="lead">While not always necessary, sometimes you need to put your DOM in a box. For those situations, try the panel component.</p> <h2 id="panels-basic">Basic example</h2> <p>By default, all the <code>.panel</code> does is apply some basic border and padding to contain some content.</p> <div class="bs-example" data-example-id="simple-panel"> <div class="panel panel-default"> <div class="panel-body"> Basic panel example </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> Basic panel example <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="panels-heading">Panel with heading</h2> <p>Easily add a heading container to your panel with <code>.panel-heading</code>. You may also include any <code><h1></code>-<code><h6></code> with a <code>.panel-title</code> class to add a pre-styled heading.</p> <p>For proper link coloring, be sure to place links in headings within <code>.panel-title</code>.</p> <div class="bs-example" data-example-id="panel-with-heading"> <div class="panel panel-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">></span>Panel heading without title<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> Panel content <span class="nt"></div></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">></span> <span class="nt"><h3</span> <span class="na">class=</span><span class="s">"panel-title"</span><span class="nt">></span>Panel title<span class="nt"></h3></span> <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> Panel content <span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="panels-footer">Panel with footer</h2> <p>Wrap buttons or secondary text in <code>.panel-footer</code>. Note that panel footers <strong>do not</strong> inherit colors and borders when using contextual variations as they are not meant to be in the foreground.</p> <div class="bs-example" data-example-id="panel-with-footer"> <div class="panel panel-default"> <div class="panel-body"> Panel content </div> <div class="panel-footer">Panel footer</div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> Panel content <span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-footer"</span><span class="nt">></span>Panel footer<span class="nt"></div></span> <span class="nt"></div></span></code></pre></div> <h2 id="panels-alternatives">Contextual alternatives</h2> <p>Like other components, easily make a panel more meaningful to a particular context by adding any of the contextual state classes.</p> <div class="bs-example" data-example-id="contextual-panels"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-success"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-info"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-danger"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-primary"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-success"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-info"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-warning"</span><span class="nt">></span>...<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-danger"</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> <h2 id="panels-tables">With tables</h2> <p>Add any non-bordered <code>.table</code> within a panel for a seamless design. If there is a <code>.panel-body</code>, we add an extra border to the top of the table for separation.</p> <div class="bs-example" data-example-id="table-within-panel"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading">Panel heading</div> <div class="panel-body"> <p>Some default panel content here. Nulla vitae elit libero, a pharetra augue. Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> </div> <!-- Table --> <table class="table"> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <th scope="row">2</th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <th scope="row">3</th> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="c"><!-- Default panel contents --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">></span>Panel heading<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> <span class="nt"><p></span>...<span class="nt"></p></span> <span class="nt"></div></span> <span class="c"><!-- Table --></span> <span class="nt"><table</span> <span class="na">class=</span><span class="s">"table"</span><span class="nt">></span> ... <span class="nt"></table></span> <span class="nt"></div></span></code></pre></div> <p>If there is no panel body, the component moves from panel header to table without interruption.</p> <div class="bs-example" data-example-id="panel-without-body-with-table"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading">Panel heading</div> <!-- Table --> <table class="table"> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <th scope="row">2</th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <th scope="row">3</th> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="c"><!-- Default panel contents --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">></span>Panel heading<span class="nt"></div></span> <span class="c"><!-- Table --></span> <span class="nt"><table</span> <span class="na">class=</span><span class="s">"table"</span><span class="nt">></span> ... <span class="nt"></table></span> <span class="nt"></div></span></code></pre></div> <h2 id="panels-list-group">With list groups</h2> <p>Easily include full-width <a href="#list-group">list groups</a> within any panel.</p> <div class="bs-example" data-example-id="panel-with-list-group"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading">Panel heading</div> <div class="panel-body"> <p>Some default panel content here. Nulla vitae elit libero, a pharetra augue. Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> </div> <!-- List group --> <ul class="list-group"> <li class="list-group-item">Cras justo odio</li> <li class="list-group-item">Dapibus ac facilisis in</li> <li class="list-group-item">Morbi leo risus</li> <li class="list-group-item">Porta ac consectetur ac</li> <li class="list-group-item">Vestibulum at eros</li> </ul> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel panel-default"</span><span class="nt">></span> <span class="c"><!-- Default panel contents --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-heading"</span><span class="nt">></span>Panel heading<span class="nt"></div></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel-body"</span><span class="nt">></span> <span class="nt"><p></span>...<span class="nt"></p></span> <span class="nt"></div></span> <span class="c"><!-- List group --></span> <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"list-group"</span><span class="nt">></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Cras justo odio<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Dapibus ac facilisis in<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Morbi leo risus<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Porta ac consectetur ac<span class="nt"></li></span> <span class="nt"><li</span> <span class="na">class=</span><span class="s">"list-group-item"</span><span class="nt">></span>Vestibulum at eros<span class="nt"></li></span> <span class="nt"></ul></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="responsive-embed" class="page-header">Responsive embed</h1> <p>Allow browsers to determine video or slideshow dimensions based on the width of their containing block by creating an intrinsic ratio that will properly scale on any device.</p> <p>Rules are directly applied to <code><iframe></code>, <code><embed></code>, <code><video></code>, and <code><object></code> elements; optionally use an explicit descendant class <code>.embed-responsive-item</code> when you want to match the styling for other attributes.</p> <p><strong>Pro-Tip!</strong> You don't need to include <code>frameborder="0"</code> in your <code><iframe></code>s as we override that for you.</p> <div class="bs-example" data-example-id="responsive-embed-16by9-iframe-youtube"> <div class="embed-responsive embed-responsive-16by9"> <iframe class="embed-responsive-item" src="//www.youtube.com/embed/zpOULjyy-n8?rel=0" allowfullscreen></iframe> </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- 16:9 aspect ratio --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"embed-responsive embed-responsive-16by9"</span><span class="nt">></span> <span class="nt"><iframe</span> <span class="na">class=</span><span class="s">"embed-responsive-item"</span> <span class="na">src=</span><span class="s">"..."</span><span class="nt">></iframe></span> <span class="nt"></div></span> <span class="c"><!-- 4:3 aspect ratio --></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"embed-responsive embed-responsive-4by3"</span><span class="nt">></span> <span class="nt"><iframe</span> <span class="na">class=</span><span class="s">"embed-responsive-item"</span> <span class="na">src=</span><span class="s">"..."</span><span class="nt">></iframe></span> <span class="nt"></div></span></code></pre></div> </div> <div class="bs-docs-section"> <h1 id="wells" class="page-header">Wells</h1> <h2>Default well</h2> <p>Use the well as a simple effect on an element to give it an inset effect.</p> <div class="bs-example" data-example-id="default-well"> <div class="well"> Look, I'm in a well! </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"well"</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> <h2>Optional classes</h2> <p>Control padding and rounded corners with two optional modifier classes.</p> <div class="bs-example" data-example-id="large-well"> <div class="well well-lg"> Look, I'm in a large well! </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"well well-lg"</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> <div class="bs-example" data-example-id="small-well"> <div class="well well-sm"> Look, I'm in a small well! </div> </div> <div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"well well-sm"</span><span class="nt">></span>...<span class="nt"></div></span></code></pre></div> </div> </div> <div class="col-md-3" role="complementary"> <nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm"> <ul class="nav bs-docs-sidenav"> <li> <a href="#glyphicons">Glyphicons</a> <ul class="nav"> <li><a href="#glyphicons-glyphs">Available glyphs</a></li> <li><a href="#glyphicons-how-to-use">How to use</a></li> <li><a href="#glyphicons-examples">Examples</a></li> </ul> </li> <li> <a href="#dropdowns">Dropdowns</a> <ul class="nav"> <li><a href="#dropdowns-example">Example</a></li> <li><a href="#dropdowns-alignment">Alignment</a></li> <li><a href="#dropdowns-headers">Headers</a></li> <li><a href="#dropdowns-divider">Divider</a></li> <li><a href="#dropdowns-disabled">Disabled menu items</a></li> </ul> </li> <li> <a href="#btn-groups">Button groups</a> <ul class="nav"> <li><a href="#btn-groups-single">Basic example</a></li> <li><a href="#btn-groups-toolbar">Button toolbar</a></li> <li><a href="#btn-groups-sizing">Sizing</a></li> <li><a href="#btn-groups-nested">Nesting</a></li> <li><a href="#btn-groups-vertical">Vertical variation</a></li> <li><a href="#btn-groups-justified">Justified button groups</a></li> </ul> </li> <li> <a href="#btn-dropdowns">Button dropdowns</a> <ul class="nav"> <li><a href="#btn-dropdowns-single">Single button dropdowns</a></li> <li><a href="#btn-dropdowns-split">Split button dropdowns</a></li> <li><a href="#btn-dropdowns-sizing">Sizing</a></li> <li><a href="#btn-dropdowns-dropup">Dropup variation</a></li> </ul> </li> <li> <a href="#input-groups">Input groups</a> <ul class="nav"> <li><a href="#input-groups-basic">Basic example</a></li> <li><a href="#input-groups-sizing">Sizing</a></li> <li><a href="#input-groups-checkboxes-radios">Checkbox and radios addons</a></li> <li><a href="#input-groups-buttons">Button addons</a></li> <li><a href="#input-groups-buttons-dropdowns">Buttons with dropdowns</a></li> <li><a href="#input-groups-buttons-segmented">Segmented buttons</a></li> </ul> </li> <li> <a href="#nav">Navs</a> <ul class="nav"> <li><a href="#nav-tabs">Tabs</a></li> <li><a href="#nav-pills">Pills</a></li> <li><a href="#nav-justified">Justified</a></li> <li><a href="#nav-disabled-links">Disabled links</a></li> <li><a href="#nav-dropdowns">Using dropdowns</a></li> </ul> </li> <li> <a href="#navbar">Navbar</a> <ul class="nav"> <li><a href="#navbar-default">Default navbar</a></li> <li><a href="#navbar-brand-image">Brand image</a></li> <li><a href="#navbar-forms">Forms</a></li> <li><a href="#navbar-buttons">Buttons</a></li> <li><a href="#navbar-text">Text</a></li> <li><a href="#navbar-links">Non-nav links</a></li> <li><a href="#navbar-component-alignment">Component alignment</a></li> <li><a href="#navbar-fixed-top">Fixed to top</a></li> <li><a href="#navbar-fixed-bottom">Fixed to bottom</a></li> <li><a href="#navbar-static-top">Static top</a></li> <li><a href="#navbar-inverted">Inverted navbar</a></li> </ul> </li> <li><a href="#breadcrumbs">Breadcrumbs</a></li> <li> <a href="#pagination">Pagination</a> <ul class="nav"> <li><a href="#pagination-default">Default pagination</a></li> <li><a href="#pagination-pager">Pager</a></li> </ul> </li> <li><a href="#labels">Labels</a></li> <li><a href="#badges">Badges</a></li> <li><a href="#jumbotron">Jumbotron</a></li> <li><a href="#page-header">Page header</a></li> <li> <a href="#thumbnails">Thumbnails</a> <ul class="nav"> <li><a href="#thumbnails-default">Default example</a></li> <li><a href="#thumbnails-custom-content">Custom content</a></li> </ul> </li> <li> <a href="#alerts">Alerts</a> <ul class="nav"> <li><a href="#alerts-examples">Examples</a></li> <li><a href="#alerts-dismissible">Dismissible alerts</a></li> <li><a href="#alerts-links">Links in alerts</a></li> </ul> </li> <li> <a href="#progress">Progress bars</a> <ul class="nav"> <li><a href="#progress-basic">Basic example</a></li> <li><a href="#progress-label">With label</a></li> <li><a href="#progress-alternatives">Contextual alternatives</a></li> <li><a href="#progress-striped">Striped</a></li> <li><a href="#progress-animated">Animated</a></li> <li><a href="#progress-stacked">Stacked</a></li> </ul> </li> <li> <a href="#media">Media object</a> <ul class="nav"> <li><a href="#media-default">Default media</a></li> <li><a href="#media-list">Media list</a></li> </ul> </li> <li> <a href="#list-group">List group</a> <ul class="nav"> <li><a href="#list-group-basic">Basic example</a></li> <li><a href="#list-group-badges">Badges</a></li> <li><a href="#list-group-linked">Linked items</a></li> <li><a href="#list-group-disabled">Disabled items</a></li> <li><a href="#list-group-contextual-classes">Contextual classes</a></li> <li><a href="#list-group-custom-content">Custom content</a></li> </ul> </li> <li> <a href="#panels">Panels</a> <ul class="nav"> <li><a href="#panels-basic">Basic example</a></li> <li><a href="#panels-heading">Panel with heading</a></li> <li><a href="#panels-alternatives">Contextual alternatives</a></li> <li><a href="#panels-tables">With tables</a> <li><a href="#panels-list-group">With list groups</a> </ul> </li> <li><a href="#responsive-embed">Responsive embed</a></li> <li><a href="#wells">Wells</a></li> </ul> <a class="back-to-top" href="#top"> Back to top </a> <a href="#" class="bs-docs-theme-toggle" role="button"> Preview theme </a> </nav> </div> </div> </div> <!-- Footer ================================================== --> <footer class="bs-docs-footer" role="contentinfo"> <div class="container"> <div class="bs-docs-social"> <ul class="bs-docs-social-buttons"> <li> <iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=twbs&repo=bootstrap&type=watch&count=true" width="100" height="20" title="Star on GitHub"></iframe> </li> <li> <iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=twbs&repo=bootstrap&type=fork&count=true" width="102" height="20" title="Fork on GitHub"></iframe> </li> <li class="follow-btn"> <a href="https://twitter.com/getbootstrap" class="twitter-follow-button" data-link-color="#0069D6" data-show-count="true">Follow @getbootstrap</a> </li> <li class="tweet-btn"> <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://getbootstrap.com/" data-count="horizontal" data-via="getbootstrap" data-related="mdo:Creator of Bootstrap">Tweet</a> </li> </ul> </div> <p>Designed and built with all the love in the world by <a href="https://twitter.com/mdo" target="_blank">@mdo</a> and <a href="https://twitter.com/fat" target="_blank">@fat</a>.</p> <p>Maintained by the <a href="https://github.com/orgs/twbs/people">core team</a> with the help of <a href="https://github.com/twbs/bootstrap/graphs/contributors">our contributors</a>.</p> <p>Code licensed under <a rel="license" href="https://github.com/twbs/bootstrap/blob/master/LICENSE" target="_blank">MIT</a>, documentation under <a rel="license" href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY 3.0</a>.</p> <ul class="bs-docs-footer-links text-muted"> <li>Currently v3.3.4</li> <li>·</li> <li><a href="https://github.com/twbs/bootstrap">GitHub</a></li> <li>·</li> <li><a href="../getting-started/#examples">Examples</a></li> <li>·</li> <li><a href="../2.3.2/">v2.3.2 docs</a></li> <li>·</li> <li><a href="../about/">About</a></li> <li>·</li> <li><a href="http://expo.getbootstrap.com">Expo</a></li> <li>·</li> <li><a href="http://blog.getbootstrap.com">Blog</a></li> <li>·</li> <li><a href="https://github.com/twbs/bootstrap/issues">Issues</a></li> <li>·</li> <li><a href="https://github.com/twbs/bootstrap/releases">Releases</a></li> </ul> </div> </footer> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="/bootstrap/dist/js/bootstrap.min.js"></script> <script src="../assets/js/docs.min.js"></script> <!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> <script src="../assets/js/ie10-viewport-bug-workaround.js"></script> <script> window.twttr = (function (d,s,id) { var t, js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js=d.createElement(s); js.id=id; js.async=1; js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } }); }(document, "script", "twitter-wjs")); </script> <!-- Analytics ================================================== --> <script> var _gauges = _gauges || []; (function() { var t = document.createElement('script'); t.async = true; t.id = 'gauges-tracker'; t.setAttribute('data-site-id', '4f0dc9fef5a1f55508000013'); t.src = '//secure.gaug.es/track.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(t, s); })(); </script> </body> </html> |
Changes to htdocs/index.tml.
︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | <li><a href="guestbook/newguest.html">Update Guest Book</a> <li><a HREF="include.shtml">Server includes</a> <li><a HREF="forms/">CGI</a> You probably need to install the Standard Tcl Library for this. <li><a HREF="map/">Imagemaps</a> <li><a HREF="/xyzzy">Sample missing page</a> <li><a HREF="/debug/raise?message=This+page+raises+errors!">A page that raises an error</a> <li><a HREF="images">A directory listing page</a> </ul> <!-- End Right Column --> </td></tr> <!-- End Two Column Format --> </table> | > | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <li><a href="guestbook/newguest.html">Update Guest Book</a> <li><a HREF="include.shtml">Server includes</a> <li><a HREF="forms/">CGI</a> You probably need to install the Standard Tcl Library for this. <li><a HREF="map/">Imagemaps</a> <li><a HREF="/xyzzy">Sample missing page</a> <li><a HREF="/debug/raise?message=This+page+raises+errors!">A page that raises an error</a> <li><a HREF="images">A directory listing page</a> <li><a HREF="bootdemo/">Bootstrap Demo</a> </ul> <!-- End Right Column --> </td></tr> <!-- End Two Column Format --> </table> |
︙ | ︙ |
Added htdocs/markdown.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | # An exhibit of Markdown This note demonstrates some of what [Markdown][1] is capable of doing. *Note: Feel free to play with this page. Unlike regular notes, this doesn't automatically save itself.* ## Basic formatting Paragraphs can be written like so. A paragraph is the basic block of Markdown. A paragraph is what text will turn into when there is no reason it should become anything else. Paragraphs must be separated by a blank line. Basic formatting of *italics* and **bold** is supported. This *can be **nested** like* so. ## Lists ### Ordered list 1. Item 1 2. A second item 3. Number 3 4. â…£ *Note: the fourth item uses the Unicode character for [Roman numeral four][2].* ### Unordered list * An item * Another item * Yet another item * And there's more... ## Paragraph modifiers ### Code block Code blocks are very useful for developers and other people who look at code or other things that are written in plain text. As you can see, it uses a fixed-width font. You can also make `inline code` to add code into other things. ### Quote > Here is a quote. What this is should be self explanatory. Quotes are automatically indented when they are used. ## Headings There are six levels of headings. They correspond with the six levels of HTML headings. You've probably noticed them already in the page. Each level down uses one more hash character. ### Headings *can* also contain **formatting** ### They can even contain `inline code` Of course, demonstrating what headings look like messes up the structure of the page. I don't recommend using more than three or four levels of headings here, because, when you're smallest heading isn't too small, and you're largest heading isn't too big, and you want each size up to look noticeably larger and more important, there there are only so many sizes that you can use. ## URLs URLs can be made in a handful of ways: * A named link to [MarkItDown][3]. The easiest way to do these is to select what you want to make a link and hit `Ctrl+L`. * Another named link to [MarkItDown](http://www.markitdown.net/) * Sometimes you just want a URL like <http://www.markitdown.net/>. ## Horizontal rule A horizontal rule is a line that goes across the middle of the page. --- It's sometimes handy for breaking things up. ## Images Markdown can also contain images. I'll need to add something here sometime. ## Finally There's actually a lot more to Markdown than this. See the official [introduction][4] and [syntax][5] for more information. However, be aware that this is not using the official implementation, and this might work subtly differently in some of the little things. [1]: http://daringfireball.net/projects/markdown/ [2]: http://www.fileformat.info/info/unicode/char/2163/index.htm [3]: http://www.markitdown.net/ [4]: http://daringfireball.net/projects/markdown/basics [5]: http://daringfireball.net/projects/markdown/syntax |
Deleted lib/MakeIndex.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/admin.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/auth.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/cgi.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/compat.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/config.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/cookie.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/counter.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/debug.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/deprecated/base64.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/digest.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/direct.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/dirlist.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/doc.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/doc_error.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/doctools.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/fallback.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/httpd.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/imagemap.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/include.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/log.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/logstd.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/mail.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/maptcl.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/maptk.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/md5hex.tcl.
|
| < < < < < < < < < < < < < < < < < < |
Deleted lib/mime.types.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/mtype.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/objects.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/open.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/passcheck.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/passgen.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/pkgIndex.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/prodebug.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/redirect.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/safecgio.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/session.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/srvui.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/status.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/stdin.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/subst.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/tclcrypt.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/template.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/thread.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/upload.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/url.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/utils.tcl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/version.tcl.
|
| < < < < < |
Added modules/bootstrap/bootstrap.tcl.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | ### # Add hooks for bootstrap ### package require httpd::doc ;# Httpd_Redirect Httpd_ReturnData set PWD [file dirname [file normalize [info script]]] Doc_AddRoot /bootstrap/css $PWD/css Doc_AddRoot /bootstrap/fonts $PWD/fonts Doc_AddRoot /bootstrap/js $PWD/js package provide httpd::bootstrap 0.1 |
Added modules/bootstrap/css/bootstrap-theme.css.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | /*! * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ .btn-default, .btn-primary, .btn-success, .btn-info, .btn-warning, .btn-danger { text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); } .btn-default:active, .btn-primary:active, .btn-success:active, .btn-info:active, .btn-warning:active, .btn-danger:active, .btn-default.active, .btn-primary.active, .btn-success.active, .btn-info.active, .btn-warning.active, .btn-danger.active { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn-default .badge, .btn-primary .badge, .btn-success .badge, .btn-info .badge, .btn-warning .badge, .btn-danger .badge { text-shadow: none; } .btn:active, .btn.active { background-image: none; } .btn-default { text-shadow: 0 1px 0 #fff; background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #dbdbdb; border-color: #ccc; } .btn-default:hover, .btn-default:focus { background-color: #e0e0e0; background-position: 0 -15px; } .btn-default:active, .btn-default.active { background-color: #e0e0e0; border-color: #dbdbdb; } .btn-default.disabled, .btn-default:disabled, .btn-default[disabled] { background-color: #e0e0e0; background-image: none; } .btn-primary { background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #245580; } .btn-primary:hover, .btn-primary:focus { background-color: #265a88; background-position: 0 -15px; } .btn-primary:active, .btn-primary.active { background-color: #265a88; border-color: #245580; } .btn-primary.disabled, .btn-primary:disabled, .btn-primary[disabled] { background-color: #265a88; background-image: none; } .btn-success { background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #3e8f3e; } .btn-success:hover, .btn-success:focus { background-color: #419641; background-position: 0 -15px; } .btn-success:active, .btn-success.active { background-color: #419641; border-color: #3e8f3e; } .btn-success.disabled, .btn-success:disabled, .btn-success[disabled] { background-color: #419641; background-image: none; } .btn-info { background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #28a4c9; } .btn-info:hover, .btn-info:focus { background-color: #2aabd2; background-position: 0 -15px; } .btn-info:active, .btn-info.active { background-color: #2aabd2; border-color: #28a4c9; } .btn-info.disabled, .btn-info:disabled, .btn-info[disabled] { background-color: #2aabd2; background-image: none; } .btn-warning { background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #e38d13; } .btn-warning:hover, .btn-warning:focus { background-color: #eb9316; background-position: 0 -15px; } .btn-warning:active, .btn-warning.active { background-color: #eb9316; border-color: #e38d13; } .btn-warning.disabled, .btn-warning:disabled, .btn-warning[disabled] { background-color: #eb9316; background-image: none; } .btn-danger { background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #b92c28; } .btn-danger:hover, .btn-danger:focus { background-color: #c12e2a; background-position: 0 -15px; } .btn-danger:active, .btn-danger.active { background-color: #c12e2a; border-color: #b92c28; } .btn-danger.disabled, .btn-danger:disabled, .btn-danger[disabled] { background-color: #c12e2a; background-image: none; } .thumbnail, .img-thumbnail { -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); box-shadow: 0 1px 2px rgba(0, 0, 0, .075); } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { background-color: #e8e8e8; background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); background-repeat: repeat-x; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { background-color: #2e6da4; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } .navbar-default { background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-radius: 4px; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .active > a { background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); background-repeat: repeat-x; -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); } .navbar-brand, .navbar-nav > li > a { text-shadow: 0 1px 0 rgba(255, 255, 255, .25); } .navbar-inverse { background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .active > a { background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); background-repeat: repeat-x; -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); } .navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav > li > a { text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); } .navbar-static-top, .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } @media (max-width: 767px) { .navbar .navbar-nav .open .dropdown-menu > .active > a, .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } } .alert { text-shadow: 0 1px 0 rgba(255, 255, 255, .2); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); } .alert-success { background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); background-repeat: repeat-x; border-color: #b2dba1; } .alert-info { background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); background-repeat: repeat-x; border-color: #9acfea; } .alert-warning { background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); background-repeat: repeat-x; border-color: #f5e79e; } .alert-danger { background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); background-repeat: repeat-x; border-color: #dca7a7; } .progress { background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); background-repeat: repeat-x; } .progress-bar { background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); background-repeat: repeat-x; } .progress-bar-success { background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); background-repeat: repeat-x; } .progress-bar-info { background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); background-repeat: repeat-x; } .progress-bar-warning { background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); background-repeat: repeat-x; } .progress-bar-danger { background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); background-repeat: repeat-x; } .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .list-group { border-radius: 4px; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); box-shadow: 0 1px 2px rgba(0, 0, 0, .075); } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { text-shadow: 0 -1px 0 #286090; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); background-repeat: repeat-x; border-color: #2b669a; } .list-group-item.active .badge, .list-group-item.active:hover .badge, .list-group-item.active:focus .badge { text-shadow: none; } .panel { -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); box-shadow: 0 1px 2px rgba(0, 0, 0, .05); } .panel-default > .panel-heading { background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); background-repeat: repeat-x; } .panel-primary > .panel-heading { background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } .panel-success > .panel-heading { background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); background-repeat: repeat-x; } .panel-info > .panel-heading { background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); background-repeat: repeat-x; } .panel-warning > .panel-heading { background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); background-repeat: repeat-x; } .panel-danger > .panel-heading { background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); background-repeat: repeat-x; } .well { background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); background-repeat: repeat-x; border-color: #dcdcdc; -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); } /*# sourceMappingURL=bootstrap-theme.css.map */ |
Added modules/bootstrap/css/bootstrap-theme.css.map.
cannot compute difference between binary files
Added modules/bootstrap/css/bootstrap-theme.min.css.
> > > > > | 1 2 3 4 5 | /*! * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} |
Added modules/bootstrap/css/bootstrap.css.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 | /*! * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ html { font-family: sans-serif; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } body { margin: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; } audio, canvas, progress, video { display: inline-block; vertical-align: baseline; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } a { background-color: transparent; } a:active, a:hover { outline: 0; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } h1 { margin: .67em 0; font-size: 2em; } mark { color: #000; background: #ff0; } small { font-size: 80%; } sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; } sup { top: -.5em; } sub { bottom: -.25em; } img { border: 0; } svg:not(:root) { overflow: hidden; } figure { margin: 1em 40px; } hr { height: 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } pre { overflow: auto; } code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; } button, input, optgroup, select, textarea { margin: 0; font: inherit; color: inherit; } button { overflow: visible; } button, select { text-transform: none; } button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; } button[disabled], html input[disabled] { cursor: default; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } input { line-height: normal; } input[type="checkbox"], input[type="radio"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } fieldset { padding: .35em .625em .75em; margin: 0 2px; border: 1px solid #c0c0c0; } legend { padding: 0; border: 0; } textarea { overflow: auto; } optgroup { font-weight: bold; } table { border-spacing: 0; border-collapse: collapse; } td, th { padding: 0; } /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ @media print { *, *:before, *:after { color: #000 !important; text-shadow: none !important; background: transparent !important; -webkit-box-shadow: none !important; box-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } a[href^="#"]:after, a[href^="javascript:"]:after { content: ""; } pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } select { background: #fff !important; } .navbar { display: none; } .btn > .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px solid #000; } .table { border-collapse: collapse !important; } .table td, .table th { background-color: #fff !important; } .table-bordered th, .table-bordered td { border: 1px solid #ddd !important; } } @font-face { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { content: "\2a"; } .glyphicon-plus:before { content: "\2b"; } .glyphicon-euro:before, .glyphicon-eur:before { content: "\20ac"; } .glyphicon-minus:before { content: "\2212"; } .glyphicon-cloud:before { content: "\2601"; } .glyphicon-envelope:before { content: "\2709"; } .glyphicon-pencil:before { content: "\270f"; } .glyphicon-glass:before { content: "\e001"; } .glyphicon-music:before { content: "\e002"; } .glyphicon-search:before { content: "\e003"; } .glyphicon-heart:before { content: "\e005"; } .glyphicon-star:before { content: "\e006"; } .glyphicon-star-empty:before { content: "\e007"; } .glyphicon-user:before { content: "\e008"; } .glyphicon-film:before { content: "\e009"; } .glyphicon-th-large:before { content: "\e010"; } .glyphicon-th:before { content: "\e011"; } .glyphicon-th-list:before { content: "\e012"; } .glyphicon-ok:before { content: "\e013"; } .glyphicon-remove:before { content: "\e014"; } .glyphicon-zoom-in:before { content: "\e015"; } .glyphicon-zoom-out:before { content: "\e016"; } .glyphicon-off:before { content: "\e017"; } .glyphicon-signal:before { content: "\e018"; } .glyphicon-cog:before { content: "\e019"; } .glyphicon-trash:before { content: "\e020"; } .glyphicon-home:before { content: "\e021"; } .glyphicon-file:before { content: "\e022"; } .glyphicon-time:before { content: "\e023"; } .glyphicon-road:before { content: "\e024"; } .glyphicon-download-alt:before { content: "\e025"; } .glyphicon-download:before { content: "\e026"; } .glyphicon-upload:before { content: "\e027"; } .glyphicon-inbox:before { content: "\e028"; } .glyphicon-play-circle:before { content: "\e029"; } .glyphicon-repeat:before { content: "\e030"; } .glyphicon-refresh:before { content: "\e031"; } .glyphicon-list-alt:before { content: "\e032"; } .glyphicon-lock:before { content: "\e033"; } .glyphicon-flag:before { content: "\e034"; } .glyphicon-headphones:before { content: "\e035"; } .glyphicon-volume-off:before { content: "\e036"; } .glyphicon-volume-down:before { content: "\e037"; } .glyphicon-volume-up:before { content: "\e038"; } .glyphicon-qrcode:before { content: "\e039"; } .glyphicon-barcode:before { content: "\e040"; } .glyphicon-tag:before { content: "\e041"; } .glyphicon-tags:before { content: "\e042"; } .glyphicon-book:before { content: "\e043"; } .glyphicon-bookmark:before { content: "\e044"; } .glyphicon-print:before { content: "\e045"; } .glyphicon-camera:before { content: "\e046"; } .glyphicon-font:before { content: "\e047"; } .glyphicon-bold:before { content: "\e048"; } .glyphicon-italic:before { content: "\e049"; } .glyphicon-text-height:before { content: "\e050"; } .glyphicon-text-width:before { content: "\e051"; } .glyphicon-align-left:before { content: "\e052"; } .glyphicon-align-center:before { content: "\e053"; } .glyphicon-align-right:before { content: "\e054"; } .glyphicon-align-justify:before { content: "\e055"; } .glyphicon-list:before { content: "\e056"; } .glyphicon-indent-left:before { content: "\e057"; } .glyphicon-indent-right:before { content: "\e058"; } .glyphicon-facetime-video:before { content: "\e059"; } .glyphicon-picture:before { content: "\e060"; } .glyphicon-map-marker:before { content: "\e062"; } .glyphicon-adjust:before { content: "\e063"; } .glyphicon-tint:before { content: "\e064"; } .glyphicon-edit:before { content: "\e065"; } .glyphicon-share:before { content: "\e066"; } .glyphicon-check:before { content: "\e067"; } .glyphicon-move:before { content: "\e068"; } .glyphicon-step-backward:before { content: "\e069"; } .glyphicon-fast-backward:before { content: "\e070"; } .glyphicon-backward:before { content: "\e071"; } .glyphicon-play:before { content: "\e072"; } .glyphicon-pause:before { content: "\e073"; } .glyphicon-stop:before { content: "\e074"; } .glyphicon-forward:before { content: "\e075"; } .glyphicon-fast-forward:before { content: "\e076"; } .glyphicon-step-forward:before { content: "\e077"; } .glyphicon-eject:before { content: "\e078"; } .glyphicon-chevron-left:before { content: "\e079"; } .glyphicon-chevron-right:before { content: "\e080"; } .glyphicon-plus-sign:before { content: "\e081"; } .glyphicon-minus-sign:before { content: "\e082"; } .glyphicon-remove-sign:before { content: "\e083"; } .glyphicon-ok-sign:before { content: "\e084"; } .glyphicon-question-sign:before { content: "\e085"; } .glyphicon-info-sign:before { content: "\e086"; } .glyphicon-screenshot:before { content: "\e087"; } .glyphicon-remove-circle:before { content: "\e088"; } .glyphicon-ok-circle:before { content: "\e089"; } .glyphicon-ban-circle:before { content: "\e090"; } .glyphicon-arrow-left:before { content: "\e091"; } .glyphicon-arrow-right:before { content: "\e092"; } .glyphicon-arrow-up:before { content: "\e093"; } .glyphicon-arrow-down:before { content: "\e094"; } .glyphicon-share-alt:before { content: "\e095"; } .glyphicon-resize-full:before { content: "\e096"; } .glyphicon-resize-small:before { content: "\e097"; } .glyphicon-exclamation-sign:before { content: "\e101"; } .glyphicon-gift:before { content: "\e102"; } .glyphicon-leaf:before { content: "\e103"; } .glyphicon-fire:before { content: "\e104"; } .glyphicon-eye-open:before { content: "\e105"; } .glyphicon-eye-close:before { content: "\e106"; } .glyphicon-warning-sign:before { content: "\e107"; } .glyphicon-plane:before { content: "\e108"; } .glyphicon-calendar:before { content: "\e109"; } .glyphicon-random:before { content: "\e110"; } .glyphicon-comment:before { content: "\e111"; } .glyphicon-magnet:before { content: "\e112"; } .glyphicon-chevron-up:before { content: "\e113"; } .glyphicon-chevron-down:before { content: "\e114"; } .glyphicon-retweet:before { content: "\e115"; } .glyphicon-shopping-cart:before { content: "\e116"; } .glyphicon-folder-close:before { content: "\e117"; } .glyphicon-folder-open:before { content: "\e118"; } .glyphicon-resize-vertical:before { content: "\e119"; } .glyphicon-resize-horizontal:before { content: "\e120"; } .glyphicon-hdd:before { content: "\e121"; } .glyphicon-bullhorn:before { content: "\e122"; } .glyphicon-bell:before { content: "\e123"; } .glyphicon-certificate:before { content: "\e124"; } .glyphicon-thumbs-up:before { content: "\e125"; } .glyphicon-thumbs-down:before { content: "\e126"; } .glyphicon-hand-right:before { content: "\e127"; } .glyphicon-hand-left:before { content: "\e128"; } .glyphicon-hand-up:before { content: "\e129"; } .glyphicon-hand-down:before { content: "\e130"; } .glyphicon-circle-arrow-right:before { content: "\e131"; } .glyphicon-circle-arrow-left:before { content: "\e132"; } .glyphicon-circle-arrow-up:before { content: "\e133"; } .glyphicon-circle-arrow-down:before { content: "\e134"; } .glyphicon-globe:before { content: "\e135"; } .glyphicon-wrench:before { content: "\e136"; } .glyphicon-tasks:before { content: "\e137"; } .glyphicon-filter:before { content: "\e138"; } .glyphicon-briefcase:before { content: "\e139"; } .glyphicon-fullscreen:before { content: "\e140"; } .glyphicon-dashboard:before { content: "\e141"; } .glyphicon-paperclip:before { content: "\e142"; } .glyphicon-heart-empty:before { content: "\e143"; } .glyphicon-link:before { content: "\e144"; } .glyphicon-phone:before { content: "\e145"; } .glyphicon-pushpin:before { content: "\e146"; } .glyphicon-usd:before { content: "\e148"; } .glyphicon-gbp:before { content: "\e149"; } .glyphicon-sort:before { content: "\e150"; } .glyphicon-sort-by-alphabet:before { content: "\e151"; } .glyphicon-sort-by-alphabet-alt:before { content: "\e152"; } .glyphicon-sort-by-order:before { content: "\e153"; } .glyphicon-sort-by-order-alt:before { content: "\e154"; } .glyphicon-sort-by-attributes:before { content: "\e155"; } .glyphicon-sort-by-attributes-alt:before { content: "\e156"; } .glyphicon-unchecked:before { content: "\e157"; } .glyphicon-expand:before { content: "\e158"; } .glyphicon-collapse-down:before { content: "\e159"; } .glyphicon-collapse-up:before { content: "\e160"; } .glyphicon-log-in:before { content: "\e161"; } .glyphicon-flash:before { content: "\e162"; } .glyphicon-log-out:before { content: "\e163"; } .glyphicon-new-window:before { content: "\e164"; } .glyphicon-record:before { content: "\e165"; } .glyphicon-save:before { content: "\e166"; } .glyphicon-open:before { content: "\e167"; } .glyphicon-saved:before { content: "\e168"; } .glyphicon-import:before { content: "\e169"; } .glyphicon-export:before { content: "\e170"; } .glyphicon-send:before { content: "\e171"; } .glyphicon-floppy-disk:before { content: "\e172"; } .glyphicon-floppy-saved:before { content: "\e173"; } .glyphicon-floppy-remove:before { content: "\e174"; } .glyphicon-floppy-save:before { content: "\e175"; } .glyphicon-floppy-open:before { content: "\e176"; } .glyphicon-credit-card:before { content: "\e177"; } .glyphicon-transfer:before { content: "\e178"; } .glyphicon-cutlery:before { content: "\e179"; } .glyphicon-header:before { content: "\e180"; } .glyphicon-compressed:before { content: "\e181"; } .glyphicon-earphone:before { content: "\e182"; } .glyphicon-phone-alt:before { content: "\e183"; } .glyphicon-tower:before { content: "\e184"; } .glyphicon-stats:before { content: "\e185"; } .glyphicon-sd-video:before { content: "\e186"; } .glyphicon-hd-video:before { content: "\e187"; } .glyphicon-subtitles:before { content: "\e188"; } .glyphicon-sound-stereo:before { content: "\e189"; } .glyphicon-sound-dolby:before { content: "\e190"; } .glyphicon-sound-5-1:before { content: "\e191"; } .glyphicon-sound-6-1:before { content: "\e192"; } .glyphicon-sound-7-1:before { content: "\e193"; } .glyphicon-copyright-mark:before { content: "\e194"; } .glyphicon-registration-mark:before { content: "\e195"; } .glyphicon-cloud-download:before { content: "\e197"; } .glyphicon-cloud-upload:before { content: "\e198"; } .glyphicon-tree-conifer:before { content: "\e199"; } .glyphicon-tree-deciduous:before { content: "\e200"; } .glyphicon-cd:before { content: "\e201"; } .glyphicon-save-file:before { content: "\e202"; } .glyphicon-open-file:before { content: "\e203"; } .glyphicon-level-up:before { content: "\e204"; } .glyphicon-copy:before { content: "\e205"; } .glyphicon-paste:before { content: "\e206"; } .glyphicon-alert:before { content: "\e209"; } .glyphicon-equalizer:before { content: "\e210"; } .glyphicon-king:before { content: "\e211"; } .glyphicon-queen:before { content: "\e212"; } .glyphicon-pawn:before { content: "\e213"; } .glyphicon-bishop:before { content: "\e214"; } .glyphicon-knight:before { content: "\e215"; } .glyphicon-baby-formula:before { content: "\e216"; } .glyphicon-tent:before { content: "\26fa"; } .glyphicon-blackboard:before { content: "\e218"; } .glyphicon-bed:before { content: "\e219"; } .glyphicon-apple:before { content: "\f8ff"; } .glyphicon-erase:before { content: "\e221"; } .glyphicon-hourglass:before { content: "\231b"; } .glyphicon-lamp:before { content: "\e223"; } .glyphicon-duplicate:before { content: "\e224"; } .glyphicon-piggy-bank:before { content: "\e225"; } .glyphicon-scissors:before { content: "\e226"; } .glyphicon-bitcoin:before { content: "\e227"; } .glyphicon-btc:before { content: "\e227"; } .glyphicon-xbt:before { content: "\e227"; } .glyphicon-yen:before { content: "\00a5"; } .glyphicon-jpy:before { content: "\00a5"; } .glyphicon-ruble:before { content: "\20bd"; } .glyphicon-rub:before { content: "\20bd"; } .glyphicon-scale:before { content: "\e230"; } .glyphicon-ice-lolly:before { content: "\e231"; } .glyphicon-ice-lolly-tasted:before { content: "\e232"; } .glyphicon-education:before { content: "\e233"; } .glyphicon-option-horizontal:before { content: "\e234"; } .glyphicon-option-vertical:before { content: "\e235"; } .glyphicon-menu-hamburger:before { content: "\e236"; } .glyphicon-modal-window:before { content: "\e237"; } .glyphicon-oil:before { content: "\e238"; } .glyphicon-grain:before { content: "\e239"; } .glyphicon-sunglasses:before { content: "\e240"; } .glyphicon-text-size:before { content: "\e241"; } .glyphicon-text-color:before { content: "\e242"; } .glyphicon-text-background:before { content: "\e243"; } .glyphicon-object-align-top:before { content: "\e244"; } .glyphicon-object-align-bottom:before { content: "\e245"; } .glyphicon-object-align-horizontal:before { content: "\e246"; } .glyphicon-object-align-left:before { content: "\e247"; } .glyphicon-object-align-vertical:before { content: "\e248"; } .glyphicon-object-align-right:before { content: "\e249"; } .glyphicon-triangle-right:before { content: "\e250"; } .glyphicon-triangle-left:before { content: "\e251"; } .glyphicon-triangle-bottom:before { content: "\e252"; } .glyphicon-triangle-top:before { content: "\e253"; } .glyphicon-console:before { content: "\e254"; } .glyphicon-superscript:before { content: "\e255"; } .glyphicon-subscript:before { content: "\e256"; } .glyphicon-menu-left:before { content: "\e257"; } .glyphicon-menu-right:before { content: "\e258"; } .glyphicon-menu-down:before { content: "\e259"; } .glyphicon-menu-up:before { content: "\e260"; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html { font-size: 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.42857143; color: #333; background-color: #fff; } input, button, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; } a { color: #337ab7; text-decoration: none; } a:hover, a:focus { color: #23527c; text-decoration: underline; } a:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } figure { margin: 0; } img { vertical-align: middle; } .img-responsive, .thumbnail > img, .thumbnail a > img, .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; max-width: 100%; height: auto; } .img-rounded { border-radius: 6px; } .img-thumbnail { display: inline-block; max-width: 100%; height: auto; padding: 4px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .img-circle { border-radius: 50%; } hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #eee; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; } [role="button"] { cursor: pointer; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-family: inherit; font-weight: 500; line-height: 1.1; color: inherit; } h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { font-weight: normal; line-height: 1; color: #777; } h1, .h1, h2, .h2, h3, .h3 { margin-top: 20px; margin-bottom: 10px; } h1 small, .h1 small, h2 small, .h2 small, h3 small, .h3 small, h1 .small, .h1 .small, h2 .small, .h2 .small, h3 .small, .h3 .small { font-size: 65%; } h4, .h4, h5, .h5, h6, .h6 { margin-top: 10px; margin-bottom: 10px; } h4 small, .h4 small, h5 small, .h5 small, h6 small, .h6 small, h4 .small, .h4 .small, h5 .small, .h5 .small, h6 .small, .h6 .small { font-size: 75%; } h1, .h1 { font-size: 36px; } h2, .h2 { font-size: 30px; } h3, .h3 { font-size: 24px; } h4, .h4 { font-size: 18px; } h5, .h5 { font-size: 14px; } h6, .h6 { font-size: 12px; } p { margin: 0 0 10px; } .lead { margin-bottom: 20px; font-size: 16px; font-weight: 300; line-height: 1.4; } @media (min-width: 768px) { .lead { font-size: 21px; } } small, .small { font-size: 85%; } mark, .mark { padding: .2em; background-color: #fcf8e3; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } .text-justify { text-align: justify; } .text-nowrap { white-space: nowrap; } .text-lowercase { text-transform: lowercase; } .text-uppercase { text-transform: uppercase; } .text-capitalize { text-transform: capitalize; } .text-muted { color: #777; } .text-primary { color: #337ab7; } a.text-primary:hover { color: #286090; } .text-success { color: #3c763d; } a.text-success:hover { color: #2b542c; } .text-info { color: #31708f; } a.text-info:hover { color: #245269; } .text-warning { color: #8a6d3b; } a.text-warning:hover { color: #66512c; } .text-danger { color: #a94442; } a.text-danger:hover { color: #843534; } .bg-primary { color: #fff; background-color: #337ab7; } a.bg-primary:hover { background-color: #286090; } .bg-success { background-color: #dff0d8; } a.bg-success:hover { background-color: #c1e2b3; } .bg-info { background-color: #d9edf7; } a.bg-info:hover { background-color: #afd9ee; } .bg-warning { background-color: #fcf8e3; } a.bg-warning:hover { background-color: #f7ecb5; } .bg-danger { background-color: #f2dede; } a.bg-danger:hover { background-color: #e4b9b9; } .page-header { padding-bottom: 9px; margin: 40px 0 20px; border-bottom: 1px solid #eee; } ul, ol { margin-top: 0; margin-bottom: 10px; } ul ul, ol ul, ul ol, ol ol { margin-bottom: 0; } .list-unstyled { padding-left: 0; list-style: none; } .list-inline { padding-left: 0; margin-left: -5px; list-style: none; } .list-inline > li { display: inline-block; padding-right: 5px; padding-left: 5px; } dl { margin-top: 0; margin-bottom: 20px; } dt, dd { line-height: 1.42857143; } dt { font-weight: bold; } dd { margin-left: 0; } @media (min-width: 768px) { .dl-horizontal dt { float: left; width: 160px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dd { margin-left: 180px; } } abbr[title], abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #777; } .initialism { font-size: 90%; text-transform: uppercase; } blockquote { padding: 10px 20px; margin: 0 0 20px; font-size: 17.5px; border-left: 5px solid #eee; } blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { margin-bottom: 0; } blockquote footer, blockquote small, blockquote .small { display: block; font-size: 80%; line-height: 1.42857143; color: #777; } blockquote footer:before, blockquote small:before, blockquote .small:before { content: '\2014 \00A0'; } .blockquote-reverse, blockquote.pull-right { padding-right: 15px; padding-left: 0; text-align: right; border-right: 5px solid #eee; border-left: 0; } .blockquote-reverse footer:before, blockquote.pull-right footer:before, .blockquote-reverse small:before, blockquote.pull-right small:before, .blockquote-reverse .small:before, blockquote.pull-right .small:before { content: ''; } .blockquote-reverse footer:after, blockquote.pull-right footer:after, .blockquote-reverse small:after, blockquote.pull-right small:after, .blockquote-reverse .small:after, blockquote.pull-right .small:after { content: '\00A0 \2014'; } address { margin-bottom: 20px; font-style: normal; line-height: 1.42857143; } code, kbd, pre, samp { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; } kbd { padding: 2px 4px; font-size: 90%; color: #fff; background-color: #333; border-radius: 3px; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); } kbd kbd { padding: 0; font-size: 100%; font-weight: bold; -webkit-box-shadow: none; box-shadow: none; } pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 1.42857143; color: #333; word-break: break-all; word-wrap: break-word; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; } pre code { padding: 0; font-size: inherit; color: inherit; white-space: pre-wrap; background-color: transparent; border-radius: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } .container { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } @media (min-width: 768px) { .container { width: 750px; } } @media (min-width: 992px) { .container { width: 970px; } } @media (min-width: 1200px) { .container { width: 1170px; } } .container-fluid { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } .row { margin-right: -15px; margin-left: -15px; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; padding-right: 15px; padding-left: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { float: left; } .col-xs-12 { width: 100%; } .col-xs-11 { width: 91.66666667%; } .col-xs-10 { width: 83.33333333%; } .col-xs-9 { width: 75%; } .col-xs-8 { width: 66.66666667%; } .col-xs-7 { width: 58.33333333%; } .col-xs-6 { width: 50%; } .col-xs-5 { width: 41.66666667%; } .col-xs-4 { width: 33.33333333%; } .col-xs-3 { width: 25%; } .col-xs-2 { width: 16.66666667%; } .col-xs-1 { width: 8.33333333%; } .col-xs-pull-12 { right: 100%; } .col-xs-pull-11 { right: 91.66666667%; } .col-xs-pull-10 { right: 83.33333333%; } .col-xs-pull-9 { right: 75%; } .col-xs-pull-8 { right: 66.66666667%; } .col-xs-pull-7 { right: 58.33333333%; } .col-xs-pull-6 { right: 50%; } .col-xs-pull-5 { right: 41.66666667%; } .col-xs-pull-4 { right: 33.33333333%; } .col-xs-pull-3 { right: 25%; } .col-xs-pull-2 { right: 16.66666667%; } .col-xs-pull-1 { right: 8.33333333%; } .col-xs-pull-0 { right: auto; } .col-xs-push-12 { left: 100%; } .col-xs-push-11 { left: 91.66666667%; } .col-xs-push-10 { left: 83.33333333%; } .col-xs-push-9 { left: 75%; } .col-xs-push-8 { left: 66.66666667%; } .col-xs-push-7 { left: 58.33333333%; } .col-xs-push-6 { left: 50%; } .col-xs-push-5 { left: 41.66666667%; } .col-xs-push-4 { left: 33.33333333%; } .col-xs-push-3 { left: 25%; } .col-xs-push-2 { left: 16.66666667%; } .col-xs-push-1 { left: 8.33333333%; } .col-xs-push-0 { left: auto; } .col-xs-offset-12 { margin-left: 100%; } .col-xs-offset-11 { margin-left: 91.66666667%; } .col-xs-offset-10 { margin-left: 83.33333333%; } .col-xs-offset-9 { margin-left: 75%; } .col-xs-offset-8 { margin-left: 66.66666667%; } .col-xs-offset-7 { margin-left: 58.33333333%; } .col-xs-offset-6 { margin-left: 50%; } .col-xs-offset-5 { margin-left: 41.66666667%; } .col-xs-offset-4 { margin-left: 33.33333333%; } .col-xs-offset-3 { margin-left: 25%; } .col-xs-offset-2 { margin-left: 16.66666667%; } .col-xs-offset-1 { margin-left: 8.33333333%; } .col-xs-offset-0 { margin-left: 0; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } .col-sm-12 { width: 100%; } .col-sm-11 { width: 91.66666667%; } .col-sm-10 { width: 83.33333333%; } .col-sm-9 { width: 75%; } .col-sm-8 { width: 66.66666667%; } .col-sm-7 { width: 58.33333333%; } .col-sm-6 { width: 50%; } .col-sm-5 { width: 41.66666667%; } .col-sm-4 { width: 33.33333333%; } .col-sm-3 { width: 25%; } .col-sm-2 { width: 16.66666667%; } .col-sm-1 { width: 8.33333333%; } .col-sm-pull-12 { right: 100%; } .col-sm-pull-11 { right: 91.66666667%; } .col-sm-pull-10 { right: 83.33333333%; } .col-sm-pull-9 { right: 75%; } .col-sm-pull-8 { right: 66.66666667%; } .col-sm-pull-7 { right: 58.33333333%; } .col-sm-pull-6 { right: 50%; } .col-sm-pull-5 { right: 41.66666667%; } .col-sm-pull-4 { right: 33.33333333%; } .col-sm-pull-3 { right: 25%; } .col-sm-pull-2 { right: 16.66666667%; } .col-sm-pull-1 { right: 8.33333333%; } .col-sm-pull-0 { right: auto; } .col-sm-push-12 { left: 100%; } .col-sm-push-11 { left: 91.66666667%; } .col-sm-push-10 { left: 83.33333333%; } .col-sm-push-9 { left: 75%; } .col-sm-push-8 { left: 66.66666667%; } .col-sm-push-7 { left: 58.33333333%; } .col-sm-push-6 { left: 50%; } .col-sm-push-5 { left: 41.66666667%; } .col-sm-push-4 { left: 33.33333333%; } .col-sm-push-3 { left: 25%; } .col-sm-push-2 { left: 16.66666667%; } .col-sm-push-1 { left: 8.33333333%; } .col-sm-push-0 { left: auto; } .col-sm-offset-12 { margin-left: 100%; } .col-sm-offset-11 { margin-left: 91.66666667%; } .col-sm-offset-10 { margin-left: 83.33333333%; } .col-sm-offset-9 { margin-left: 75%; } .col-sm-offset-8 { margin-left: 66.66666667%; } .col-sm-offset-7 { margin-left: 58.33333333%; } .col-sm-offset-6 { margin-left: 50%; } .col-sm-offset-5 { margin-left: 41.66666667%; } .col-sm-offset-4 { margin-left: 33.33333333%; } .col-sm-offset-3 { margin-left: 25%; } .col-sm-offset-2 { margin-left: 16.66666667%; } .col-sm-offset-1 { margin-left: 8.33333333%; } .col-sm-offset-0 { margin-left: 0; } } @media (min-width: 992px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } .col-md-12 { width: 100%; } .col-md-11 { width: 91.66666667%; } .col-md-10 { width: 83.33333333%; } .col-md-9 { width: 75%; } .col-md-8 { width: 66.66666667%; } .col-md-7 { width: 58.33333333%; } .col-md-6 { width: 50%; } .col-md-5 { width: 41.66666667%; } .col-md-4 { width: 33.33333333%; } .col-md-3 { width: 25%; } .col-md-2 { width: 16.66666667%; } .col-md-1 { width: 8.33333333%; } .col-md-pull-12 { right: 100%; } .col-md-pull-11 { right: 91.66666667%; } .col-md-pull-10 { right: 83.33333333%; } .col-md-pull-9 { right: 75%; } .col-md-pull-8 { right: 66.66666667%; } .col-md-pull-7 { right: 58.33333333%; } .col-md-pull-6 { right: 50%; } .col-md-pull-5 { right: 41.66666667%; } .col-md-pull-4 { right: 33.33333333%; } .col-md-pull-3 { right: 25%; } .col-md-pull-2 { right: 16.66666667%; } .col-md-pull-1 { right: 8.33333333%; } .col-md-pull-0 { right: auto; } .col-md-push-12 { left: 100%; } .col-md-push-11 { left: 91.66666667%; } .col-md-push-10 { left: 83.33333333%; } .col-md-push-9 { left: 75%; } .col-md-push-8 { left: 66.66666667%; } .col-md-push-7 { left: 58.33333333%; } .col-md-push-6 { left: 50%; } .col-md-push-5 { left: 41.66666667%; } .col-md-push-4 { left: 33.33333333%; } .col-md-push-3 { left: 25%; } .col-md-push-2 { left: 16.66666667%; } .col-md-push-1 { left: 8.33333333%; } .col-md-push-0 { left: auto; } .col-md-offset-12 { margin-left: 100%; } .col-md-offset-11 { margin-left: 91.66666667%; } .col-md-offset-10 { margin-left: 83.33333333%; } .col-md-offset-9 { margin-left: 75%; } .col-md-offset-8 { margin-left: 66.66666667%; } .col-md-offset-7 { margin-left: 58.33333333%; } .col-md-offset-6 { margin-left: 50%; } .col-md-offset-5 { margin-left: 41.66666667%; } .col-md-offset-4 { margin-left: 33.33333333%; } .col-md-offset-3 { margin-left: 25%; } .col-md-offset-2 { margin-left: 16.66666667%; } .col-md-offset-1 { margin-left: 8.33333333%; } .col-md-offset-0 { margin-left: 0; } } @media (min-width: 1200px) { .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { float: left; } .col-lg-12 { width: 100%; } .col-lg-11 { width: 91.66666667%; } .col-lg-10 { width: 83.33333333%; } .col-lg-9 { width: 75%; } .col-lg-8 { width: 66.66666667%; } .col-lg-7 { width: 58.33333333%; } .col-lg-6 { width: 50%; } .col-lg-5 { width: 41.66666667%; } .col-lg-4 { width: 33.33333333%; } .col-lg-3 { width: 25%; } .col-lg-2 { width: 16.66666667%; } .col-lg-1 { width: 8.33333333%; } .col-lg-pull-12 { right: 100%; } .col-lg-pull-11 { right: 91.66666667%; } .col-lg-pull-10 { right: 83.33333333%; } .col-lg-pull-9 { right: 75%; } .col-lg-pull-8 { right: 66.66666667%; } .col-lg-pull-7 { right: 58.33333333%; } .col-lg-pull-6 { right: 50%; } .col-lg-pull-5 { right: 41.66666667%; } .col-lg-pull-4 { right: 33.33333333%; } .col-lg-pull-3 { right: 25%; } .col-lg-pull-2 { right: 16.66666667%; } .col-lg-pull-1 { right: 8.33333333%; } .col-lg-pull-0 { right: auto; } .col-lg-push-12 { left: 100%; } .col-lg-push-11 { left: 91.66666667%; } .col-lg-push-10 { left: 83.33333333%; } .col-lg-push-9 { left: 75%; } .col-lg-push-8 { left: 66.66666667%; } .col-lg-push-7 { left: 58.33333333%; } .col-lg-push-6 { left: 50%; } .col-lg-push-5 { left: 41.66666667%; } .col-lg-push-4 { left: 33.33333333%; } .col-lg-push-3 { left: 25%; } .col-lg-push-2 { left: 16.66666667%; } .col-lg-push-1 { left: 8.33333333%; } .col-lg-push-0 { left: auto; } .col-lg-offset-12 { margin-left: 100%; } .col-lg-offset-11 { margin-left: 91.66666667%; } .col-lg-offset-10 { margin-left: 83.33333333%; } .col-lg-offset-9 { margin-left: 75%; } .col-lg-offset-8 { margin-left: 66.66666667%; } .col-lg-offset-7 { margin-left: 58.33333333%; } .col-lg-offset-6 { margin-left: 50%; } .col-lg-offset-5 { margin-left: 41.66666667%; } .col-lg-offset-4 { margin-left: 33.33333333%; } .col-lg-offset-3 { margin-left: 25%; } .col-lg-offset-2 { margin-left: 16.66666667%; } .col-lg-offset-1 { margin-left: 8.33333333%; } .col-lg-offset-0 { margin-left: 0; } } table { background-color: transparent; } caption { padding-top: 8px; padding-bottom: 8px; color: #777; text-align: left; } th { text-align: left; } .table { width: 100%; max-width: 100%; margin-bottom: 20px; } .table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td { padding: 8px; line-height: 1.42857143; vertical-align: top; border-top: 1px solid #ddd; } .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, .table > thead:first-child > tr:first-child > th, .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > td { border-top: 0; } .table > tbody + tbody { border-top: 2px solid #ddd; } .table .table { background-color: #fff; } .table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td { padding: 5px; } .table-bordered { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { border-bottom-width: 2px; } .table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } .table-hover > tbody > tr:hover { background-color: #f5f5f5; } table col[class*="col-"] { position: static; display: table-column; float: none; } table td[class*="col-"], table th[class*="col-"] { position: static; display: table-cell; float: none; } .table > thead > tr > td.active, .table > tbody > tr > td.active, .table > tfoot > tr > td.active, .table > thead > tr > th.active, .table > tbody > tr > th.active, .table > tfoot > tr > th.active, .table > thead > tr.active > td, .table > tbody > tr.active > td, .table > tfoot > tr.active > td, .table > thead > tr.active > th, .table > tbody > tr.active > th, .table > tfoot > tr.active > th { background-color: #f5f5f5; } .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th { background-color: #e8e8e8; } .table > thead > tr > td.success, .table > tbody > tr > td.success, .table > tfoot > tr > td.success, .table > thead > tr > th.success, .table > tbody > tr > th.success, .table > tfoot > tr > th.success, .table > thead > tr.success > td, .table > tbody > tr.success > td, .table > tfoot > tr.success > td, .table > thead > tr.success > th, .table > tbody > tr.success > th, .table > tfoot > tr.success > th { background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } .table > thead > tr > td.info, .table > tbody > tr > td.info, .table > tfoot > tr > td.info, .table > thead > tr > th.info, .table > tbody > tr > th.info, .table > tfoot > tr > th.info, .table > thead > tr.info > td, .table > tbody > tr.info > td, .table > tfoot > tr.info > td, .table > thead > tr.info > th, .table > tbody > tr.info > th, .table > tfoot > tr.info > th { background-color: #d9edf7; } .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th { background-color: #c4e3f3; } .table > thead > tr > td.warning, .table > tbody > tr > td.warning, .table > tfoot > tr > td.warning, .table > thead > tr > th.warning, .table > tbody > tr > th.warning, .table > tfoot > tr > th.warning, .table > thead > tr.warning > td, .table > tbody > tr.warning > td, .table > tfoot > tr.warning > td, .table > thead > tr.warning > th, .table > tbody > tr.warning > th, .table > tfoot > tr.warning > th { background-color: #fcf8e3; } .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th { background-color: #faf2cc; } .table > thead > tr > td.danger, .table > tbody > tr > td.danger, .table > tfoot > tr > td.danger, .table > thead > tr > th.danger, .table > tbody > tr > th.danger, .table > tfoot > tr > th.danger, .table > thead > tr.danger > td, .table > tbody > tr.danger > td, .table > tfoot > tr.danger > td, .table > thead > tr.danger > th, .table > tbody > tr.danger > th, .table > tfoot > tr.danger > th { background-color: #f2dede; } .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th { background-color: #ebcccc; } .table-responsive { min-height: .01%; overflow-x: auto; } @media screen and (max-width: 767px) { .table-responsive { width: 100%; margin-bottom: 15px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } .table-responsive > .table { margin-bottom: 0; } .table-responsive > .table > thead > tr > th, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } .table-responsive > .table-bordered { border: 0; } .table-responsive > .table-bordered > thead > tr > th:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .table-responsive > .table-bordered > thead > tr > th:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > th, .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > td { border-bottom: 0; } } fieldset { min-width: 0; padding: 0; margin: 0; border: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: inherit; color: #333; border: 0; border-bottom: 1px solid #e5e5e5; } label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } input[type="search"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } input[type="file"] { display: block; } input[type="range"] { display: block; width: 100%; } select[multiple], select[size] { height: auto; } input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } output { display: block; padding-top: 7px; font-size: 14px; line-height: 1.42857143; color: #555; } .form-control { display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; color: #555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); } .form-control::-moz-placeholder { color: #999; opacity: 1; } .form-control:-ms-input-placeholder { color: #999; } .form-control::-webkit-input-placeholder { color: #999; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { background-color: #eee; opacity: 1; } .form-control[disabled], fieldset[disabled] .form-control { cursor: not-allowed; } textarea.form-control { height: auto; } input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { line-height: 34px; } input[type="date"].input-sm, input[type="time"].input-sm, input[type="datetime-local"].input-sm, input[type="month"].input-sm, .input-group-sm input[type="date"], .input-group-sm input[type="time"], .input-group-sm input[type="datetime-local"], .input-group-sm input[type="month"] { line-height: 30px; } input[type="date"].input-lg, input[type="time"].input-lg, input[type="datetime-local"].input-lg, input[type="month"].input-lg, .input-group-lg input[type="date"], .input-group-lg input[type="time"], .input-group-lg input[type="datetime-local"], .input-group-lg input[type="month"] { line-height: 46px; } } .form-group { margin-bottom: 15px; } .radio, .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } .radio label, .checkbox label { min-height: 20px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: absolute; margin-top: 4px \9; margin-left: -20px; } .radio + .radio, .checkbox + .checkbox { margin-top: -5px; } .radio-inline, .checkbox-inline { position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; font-weight: normal; vertical-align: middle; cursor: pointer; } .radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } input[type="radio"][disabled], input[type="checkbox"][disabled], input[type="radio"].disabled, input[type="checkbox"].disabled, fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"] { cursor: not-allowed; } .radio-inline.disabled, .checkbox-inline.disabled, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox-inline { cursor: not-allowed; } .radio.disabled label, .checkbox.disabled label, fieldset[disabled] .radio label, fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { min-height: 34px; padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; } .form-control-static.input-lg, .form-control-static.input-sm { padding-right: 0; padding-left: 0; } .input-sm { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-sm { height: 30px; line-height: 30px; } textarea.input-sm, select[multiple].input-sm { height: auto; } .form-group-sm .form-control { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.form-group-sm .form-control { height: 30px; line-height: 30px; } textarea.form-group-sm .form-control, select[multiple].form-group-sm .form-control { height: auto; } .form-group-sm .form-control-static { height: 30px; min-height: 32px; padding: 5px 10px; font-size: 12px; line-height: 1.5; } .input-lg { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-lg { height: 46px; line-height: 46px; } textarea.input-lg, select[multiple].input-lg { height: auto; } .form-group-lg .form-control { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.form-group-lg .form-control { height: 46px; line-height: 46px; } textarea.form-group-lg .form-control, select[multiple].form-group-lg .form-control { height: auto; } .form-group-lg .form-control-static { height: 46px; min-height: 38px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; } .has-feedback { position: relative; } .has-feedback .form-control { padding-right: 42.5px; } .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 34px; height: 34px; line-height: 34px; text-align: center; pointer-events: none; } .input-lg + .form-control-feedback { width: 46px; height: 46px; line-height: 46px; } .input-sm + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; } .has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline, .has-success.radio label, .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label { color: #3c763d; } .has-success .form-control { border-color: #3c763d; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-success .form-control:focus { border-color: #2b542c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; } .has-success .input-group-addon { color: #3c763d; background-color: #dff0d8; border-color: #3c763d; } .has-success .form-control-feedback { color: #3c763d; } .has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline, .has-warning.radio label, .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label { color: #8a6d3b; } .has-warning .form-control { border-color: #8a6d3b; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-warning .form-control:focus { border-color: #66512c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; } .has-warning .input-group-addon { color: #8a6d3b; background-color: #fcf8e3; border-color: #8a6d3b; } .has-warning .form-control-feedback { color: #8a6d3b; } .has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline, .has-error.radio label, .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label { color: #a94442; } .has-error .form-control { border-color: #a94442; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-error .form-control:focus { border-color: #843534; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; } .has-error .input-group-addon { color: #a94442; background-color: #f2dede; border-color: #a94442; } .has-error .form-control-feedback { color: #a94442; } .has-feedback label ~ .form-control-feedback { top: 25px; } .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } @media (min-width: 768px) { .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } .form-inline .form-control-static { display: inline-block; } .form-inline .input-group { display: inline-table; vertical-align: middle; } .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn, .form-inline .input-group .form-control { width: auto; } .form-inline .input-group > .form-control { width: 100%; } .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } .form-inline .radio, .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .form-inline .radio label, .form-inline .checkbox label { padding-left: 0; } .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .form-inline .has-feedback .form-control-feedback { top: 0; } } .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { padding-top: 7px; margin-top: 0; margin-bottom: 0; } .form-horizontal .radio, .form-horizontal .checkbox { min-height: 27px; } .form-horizontal .form-group { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .form-horizontal .control-label { padding-top: 7px; margin-bottom: 0; text-align: right; } } .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { padding-top: 14.333333px; } } @media (min-width: 768px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; } } .btn { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: normal; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px; } .btn:focus, .btn:active:focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn.active.focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn:hover, .btn:focus, .btn.focus { color: #333; text-decoration: none; } .btn:active, .btn.active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { pointer-events: none; cursor: not-allowed; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; opacity: .65; } .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .btn-default:hover, .btn-default:focus, .btn-default.focus, .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { color: #333; background-color: #e6e6e6; border-color: #adadad; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { background-image: none; } .btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, fieldset[disabled] .btn-default.focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { background-color: #fff; border-color: #ccc; } .btn-default .badge { color: #fff; background-color: #333; } .btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } .btn-primary:hover, .btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { color: #fff; background-color: #286090; border-color: #204d74; } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { background-image: none; } .btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled.focus, .btn-primary[disabled].focus, fieldset[disabled] .btn-primary.focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #337ab7; border-color: #2e6da4; } .btn-primary .badge { color: #337ab7; background-color: #fff; } .btn-success { color: #fff; background-color: #5cb85c; border-color: #4cae4c; } .btn-success:hover, .btn-success:focus, .btn-success.focus, .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { color: #fff; background-color: #449d44; border-color: #398439; } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { background-image: none; } .btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled.focus, .btn-success[disabled].focus, fieldset[disabled] .btn-success.focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { background-color: #5cb85c; border-color: #4cae4c; } .btn-success .badge { color: #5cb85c; background-color: #fff; } .btn-info { color: #fff; background-color: #5bc0de; border-color: #46b8da; } .btn-info:hover, .btn-info:focus, .btn-info.focus, .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { color: #fff; background-color: #31b0d5; border-color: #269abc; } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { background-image: none; } .btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled.focus, .btn-info[disabled].focus, fieldset[disabled] .btn-info.focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { background-color: #5bc0de; border-color: #46b8da; } .btn-info .badge { color: #5bc0de; background-color: #fff; } .btn-warning { color: #fff; background-color: #f0ad4e; border-color: #eea236; } .btn-warning:hover, .btn-warning:focus, .btn-warning.focus, .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { color: #fff; background-color: #ec971f; border-color: #d58512; } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { background-image: none; } .btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled.focus, .btn-warning[disabled].focus, fieldset[disabled] .btn-warning.focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { background-color: #f0ad4e; border-color: #eea236; } .btn-warning .badge { color: #f0ad4e; background-color: #fff; } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d43f3a; } .btn-danger:hover, .btn-danger:focus, .btn-danger.focus, .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { color: #fff; background-color: #c9302c; border-color: #ac2925; } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { background-image: none; } .btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled.focus, .btn-danger[disabled].focus, fieldset[disabled] .btn-danger.focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { background-color: #d9534f; border-color: #d43f3a; } .btn-danger .badge { color: #d9534f; background-color: #fff; } .btn-link { font-weight: normal; color: #337ab7; border-radius: 0; } .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], fieldset[disabled] .btn-link { background-color: transparent; -webkit-box-shadow: none; box-shadow: none; } .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { border-color: transparent; } .btn-link:hover, .btn-link:focus { color: #23527c; text-decoration: underline; background-color: transparent; } .btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { color: #777; text-decoration: none; } .btn-lg, .btn-group-lg > .btn { padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } .btn-sm, .btn-group-sm > .btn { padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-xs, .btn-group-xs > .btn { padding: 1px 5px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-block { display: block; width: 100%; } .btn-block + .btn-block { margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { width: 100%; } .fade { opacity: 0; -webkit-transition: opacity .15s linear; -o-transition: opacity .15s linear; transition: opacity .15s linear; } .fade.in { opacity: 1; } .collapse { display: none; } .collapse.in { display: block; } tr.collapse.in { display: table-row; } tbody.collapse.in { display: table-row-group; } .collapsing { position: relative; height: 0; overflow: hidden; -webkit-transition-timing-function: ease; -o-transition-timing-function: ease; transition-timing-function: ease; -webkit-transition-duration: .35s; -o-transition-duration: .35s; transition-duration: .35s; -webkit-transition-property: height, visibility; -o-transition-property: height, visibility; transition-property: height, visibility; } .caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px dashed; border-right: 4px solid transparent; border-left: 4px solid transparent; } .dropup, .dropdown { position: relative; } .dropdown-toggle:focus { outline: 0; } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; font-size: 14px; text-align: left; list-style: none; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); box-shadow: 0 6px 12px rgba(0, 0, 0, .175); } .dropdown-menu.pull-right { right: 0; left: auto; } .dropdown-menu .divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.42857143; color: #333; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { color: #262626; text-decoration: none; background-color: #f5f5f5; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #fff; text-decoration: none; background-color: #337ab7; outline: 0; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { color: #777; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; cursor: not-allowed; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } .open > .dropdown-menu { display: block; } .open > a { outline: 0; } .dropdown-menu-right { right: 0; left: auto; } .dropdown-menu-left { right: auto; left: 0; } .dropdown-header { display: block; padding: 3px 20px; font-size: 12px; line-height: 1.42857143; color: #777; white-space: nowrap; } .dropdown-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 990; } .pull-right > .dropdown-menu { right: 0; left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { content: ""; border-top: 0; border-bottom: 4px solid; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; } @media (min-width: 768px) { .navbar-right .dropdown-menu { right: 0; left: auto; } .navbar-right .dropdown-menu-left { right: auto; left: 0; } } .btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } .btn-group > .btn, .btn-group-vertical > .btn { position: relative; float: left; } .btn-group > .btn:hover, .btn-group-vertical > .btn:hover, .btn-group > .btn:focus, .btn-group-vertical > .btn:focus, .btn-group > .btn:active, .btn-group-vertical > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn.active { z-index: 2; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { margin-left: -1px; } .btn-toolbar { margin-left: -5px; } .btn-toolbar .btn-group, .btn-toolbar .input-group { float: left; } .btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group { margin-left: 5px; } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } .btn-group > .btn:first-child { margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group > .btn-group { float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { padding-right: 8px; padding-left: 8px; } .btn-group > .btn-lg + .dropdown-toggle { padding-right: 12px; padding-left: 12px; } .btn-group.open .dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; box-shadow: none; } .btn .caret { margin-left: 0; } .btn-lg .caret { border-width: 5px 5px 0; border-bottom-width: 0; } .dropup .btn-lg .caret { border-width: 0 5px 5px; } .btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } .btn-group-vertical > .btn-group > .btn { float: none; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: 4px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-top-right-radius: 0; } .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } .btn-group-justified > .btn, .btn-group-justified > .btn-group { display: table-cell; float: none; width: 1%; } .btn-group-justified > .btn-group .btn { width: 100%; } .btn-group-justified > .btn-group .dropdown-menu { left: auto; } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } .input-group { position: relative; display: table; border-collapse: separate; } .input-group[class*="col-"] { float: none; padding-right: 0; padding-left: 0; } .input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0; } .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn { height: 46px; line-height: 46px; } textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group-addon, textarea.input-group-lg > .input-group-btn > .btn, select[multiple].input-group-lg > .form-control, select[multiple].input-group-lg > .input-group-addon, select[multiple].input-group-lg > .input-group-btn > .btn { height: auto; } .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn { height: 30px; line-height: 30px; } textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-addon, textarea.input-group-sm > .input-group-btn > .btn, select[multiple].input-group-sm > .form-control, select[multiple].input-group-sm > .input-group-addon, select[multiple].input-group-sm > .input-group-btn > .btn { height: auto; } .input-group-addon, .input-group-btn, .input-group .form-control { display: table-cell; } .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { border-radius: 0; } .input-group-addon, .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle; } .input-group-addon { padding: 6px 12px; font-size: 14px; font-weight: normal; line-height: 1; color: #555; text-align: center; background-color: #eee; border: 1px solid #ccc; border-radius: 4px; } .input-group-addon.input-sm { padding: 5px 10px; font-size: 12px; border-radius: 3px; } .input-group-addon.input-lg { padding: 10px 16px; font-size: 18px; border-radius: 6px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { margin-top: 0; } .input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { border-top-right-radius: 0; border-bottom-right-radius: 0; } .input-group-addon:first-child { border-right: 0; } .input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { border-top-left-radius: 0; border-bottom-left-radius: 0; } .input-group-addon:last-child { border-left: 0; } .input-group-btn { position: relative; font-size: 0; white-space: nowrap; } .input-group-btn > .btn { position: relative; } .input-group-btn > .btn + .btn { margin-left: -1px; } .input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active { z-index: 2; } .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group { margin-right: -1px; } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { margin-left: -1px; } .nav { padding-left: 0; margin-bottom: 0; list-style: none; } .nav > li { position: relative; display: block; } .nav > li > a { position: relative; display: block; padding: 10px 15px; } .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; background-color: #eee; } .nav > li.disabled > a { color: #777; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { color: #777; text-decoration: none; cursor: not-allowed; background-color: transparent; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { background-color: #eee; border-color: #337ab7; } .nav .nav-divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .nav > li > a > img { max-width: none; } .nav-tabs { border-bottom: 1px solid #ddd; } .nav-tabs > li { float: left; margin-bottom: -1px; } .nav-tabs > li > a { margin-right: 2px; line-height: 1.42857143; border: 1px solid transparent; border-radius: 4px 4px 0 0; } .nav-tabs > li > a:hover { border-color: #eee #eee #ddd; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { color: #555; cursor: default; background-color: #fff; border: 1px solid #ddd; border-bottom-color: transparent; } .nav-tabs.nav-justified { width: 100%; border-bottom: 0; } .nav-tabs.nav-justified > li { float: none; } .nav-tabs.nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-tabs.nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-tabs.nav-justified > li { display: table-cell; width: 1%; } .nav-tabs.nav-justified > li > a { margin-bottom: 0; } } .nav-tabs.nav-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs.nav-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border-bottom-color: #fff; } } .nav-pills > li { float: left; } .nav-pills > li > a { border-radius: 4px; } .nav-pills > li + li { margin-left: 2px; } .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { color: #fff; background-color: #337ab7; } .nav-stacked > li { float: none; } .nav-stacked > li + li { margin-top: 2px; margin-left: 0; } .nav-justified { width: 100%; } .nav-justified > li { float: none; } .nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-justified > li { display: table-cell; width: 1%; } .nav-justified > li > a { margin-bottom: 0; } } .nav-tabs-justified { border-bottom: 0; } .nav-tabs-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border-bottom-color: #fff; } } .tab-content > .tab-pane { display: none; } .tab-content > .active { display: block; } .nav-tabs .dropdown-menu { margin-top: -1px; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar { position: relative; min-height: 50px; margin-bottom: 20px; border: 1px solid transparent; } @media (min-width: 768px) { .navbar { border-radius: 4px; } } @media (min-width: 768px) { .navbar-header { float: left; } } .navbar-collapse { padding-right: 15px; padding-left: 15px; overflow-x: visible; -webkit-overflow-scrolling: touch; border-top: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); } .navbar-collapse.in { overflow-y: auto; } @media (min-width: 768px) { .navbar-collapse { width: auto; border-top: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-collapse.collapse { display: block !important; height: auto !important; padding-bottom: 0; overflow: visible !important; } .navbar-collapse.in { overflow-y: visible; } .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { padding-right: 0; padding-left: 0; } } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 340px; } @media (max-device-width: 480px) and (orientation: landscape) { .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 200px; } } .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: 0; margin-left: 0; } } .navbar-static-top { z-index: 1000; border-width: 0 0 1px; } @media (min-width: 768px) { .navbar-static-top { border-radius: 0; } } .navbar-fixed-top, .navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; } @media (min-width: 768px) { .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } } .navbar-fixed-top { top: 0; border-width: 0 0 1px; } .navbar-fixed-bottom { bottom: 0; margin-bottom: 0; border-width: 1px 0 0; } .navbar-brand { float: left; height: 50px; padding: 15px 15px; font-size: 18px; line-height: 20px; } .navbar-brand:hover, .navbar-brand:focus { text-decoration: none; } .navbar-brand > img { display: block; } @media (min-width: 768px) { .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { margin-left: -15px; } } .navbar-toggle { position: relative; float: right; padding: 9px 10px; margin-top: 8px; margin-right: 15px; margin-bottom: 8px; background-color: transparent; background-image: none; border: 1px solid transparent; border-radius: 4px; } .navbar-toggle:focus { outline: 0; } .navbar-toggle .icon-bar { display: block; width: 22px; height: 2px; border-radius: 1px; } .navbar-toggle .icon-bar + .icon-bar { margin-top: 4px; } @media (min-width: 768px) { .navbar-toggle { display: none; } } .navbar-nav { margin: 7.5px -15px; } .navbar-nav > li > a { padding-top: 10px; padding-bottom: 10px; line-height: 20px; } @media (max-width: 767px) { .navbar-nav .open .dropdown-menu { position: static; float: none; width: auto; margin-top: 0; background-color: transparent; border: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header { padding: 5px 15px 5px 25px; } .navbar-nav .open .dropdown-menu > li > a { line-height: 20px; } .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus { background-image: none; } } @media (min-width: 768px) { .navbar-nav { float: left; margin: 0; } .navbar-nav > li { float: left; } .navbar-nav > li > a { padding-top: 15px; padding-bottom: 15px; } } .navbar-form { padding: 10px 15px; margin-top: 8px; margin-right: -15px; margin-bottom: 8px; margin-left: -15px; border-top: 1px solid transparent; border-bottom: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); } @media (min-width: 768px) { .navbar-form .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .navbar-form .form-control { display: inline-block; width: auto; vertical-align: middle; } .navbar-form .form-control-static { display: inline-block; } .navbar-form .input-group { display: inline-table; vertical-align: middle; } .navbar-form .input-group .input-group-addon, .navbar-form .input-group .input-group-btn, .navbar-form .input-group .form-control { width: auto; } .navbar-form .input-group > .form-control { width: 100%; } .navbar-form .control-label { margin-bottom: 0; vertical-align: middle; } .navbar-form .radio, .navbar-form .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .navbar-form .radio label, .navbar-form .checkbox label { padding-left: 0; } .navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .navbar-form .has-feedback .form-control-feedback { top: 0; } } @media (max-width: 767px) { .navbar-form .form-group { margin-bottom: 5px; } .navbar-form .form-group:last-child { margin-bottom: 0; } } @media (min-width: 768px) { .navbar-form { width: auto; padding-top: 0; padding-bottom: 0; margin-right: 0; margin-left: 0; border: 0; -webkit-box-shadow: none; box-shadow: none; } } .navbar-nav > li > .dropdown-menu { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { margin-bottom: 0; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .navbar-btn { margin-top: 8px; margin-bottom: 8px; } .navbar-btn.btn-sm { margin-top: 10px; margin-bottom: 10px; } .navbar-btn.btn-xs { margin-top: 14px; margin-bottom: 14px; } .navbar-text { margin-top: 15px; margin-bottom: 15px; } @media (min-width: 768px) { .navbar-text { float: left; margin-right: 15px; margin-left: 15px; } } @media (min-width: 768px) { .navbar-left { float: left !important; } .navbar-right { float: right !important; margin-right: -15px; } .navbar-right ~ .navbar-right { margin-right: 0; } } .navbar-default { background-color: #f8f8f8; border-color: #e7e7e7; } .navbar-default .navbar-brand { color: #777; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { color: #5e5e5e; background-color: transparent; } .navbar-default .navbar-text { color: #777; } .navbar-default .navbar-nav > li > a { color: #777; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { color: #ccc; background-color: transparent; } .navbar-default .navbar-toggle { border-color: #ddd; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: #ddd; } .navbar-default .navbar-toggle .icon-bar { background-color: #888; } .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: #e7e7e7; } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { color: #555; background-color: #e7e7e7; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { color: #777; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { color: #777; } .navbar-default .navbar-link:hover { color: #333; } .navbar-default .btn-link { color: #777; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { color: #333; } .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:focus { color: #ccc; } .navbar-inverse { background-color: #222; border-color: #080808; } .navbar-inverse .navbar-brand { color: #9d9d9d; } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-text { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { color: #444; background-color: transparent; } .navbar-inverse .navbar-toggle { border-color: #333; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { background-color: #333; } .navbar-inverse .navbar-toggle .icon-bar { background-color: #fff; } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { border-color: #101010; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { color: #fff; background-color: #080808; } @media (max-width: 767px) { .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { border-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu .divider { background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #444; background-color: transparent; } } .navbar-inverse .navbar-link { color: #9d9d9d; } .navbar-inverse .navbar-link:hover { color: #fff; } .navbar-inverse .btn-link { color: #9d9d9d; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { color: #fff; } .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:focus { color: #444; } .breadcrumb { padding: 8px 15px; margin-bottom: 20px; list-style: none; background-color: #f5f5f5; border-radius: 4px; } .breadcrumb > li { display: inline-block; } .breadcrumb > li + li:before { padding: 0 5px; color: #ccc; content: "/\00a0"; } .breadcrumb > .active { color: #777; } .pagination { display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; } .pagination > li { display: inline; } .pagination > li > a, .pagination > li > span { position: relative; float: left; padding: 6px 12px; margin-left: -1px; line-height: 1.42857143; color: #337ab7; text-decoration: none; background-color: #fff; border: 1px solid #ddd; } .pagination > li:first-child > a, .pagination > li:first-child > span { margin-left: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .pagination > li:last-child > a, .pagination > li:last-child > span { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .pagination > li > a:hover, .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { color: #23527c; background-color: #eee; border-color: #ddd; } .pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { z-index: 2; color: #fff; cursor: default; background-color: #337ab7; border-color: #337ab7; } .pagination > .disabled > span, .pagination > .disabled > span:hover, .pagination > .disabled > span:focus, .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { color: #777; cursor: not-allowed; background-color: #fff; border-color: #ddd; } .pagination-lg > li > a, .pagination-lg > li > span { padding: 10px 16px; font-size: 18px; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { border-top-left-radius: 6px; border-bottom-left-radius: 6px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { border-top-right-radius: 6px; border-bottom-right-radius: 6px; } .pagination-sm > li > a, .pagination-sm > li > span { padding: 5px 10px; font-size: 12px; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } .pager { padding-left: 0; margin: 20px 0; text-align: center; list-style: none; } .pager li { display: inline; } .pager li > a, .pager li > span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; background-color: #eee; } .pager .next > a, .pager .next > span { float: right; } .pager .previous > a, .pager .previous > span { float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { color: #777; cursor: not-allowed; background-color: #fff; } .label { display: inline; padding: .2em .6em .3em; font-size: 75%; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; } a.label:hover, a.label:focus { color: #fff; text-decoration: none; cursor: pointer; } .label:empty { display: none; } .btn .label { position: relative; top: -1px; } .label-default { background-color: #777; } .label-default[href]:hover, .label-default[href]:focus { background-color: #5e5e5e; } .label-primary { background-color: #337ab7; } .label-primary[href]:hover, .label-primary[href]:focus { background-color: #286090; } .label-success { background-color: #5cb85c; } .label-success[href]:hover, .label-success[href]:focus { background-color: #449d44; } .label-info { background-color: #5bc0de; } .label-info[href]:hover, .label-info[href]:focus { background-color: #31b0d5; } .label-warning { background-color: #f0ad4e; } .label-warning[href]:hover, .label-warning[href]:focus { background-color: #ec971f; } .label-danger { background-color: #d9534f; } .label-danger[href]:hover, .label-danger[href]:focus { background-color: #c9302c; } .badge { display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 12px; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; background-color: #777; border-radius: 10px; } .badge:empty { display: none; } .btn .badge { position: relative; top: -1px; } .btn-xs .badge, .btn-group-xs > .btn .badge { top: 0; padding: 1px 5px; } a.badge:hover, a.badge:focus { color: #fff; text-decoration: none; cursor: pointer; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { color: #337ab7; background-color: #fff; } .list-group-item > .badge { float: right; } .list-group-item > .badge + .badge { margin-right: 5px; } .nav-pills > li > a > .badge { margin-left: 3px; } .jumbotron { padding: 30px 15px; margin-bottom: 30px; color: inherit; background-color: #eee; } .jumbotron h1, .jumbotron .h1 { color: inherit; } .jumbotron p { margin-bottom: 15px; font-size: 21px; font-weight: 200; } .jumbotron > hr { border-top-color: #d5d5d5; } .container .jumbotron, .container-fluid .jumbotron { border-radius: 6px; } .jumbotron .container { max-width: 100%; } @media screen and (min-width: 768px) { .jumbotron { padding: 48px 0; } .container .jumbotron, .container-fluid .jumbotron { padding-right: 60px; padding-left: 60px; } .jumbotron h1, .jumbotron .h1 { font-size: 63px; } } .thumbnail { display: block; padding: 4px; margin-bottom: 20px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: border .2s ease-in-out; -o-transition: border .2s ease-in-out; transition: border .2s ease-in-out; } .thumbnail > img, .thumbnail a > img { margin-right: auto; margin-left: auto; } a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { border-color: #337ab7; } .thumbnail .caption { padding: 9px; color: #333; } .alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .alert h4 { margin-top: 0; color: inherit; } .alert .alert-link { font-weight: bold; } .alert > p, .alert > ul { margin-bottom: 0; } .alert > p + p { margin-top: 5px; } .alert-dismissable, .alert-dismissible { padding-right: 35px; } .alert-dismissable .close, .alert-dismissible .close { position: relative; top: -2px; right: -21px; color: inherit; } .alert-success { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .alert-success hr { border-top-color: #c9e2b3; } .alert-success .alert-link { color: #2b542c; } .alert-info { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .alert-info hr { border-top-color: #a6e1ec; } .alert-info .alert-link { color: #245269; } .alert-warning { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .alert-warning hr { border-top-color: #f7e1b5; } .alert-warning .alert-link { color: #66512c; } .alert-danger { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .alert-danger hr { border-top-color: #e4b9c0; } .alert-danger .alert-link { color: #843534; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-o-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress { height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f5f5f5; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); } .progress-bar { float: left; width: 0; height: 100%; font-size: 12px; line-height: 20px; color: #fff; text-align: center; background-color: #337ab7; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); -webkit-transition: width .6s ease; -o-transition: width .6s ease; transition: width .6s ease; } .progress-striped .progress-bar, .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); -webkit-background-size: 40px 40px; background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { background-color: #5cb85c; } .progress-striped .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-info { background-color: #5bc0de; } .progress-striped .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-warning { background-color: #f0ad4e; } .progress-striped .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-danger { background-color: #d9534f; } .progress-striped .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .media { margin-top: 15px; } .media:first-child { margin-top: 0; } .media, .media-body { overflow: hidden; zoom: 1; } .media-body { width: 10000px; } .media-object { display: block; } .media-right, .media > .pull-right { padding-left: 10px; } .media-left, .media > .pull-left { padding-right: 10px; } .media-left, .media-right, .media-body { display: table-cell; vertical-align: top; } .media-middle { vertical-align: middle; } .media-bottom { vertical-align: bottom; } .media-heading { margin-top: 0; margin-bottom: 5px; } .media-list { padding-left: 0; list-style: none; } .list-group { padding-left: 0; margin-bottom: 20px; } .list-group-item { position: relative; display: block; padding: 10px 15px; margin-bottom: -1px; background-color: #fff; border: 1px solid #ddd; } .list-group-item:first-child { border-top-left-radius: 4px; border-top-right-radius: 4px; } .list-group-item:last-child { margin-bottom: 0; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; } a.list-group-item { color: #555; } a.list-group-item .list-group-item-heading { color: #333; } a.list-group-item:hover, a.list-group-item:focus { color: #555; text-decoration: none; background-color: #f5f5f5; } .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { color: #777; cursor: not-allowed; background-color: #eee; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading { color: inherit; } .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { color: #777; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { z-index: 2; color: #fff; background-color: #337ab7; border-color: #337ab7; } .list-group-item.active .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading > .small { color: inherit; } .list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text { color: #c7ddef; } .list-group-item-success { color: #3c763d; background-color: #dff0d8; } a.list-group-item-success { color: #3c763d; } a.list-group-item-success .list-group-item-heading { color: inherit; } a.list-group-item-success:hover, a.list-group-item-success:focus { color: #3c763d; background-color: #d0e9c6; } a.list-group-item-success.active, a.list-group-item-success.active:hover, a.list-group-item-success.active:focus { color: #fff; background-color: #3c763d; border-color: #3c763d; } .list-group-item-info { color: #31708f; background-color: #d9edf7; } a.list-group-item-info { color: #31708f; } a.list-group-item-info .list-group-item-heading { color: inherit; } a.list-group-item-info:hover, a.list-group-item-info:focus { color: #31708f; background-color: #c4e3f3; } a.list-group-item-info.active, a.list-group-item-info.active:hover, a.list-group-item-info.active:focus { color: #fff; background-color: #31708f; border-color: #31708f; } .list-group-item-warning { color: #8a6d3b; background-color: #fcf8e3; } a.list-group-item-warning { color: #8a6d3b; } a.list-group-item-warning .list-group-item-heading { color: inherit; } a.list-group-item-warning:hover, a.list-group-item-warning:focus { color: #8a6d3b; background-color: #faf2cc; } a.list-group-item-warning.active, a.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus { color: #fff; background-color: #8a6d3b; border-color: #8a6d3b; } .list-group-item-danger { color: #a94442; background-color: #f2dede; } a.list-group-item-danger { color: #a94442; } a.list-group-item-danger .list-group-item-heading { color: inherit; } a.list-group-item-danger:hover, a.list-group-item-danger:focus { color: #a94442; background-color: #ebcccc; } a.list-group-item-danger.active, a.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus { color: #fff; background-color: #a94442; border-color: #a94442; } .list-group-item-heading { margin-top: 0; margin-bottom: 5px; } .list-group-item-text { margin-bottom: 0; line-height: 1.3; } .panel { margin-bottom: 20px; background-color: #fff; border: 1px solid transparent; border-radius: 4px; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); box-shadow: 0 1px 1px rgba(0, 0, 0, .05); } .panel-body { padding: 15px; } .panel-heading { padding: 10px 15px; border-bottom: 1px solid transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel-heading > .dropdown .dropdown-toggle { color: inherit; } .panel-title { margin-top: 0; margin-bottom: 0; font-size: 16px; color: inherit; } .panel-title > a, .panel-title > small, .panel-title > .small, .panel-title > small > a, .panel-title > .small > a { color: inherit; } .panel-footer { padding: 10px 15px; background-color: #f5f5f5; border-top: 1px solid #ddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .list-group, .panel > .panel-collapse > .list-group { margin-bottom: 0; } .panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item { border-width: 1px 0; border-radius: 0; } .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { border-top: 0; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { border-bottom: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; } .list-group + .panel-footer { border-top-width: 0; } .panel > .table, .panel > .table-responsive > .table, .panel > .panel-collapse > .table { margin-bottom: 0; } .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { padding-right: 15px; padding-left: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { border-top-left-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { border-top-right-radius: 3px; } .panel > .table:last-child, .panel > .table-responsive:last-child > .table:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { border-bottom-right-radius: 3px; } .panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { border-top: 1px solid #ddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { border-top: 0; } .panel > .table-bordered, .panel > .table-responsive > .table-bordered { border: 0; } .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, .panel > .table-bordered > tbody > tr > th:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, .panel > .table-bordered > tfoot > tr > th:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, .panel > .table-bordered > thead > tr > td:first-child, .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, .panel > .table-bordered > tbody > tr > td:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, .panel > .table-bordered > tbody > tr > th:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, .panel > .table-bordered > tfoot > tr > th:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, .panel > .table-bordered > thead > tr > td:last-child, .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, .panel > .table-bordered > tbody > tr > td:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, .panel > .table-bordered > tbody > tr:first-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, .panel > .table-bordered > thead > tr:first-child > th, .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { border-bottom: 0; } .panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, .panel > .table-bordered > tfoot > tr:last-child > td, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, .panel > .table-bordered > tbody > tr:last-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { border-bottom: 0; } .panel > .table-responsive { margin-bottom: 0; border: 0; } .panel-group { margin-bottom: 20px; } .panel-group .panel { margin-bottom: 0; border-radius: 4px; } .panel-group .panel + .panel { margin-top: 5px; } .panel-group .panel-heading { border-bottom: 0; } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { border-top: 1px solid #ddd; } .panel-group .panel-footer { border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { border-bottom: 1px solid #ddd; } .panel-default { border-color: #ddd; } .panel-default > .panel-heading { color: #333; background-color: #f5f5f5; border-color: #ddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ddd; } .panel-default > .panel-heading .badge { color: #f5f5f5; background-color: #333; } .panel-default > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ddd; } .panel-primary { border-color: #337ab7; } .panel-primary > .panel-heading { color: #fff; background-color: #337ab7; border-color: #337ab7; } .panel-primary > .panel-heading + .panel-collapse > .panel-body { border-top-color: #337ab7; } .panel-primary > .panel-heading .badge { color: #337ab7; background-color: #fff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #337ab7; } .panel-success { border-color: #d6e9c6; } .panel-success > .panel-heading { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .panel-success > .panel-heading + .panel-collapse > .panel-body { border-top-color: #d6e9c6; } .panel-success > .panel-heading .badge { color: #dff0d8; background-color: #3c763d; } .panel-success > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #d6e9c6; } .panel-info { border-color: #bce8f1; } .panel-info > .panel-heading { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .panel-info > .panel-heading + .panel-collapse > .panel-body { border-top-color: #bce8f1; } .panel-info > .panel-heading .badge { color: #d9edf7; background-color: #31708f; } .panel-info > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #bce8f1; } .panel-warning { border-color: #faebcc; } .panel-warning > .panel-heading { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .panel-warning > .panel-heading + .panel-collapse > .panel-body { border-top-color: #faebcc; } .panel-warning > .panel-heading .badge { color: #fcf8e3; background-color: #8a6d3b; } .panel-warning > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #faebcc; } .panel-danger { border-color: #ebccd1; } .panel-danger > .panel-heading { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .panel-danger > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ebccd1; } .panel-danger > .panel-heading .badge { color: #f2dede; background-color: #a94442; } .panel-danger > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ebccd1; } .embed-responsive { position: relative; display: block; height: 0; padding: 0; overflow: hidden; } .embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video { position: absolute; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; border: 0; } .embed-responsive-16by9 { padding-bottom: 56.25%; } .embed-responsive-4by3 { padding-bottom: 75%; } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, .15); } .well-lg { padding: 24px; border-radius: 6px; } .well-sm { padding: 9px; border-radius: 3px; } .close { float: right; font-size: 21px; font-weight: bold; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .2; } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .5; } button.close { -webkit-appearance: none; padding: 0; cursor: pointer; background: transparent; border: 0; } .modal-open { overflow: hidden; } .modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1050; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; } .modal.fade .modal-dialog { -webkit-transition: -webkit-transform .3s ease-out; -o-transition: -o-transform .3s ease-out; transition: transform .3s ease-out; -webkit-transform: translate(0, -25%); -ms-transform: translate(0, -25%); -o-transform: translate(0, -25%); transform: translate(0, -25%); } .modal.in .modal-dialog { -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); } .modal-open .modal { overflow-x: hidden; overflow-y: auto; } .modal-dialog { position: relative; width: auto; margin: 10px; } .modal-content { position: relative; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #999; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; outline: 0; -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); box-shadow: 0 3px 9px rgba(0, 0, 0, .5); } .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000; } .modal-backdrop.fade { filter: alpha(opacity=0); opacity: 0; } .modal-backdrop.in { filter: alpha(opacity=50); opacity: .5; } .modal-header { min-height: 16.42857143px; padding: 15px; border-bottom: 1px solid #e5e5e5; } .modal-header .close { margin-top: -2px; } .modal-title { margin: 0; line-height: 1.42857143; } .modal-body { position: relative; padding: 15px; } .modal-footer { padding: 15px; text-align: right; border-top: 1px solid #e5e5e5; } .modal-footer .btn + .btn { margin-bottom: 0; margin-left: 5px; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; } .modal-footer .btn-block + .btn-block { margin-left: 0; } .modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; } @media (min-width: 768px) { .modal-dialog { width: 600px; margin: 30px auto; } .modal-content { -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); box-shadow: 0 5px 15px rgba(0, 0, 0, .5); } .modal-sm { width: 300px; } } @media (min-width: 992px) { .modal-lg { width: 900px; } } .tooltip { position: absolute; z-index: 1070; display: block; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 12px; font-weight: normal; line-height: 1.4; filter: alpha(opacity=0); opacity: 0; } .tooltip.in { filter: alpha(opacity=90); opacity: .9; } .tooltip.top { padding: 5px 0; margin-top: -3px; } .tooltip.right { padding: 0 5px; margin-left: 3px; } .tooltip.bottom { padding: 5px 0; margin-top: 3px; } .tooltip.left { padding: 0 5px; margin-left: -3px; } .tooltip-inner { max-width: 200px; padding: 3px 8px; color: #fff; text-align: center; text-decoration: none; background-color: #000; border-radius: 4px; } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-left .tooltip-arrow { right: 5px; bottom: 0; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #000; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #000; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .popover { position: absolute; top: 0; left: 0; z-index: 1060; display: none; max-width: 276px; padding: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 1.42857143; text-align: left; white-space: normal; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); box-shadow: 0 5px 10px rgba(0, 0, 0, .2); } .popover.top { margin-top: -10px; } .popover.right { margin-left: 10px; } .popover.bottom { margin-top: 10px; } .popover.left { margin-left: -10px; } .popover-title { padding: 8px 14px; margin: 0; font-size: 14px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; border-radius: 5px 5px 0 0; } .popover-content { padding: 9px 14px; } .popover > .arrow, .popover > .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popover > .arrow { border-width: 11px; } .popover > .arrow:after { content: ""; border-width: 10px; } .popover.top > .arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: #999; border-top-color: rgba(0, 0, 0, .25); border-bottom-width: 0; } .popover.top > .arrow:after { bottom: 1px; margin-left: -10px; content: " "; border-top-color: #fff; border-bottom-width: 0; } .popover.right > .arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: #999; border-right-color: rgba(0, 0, 0, .25); border-left-width: 0; } .popover.right > .arrow:after { bottom: -10px; left: 1px; content: " "; border-right-color: #fff; border-left-width: 0; } .popover.bottom > .arrow { top: -11px; left: 50%; margin-left: -11px; border-top-width: 0; border-bottom-color: #999; border-bottom-color: rgba(0, 0, 0, .25); } .popover.bottom > .arrow:after { top: 1px; margin-left: -10px; content: " "; border-top-width: 0; border-bottom-color: #fff; } .popover.left > .arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; border-left-color: #999; border-left-color: rgba(0, 0, 0, .25); } .popover.left > .arrow:after { right: 1px; bottom: -10px; content: " "; border-right-width: 0; border-left-color: #fff; } .carousel { position: relative; } .carousel-inner { position: relative; width: 100%; overflow: hidden; } .carousel-inner > .item { position: relative; display: none; -webkit-transition: .6s ease-in-out left; -o-transition: .6s ease-in-out left; transition: .6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { line-height: 1; } @media all and (transform-3d), (-webkit-transform-3d) { .carousel-inner > .item { -webkit-transition: -webkit-transform .6s ease-in-out; -o-transition: -o-transform .6s ease-in-out; transition: transform .6s ease-in-out; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-perspective: 1000; perspective: 1000; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { left: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } .carousel-inner > .item.prev, .carousel-inner > .item.active.left { left: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { left: 0; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } .carousel-control { position: absolute; top: 0; bottom: 0; left: 0; width: 15%; font-size: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); filter: alpha(opacity=50); opacity: .5; } .carousel-control.left { background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); background-repeat: repeat-x; } .carousel-control.right { right: 0; left: auto; background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); background-repeat: repeat-x; } .carousel-control:hover, .carousel-control:focus { color: #fff; text-decoration: none; filter: alpha(opacity=90); outline: 0; opacity: .9; } .carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; z-index: 5; display: inline-block; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { left: 50%; margin-left: -10px; } .carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { right: 50%; margin-right: -10px; } .carousel-control .icon-prev, .carousel-control .icon-next { width: 20px; height: 20px; margin-top: -10px; font-family: serif; line-height: 1; } .carousel-control .icon-prev:before { content: '\2039'; } .carousel-control .icon-next:before { content: '\203a'; } .carousel-indicators { position: absolute; bottom: 10px; left: 50%; z-index: 15; width: 60%; padding-left: 0; margin-left: -30%; text-align: center; list-style: none; } .carousel-indicators li { display: inline-block; width: 10px; height: 10px; margin: 1px; text-indent: -999px; cursor: pointer; background-color: #000 \9; background-color: rgba(0, 0, 0, 0); border: 1px solid #fff; border-radius: 10px; } .carousel-indicators .active { width: 12px; height: 12px; margin: 0; background-color: #fff; } .carousel-caption { position: absolute; right: 15%; bottom: 20px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); } .carousel-caption .btn { text-shadow: none; } @media screen and (min-width: 768px) { .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { width: 30px; height: 30px; margin-top: -15px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { margin-left: -15px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { margin-right: -15px; } .carousel-caption { right: 20%; left: 20%; padding-bottom: 30px; } .carousel-indicators { bottom: 20px; } } .clearfix:before, .clearfix:after, .dl-horizontal dd:before, .dl-horizontal dd:after, .container:before, .container:after, .container-fluid:before, .container-fluid:after, .row:before, .row:after, .form-horizontal .form-group:before, .form-horizontal .form-group:after, .btn-toolbar:before, .btn-toolbar:after, .btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after, .nav:before, .nav:after, .navbar:before, .navbar:after, .navbar-header:before, .navbar-header:after, .navbar-collapse:before, .navbar-collapse:after, .pager:before, .pager:after, .panel-body:before, .panel-body:after, .modal-footer:before, .modal-footer:after { display: table; content: " "; } .clearfix:after, .dl-horizontal dd:after, .container:after, .container-fluid:after, .row:after, .form-horizontal .form-group:after, .btn-toolbar:after, .btn-group-vertical > .btn-group:after, .nav:after, .navbar:after, .navbar-header:after, .navbar-collapse:after, .pager:after, .panel-body:after, .modal-footer:after { clear: both; } .center-block { display: block; margin-right: auto; margin-left: auto; } .pull-right { float: right !important; } .pull-left { float: left !important; } .hide { display: none !important; } .show { display: block !important; } .invisible { visibility: hidden; } .text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .hidden { display: none !important; } .affix { position: fixed; } @-ms-viewport { width: device-width; } .visible-xs, .visible-sm, .visible-md, .visible-lg { display: none !important; } .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { display: none !important; } @media (max-width: 767px) { .visible-xs { display: block !important; } table.visible-xs { display: table; } tr.visible-xs { display: table-row !important; } th.visible-xs, td.visible-xs { display: table-cell !important; } } @media (max-width: 767px) { .visible-xs-block { display: block !important; } } @media (max-width: 767px) { .visible-xs-inline { display: inline !important; } } @media (max-width: 767px) { .visible-xs-inline-block { display: inline-block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm { display: block !important; } table.visible-sm { display: table; } tr.visible-sm { display: table-row !important; } th.visible-sm, td.visible-sm { display: table-cell !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-block { display: block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline { display: inline !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline-block { display: inline-block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md { display: block !important; } table.visible-md { display: table; } tr.visible-md { display: table-row !important; } th.visible-md, td.visible-md { display: table-cell !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-block { display: block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline { display: inline !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline-block { display: inline-block !important; } } @media (min-width: 1200px) { .visible-lg { display: block !important; } table.visible-lg { display: table; } tr.visible-lg { display: table-row !important; } th.visible-lg, td.visible-lg { display: table-cell !important; } } @media (min-width: 1200px) { .visible-lg-block { display: block !important; } } @media (min-width: 1200px) { .visible-lg-inline { display: inline !important; } } @media (min-width: 1200px) { .visible-lg-inline-block { display: inline-block !important; } } @media (max-width: 767px) { .hidden-xs { display: none !important; } } @media (min-width: 768px) and (max-width: 991px) { .hidden-sm { display: none !important; } } @media (min-width: 992px) and (max-width: 1199px) { .hidden-md { display: none !important; } } @media (min-width: 1200px) { .hidden-lg { display: none !important; } } .visible-print { display: none !important; } @media print { .visible-print { display: block !important; } table.visible-print { display: table; } tr.visible-print { display: table-row !important; } th.visible-print, td.visible-print { display: table-cell !important; } } .visible-print-block { display: none !important; } @media print { .visible-print-block { display: block !important; } } .visible-print-inline { display: none !important; } @media print { .visible-print-inline { display: inline !important; } } .visible-print-inline-block { display: none !important; } @media print { .visible-print-inline-block { display: inline-block !important; } } @media print { .hidden-print { display: none !important; } } /*# sourceMappingURL=bootstrap.css.map */ |
Added modules/bootstrap/css/bootstrap.css.map.
cannot compute difference between binary files
Added modules/bootstrap/css/bootstrap.min.css.
cannot compute difference between binary files
Added modules/bootstrap/fonts/glyphicons-halflings-regular.eot.
cannot compute difference between binary files
Added modules/bootstrap/fonts/glyphicons-halflings-regular.svg.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > <svg xmlns="http://www.w3.org/2000/svg"> <metadata></metadata> <defs> <font id="glyphicons_halflingsregular" horiz-adv-x="1200" > <font-face units-per-em="1200" ascent="960" descent="-240" /> <missing-glyph horiz-adv-x="500" /> <glyph horiz-adv-x="0" /> <glyph horiz-adv-x="400" /> <glyph unicode=" " /> <glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" /> <glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode=" " /> <glyph unicode="¥" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" /> <glyph unicode=" " horiz-adv-x="650" /> <glyph unicode=" " horiz-adv-x="1300" /> <glyph unicode=" " horiz-adv-x="650" /> <glyph unicode=" " horiz-adv-x="1300" /> <glyph unicode=" " horiz-adv-x="433" /> <glyph unicode=" " horiz-adv-x="325" /> <glyph unicode=" " horiz-adv-x="216" /> <glyph unicode=" " horiz-adv-x="216" /> <glyph unicode=" " horiz-adv-x="162" /> <glyph unicode=" " horiz-adv-x="260" /> <glyph unicode=" " horiz-adv-x="72" /> <glyph unicode=" " horiz-adv-x="260" /> <glyph unicode=" " horiz-adv-x="325" /> <glyph unicode="€" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" /> <glyph unicode="₽" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" /> <glyph unicode="−" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="⌛" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" /> <glyph unicode="◼" horiz-adv-x="500" d="M0 0z" /> <glyph unicode="☁" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" /> <glyph unicode="⛺" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " /> <glyph unicode="✉" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" /> <glyph unicode="✏" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" /> <glyph unicode="" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" /> <glyph unicode="" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" /> <glyph unicode="" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" /> <glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" /> <glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" /> <glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" /> <glyph unicode="" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" /> <glyph unicode="" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" /> <glyph unicode="" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" /> <glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" /> <glyph unicode="" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" /> <glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" /> <glyph unicode="" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" /> <glyph unicode="" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" /> <glyph unicode="" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" /> <glyph unicode="" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" /> <glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" /> <glyph unicode="" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> <glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" /> <glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" /> <glyph unicode="" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" /> <glyph unicode="" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" /> <glyph unicode="" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" /> <glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" /> <glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" /> <glyph unicode="" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" /> <glyph unicode="" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" /> <glyph unicode="" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" /> <glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> <glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> <glyph unicode="" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" /> <glyph unicode="" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" /> <glyph unicode="" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" /> <glyph unicode="" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" /> <glyph unicode="" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" /> <glyph unicode="" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" /> <glyph unicode="" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" /> <glyph unicode="" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" /> <glyph unicode="" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" /> <glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" /> <glyph unicode="" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" /> <glyph unicode="" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" /> <glyph unicode="" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" /> <glyph unicode="" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" /> <glyph unicode="" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" /> <glyph unicode="" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" /> <glyph unicode="" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" /> <glyph unicode="" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" /> <glyph unicode="" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" /> <glyph unicode="" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" /> <glyph unicode="" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" /> <glyph unicode="" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" /> <glyph unicode="" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" /> <glyph unicode="" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" /> <glyph unicode="" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" /> <glyph unicode="" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" /> <glyph unicode="" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" /> <glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" /> <glyph unicode="" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" /> <glyph unicode="" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" /> <glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> <glyph unicode="" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" /> <glyph unicode="" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" /> <glyph unicode="" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" /> <glyph unicode="" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> <glyph unicode="" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> <glyph unicode="" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" /> <glyph unicode="" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" /> <glyph unicode="" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" /> <glyph unicode="" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" /> <glyph unicode="" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" /> <glyph unicode="" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" /> <glyph unicode="" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" /> <glyph unicode="" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" /> <glyph unicode="" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> <glyph unicode="" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" /> <glyph unicode="" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" /> <glyph unicode="" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" /> <glyph unicode="" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> <glyph unicode="" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" /> <glyph unicode="" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" /> <glyph unicode="" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" /> <glyph unicode="" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" /> <glyph unicode="" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" /> <glyph unicode="" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" /> <glyph unicode="" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" /> <glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" /> <glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" /> <glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" /> <glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" /> <glyph unicode="" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" /> <glyph unicode="" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" /> <glyph unicode="" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " /> <glyph unicode="" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" /> <glyph unicode="" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" /> <glyph unicode="" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" /> <glyph unicode="" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" /> <glyph unicode="" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" /> <glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" /> <glyph unicode="" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" /> <glyph unicode="" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" /> <glyph unicode="" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" /> <glyph unicode="" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" /> <glyph unicode="" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> <glyph unicode="" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" /> <glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" /> <glyph unicode="" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" /> <glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> <glyph unicode="" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" /> <glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" /> <glyph unicode="" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> <glyph unicode="" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" /> <glyph unicode="" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> <glyph unicode="" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" /> <glyph unicode="" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" /> <glyph unicode="" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> <glyph unicode="" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> <glyph unicode="" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" /> <glyph unicode="" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> <glyph unicode="" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> <glyph unicode="" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" /> <glyph unicode="" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" /> <glyph unicode="" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" /> <glyph unicode="" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" /> <glyph unicode="" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" /> <glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" /> <glyph unicode="" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" /> <glyph unicode="" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" /> <glyph unicode="" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" /> <glyph unicode="" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" /> <glyph unicode="" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" /> <glyph unicode="" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" /> <glyph unicode="" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" /> <glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" /> <glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" /> <glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" /> <glyph unicode="" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" /> <glyph unicode="" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" /> <glyph unicode="" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" /> <glyph unicode="" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" /> <glyph unicode="" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" /> <glyph unicode="" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" /> <glyph unicode="" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" /> <glyph unicode="" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" /> <glyph unicode="" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" /> <glyph unicode="" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" /> <glyph unicode="" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" /> <glyph unicode="" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" /> <glyph unicode="" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" /> <glyph unicode="" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" /> <glyph unicode="" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " /> <glyph unicode="" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" /> <glyph unicode="" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" /> <glyph unicode="" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" /> <glyph unicode="" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" /> <glyph unicode="" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> <glyph unicode="" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> <glyph unicode="" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" /> <glyph unicode="" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> <glyph unicode="" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> <glyph unicode="" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> <glyph unicode="" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" /> <glyph unicode="" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" /> <glyph unicode="" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" /> <glyph unicode="" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" /> <glyph unicode="" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" /> <glyph unicode="" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" /> <glyph unicode="" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" /> <glyph unicode="" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" /> <glyph unicode="" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" /> <glyph unicode="" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" /> <glyph unicode="" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> <glyph unicode="" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" /> <glyph unicode="" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" /> <glyph unicode="" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" /> <glyph unicode="" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" /> <glyph unicode="" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" /> <glyph unicode="" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" /> <glyph unicode="" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" /> <glyph unicode="" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" /> <glyph unicode="" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" /> <glyph unicode="" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" /> <glyph unicode="" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" /> <glyph unicode="" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" /> <glyph unicode="🔑" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" /> <glyph unicode="🚪" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" /> </font> </defs></svg> |
Added modules/bootstrap/fonts/glyphicons-halflings-regular.ttf.
cannot compute difference between binary files
Added modules/bootstrap/fonts/glyphicons-halflings-regular.woff.
cannot compute difference between binary files
Added modules/bootstrap/fonts/glyphicons-halflings-regular.woff2.
cannot compute difference between binary files
Added modules/bootstrap/js/bootstrap.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 | /*! * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') } +function ($) { 'use strict'; var version = $.fn.jquery.split(' ')[0].split('.') if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') } }(jQuery); /* ======================================================================== * Bootstrap: transition.js v3.3.4 * http://getbootstrap.com/javascript/#transitions * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) // ============================================================ function transitionEnd() { var el = document.createElement('bootstrap') var transEndEventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd otransitionend', transition : 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return { end: transEndEventNames[name] } } } return false // explicit for ie8 ( ._.) } // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function () { called = true }) var callback = function () { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function () { $.support.transition = transitionEnd() if (!$.support.transition) return $.event.special.bsTransitionEnd = { bindType: $.support.transition.end, delegateType: $.support.transition.end, handle: function (e) { if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } }) }(jQuery); /* ======================================================================== * Bootstrap: alert.js v3.3.4 * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // ALERT CLASS DEFINITION // ====================== var dismiss = '[data-dismiss="alert"]' var Alert = function (el) { $(el).on('click', dismiss, this.close) } Alert.VERSION = '3.3.4' Alert.TRANSITION_DURATION = 150 Alert.prototype.close = function (e) { var $this = $(this) var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('close.bs.alert')) if (e.isDefaultPrevented()) return $parent.removeClass('in') function removeElement() { // detach from parent, fire event then clean up data $parent.detach().trigger('closed.bs.alert').remove() } $.support.transition && $parent.hasClass('fade') ? $parent .one('bsTransitionEnd', removeElement) .emulateTransitionEnd(Alert.TRANSITION_DURATION) : removeElement() } // ALERT PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.alert') if (!data) $this.data('bs.alert', (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.alert $.fn.alert = Plugin $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function () { $.fn.alert = old return this } // ALERT DATA-API // ============== $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) }(jQuery); /* ======================================================================== * Bootstrap: button.js v3.3.4 * http://getbootstrap.com/javascript/#buttons * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // BUTTON PUBLIC CLASS DEFINITION // ============================== var Button = function (element, options) { this.$element = $(element) this.options = $.extend({}, Button.DEFAULTS, options) this.isLoading = false } Button.VERSION = '3.3.4' Button.DEFAULTS = { loadingText: 'loading...' } Button.prototype.setState = function (state) { var d = 'disabled' var $el = this.$element var val = $el.is('input') ? 'val' : 'html' var data = $el.data() state = state + 'Text' if (data.resetText == null) $el.data('resetText', $el[val]()) // push to event loop to allow forms to submit setTimeout($.proxy(function () { $el[val](data[state] == null ? this.options[state] : data[state]) if (state == 'loadingText') { this.isLoading = true $el.addClass(d).attr(d, d) } else if (this.isLoading) { this.isLoading = false $el.removeClass(d).removeAttr(d) } }, this), 0) } Button.prototype.toggle = function () { var changed = true var $parent = this.$element.closest('[data-toggle="buttons"]') if ($parent.length) { var $input = this.$element.find('input') if ($input.prop('type') == 'radio') { if ($input.prop('checked') && this.$element.hasClass('active')) changed = false else $parent.find('.active').removeClass('active') } if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') } else { this.$element.attr('aria-pressed', !this.$element.hasClass('active')) } if (changed) this.$element.toggleClass('active') } // BUTTON PLUGIN DEFINITION // ======================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.button') var options = typeof option == 'object' && option if (!data) $this.data('bs.button', (data = new Button(this, options))) if (option == 'toggle') data.toggle() else if (option) data.setState(option) }) } var old = $.fn.button $.fn.button = Plugin $.fn.button.Constructor = Button // BUTTON NO CONFLICT // ================== $.fn.button.noConflict = function () { $.fn.button = old return this } // BUTTON DATA-API // =============== $(document) .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { var $btn = $(e.target) if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') Plugin.call($btn, 'toggle') e.preventDefault() }) .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) }) }(jQuery); /* ======================================================================== * Bootstrap: carousel.js v3.3.4 * http://getbootstrap.com/javascript/#carousel * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CAROUSEL CLASS DEFINITION // ========================= var Carousel = function (element, options) { this.$element = $(element) this.$indicators = this.$element.find('.carousel-indicators') this.options = options this.paused = null this.sliding = null this.interval = null this.$active = null this.$items = null this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } Carousel.VERSION = '3.3.4' Carousel.TRANSITION_DURATION = 600 Carousel.DEFAULTS = { interval: 5000, pause: 'hover', wrap: true, keyboard: true } Carousel.prototype.keydown = function (e) { if (/input|textarea/i.test(e.target.tagName)) return switch (e.which) { case 37: this.prev(); break case 39: this.next(); break default: return } e.preventDefault() } Carousel.prototype.cycle = function (e) { e || (this.paused = false) this.interval && clearInterval(this.interval) this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) return this } Carousel.prototype.getItemIndex = function (item) { this.$items = item.parent().children('.item') return this.$items.index(item || this.$active) } Carousel.prototype.getItemForDirection = function (direction, active) { var activeIndex = this.getItemIndex(active) var willWrap = (direction == 'prev' && activeIndex === 0) || (direction == 'next' && activeIndex == (this.$items.length - 1)) if (willWrap && !this.options.wrap) return active var delta = direction == 'prev' ? -1 : 1 var itemIndex = (activeIndex + delta) % this.$items.length return this.$items.eq(itemIndex) } Carousel.prototype.to = function (pos) { var that = this var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) if (pos > (this.$items.length - 1) || pos < 0) return if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" if (activeIndex == pos) return this.pause().cycle() return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) } Carousel.prototype.pause = function (e) { e || (this.paused = true) if (this.$element.find('.next, .prev').length && $.support.transition) { this.$element.trigger($.support.transition.end) this.cycle(true) } this.interval = clearInterval(this.interval) return this } Carousel.prototype.next = function () { if (this.sliding) return return this.slide('next') } Carousel.prototype.prev = function () { if (this.sliding) return return this.slide('prev') } Carousel.prototype.slide = function (type, next) { var $active = this.$element.find('.item.active') var $next = next || this.getItemForDirection(type, $active) var isCycling = this.interval var direction = type == 'next' ? 'left' : 'right' var that = this if ($next.hasClass('active')) return (this.sliding = false) var relatedTarget = $next[0] var slideEvent = $.Event('slide.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) this.$element.trigger(slideEvent) if (slideEvent.isDefaultPrevented()) return this.sliding = true isCycling && this.pause() if (this.$indicators.length) { this.$indicators.find('.active').removeClass('active') var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) $nextIndicator && $nextIndicator.addClass('active') } var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) $next.addClass(direction) $active .one('bsTransitionEnd', function () { $next.removeClass([type, direction].join(' ')).addClass('active') $active.removeClass(['active', direction].join(' ')) that.sliding = false setTimeout(function () { that.$element.trigger(slidEvent) }, 0) }) .emulateTransitionEnd(Carousel.TRANSITION_DURATION) } else { $active.removeClass('active') $next.addClass('active') this.sliding = false this.$element.trigger(slidEvent) } isCycling && this.cycle() return this } // CAROUSEL PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.carousel') var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) var action = typeof option == 'string' ? option : options.slide if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) if (typeof option == 'number') data.to(option) else if (action) data[action]() else if (options.interval) data.pause().cycle() }) } var old = $.fn.carousel $.fn.carousel = Plugin $.fn.carousel.Constructor = Carousel // CAROUSEL NO CONFLICT // ==================== $.fn.carousel.noConflict = function () { $.fn.carousel = old return this } // CAROUSEL DATA-API // ================= var clickHandler = function (e) { var href var $this = $(this) var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 if (!$target.hasClass('carousel')) return var options = $.extend({}, $target.data(), $this.data()) var slideIndex = $this.attr('data-slide-to') if (slideIndex) options.interval = false Plugin.call($target, options) if (slideIndex) { $target.data('bs.carousel').to(slideIndex) } e.preventDefault() } $(document) .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) $(window).on('load', function () { $('[data-ride="carousel"]').each(function () { var $carousel = $(this) Plugin.call($carousel, $carousel.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: collapse.js v3.3.4 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // COLLAPSE PUBLIC CLASS DEFINITION // ================================ var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + '[data-toggle="collapse"][data-target="#' + element.id + '"]') this.transitioning = null if (this.options.parent) { this.$parent = this.getParent() } else { this.addAriaAndCollapsedClass(this.$element, this.$trigger) } if (this.options.toggle) this.toggle() } Collapse.VERSION = '3.3.4' Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { toggle: true } Collapse.prototype.dimension = function () { var hasWidth = this.$element.hasClass('width') return hasWidth ? 'width' : 'height' } Collapse.prototype.show = function () { if (this.transitioning || this.$element.hasClass('in')) return var activesData var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') if (actives && actives.length) { activesData = actives.data('bs.collapse') if (activesData && activesData.transitioning) return } var startEvent = $.Event('show.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return if (actives && actives.length) { Plugin.call(actives, 'hide') activesData || actives.data('bs.collapse', null) } var dimension = this.dimension() this.$element .removeClass('collapse') .addClass('collapsing')[dimension](0) .attr('aria-expanded', true) this.$trigger .removeClass('collapsed') .attr('aria-expanded', true) this.transitioning = 1 var complete = function () { this.$element .removeClass('collapsing') .addClass('collapse in')[dimension]('') this.transitioning = 0 this.$element .trigger('shown.bs.collapse') } if (!$.support.transition) return complete.call(this) var scrollSize = $.camelCase(['scroll', dimension].join('-')) this.$element .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) } Collapse.prototype.hide = function () { if (this.transitioning || !this.$element.hasClass('in')) return var startEvent = $.Event('hide.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var dimension = this.dimension() this.$element[dimension](this.$element[dimension]())[0].offsetHeight this.$element .addClass('collapsing') .removeClass('collapse in') .attr('aria-expanded', false) this.$trigger .addClass('collapsed') .attr('aria-expanded', false) this.transitioning = 1 var complete = function () { this.transitioning = 0 this.$element .removeClass('collapsing') .addClass('collapse') .trigger('hidden.bs.collapse') } if (!$.support.transition) return complete.call(this) this.$element [dimension](0) .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION) } Collapse.prototype.toggle = function () { this[this.$element.hasClass('in') ? 'hide' : 'show']() } Collapse.prototype.getParent = function () { return $(this.options.parent) .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') .each($.proxy(function (i, element) { var $element = $(element) this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) }, this)) .end() } Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { var isOpen = $element.hasClass('in') $element.attr('aria-expanded', isOpen) $trigger .toggleClass('collapsed', !isOpen) .attr('aria-expanded', isOpen) } function getTargetFromTrigger($trigger) { var href var target = $trigger.attr('data-target') || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 return $(target) } // COLLAPSE PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.collapse') var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.collapse $.fn.collapse = Plugin $.fn.collapse.Constructor = Collapse // COLLAPSE NO CONFLICT // ==================== $.fn.collapse.noConflict = function () { $.fn.collapse = old return this } // COLLAPSE DATA-API // ================= $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { var $this = $(this) if (!$this.attr('data-target')) e.preventDefault() var $target = getTargetFromTrigger($this) var data = $target.data('bs.collapse') var option = data ? 'toggle' : $this.data() Plugin.call($target, option) }) }(jQuery); /* ======================================================================== * Bootstrap: dropdown.js v3.3.4 * http://getbootstrap.com/javascript/#dropdowns * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // DROPDOWN CLASS DEFINITION // ========================= var backdrop = '.dropdown-backdrop' var toggle = '[data-toggle="dropdown"]' var Dropdown = function (element) { $(element).on('click.bs.dropdown', this.toggle) } Dropdown.VERSION = '3.3.4' Dropdown.prototype.toggle = function (e) { var $this = $(this) if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus) } var relatedTarget = { relatedTarget: this } $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this .trigger('focus') .attr('aria-expanded', 'true') $parent .toggleClass('open') .trigger('shown.bs.dropdown', relatedTarget) } return false } Dropdown.prototype.keydown = function (e) { if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return var $this = $(this) e.preventDefault() e.stopPropagation() if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { if (e.which == 27) $parent.find(toggle).trigger('focus') return $this.trigger('click') } var desc = ' li:not(.disabled):visible a' var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) if (!$items.length) return var index = $items.index(e.target) if (e.which == 38 && index > 0) index-- // up if (e.which == 40 && index < $items.length - 1) index++ // down if (!~index) index = 0 $items.eq(index).trigger('focus') } function clearMenus(e) { if (e && e.which === 3) return $(backdrop).remove() $(toggle).each(function () { var $this = $(this) var $parent = getParent($this) var relatedTarget = { relatedTarget: this } if (!$parent.hasClass('open')) return $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this.attr('aria-expanded', 'false') $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) }) } function getParent($this) { var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = selector && $(selector) return $parent && $parent.length ? $parent : $this.parent() } // DROPDOWN PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.dropdown') if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.dropdown $.fn.dropdown = Plugin $.fn.dropdown.Constructor = Dropdown // DROPDOWN NO CONFLICT // ==================== $.fn.dropdown.noConflict = function () { $.fn.dropdown = old return this } // APPLY TO STANDARD DROPDOWN ELEMENTS // =================================== $(document) .on('click.bs.dropdown.data-api', clearMenus) .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) }(jQuery); /* ======================================================================== * Bootstrap: modal.js v3.3.4 * http://getbootstrap.com/javascript/#modals * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // MODAL CLASS DEFINITION // ====================== var Modal = function (element, options) { this.options = options this.$body = $(document.body) this.$element = $(element) this.$dialog = this.$element.find('.modal-dialog') this.$backdrop = null this.isShown = null this.originalBodyPad = null this.scrollbarWidth = 0 this.ignoreBackdropClick = false if (this.options.remote) { this.$element .find('.modal-content') .load(this.options.remote, $.proxy(function () { this.$element.trigger('loaded.bs.modal') }, this)) } } Modal.VERSION = '3.3.4' Modal.TRANSITION_DURATION = 300 Modal.BACKDROP_TRANSITION_DURATION = 150 Modal.DEFAULTS = { backdrop: true, keyboard: true, show: true } Modal.prototype.toggle = function (_relatedTarget) { return this.isShown ? this.hide() : this.show(_relatedTarget) } Modal.prototype.show = function (_relatedTarget) { var that = this var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) this.$element.trigger(e) if (this.isShown || e.isDefaultPrevented()) return this.isShown = true this.checkScrollbar() this.setScrollbar() this.$body.addClass('modal-open') this.escape() this.resize() this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) this.$dialog.on('mousedown.dismiss.bs.modal', function () { that.$element.one('mouseup.dismiss.bs.modal', function (e) { if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true }) }) this.backdrop(function () { var transition = $.support.transition && that.$element.hasClass('fade') if (!that.$element.parent().length) { that.$element.appendTo(that.$body) // don't move modals dom position } that.$element .show() .scrollTop(0) that.adjustDialog() if (transition) { that.$element[0].offsetWidth // force reflow } that.$element .addClass('in') .attr('aria-hidden', false) that.enforceFocus() var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) transition ? that.$dialog // wait for modal to slide in .one('bsTransitionEnd', function () { that.$element.trigger('focus').trigger(e) }) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : that.$element.trigger('focus').trigger(e) }) } Modal.prototype.hide = function (e) { if (e) e.preventDefault() e = $.Event('hide.bs.modal') this.$element.trigger(e) if (!this.isShown || e.isDefaultPrevented()) return this.isShown = false this.escape() this.resize() $(document).off('focusin.bs.modal') this.$element .removeClass('in') .attr('aria-hidden', true) .off('click.dismiss.bs.modal') .off('mouseup.dismiss.bs.modal') this.$dialog.off('mousedown.dismiss.bs.modal') $.support.transition && this.$element.hasClass('fade') ? this.$element .one('bsTransitionEnd', $.proxy(this.hideModal, this)) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : this.hideModal() } Modal.prototype.enforceFocus = function () { $(document) .off('focusin.bs.modal') // guard against infinite focus loop .on('focusin.bs.modal', $.proxy(function (e) { if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { this.$element.trigger('focus') } }, this)) } Modal.prototype.escape = function () { if (this.isShown && this.options.keyboard) { this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { e.which == 27 && this.hide() }, this)) } else if (!this.isShown) { this.$element.off('keydown.dismiss.bs.modal') } } Modal.prototype.resize = function () { if (this.isShown) { $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) } else { $(window).off('resize.bs.modal') } } Modal.prototype.hideModal = function () { var that = this this.$element.hide() this.backdrop(function () { that.$body.removeClass('modal-open') that.resetAdjustments() that.resetScrollbar() that.$element.trigger('hidden.bs.modal') }) } Modal.prototype.removeBackdrop = function () { this.$backdrop && this.$backdrop.remove() this.$backdrop = null } Modal.prototype.backdrop = function (callback) { var that = this var animate = this.$element.hasClass('fade') ? 'fade' : '' if (this.isShown && this.options.backdrop) { var doAnimate = $.support.transition && animate this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') .appendTo(this.$body) this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { if (this.ignoreBackdropClick) { this.ignoreBackdropClick = false return } if (e.target !== e.currentTarget) return this.options.backdrop == 'static' ? this.$element[0].focus() : this.hide() }, this)) if (doAnimate) this.$backdrop[0].offsetWidth // force reflow this.$backdrop.addClass('in') if (!callback) return doAnimate ? this.$backdrop .one('bsTransitionEnd', callback) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callback() } else if (!this.isShown && this.$backdrop) { this.$backdrop.removeClass('in') var callbackRemove = function () { that.removeBackdrop() callback && callback() } $.support.transition && this.$element.hasClass('fade') ? this.$backdrop .one('bsTransitionEnd', callbackRemove) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callbackRemove() } else if (callback) { callback() } } // these following methods are used to handle overflowing modals Modal.prototype.handleUpdate = function () { this.adjustDialog() } Modal.prototype.adjustDialog = function () { var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight this.$element.css({ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' }) } Modal.prototype.resetAdjustments = function () { this.$element.css({ paddingLeft: '', paddingRight: '' }) } Modal.prototype.checkScrollbar = function () { var fullWindowWidth = window.innerWidth if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 var documentElementRect = document.documentElement.getBoundingClientRect() fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) } this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth this.scrollbarWidth = this.measureScrollbar() } Modal.prototype.setScrollbar = function () { var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) this.originalBodyPad = document.body.style.paddingRight || '' if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) } Modal.prototype.resetScrollbar = function () { this.$body.css('padding-right', this.originalBodyPad) } Modal.prototype.measureScrollbar = function () { // thx walsh var scrollDiv = document.createElement('div') scrollDiv.className = 'modal-scrollbar-measure' this.$body.append(scrollDiv) var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth this.$body[0].removeChild(scrollDiv) return scrollbarWidth } // MODAL PLUGIN DEFINITION // ======================= function Plugin(option, _relatedTarget) { return this.each(function () { var $this = $(this) var data = $this.data('bs.modal') var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data) $this.data('bs.modal', (data = new Modal(this, options))) if (typeof option == 'string') data[option](_relatedTarget) else if (options.show) data.show(_relatedTarget) }) } var old = $.fn.modal $.fn.modal = Plugin $.fn.modal.Constructor = Modal // MODAL NO CONFLICT // ================= $.fn.modal.noConflict = function () { $.fn.modal = old return this } // MODAL DATA-API // ============== $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { var $this = $(this) var href = $this.attr('href') var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) if ($this.is('a')) e.preventDefault() $target.one('show.bs.modal', function (showEvent) { if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown $target.one('hidden.bs.modal', function () { $this.is(':visible') && $this.trigger('focus') }) }) Plugin.call($target, option, this) }) }(jQuery); /* ======================================================================== * Bootstrap: tooltip.js v3.3.4 * http://getbootstrap.com/javascript/#tooltip * Inspired by the original jQuery.tipsy by Jason Frame * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TOOLTIP PUBLIC CLASS DEFINITION // =============================== var Tooltip = function (element, options) { this.type = null this.options = null this.enabled = null this.timeout = null this.hoverState = null this.$element = null this.init('tooltip', element, options) } Tooltip.VERSION = '3.3.4' Tooltip.TRANSITION_DURATION = 150 Tooltip.DEFAULTS = { animation: true, placement: 'top', selector: false, template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', trigger: 'hover focus', title: '', delay: 0, html: false, container: false, viewport: { selector: 'body', padding: 0 } } Tooltip.prototype.init = function (type, element, options) { this.enabled = true this.type = type this.$element = $(element) this.options = this.getOptions(options) this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) if (this.$element[0] instanceof document.constructor && !this.options.selector) { throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') } var triggers = this.options.trigger.split(' ') for (var i = triggers.length; i--;) { var trigger = triggers[i] if (trigger == 'click') { this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) } else if (trigger != 'manual') { var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) } } this.options.selector ? (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle() } Tooltip.prototype.getDefaults = function () { return Tooltip.DEFAULTS } Tooltip.prototype.getOptions = function (options) { options = $.extend({}, this.getDefaults(), this.$element.data(), options) if (options.delay && typeof options.delay == 'number') { options.delay = { show: options.delay, hide: options.delay } } return options } Tooltip.prototype.getDelegateOptions = function () { var options = {} var defaults = this.getDefaults() this._options && $.each(this._options, function (key, value) { if (defaults[key] != value) options[key] = value }) return options } Tooltip.prototype.enter = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (self && self.$tip && self.$tip.is(':visible')) { self.hoverState = 'in' return } if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } clearTimeout(self.timeout) self.hoverState = 'in' if (!self.options.delay || !self.options.delay.show) return self.show() self.timeout = setTimeout(function () { if (self.hoverState == 'in') self.show() }, self.options.delay.show) } Tooltip.prototype.leave = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } clearTimeout(self.timeout) self.hoverState = 'out' if (!self.options.delay || !self.options.delay.hide) return self.hide() self.timeout = setTimeout(function () { if (self.hoverState == 'out') self.hide() }, self.options.delay.hide) } Tooltip.prototype.show = function () { var e = $.Event('show.bs.' + this.type) if (this.hasContent() && this.enabled) { this.$element.trigger(e) var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) if (e.isDefaultPrevented() || !inDom) return var that = this var $tip = this.tip() var tipId = this.getUID(this.type) this.setContent() $tip.attr('id', tipId) this.$element.attr('aria-describedby', tipId) if (this.options.animation) $tip.addClass('fade') var placement = typeof this.options.placement == 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement var autoToken = /\s?auto?\s?/i var autoPlace = autoToken.test(placement) if (autoPlace) placement = placement.replace(autoToken, '') || 'top' $tip .detach() .css({ top: 0, left: 0, display: 'block' }) .addClass(placement) .data('bs.' + this.type, this) this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) var pos = this.getPosition() var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (autoPlace) { var orgPlacement = placement var $container = this.options.container ? $(this.options.container) : this.$element.parent() var containerDim = this.getPosition($container) placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : placement $tip .removeClass(orgPlacement) .addClass(placement) } var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) this.applyPlacement(calculatedOffset, placement) var complete = function () { var prevHoverState = that.hoverState that.$element.trigger('shown.bs.' + that.type) that.hoverState = null if (prevHoverState == 'out') that.leave(that) } $.support.transition && this.$tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() } } Tooltip.prototype.applyPlacement = function (offset, placement) { var $tip = this.tip() var width = $tip[0].offsetWidth var height = $tip[0].offsetHeight // manually read margins because getBoundingClientRect includes difference var marginTop = parseInt($tip.css('margin-top'), 10) var marginLeft = parseInt($tip.css('margin-left'), 10) // we must check for NaN for ie 8/9 if (isNaN(marginTop)) marginTop = 0 if (isNaN(marginLeft)) marginLeft = 0 offset.top = offset.top + marginTop offset.left = offset.left + marginLeft // $.fn.offset doesn't round pixel values // so we use setOffset directly with our own function B-0 $.offset.setOffset($tip[0], $.extend({ using: function (props) { $tip.css({ top: Math.round(props.top), left: Math.round(props.left) }) } }, offset), 0) $tip.addClass('in') // check to see if placing tip in new offset caused the tip to resize itself var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (placement == 'top' && actualHeight != height) { offset.top = offset.top + height - actualHeight } var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) if (delta.left) offset.left += delta.left else offset.top += delta.top var isVertical = /top|bottom/.test(placement) var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' $tip.offset(offset) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) } Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { this.arrow() .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') .css(isVertical ? 'top' : 'left', '') } Tooltip.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) $tip.removeClass('fade in top bottom left right') } Tooltip.prototype.hide = function (callback) { var that = this var $tip = $(this.$tip) var e = $.Event('hide.bs.' + this.type) function complete() { if (that.hoverState != 'in') $tip.detach() that.$element .removeAttr('aria-describedby') .trigger('hidden.bs.' + that.type) callback && callback() } this.$element.trigger(e) if (e.isDefaultPrevented()) return $tip.removeClass('in') $.support.transition && $tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() this.hoverState = null return this } Tooltip.prototype.fixTitle = function () { var $e = this.$element if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') } } Tooltip.prototype.hasContent = function () { return this.getTitle() } Tooltip.prototype.getPosition = function ($element) { $element = $element || this.$element var el = $element[0] var isBody = el.tagName == 'BODY' var elRect = el.getBoundingClientRect() if (elRect.width == null) { // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) } var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null return $.extend({}, elRect, scroll, outerDims, elOffset) } Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } } Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { var delta = { top: 0, left: 0 } if (!this.$viewport) return delta var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 var viewportDimensions = this.getPosition(this.$viewport) if (/right|left/.test(placement)) { var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight if (topEdgeOffset < viewportDimensions.top) { // top overflow delta.top = viewportDimensions.top - topEdgeOffset } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset } } else { var leftEdgeOffset = pos.left - viewportPadding var rightEdgeOffset = pos.left + viewportPadding + actualWidth if (leftEdgeOffset < viewportDimensions.left) { // left overflow delta.left = viewportDimensions.left - leftEdgeOffset } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset } } return delta } Tooltip.prototype.getTitle = function () { var title var $e = this.$element var o = this.options title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) return title } Tooltip.prototype.getUID = function (prefix) { do prefix += ~~(Math.random() * 1000000) while (document.getElementById(prefix)) return prefix } Tooltip.prototype.tip = function () { return (this.$tip = this.$tip || $(this.options.template)) } Tooltip.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) } Tooltip.prototype.enable = function () { this.enabled = true } Tooltip.prototype.disable = function () { this.enabled = false } Tooltip.prototype.toggleEnabled = function () { this.enabled = !this.enabled } Tooltip.prototype.toggle = function (e) { var self = this if (e) { self = $(e.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(e.currentTarget, this.getDelegateOptions()) $(e.currentTarget).data('bs.' + this.type, self) } } self.tip().hasClass('in') ? self.leave(self) : self.enter(self) } Tooltip.prototype.destroy = function () { var that = this clearTimeout(this.timeout) this.hide(function () { that.$element.off('.' + that.type).removeData('bs.' + that.type) }) } // TOOLTIP PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tooltip') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tooltip $.fn.tooltip = Plugin $.fn.tooltip.Constructor = Tooltip // TOOLTIP NO CONFLICT // =================== $.fn.tooltip.noConflict = function () { $.fn.tooltip = old return this } }(jQuery); /* ======================================================================== * Bootstrap: popover.js v3.3.4 * http://getbootstrap.com/javascript/#popovers * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // POPOVER PUBLIC CLASS DEFINITION // =============================== var Popover = function (element, options) { this.init('popover', element, options) } if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') Popover.VERSION = '3.3.4' Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { placement: 'right', trigger: 'click', content: '', template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' }) // NOTE: POPOVER EXTENDS tooltip.js // ================================ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) Popover.prototype.constructor = Popover Popover.prototype.getDefaults = function () { return Popover.DEFAULTS } Popover.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() var content = this.getContent() $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' ](content) $tip.removeClass('fade top bottom left right in') // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do // this manually by checking the contents. if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() } Popover.prototype.hasContent = function () { return this.getTitle() || this.getContent() } Popover.prototype.getContent = function () { var $e = this.$element var o = this.options return $e.attr('data-content') || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) } Popover.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.arrow')) } // POPOVER PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.popover') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.popover', (data = new Popover(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.popover $.fn.popover = Plugin $.fn.popover.Constructor = Popover // POPOVER NO CONFLICT // =================== $.fn.popover.noConflict = function () { $.fn.popover = old return this } }(jQuery); /* ======================================================================== * Bootstrap: scrollspy.js v3.3.4 * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // SCROLLSPY CLASS DEFINITION // ========================== function ScrollSpy(element, options) { this.$body = $(document.body) this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) this.selector = (this.options.target || '') + ' .nav li > a' this.offsets = [] this.targets = [] this.activeTarget = null this.scrollHeight = 0 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) this.refresh() this.process() } ScrollSpy.VERSION = '3.3.4' ScrollSpy.DEFAULTS = { offset: 10 } ScrollSpy.prototype.getScrollHeight = function () { return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) } ScrollSpy.prototype.refresh = function () { var that = this var offsetMethod = 'offset' var offsetBase = 0 this.offsets = [] this.targets = [] this.scrollHeight = this.getScrollHeight() if (!$.isWindow(this.$scrollElement[0])) { offsetMethod = 'position' offsetBase = this.$scrollElement.scrollTop() } this.$body .find(this.selector) .map(function () { var $el = $(this) var href = $el.data('target') || $el.attr('href') var $href = /^#./.test(href) && $(href) return ($href && $href.length && $href.is(':visible') && [[$href[offsetMethod]().top + offsetBase, href]]) || null }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { that.offsets.push(this[0]) that.targets.push(this[1]) }) } ScrollSpy.prototype.process = function () { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset var scrollHeight = this.getScrollHeight() var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() var offsets = this.offsets var targets = this.targets var activeTarget = this.activeTarget var i if (this.scrollHeight != scrollHeight) { this.refresh() } if (scrollTop >= maxScroll) { return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) } if (activeTarget && scrollTop < offsets[0]) { this.activeTarget = null return this.clear() } for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) && this.activate(targets[i]) } } ScrollSpy.prototype.activate = function (target) { this.activeTarget = target this.clear() var selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') .addClass('active') if (active.parent('.dropdown-menu').length) { active = active .closest('li.dropdown') .addClass('active') } active.trigger('activate.bs.scrollspy') } ScrollSpy.prototype.clear = function () { $(this.selector) .parentsUntil(this.options.target, '.active') .removeClass('active') } // SCROLLSPY PLUGIN DEFINITION // =========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.scrollspy') var options = typeof option == 'object' && option if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.scrollspy $.fn.scrollspy = Plugin $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function () { $.fn.scrollspy = old return this } // SCROLLSPY DATA-API // ================== $(window).on('load.bs.scrollspy.data-api', function () { $('[data-spy="scroll"]').each(function () { var $spy = $(this) Plugin.call($spy, $spy.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: tab.js v3.3.4 * http://getbootstrap.com/javascript/#tabs * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TAB CLASS DEFINITION // ==================== var Tab = function (element) { this.element = $(element) } Tab.VERSION = '3.3.4' Tab.TRANSITION_DURATION = 150 Tab.prototype.show = function () { var $this = this.element var $ul = $this.closest('ul:not(.dropdown-menu)') var selector = $this.data('target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } if ($this.parent('li').hasClass('active')) return var $previous = $ul.find('.active:last a') var hideEvent = $.Event('hide.bs.tab', { relatedTarget: $this[0] }) var showEvent = $.Event('show.bs.tab', { relatedTarget: $previous[0] }) $previous.trigger(hideEvent) $this.trigger(showEvent) if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return var $target = $(selector) this.activate($this.closest('li'), $ul) this.activate($target, $target.parent(), function () { $previous.trigger({ type: 'hidden.bs.tab', relatedTarget: $this[0] }) $this.trigger({ type: 'shown.bs.tab', relatedTarget: $previous[0] }) }) } Tab.prototype.activate = function (element, container, callback) { var $active = container.find('> .active') var transition = callback && $.support.transition && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', false) element .addClass('active') .find('[data-toggle="tab"]') .attr('aria-expanded', true) if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if (element.parent('.dropdown-menu').length) { element .closest('li.dropdown') .addClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', true) } callback && callback() } $active.length && transition ? $active .one('bsTransitionEnd', next) .emulateTransitionEnd(Tab.TRANSITION_DURATION) : next() $active.removeClass('in') } // TAB PLUGIN DEFINITION // ===================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tab') if (!data) $this.data('bs.tab', (data = new Tab(this))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tab $.fn.tab = Plugin $.fn.tab.Constructor = Tab // TAB NO CONFLICT // =============== $.fn.tab.noConflict = function () { $.fn.tab = old return this } // TAB DATA-API // ============ var clickHandler = function (e) { e.preventDefault() Plugin.call($(this), 'show') } $(document) .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) }(jQuery); /* ======================================================================== * Bootstrap: affix.js v3.3.4 * http://getbootstrap.com/javascript/#affix * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // AFFIX CLASS DEFINITION // ====================== var Affix = function (element, options) { this.options = $.extend({}, Affix.DEFAULTS, options) this.$target = $(this.options.target) .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) this.$element = $(element) this.affixed = null this.unpin = null this.pinnedOffset = null this.checkPosition() } Affix.VERSION = '3.3.4' Affix.RESET = 'affix affix-top affix-bottom' Affix.DEFAULTS = { offset: 0, target: window } Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { var scrollTop = this.$target.scrollTop() var position = this.$element.offset() var targetHeight = this.$target.height() if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false if (this.affixed == 'bottom') { if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' } var initializing = this.affixed == null var colliderTop = initializing ? scrollTop : position.top var colliderHeight = initializing ? targetHeight : height if (offsetTop != null && scrollTop <= offsetTop) return 'top' if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' return false } Affix.prototype.getPinnedOffset = function () { if (this.pinnedOffset) return this.pinnedOffset this.$element.removeClass(Affix.RESET).addClass('affix') var scrollTop = this.$target.scrollTop() var position = this.$element.offset() return (this.pinnedOffset = position.top - scrollTop) } Affix.prototype.checkPositionWithEventLoop = function () { setTimeout($.proxy(this.checkPosition, this), 1) } Affix.prototype.checkPosition = function () { if (!this.$element.is(':visible')) return var height = this.$element.height() var offset = this.options.offset var offsetTop = offset.top var offsetBottom = offset.bottom var scrollHeight = $(document.body).height() if (typeof offset != 'object') offsetBottom = offsetTop = offset if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) if (this.affixed != affix) { if (this.unpin != null) this.$element.css('top', '') var affixType = 'affix' + (affix ? '-' + affix : '') var e = $.Event(affixType + '.bs.affix') this.$element.trigger(e) if (e.isDefaultPrevented()) return this.affixed = affix this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null this.$element .removeClass(Affix.RESET) .addClass(affixType) .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') } if (affix == 'bottom') { this.$element.offset({ top: scrollHeight - height - offsetBottom }) } } // AFFIX PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.affix') var options = typeof option == 'object' && option if (!data) $this.data('bs.affix', (data = new Affix(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.affix $.fn.affix = Plugin $.fn.affix.Constructor = Affix // AFFIX NO CONFLICT // ================= $.fn.affix.noConflict = function () { $.fn.affix = old return this } // AFFIX DATA-API // ============== $(window).on('load', function () { $('[data-spy="affix"]').each(function () { var $spy = $(this) var data = $spy.data() data.offset = data.offset || {} if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom if (data.offsetTop != null) data.offset.top = data.offsetTop Plugin.call($spy, data) }) }) }(jQuery); |
Added modules/bootstrap/js/bootstrap.min.js.
> > > > > > > | 1 2 3 4 5 6 7 | /*! * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){ var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); |
Added modules/bootstrap/js/jquery.min.js.
> > > > | 1 2 3 4 | /*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=mb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=nb(b);function qb(){}qb.prototype=d.filters=d.pseudos,d.setFilters=new qb,g=gb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?gb.error(a):z(a,i).slice(0)};function rb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) },removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b)) },removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.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 contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec=/#.*$/,fc=/([?&])_=[^&]*/,gc=/^(.*?):[ \t]*([^\r\n]*)$/gm,hc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ic=/^(?:GET|HEAD)$/,jc=/^\/\//,kc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lc={},mc={},nc="*/".concat("*"),oc=a.location.href,pc=kc.exec(oc.toLowerCase())||[];function qc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rc(a,b,c,d){var e={},f=a===mc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function uc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:oc,type:"GET",isLocal:hc.test(pc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sc(sc(a,n.ajaxSettings),b):sc(n.ajaxSettings,a)},ajaxPrefilter:qc(lc),ajaxTransport:qc(mc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gc.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||oc)+"").replace(ec,"").replace(jc,pc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pc[1]&&h[2]===pc[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pc[3]||("http:"===pc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rc(lc,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ic.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fc.test(d)?d.replace(fc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rc(mc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tc(k,v,f)),u=uc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vc=/%20/g,wc=/\[\]$/,xc=/\r?\n/g,yc=/^(?:submit|button|image|reset|file)$/i,zc=/^(?:input|select|textarea|keygen)/i;function Ac(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wc.test(a)?d(a,e):Ac(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ac(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ac(c,a[c],b,e);return d.join("&").replace(vc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zc.test(this.nodeName)&&!yc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xc,"\r\n")}}):{name:b.name,value:c.replace(xc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bc=0,Cc={},Dc={0:200,1223:204},Ec=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cc)Cc[a]()}),k.cors=!!Ec&&"withCredentials"in Ec,k.ajax=Ec=!!Ec,n.ajaxTransport(function(a){var b;return k.cors||Ec&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Dc[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fc=[],Gc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hc)return Hc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ic=a.document.documentElement;function Jc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ic;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ic})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kc=a.jQuery,Lc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lc),b&&a.jQuery===n&&(a.jQuery=Kc),n},typeof b===U&&(a.jQuery=a.$=n),n}); |
Added modules/bootstrap/js/npm.js.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. require('../../js/transition.js') require('../../js/alert.js') require('../../js/button.js') require('../../js/carousel.js') require('../../js/collapse.js') require('../../js/dropdown.js') require('../../js/modal.js') require('../../js/tooltip.js') require('../../js/popover.js') require('../../js/scrollspy.js') require('../../js/tab.js') require('../../js/affix.js') |
Added modules/bootstrap/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::bootstrap 0.1 [list source [file join $dir bootstrap.tcl]] |
Added modules/community/acl.md.
Added modules/community/acl.tcl.
Added modules/community/community.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | *httpd.community* is a decendent of . It adds an sqlite based user, group, and access control system. It is implemented in [community.tcl](finfo?name=modules/community/community.tcl). ## Ancestors * [httpd.taourl](../directoo/taourl.md) * [yggdrasil](../tao-sqlite/yggdrasil.md) ## Required Packages Community relies on the following external packages: * sha1 from [tcllib](http://core.tcl.tk/tcllib) * sqlite3 from [sqlite](http://www.sqlite.org) Community uses the following internal packages: * tao from [tao](../tao/tao.md) * tao-sqlite [tao-sqlite](../tao-sqlite/tao-sqlite.md) ## Properties * create\_sql - An SQL script that implements the schema ## Options * filename - Path to a file which stores the sqlite database for the community (default in-memory) * virtual - Root Url of this object. ## Attached Objects Community objects (and their derived classes) contain an embedded sqlite database. This database can be accessed via that \<db\> method. ## Methods ### method Database\_Functions Adds the following functions to the database: * uuid\_generate() - Generates sha1 UUIDs on demand * sha1() - Returns the SHA1 hash of the input ### aclAccessTypes Returns a list of all possible rights. ### aclRights *aclname* *user\_or\_group\_id* Return a list of rights that the user or group to the access control list (specified by name.) ### method httpdSessionLoad *sock* *prefix* *suffix* This method looks for a sessionid cookie or a sessionid field in the GET or POST query, and pairs it with a session in the *session* table. If no session is found, a new session is generated for an anonymous user. ### method httpdSessionSave *sock* This method compares the current value of **result\(session\)** to **result\(session\_delta\)** (a copy of the session when the pageview began. Fields that are in the delta, but not in the current session are delete from **session\_property**. Fields that are present in the session but not the delta are inserted into **session\_property**. Fields present in both, but with a different value, are updated. The server will generate a cookie called **sessionid** which will be loaded on the next page view. |
Added modules/community/community.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | ### # Facilities for user, group, and community management ### package require tao package require sqlite3 package require tao-sqlite package require md5 2 package require sha1 2 package require httpd::directoo package require httpd::cookie ;# Cookie_GetSock Cookie_Make package require httpd::doc ;# Doc_Root package require httpd::utils ;# Stderr file iscommand randomx package require httpd::jshash ;# Javascript password hashes package require httpd::bootstrap package require cron tao::class community.layer { superclass httpd.url tao::layer taodb::table ### # Code to produce the schema in sql ### property schema create_sql {} property schema version 0.1 property module {} constructor {sharedobjects threadargs args} { foreach {organ object} $sharedobjects { my graft $organ $object } my graft layer [self] my configurelist [::tao::args_to_options {*}$args] ::Url_PrefixInstall [my cget virtual] [namespace code {my httpdDirect}] {*}$threadargs } destructor { catch {::Url_PrefixRemove [my cget virtual]} } method schema_check {} { set module [my property module] set version [my property schema version] ### # Create our schema if it doesn't exist ### if {![my <db> exists {select version from module where name=:module}]} { my <db> eval [my property schema create_sql] my <db> eval {insert or replace into module(name,version) VALUES (:module,:version)} # Send a signal to child classes calling us through [next] return 1 } ### # From here on out, swap out components to incrementally update # the schema ### return 0 } method initialize {} { my schema_check } # # Use the url prefix, suffix, and cgi values (set with the # ncgi package) to create a Tcl command line to invoke. # # Arguments: # suffix The part of the url after the domain prefix. # # Results: # Returns a Tcl command line. # # Side effects: # If the suffix (and query args) do not map to a Tcl procedure, # returns empty string. method httpdMarshalArguments resultObj { set prefix [$resultObj cget url_prefix] set suffix [$resultObj cget url_suffix] set uuid {} if { $suffix in {/ {}} } { set method /html } else { set parts [split [string trim $suffix /] /] set uuid [lindex $parts 0] set method /html/[join [lrange $parts 1 end] /] } set pkey [my property schema primary_key] foreach {name value} [$resultObj query] { if { $name in [list uuid $pkey]} { set uuid $value } if { $name eq "method" } { set method /html/$value break } } if {$uuid ne {}} { resultObj configure uuid $uuid } return [list my $method $resultObj] } ### # topic: 88c79c0e9188a477f535b66b01631961 ### method node_is_managed unit { set prefix [my cget prefix] if { $unit eq $prefix } { return 1 } set table [my property schema table] set pkey [my property schema primary_key] return [my <db> exists "select $pkey from $table where $pkey=:unit"] } ### # Return a command if this object hijacks a method # from the community ### method url_is_managed resultObj { return {} } method task_hourly {} {} method task_daily {} {} method /html resultObj { $resultObj puts [my <community> pageHeader] $resultObj puts "Node: [$resultObj cget uuid] $resultObj puts [my <community> pageFooter] } } tao::class community.layer.user { superclass community.layer property module user property schema version 1.0 property schema table users property schema primary_key userid property schema create_sql { CREATE TABLE if not exists users ( userid string default (uuid_generate()), username STRING, password STRING, name STRING, email STRING, type STRING, primary key (userid) ); CREATE UNIQUE INDEX if not exists username on users (username); create table if not exists user_property ( userid string references users (userid) ON UPDATE CASCADE ON DELETE CASCADE, field string, value string, primary key (userid,field) ); insert into users(userid,username,password) VALUES ('local.webmaster','webmaster',sha1((select value from config where name='community-id')||'password')); insert into users(userid,username,password) VALUES ('local.anonymous','anonymous',''); } method /html resultObj { set uuid [$resultObj cget uuid] set method [lindex $parts 1] set props [my <db> eval {select field,value from user_property where userid=:uuid}] my <db> eval {select * from users where userid=:uuid} record break $resultObj configure title "User $record(username)" $resultObj puts [my <community> pageHeader] $resultObj puts "<TABLE>" foreach {field value} [array get record] { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } foreach {field value} $props { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } my <db> eval {select distinct acl_name from acl} { $resultObj puts "<TR><TH>Rights $acl_name</TH><Td>[my aclRights $acl_name $record(userid)]</TD></TR>" } $resultObj puts "</TABLE>" $resultObj puts <hr> $resultObj puts "<hr>Session<p>" $resultObj puts "<TABLE>" foreach {field value} [$resultObj session dump] { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } $resultObj puts "</TABLE>" $resultObj puts "<hr>ENV<p>" $resultObj puts "<TABLE>" foreach {field value} [$resultObj cgi dump] { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } $resultObj puts "</TABLE>" $resultObj puts [my <community> pageFooter] } } tao::class community.layer.group { superclass community.layer property module group property schema version 1.0 property schema table groups property schema primary_key groupid property schema create_sql { CREATE TABLE if not exists groups ( groupid string default (uuid_generate()), groupname STRING, acl_name string references acl (acl_name) ON UPDATE CASCADE ON DELETE SET NULL, primary key (groupid) ); CREATE TABLE if not exists group_members ( groupid string references groups (groupid) ON UPDATE CASCADE ON DELETE CASCADE, userid string references users (userid) ON UPDATE CASCADE ON DELETE CASCADE ); create table if not exists group_property ( groupid string references groups (groupid) ON UPDATE CASCADE ON DELETE CASCADE, field string, value string, primary key (groupid,field) ); insert into groups(groupid,groupname) VALUES ('local.wheel','wheel'); insert into group_members(userid,groupid) VALUES ('local.webmaster','local.wheel'); } } tao::class community.layer.session { superclass community.layer property module session property module session property schema version 1.0 property schema table session property schema primary_key sesid property schema create_sql { CREATE TABLE session ( sesid string default (uuid_generate()), userid string references users (userid) ON UPDATE CASCADE ON DELETE CASCADE, expires int, primary key (sesid) ); create table if not exists session_property ( sesid string references session (sesid) ON UPDATE CASCADE ON DELETE CASCADE, field string, value string, primary key (sesid,field) ); } method task_hourly {} { set now [clock seconds] my <db> eval {delete from session where expires<:now;} } } tao::class community.layer.acl { superclass community.layer property module acl property module acl property schema version 1.0 property schema table acl property schema primary_key acl_name property schema create_sql { CREATE TABLE acl ( parent string references acl (acl_name) ON UPDATE CASCADE ON DELETE SET NULL, acl_name text not null, primary key (acl_name) ); CREATE TABLE acl_grants ( acl_name string references acl (acl_name) ON UPDATE CASCADE ON DELETE SET NULL, userid string references users (userid) ON UPDATE CASCADE ON DELETE SET NULL, grant int default 1, right text, UNIQUE (acl_name,userid,right) ); insert into acl (acl_name) VALUES ('admin'); insert into acl_grants (acl_name,userid,grant,right) VALUES ('admin','local.wheel',1,'all'); insert into acl (acl_name) VALUES ('default'); insert into acl_grants (acl_name,userid,grant,right) VALUES ('default',NULL,1,'view'); } } tao::class httpd.community { superclass httpd.url taodb::connection.sqlite option virtual {} option community-id {} ### # This class extents the yggdrasil schema to # include session management, user management, # and access control lists ### property schema create_sql { CREATE TABLE if not exists config( name TEXT PRIMARY KEY, value ANY ); CREATE TABLE if not exists module( name TEXT PRIMARY KEY, version ANY ); --- POPULATE WITH DATA --- insert into config(name,value) VALUES ('community-id',uuid_generate()); } destructor { next cron::cancel [self].session_flush cron::cancel [self].backup_db } method Shared_Organs {} { set shared {} dict set shared db [my organ db] dict set shared community [self] return $shared } method active_layers {} { return { user {prefix uid class community.layer.user} group {prefix gid class community.layer.group} session {prefix sesid class community.layer.session} acl {prefix acl class community.layer.acl} } } ### # topic: 81232b0943dce1f2586e0ac6159b1e2e ### method activate_layers {{force 0}} { set self [self] my variable layers set result {} set active [my active_layers] ### # Destroy any layers we are not using ### set lbefore [get layers] foreach {lname obj} $lbefore { if {![dict exists $active $lname] || $force} { $obj destroy dict unset layers $lname } } ### # Create or Morph the objects to represent # the layers, and then stitch them into # the application, and the application to # the layers ### set shared [my Shared_Organs] set root [my cget virtual] set threadargs [my cget threadargs] foreach {lname info} $active { set created 0 set prefix [dict get $info prefix] set class [dict get $info class] set layer_obj [my SubObject layer $lname] dict set layers $lname $layer_obj if {[info command $layer_obj] == {} } { $class create $layer_obj $shared $threadargs virtual $root/$prefix prefix $prefix layer_name $lname threadargs $threadargs set created 1 foreach {organ object} $shared { $layer_obj graft $organ $object } } else { foreach {organ object} $shared { $layer_obj graft $organ $object } $layer_obj morph $class } ::ladd result $layer_obj $layer_obj event subscribe [self] * $layer_obj initialize } my action activate_layers return $result } method initialize {} { if {[my cget filename] eq {}} { my configure filename :memory: } my Database_Attach [my cget filename] my configurelist [my <db> eval {select name,value from config}] if {[my cget community-id] eq {}} { my configure community-id [::tao::uuid_generate] } my activate_layers ### # Clean up expired sessions ### cron::every [self].hourly [expr {3600}] [namespace code {my task_hourly}] ### # Back up the database every day ### cron::every [self].daily [expr {3600*24}] [namespace code {my task_daily}] } method task_hourly {} { my variable layers foreach {name obj} $layers { $obj task_hourly } } method task_daily {} { my variable layers my Database_Backup foreach {name obj} $layers { $obj task_hourly } } method Database_Create {} { my <db> eval [my schema create_sql] } method ClockFormat {time {format {}}} { if { $format eq {} } { return [clock format $time] } return [clock format $time -format $format] } method ClockScan {time {format {}}} { if { $format eq {} } { return [clock format $time] } return [clock scan $time -format $format] } method Database_Functions {} { set seed [info hostname] my <db> function uuid_generate ::tao::uuid_generate my <db> function sha1 {::sha1::sha1 -hex} my <db> function now {clock seconds} my <db> function clock_format [namespace code {my ClockFormat}] my <db> function clock_scan [namespace code {my ClockScan}] } method aclAccessTypes {} { set aclAccessTypes {admin edit view} foreach type [my <db> eval "select distinct right from acl_grants order by right"] { logicset add aclAccessTypes $type } return $aclAccessTypes } method aclRights {aclname userid} { set parentlist {} set thisnode $aclname while 1 { set parentlist [linsert $parentlist 0 $thisnode] set parent [my one "select parent from acl where acl_name=:thisnode"] if { $parent == {} } { break } # Something is mislinked, stop early if {$parent in $parentlist} break set thisnode $parent } ### # Build grouplist ### set rights {} ### # Apply default rights ### foreach {right grant} [my <db> eval "select right,grant from acl_grants where acl_name='default'"] { if { $grant == "0"} { if { $right == "all" } { set rights {} } else { logicset remove rights $right } } else { if { $right eq "all" } { logicset add rights {*}[my aclAccessTypes] } else { logicset add rights $right } } } foreach p $parentlist { set stmt "select right,grant from acl_grants where \ acl_name=:p and userid=:userid or userid=(select username from users where userid=:userid) or userid in (select groupid from group_members where userid=:userid); " foreach {right grant} [my <db> eval $stmt] { if { $grant == "0"} { if { $right == "all" } { set rights {} } else { logicset remove rights $right } } else { if { $right eq "all" } { logicset add rights {*}[my aclAccessTypes] } else { logicset add rights $right } } } } return $rights } # # Use the url prefix, suffix, and cgi values (set with the # ncgi package) to create a Tcl command line to invoke. # # Arguments: # suffix The part of the url after the domain prefix. # # Results: # Returns a Tcl command line. # # Side effects: # If the suffix (and query args) do not map to a Tcl procedure, # returns empty string. method httpdMarshalArguments resultObj { my variable layers ### # Try to pass the page off to one of my layers ### foreach {lname layer} $layers { if {[set cmd [$layer url_is_managed $resultObj]] ne {}} { return $cmd } } ### # Otherwise look for a local method ### return [next $resultObj] } method httpdSessionLoad {resultObj prefix suffix} { set found 0 set sessionid {} set userid {} ### # Look for a session id in the query ### foreach {field value} [$resultObj query] { if {$field eq "sessionid"} { set stmt {select userid from session where sesid=:value} if {[my <db> exists $stmt]} { set userid [my <db> one $stmt] set sessionid $value break } } } if {$sessionid eq {}} { ### # Look for a sessionid in cookies ### foreach {value} [$resultObj cookie_get sessionid] { set stmt {select userid from session where sesid=:value} if {[my <db> exists $stmt]} { set userid [my <db> one $stmt] set sessionid $value break } } } if {![my <db> exists {select username from users where userid=:userid}]} { set userid local.anonymous set username anonymous set anonymous 1 } else { set username [my <db> one {select username from users where userid=:userid}] if { $userid == "local.anonymous" } { set anonymous 1 } else { set anonymous 0 } } if {$sessionid eq {}} { set sessionid [::tao::uuid_generate] my <db> eval { insert into session(sesid,userid) VALUES (:sessionid,:userid); } } $resultObj configure \ sessionid $sessionid \ userid $userid \ username $username set session [my <db> eval {select field,value from session_property where sesid=:sessionid}] dict set session userid $userid dict set session username $username dict set session anonymous $anonymous $resultObj session build $session # Save any return cookies which have been set. # This works with the Doc_SetCookie procedure that populates # the global cookie array. set expdate [expr {14*86400}] set expires [expr {[clock seconds]+$expdate}] my <db> eval {update session set expires=:expires where sesid=:sesid;} $resultObj cookie_set sessionid $sessionid $expdate } method httpdSessionSave result { dict unset result body set sesid [dict get $result sessionid] set session [dict get $result session] set session_delta [my <db> eval {select field,value from session_property where sesid=:sesid}] set add {} set delete {} set modify {} foreach {field value} $session { if {![dict exists $session_delta $field]} { lappend add $field $value } elseif {$value != [dict get $session_delta $field]} { lappend modify $field $value } } foreach {field value} $session_delta { if {![dict exists $session $field]} { lappend delete $field $value } } if {[llength $add]||[llength $delete]||[llength $modify]} { my db eval "BEGIN TRANSACTION" foreach {field value} $add { my <db> eval {insert or replace into session_property(sesid,field,value) VALUES (:sessionid,:field,:value);} } foreach {field value} $modify { my <db> eval {update session_property set value=:value where sesid=:sessionid and field=:field;} } foreach {field value} $delete { my <db> eval {delete from session_property where sesid=:sessionid and field=:field;} } my <db> eval "COMMIT" } } method pageHeader {} { return { <HTML> <HEAD> <TITLE>@TITLE@</TITLE> <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"> </HEAD> <BODY> } } method pageFooter {} { return { <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script> </BODY></HTML> } } method /html/logout resultObj { set sesid [$resultObj cget sessionid] my <db> eval { update session set userid='local.anonymous' where sesid=:sesid; delete from session_property where sesid=:sesid; } $resultObj session build username anonymous userid local.anonymous anonymous 1 $resultObj configure login-message {You have been logged out} my /html/login $resultObj } method /html/login resultObj { set sessionid [$resultObj cget sessionid] $resultObj reset $resultObj puts <html> $resultObj puts { <head> <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"> <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script> <TITLE>Log In</TITLE> <script type="text/javascript" src="/jshash/sha1-min.js"></script> <script type="text/javascript"> function login() { var p = hex_sha1(document.getElementById('key').value+document.getElementById('pass').value); var k = document.getElementById('sesid').value; var h = hex_sha1(k+p); var hash = document.getElementById('hash'); hash.value = h; var f = document.getElementById('finalform'); f.submit(); } </script> </head> } $resultObj puts { <body> } set msg [$resultObj cget login-message] if { $msg ne {} } { $resultObj puts "<pre><font color=ÓredÓ face=Ósans-serifÓ size=Ó1Ó>$msg</font></pre><hr>" } $resultObj puts { <table> <form action="authenticate" method="post" id="finalform"> <tr><th>Username:</th><td><input name="uid" id="uid" /></td></tr> <input type="hidden" name="hash" id="hash" /> </form> } $resultObj puts {<form action="javascript:login()" method="post" >} $resultObj puts "<input type=\"hidden\" id=\"key\" value=\"[my cget community-id]\" />" $resultObj puts "<input type=\"hidden\" id=\"sesid\" value=\"$sessionid\" />" $resultObj puts { <tr><th>Password:</th><td><input type="password" id="pass" /></td></tr> <tr><th> </th></th><td><input type="submit" value="Log In" /></td></tr> </table> </form> </body> } $resultObj puts </html> } method /html/authenticate resultObj { set sessionid [$resultObj cget sessionid] foreach {field value} [$resultObj query] { if {$field eq "uid"} { set username $value foreach {field value} [$resultObj query] { if {$field eq "hash"} { set passhash [my <db> one {select password from users where username=:username}] set realhash [::sha1::sha1 -hex "$sessionid$passhash"] if { $realhash eq $value } { set userid [my <db> one {select userid from users where username=:username}] my <db> eval { update session set userid=:userid where sesid=:sessionid; } $resultObj session set username $username $resultObj session set userid $userid set root [my cget virtual] $resultObj puts "<HTML><HEAD><META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=$root\"></HEAD>" $resultObj puts { <BODY> You are now being logged in. You will be redirected in a moment. <p> } $resultObj puts "<A href=\$root\>Home...</a>" $resultObj puts </BODY></HTML> return } } } } } $resultObj configure login-message {Password or Username was incorrect or invalid.} my /html/login $resultObj } method /html/env resultObj { if {[$resultObj session anonymous]} { $resultObj configure code 401 return } $resultObj puts [my pageHeader] $resultObj puts "<TABLE>" foreach {field value} [$resultObj cgi dump] { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } $resultObj puts "</TABLE>" $resultObj puts [my pageFooter] } method /html/session resultObj { if {[$resultObj session anonymous]} { $resultObj configure code 401 return } $resultObj puts [my pageHeader] $resultObj puts "<TABLE>" foreach {field value} [$resultObj session dump] { $resultObj puts "<TR><TH>$field</TH><TD>$value</TD></TR>" } $resultObj puts "</TABLE>" $resultObj puts [my pageFooter] } } package provide httpd::community 0.1 |
Added modules/community/pkgIndex.tcl.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::community 0.1 [list source [file join $dir community.tcl]] package ifneeded httpd::acl 0.1 [list source [file join $dir acl.tcl]] |
Added modules/compat/compat.tcl.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | package provide httpd::compat 4.0 namespace eval ::httpd {} set ::httpd::compat_dir [file dirname [file normalize [info script]]] proc httpd::compat_level level { set cfiles {} foreach file [lsort -dictionary -decreasing [glob -nocomplain [file join $::httpd::compat_dir version-*.tcl]]] { set version [lindex [split [file tail $file] -] 1] if { "$version" >= $level } { source $file } } } |
Added modules/compat/pkgIndex.tcl.
> > | 1 2 | package ifneeded httpd::compat 4.0 [list source [file join $dir compat.tcl]] |
Added modules/compat/version-3.3.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # compat.tcl #@c Compatibility layer - deprecated # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # Colin McCormack (c) 2002 # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # foreach {oldname newname} { Doc_Cookie Cookie_Get Doc_GetCookie Cookie_Get Doc_SetCookie Cookie_Set Doc_IsLinkToSelf Url_IsLinkToSelf Doc_Redirect Redirect_To Doc_RedirectSelf Redirect_Self Doc_IsLinkToSelf Url_IsLinkToSelf Doc_IndexFile DirList_IndexFile Doc_Webmaster Httpd_Webmaster Doc_CheckTemplates Template_Check Doc_TemplateInterp Template_Interp Doc_TemplateLibrary Template_Library Doc_Dynamic Template_Dynamic Doc_Subst Subst_ReturnFile Doc_TemplateScope Subst_Scope Doc_SubstInstall Subst_Install Url_Redirect Redirect_Url Url_RedirectSelf Redirect_UrlSelf } { interp alias {} $oldname {} $newname } |
Added modules/compat/version-3.4.tcl.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | # Compat routines with 3.4 routines catch {interp alias {} Doc_Dynamic {} Template_Dynamic} catch {interp alias {} Doc_Redirect {} Redirect_To} catch {interp alias {} Doc_RedirectSelf {} Redirect_Self} catch {interp alias {} Doc_Webmaster {} Httpd_Webmaster} catch {interp alias {} Httpd_RedirectDir {} Redirect_Dir} |
Added modules/compat/version-3.5.tcl.
> > > | 1 2 3 | ### # script to maintain compadibilty with Tclhttpd 3.5 ### |
Added modules/directoo/directoo.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | # The httpd.url class [Implementation](finfo?name=modules/httpd/directoo.tcl) *httpd.url* is a TclOO class. The first argument (after the name of the new object) is the virtual root for this object. For more complex classes, the second argument is a key/value list of configuration options. Any arguments after that are passed to *Url_PrefixInstall* ## Variables ### env An array which contains CGI data. It is populated every page view *Cgi_SetEnv* in Tclhttpd. ### result An array which contains the meta information and content about the page view in progress. Important fields: * code - HTTP code to return (default 400) * body - The block of data to be sent via *Httpd_ReturnData* or *Httpd_ReturnCacheableData* at the conclusion of the operation. * content-type - The type of content in *block* (default text/html) ## Methods ### method configurelist *keyvaluelist* Pass configuration items as a key/value list. ### method cget *field* Retrieve the value of a configuration item ### /html A method which implements the default root page of the object. ### method initialize A method which is called in the constructor, after the configuration items have been applied and the domain registered with Tclhttpd. ### method httpdCookieSet *field* *value* *?expire?* Set a cookie named *field* and value of *value*. If *expire* is a postitive integer, it indicates how long (in seconds) this cookie should last. Note: Cookies destined for "localhost" are mapped to null so browser will honor them properly. ### method httpdHostName Return the host name by which this page was accessed. Derived from env\(HTTP\_HOST\). ### method httpdDirect *sock* *suffix* This method is the first called when resolving a dynamic page. It calles *httpdSessionLoad* to load the session, *httpdMarshalArguments* do compute the method to call. On error, this method returns an error message. On success it calls *httpdSessionSave*, before sending the resulting data out to TclHttpd via the *Httpd_ReturnData* or *Httpd_ReturnCacheableData* procs. ### method httpdMarshalArguments *sock* *suffix* Calculate the command which will implement the current page view. ### method httpdSessionLoad *sock *prefix* *suffix* Initializes the *result* variable, and load session data from either cookies or the incoming GET/POST query. This method also calls the *Cgi_SetEnv* and *Url_QuerySetup* procs from Tclhttpd. Rather than populate the global *env* variable, Cgi_SetEnv populates the private *env* variable for this object. ### method httpdSessionSave *sock* Updates the current session, and writes cookies back to the browser. ### method reset Reset the current value of result(body) ### method puts Append to the value of result(body). Accepts multiple arguments. An implied \n is appended at the tail end. ### method unknown *args* Handler for unknown, incomplete, or invalid queries. |
Added modules/directoo/directoo.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | ### # This package adds support for direct URLs implemented by # TclOO Objects. They need a little extra massaging as an # object may have its own rules about which method is being # exercised # # Derived from direct.tcl ### package provide httpd::directoo 0.1 package require httpd ;# Httpd_Redirect Httpd_ReturnData package require httpd::cgi ;# Cgi_SetEnv package require httpd::doc_error ;# Doc_NotFound package require httpd::url ;# Url_PrefixInstall Url_PrefixRemove Url_QuerySetup package require httpd::utils ;# file iscommand package require TclOO package require tao ### # Class that represents a web page in # progress ### tao::class httpd.result { superclass variable sock variable data variable state variable body variable cookie variable query variable session_data option cache-until {type unixtime default 0} option url_prefix {} option url_suffix {} option code { default 200 } option content-type { default text/html } option title {} option redirect {} constructor {newsock prefix suffix} { my variable sock cgienv set sock $newsock my configurelist [list url_prefix $prefix url_suffix $suffix] # Set up the environment a-la CGI. ::Cgi_SetEnv $sock $prefix$suffix [my varname cgienv] # Prepare an argument data from the query data. my variable query ::Url_QuerySetup $sock set query [ncgi::nvlist] } destructor { } method sock {} { my variable sock return $sock } method data_get {field} { my variable sock upvar #0 Httpd$sock data if {![info exists data($field)]} { return {} } return $data(field) } method cgi {method args} { my variable cgienv switch $method { dump { return [array get cgienv] } get { set field [lindex $args 0] if {[info exists cgienv($field)]} { return $cgienv($field) } return {} } varname { return [my varname cgienv] } default { error "Valid: dump,get,varname" } } } method httpdHostName {} { my variable cgienv return [lindex [split [get cgienv(HTTP_HOST)] :] 0] } ### # Return a dict with: # * body # * content-type # * code (200,404,etc) # * cache-until (Unix datestamp when cache of this data expires, or 0) ### method httpReply {} { my variable body session_data set result {} dict set result content-type [my cget content-type] dict set result code [my cget code] dict set result cache-until [my cget cache-until] dict set result redirect [my cget redirect] dict set result sessionid [my cget sessionid] dict set result session $session_data dict set result body $body return $result } method body {} { my variable body set title [my cget title] return [string map [list @TITLE@ $title] $body] } method query {} { my variable query return $query } method reset {} { my variable body set body {} } method puts args { my variable body append body {*}$args \n } # #@c Return a *list* of cookie values, if present, else "" #@c It is possible for multiple cookies with the same key #@c to be present, so we return a list. #@c This always gets the cookie state associated with the specified #@c socket, unlike Cookie_Get that looks at the environment. # # Arguments: #@a cookie The name of the cookie (the key) #@a sock A handle on the socket connection # Returns: #@r a list of cookie values matching argument method cookie_get {cookie} { my variable sock upvar #0 Httpd$sock data set result "" set rawcookie "" if {[info exist data(mime,cookie)]} { set rawcookie $data(mime,cookie) } foreach pair [split $rawcookie \;] { lassign [split [string trim $pair] =] key value if {[string compare $cookie $key] == 0} { lappend result $value } } return $result } #$c make a cookie from name value pairs # # Arguments: # args Name value pairs, where the names are: #@a -name Cookie name #@a -value Cookie value #@a -path Path restriction #@a -domain domain restriction #@a -expires Time restriction #@a -secure Append "secure" to cookie attributes #@r a formatted cookie method cookie_make {args} { array set opt $args set line "$opt(-name)=$opt(-value) ;" foreach extra {path domain} { if {[info exist opt(-$extra)]} { append line " $extra=$opt(-$extra) ;" } } if {[info exist opt(-expires)]} { switch -glob -- $opt(-expires) { *GMT { set expires $opt(-expires) } default { set expires [clock format [clock scan $opt(-expires)] \ -format "%A, %d-%b-%Y %H:%M:%S GMT" -gmt 1] } } append line " expires=$expires ;" } if {[info exist opt(-secure)]} { append line " secure " } return $line } method cookie_set {field value {expire {}}} { my variable sock upvar #0 Httpd$sock data foreach host [my httpdHostName] { if { $host eq "localhost" } { set host {} } set cookie_args [list -name $field \ -value $value \ -domain $host \ -path [my cget virtual]] if {[string is integer expire]} { lappend cookie_args -expires [clock format [expr [clock seconds] + [set expire]] -format "%Y-%m-%d"] } # Appending to the data(set-cookie) elimates the entire # kangaroo code that normally goes on with httpd lappend data(set-cookie) [my cookie_make {*}$cookie_args] } } method session {method args} { my variable session_data switch $method { anonymous { if {[dict getnull $session_data username] in {{} nobody anonymous}} { return 1 } return 0 } build { set session_data [::tao::args_to_options {*}$args] } dump { return $session_data } get { return [dict getnull $session_data [lindex $args 0]] } userid { set userid [dict getnull $session_data userid] if { $userid eq {} } { return local.anonymous } return $userid } set { #dict set session_data {*}args foreach {key value} [::tao::args_to_options {*}$args] { dict set session_data $key $value } } unset { dict unset session_data {*}args } varname { return [my varname session_data] } default { error "Valid: build.dump,get,set,unset,varname" } } } } ### # Create a standalone class suitable for using in a pure tcloo # environment ### tao::class httpd.url { superclass aliases httpd.meta httpd.taourl property options_strict 0 option virtual {} option threadargs {} #method Option_set::virtual newvalue { # #} constructor {virtual {localopts {}} args} { my configurelist [list virtual $virtual threadargs $args {*}$localopts] ::Url_PrefixInstall $virtual [namespace code {my httpdDirect}] {*}$args my initialize } destructor { catch {::Url_PrefixRemove [my cget virtual]} } method initialize {} {} # This calls out to the Tcl procedure named "$prefix$suffix", # with arguments taken from the form parameters. # Example: # httpdDirect /device Device # if the URL is /device/a/b/c, then the Tcl command to handle it # should be # [self] /html/Device/a/b/c # You can define the content type for the results of your procedure by # defining a global variable with the same name as the procedure: # set Device/a/b/c text/plain # The default type is text/html # # This function returns the result of evaluating the direct # url. Usually, this involves returning a page, but a redirect # could also occur. # # Arguments: # sock The socket back to the client. # code The return code from evaluating the direct url. # result The return string from evaluating the direct url. # type The mime type to use for the result. (Defaults to text/html). # # # Results: # None. # # Side effects: # If code 302 (redirect) is passed, calls Httpd_Redirect to # redirect the current request to the url in result. # If code 0 is passed, the result is returned to the client. # If any other code is passed, an exception is raised, which # will cause a stack trace to be returned to the client. # method httpdDirect {sock suffix} { set prefix [my cget virtual] set resultObj [httpd.result new $sock $prefix $suffix] my httpdSessionLoad $resultObj $prefix $suffix set cmd [my httpdMarshalArguments $resultObj] # Eval the command. Errors can be used to trigger redirects. if [catch $cmd] { ::Httpd_ReturnData $sock text/html "<HTML><BODY>Error: <PRE><VERBATIM>$::errorInfo</VERBATIM></PRE></BODY></HTML>" 505 $resultObj destroy return } set result [$resultObj httpReply] set code [dict get $result code] if {[string index $code 0] in {0 2}} { # Normal reply my httpdSessionSave $result } switch $code { 401 { ::Httpd_ReturnData $sock text/html $::HttpdAuthorizationFormat $code } 404 { ::Doc_NotFound $sock } 302 { # Redirect. ::Httpd_Redirect [dict get $result redirect] $sock } default { if {[dict get $result cache-until] > 0} { ::Httpd_ReturnCacheableData $sock [dict get $result content-type] [dict get $result body] [dict get $result cache-until] [dict get $result code] } else { ::Httpd_ReturnData $sock [dict get $result content-type] [dict get $result body] [dict get $result code] } } } $resultObj destroy } method httpdSessionLoad {resultObj prefix suffix} {} method httpdSessionSave result {} # # Use the url prefix, suffix, and cgi values (set with the # ncgi package) to create a Tcl command line to invoke. # # Arguments: # suffix The part of the url after the domain prefix. # # Results: # Returns a Tcl command line. # # Side effects: # If the suffix (and query args) do not map to a Tcl procedure, # returns empty string. method httpdMarshalArguments resultObj { set prefix [$resultObj cget url_prefix] set suffix [$resultObj cget url_suffix] if { $suffix in {/ {}} } { set method /html } else { set method /html$suffix } foreach {name value} [$resultObj query] { if { $name eq "method" } { set method /html/$value break } } return [list my $method $resultObj] } method unknown {args} { if {[string range [lindex $args 0] 0 4] eq "/html"} { my HtmlNotFound {*}$args return } next {*}$args } ### # title: Implement html content at a toplevel ### method /html resultObj { $resultObj reset $resultObj configure title {Welcome!} $resultObj puts [my pageHeader] $resultObj puts { Hello World } $resultObj puts [my pageFooter] } method HtmlNotFound args { set resultObj [lindex $args 0] $resultObj configure code 404 $resultObj configure title {Page Not Found} } method pageHeader {} { return { <HTML> <HEAD> <TITLE>@TITLE@</TITLE> <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"> </HEAD> <BODY> } } method pageFooter {} { return { <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script> </BODY></HTML> } } } |
Added modules/directoo/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::directoo 0.1 [list source [file join $dir directoo.tcl]] |
Added modules/httpd/MakeIndex.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #!/usr/bin/tclsh # First, auto-generate the standard direct-style package index pkg_mkIndex -verbose -direct . *.tcl return file rename -force pkgIndex.tcl pkgIndex.tcl.direct set in [open pkgIndex.tcl.direct r] set out [open pkgIndex.tcl w] # Now generate a new version that hides the sub-packages puts $out [gets $in] # Tcl package index file, version 1.1 puts $out " # This file is generated by the MakeIndex script in the tclhttpd # lib directory. The goal is to not pollute the package namespace # until you package require httpd " # Skip the other comment block. We know the line for # httpd comes first. while {[gets $in line] >= 0} { if {[regexp {package ifneeded httpd ([^ ]+)} $line x version]} { puts $out "package ifneeded httpd $version \"" puts $out "\tsource \\\[file join \[list \$dir] httpd.tcl\\\]" break } } # Now reformat the other lines slightly to protect the # list and file join commands, but let the $dir get expanded while {[gets $in line] >= 0} { regsub -all {[][]} $line {\\&} line regsub -all {\$dir} $line {[list &]} line puts $out \t$line } puts $out "\"" |
Added modules/httpd/admin.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | # URL-based administration # Copyright # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: admin.tcl,v 1.9 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::admin 1.0 package require httpd::auth ;# AuthVerifyBasic package require httpd::counter ;# Count Counter_Reset package require httpd::direct ;# DirectDomain Direct_Url package require httpd::redirect ;# Redirect_Url #package require httpd::utils ;# file proc Admin_Url {dir} { Direct_Url $dir Admin } proc Admin/redirect {old new} { global Doc Httpd if {[string length $old] == 0} { return "<h1>Redirect URL</h1>\n\ <form action=redirect method=post>\n\ OLD: <input type=input name=old><br>\n\ NEW: <input type=input name=new><br>\n\ <input type=submit value=\"Redirect URL\"></form>" } if {[string length $new] == 0} { return "<h1>Redirect URL</h1>\n\ <form action=redirect method=post>\n\ <input type=hidden name=old value=$old>\n\ OLD: $old<br>\n\ NEW: <input type=input name=new><br>\n\ <input type=submit value=\"Redirect URL\"></form>" } set server $Httpd(name) if {$Httpd(port) != 80} { append server :$Httpd(port) } if {![regexp ^http: $new]} { set new http://$server$new } #### # Need password protection for this page #### return "<h1>Redirect Form Disabled</h1>\n\ Redirect_Url $old http:$server$new" Redirect_Url $old $new if {[info exists Doc(notfound,$old)]} { unset Doc(notfound,$old) } return <h1>ok</h1> } proc Admin/reset/counter {name} { if {0} { # Ugh - get the socket handle in the DirectDomain procedure upvar 1 sock sock # Need a way to register administrator passwords # For now we just allow this to happen. if {![AuthVerifyBasic $sock $admin(authfile)]} { return "Password Check Failed" } } Counter_Reset $name return "Reset Counter $name" } |
Added modules/httpd/auth.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 | # auth.tcl # # Basic authentication # This module parses .htaccess files and does the Basic Authentication # protocol. There is some generality in here to support multiple # authentication schemes, but in practice only Basic is used right now. # # Each .htaccess file is parsed once and the information is kept in a # Tcl global array named auth$filename, and upvar aliases this to "info". # "info" contains the info provided by the .htaccess file ( info(htaccessp,..) ) # # The AuthUserFile and the AuthGroupFile are parsed and stored # in authentication array auth$filename. # # Authentication arrays need not be associated with physical files. # To create an authentication array: # array set auth$pseudo [list mtime 0 user,$u password group,$g group] # # Configuration creates an authentication array authdefault, for bootstrapping. # # There is also support for ".tclaccess" files in each directory. # These contain hook code that define password checking procedures # that apply at that point in the hierarchy. # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # Piet Vloet (c) 2001 # Brent Welch (c) 2001 # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: auth.tcl,v 1.25 2006/11/09 23:41:41 coldstore Exp $ package provide httpd::auth 2.0 package require base64 package require httpd ;# Httpd_Error Httpd_RequestAuth package require httpd::config ;# Config package require httpd::digest ;# Digest_Passwd package require httpd::log ;# Log package require httpd::passgen ;# Passgen_Generate Passgen_Salt package require httpd::utils ;# K Stderr file package require tclcrypt ;# crypt set Auth_DigestOnly 0; # set this to 1 to only use Digest auth # Crypto packages if {[catch {package require crypt}] || [catch {crypt foo ba}]} { # if we don't have a C library, fall back to pure tcl crypt package require tclcrypt } # set default user/group files if {![info exists Config(AuthUserFile)]} { set Config(AuthUserFile) default } if {![info exists Config(AuthGroupFile)]} { set Config(AuthGroupFile) default } # Authentication bootstrap. # # The /htaccess URL allows admins to create passwords and groups, # and .htaccess files per directory, however it is necessary to have a # password to bootstrap this process. # # The approach taken is to allow the administrator to give plaintext # passwords via Config, or (failing that) to generate and Log a random # password at runtime. A new random password will be created on each # server startup. # # Here, we create a default authentication array from Config(Auth) array set authdefault {mtime -1} package require httpd::passgen ;# random password generation # Auth_InitCrypt -- # Attempt to turn on the crypt feature used to store crypted passwords. proc Auth_InitCrypt {} { global authdefault global Config if {[info exists Config(Auth)]} { foreach {var val} $Config(Auth) { if {[string match user,* $var]} { # encrypt the password set salt [Passgen_Salt] set val [crypt $val $salt] } set authdefault($var) $val } } else { # we weren't given an Auth Config - generate a default for webmaster # and write it to Stderr set webmaster_password [Passgen_Generate] set salt [Passgen_Salt] set authdefault(user,webmaster) [crypt $webmaster_password $salt] set authdefault(group,webmaster) webmaster set authdefault(user,webmaster@webmaster) [Digest_Passwd webmaster webmaster $webmaster_password] # This lets the admin see this important password during startup. # It is also displayed by the Tk srvui interface. Stderr "User \"webmaster\" default password \"$webmaster_password\"" } } proc Auth_AccessFile {args} { Stderr "Auth_AccessFile is obsolete: use Auth_InitCrypt instead" Auth_InitCrypt } # Auth_Check -- # This looks for access files along the path. # It returns a "cookie" that is checked by Auth_Verify. # NOTE: this looks for the lowest (i.e., deepest) access file # and only returns information about one. Consider changing # Auth_Check/Auth_Verify to check all files. proc Auth_Check {sock directory pathlist} { global auth set cookie {} # Make sure we do checks in the root if {$pathlist==""} { set pathlist ./ } # Look for the .htaccess files that keep Basic Authtication info # or .tclaccess files with a general authorization callback set path $directory foreach component $pathlist { if {![file isdirectory $path]} { # Don't bother looking if we are in an "artificial" # url domain that isn't mapped to files. break } foreach {name type} {.htaccess Basic .tclaccess Tcl} { set file [file join $path $name] if {[file exists $file]} { set cookie [list $type $file] # Keep looking for cookie files lower in the directory tree } } set path [file join $path $component] } # Block access to the access control files themselves. # We toss in a block against the .tml files as well, # although that isn't strictly clean modularity. set tail [file tail $path] if {$tail == ".tclaccess" || $tail == ".htaccess" || $tail == ".tml"} { set cookie [list Deny $path] return $cookie } return $cookie } proc Auth_Verify {sock cookie} { if {[llength $cookie] == 0} { return 1 } set type [lindex $cookie 0] set key [lindex $cookie 1] if {$type == "Deny"} { return 0 } else { return [AuthVerify$type $sock $key] } } # Auth_VerifyCallback -- # # Check for a Basic authorization string, and use a callback # to verify the password # # Arguments: # sock Handle on the client connection # realm Realm for basic authentication. This appears # in the password prompt from the browser. # callback Tcl command to check the password. This gets # as arguments the sock, realm, username and password. # # Results: # return 1 or 0, 1 for success. proc Auth_VerifyCallback {sock realm callback} { upvar #0 Httpd$sock data if {![info exists data(mime,authorization)]} { set ok 0 } else { set parts [split $data(mime,authorization)] set type [lindex $parts 0] set code [lindex $parts 1] if {[string compare $type Basic] != 0} { set user {} set pass {} } else { set parts [split [base64::decode $code] :] set user [lindex $parts 0] set pass [lindex $parts 1] } set ok [eval $callback {$sock $realm $user $pass}] } if {!$ok} { Httpd_RequestAuth $sock Basic $realm return 0 } else { set data(auth_type) Basic set data(remote_user) $user set data(session) $realm,$user return 1 } } # AuthVerifyTcl -- # # "Tcl" verification uses a .tclaccess file that defines the # realm and callback to use to check the password. # # Arguments: # sock Handle on the client connection # file Tcl source file that contains set commands for # realm and callback # # Results: # 1 for success, 0 for access denied. proc AuthVerifyTcl {sock file} { upvar #0 Httpd$sock data # The file contains definitions for the "realm" variable # and the "callback" script value. set realm Realm set callback AuthNullCallback catch {source $file} return [Auth_VerifyCallback $sock $realm $callback] } proc AuthNullCallback {sock realm user pass} { upvar #0 Httpd$sock data global auth if {[info exists auth($realm,$user)]} { switch -exact -- $auth($realm,$user) \ $pass { Stderr "Session: $realm,$user" return 1 } \ PasswordRequired { set auth($realm,$user) $pass Stderr "Session: $realm,$user" return 1 } \ default { return 0 } } else { set auth($realm,$user) PasswordRequired return 0 } } # AuthUserOp - see if the user is permitted to perform a requested # operation (PUT, GET, etc) # The .htaccess file is searched for the user or a group containing # the user, to ascertain whether the user could possibly perform # the op before the proffered credentials are checked. proc AuthUserOp {sock file op user} { upvar #0 auth$file info upvar #0 Httpd$sock data if {[info exists info(htaccessp,require,$op,group)]} { if {![AuthGroupCheck $sock $file \ $info(htaccessp,require,$op,group) $user]} { return 0 ;# Not in a required group } } if {[info exists info(htaccessp,require,$op,user)]} { if {![AuthUserCheck $sock $file \ $info(htaccessp,require,$op,user) $user]} { return 0 ;# Not the required user } } return 1 } # AuthVerifyBasic - see if the user is granted access. # First domain based protection is performed. In the case the # user is not in the domain user based protection is performed. # The user must be in a group or mentioned as user. The password # must match the user's entry. If neither group nor user are # required for the operation, then the check passes. proc AuthVerifyBasic {sock file} { upvar #0 auth$file info upvar #0 Httpd$sock data set user "" AuthParseHtaccess $sock $file set op $data(proto) ;# GET, POST etc. set realm $info(htaccessp,name) # check whether the operation is controlled if {[info exists info(htaccessp,order,$op)]} { if {! [AuthVerifyNet $sock $file $op]} { # it is controlled and network address is excluded Httpd_Error $sock 403 return 0 } } if {![info exists info(htaccessp,require,$op,group)] && ![info exists info(htaccessp,require,$op,user)]} { # No "require group .." or "require user .." in .htaccess file return 1 } set ok 0 # the operation requires a user or group - check authorization if {[info exists data(mime,authorization)]} { # client has sent auth data set parts [split $data(mime,authorization)] set type [lindex $parts 0] switch -- [string tolower $type] { digest { # unpack the digest request Digest_Get $sock $parts # check that the proferred user can have access set user $data(digest,username) set ok [AuthUserOp $sock $file $op $user] if {$ok} { # now check the Digest credentials set ok [Digest_Request $sock $realm $file] } } basic { set code [lindex $parts 1] set parts [split [base64::decode $code] :] # check that the proferred user can have access set user [lindex $parts 0] set ok [AuthUserOp $sock $file $op $user] if {$ok} { # now check the Basic credentials set pass [lindex $parts 1] set crypt [AuthGetPass $sock $file $user] set salt [string range $crypt 0 1] set crypt2 [crypt $pass $salt] if {[string compare $crypt $crypt2] != 0} { set ok 0 ;# Not the right password } } } default { # this is an unknown auth method - it's not ok, we can't handle it set ok 0 } } } if {! $ok} { # client hasn't sent auth or auth doesn't satisfy global Auth_DigestOnly if {!$Auth_DigestOnly && ($info(htaccessp,type) == "Basic")} { Httpd_RequestAuth $sock Basic $realm } else { # make Digest the default Digest_Challenge $sock $realm $user } } else { # client is permitted and credentials check out set data(auth_type) $type set data(remote_user) $user set data(session) $realm,$user } return $ok } proc AuthUserCheck {sock file users user } { return [expr {[lsearch $users $user] >= 0}] } # Parse the AuthGroupFile and find the user in it. # The information is built up in the array: # auth$info(htaccessp,groupfile) # # To create an authentication array, unconnected to a physical file: # array set auth$pseudo [list mtime 0 user,$u password group,$g group] # # If the .htaccess file didn't specify a groupfile, it defaults to an authentication # array authdefault, which contains configured default passwords and groups proc AuthGroupCheck {sock file groups user} { upvar #0 auth$file info upvar #0 auth$info(htaccessp,groupfile) group if {[catch {file mtime $info(htaccessp,groupfile)} mtime]} { set mtime -1 ;# the file may not exist } # Only parse the group file if it has changed if {![info exists group(mtime)] || ($mtime > $group(mtime))} { catch {unset group(mtime)} ;# unset to catch errors foreach i [array names group "group*"] { unset group($i) } if {[catch {open $info(htaccessp,groupfile)} in]} { return 0 } while {[gets $in line] >= 0} { if {[regexp {^([^:]+):[ ]*(.+)} $line x key value]} { set group(group,$key) [split $value " ,"] } } close $in set group(mtime) $mtime } foreach index $groups { if {[info exist group(group,$index)]} { if {[lsearch $group(group,$index) $user] >= 0} { return 1 } } } return 0 } # Parse the AuthUserFile and return the user's information. # The information is built up in the array: # auth$info(htaccessp,userfile) # # To create an authentication array, unconnected to a physical file: # array set auth$pseudo [list mtime 0 user,$u password group,$g group] # # If the .htaccess file didn't specify a userfile, it defaults to an authentication # array authdefault, which contains configured default passwords and groups proc AuthGetPass {sock file user} { upvar #0 auth$file info upvar #0 auth$info(htaccessp,userfile) passwd if {[catch {file mtime $info(htaccessp,userfile)} mtime]} { set mtime -1 ;# the file may not exist } if {![info exists passwd(mtime)] || ($mtime > $passwd(mtime))} { catch {unset passwd(mtime)} ;# unset to catch errors foreach i [array names passwd "user*"] { unset passwd($i) } if {[catch {open $info(htaccessp,userfile)} in]} { return * } while {[gets $in line] >= 0} { if {[regexp {^([^:]+):[ ]*([^:]+)} $line x key value]} { set passwd(user,$key) $value } } close $in set passwd(mtime) $mtime } if {[info exists passwd(user,$user)]} { return $passwd(user,$user) } else { return * } } # Check the allow/deny lists for this operation proc AuthVerifyNet {sock file op} { upvar #0 auth$file info set order [split $info(htaccessp,order,$op) ,] set peer [fconfigure $sock -peername] set rname [string tolower [lindex $peer 1]] set raddr [lindex $peer 0] set ok 0 foreach way $order { if {![info exists info(htaccessp,network,$way,$op)]} { continue } foreach addr $info(htaccessp,network,$way,$op) { if {[AuthNetMatch $sock $addr $rname $raddr]} { if {[string compare $way "allow"] == 0} { set ok 1 } else { set ok 0 } } } } if {! $ok} { Log $sock AuthVerifyNet "access denied to $rname in [file tail [file dirname $file]]" } return $ok } proc AuthNetMatch {sock addr rname raddr} { if {[string compare $addr "all"] == 0} { return 1 } if {[string match *$addr $rname] || [string match ${addr}* $raddr]} { return 1 } return 0 } # Parse the htaccess file. Uhler would probably regsub/subst this, # but here we just call a Tcl proc to handle each "command" in the file. # The information is built up in the info array. proc AuthParseHtaccess {sock file} { upvar #0 auth$file info set mtime [file mtime $file] if {![info exists info] || ($mtime > $info(htaccessp,mtime))} { # Parse .htaccess file foreach i [array names info "htaccessp*"] { unset info($i) } set info(htaccessp,mtime) $mtime global Config set info(htaccessp,userfile) $Config(AuthUserFile) set info(htaccessp,groupfile) $Config(AuthGroupFile) set info(htaccessp,name) Digest if {[catch {open $file} in]} { return 1 } set state [list vars] foreach line [split [read $in] \n] { if {[regexp ^# $line] || [string length [string trim $line]] == 0} { continue } if {[regexp <(.+)> $line x tag]} { set line $tag } set words [split $line] set cmd [string tolower [lindex $words 0]] if {[catch { eval {Ht-$cmd auth$file} [lrange $words 1 end] } err]} { Log $sock Error $err } } close $in } return 1 } proc Ht-authtype {infoName type} { upvar #0 $infoName info set info(htaccessp,type) $type } proc Ht-authname {infoName name} { upvar #0 $infoName info set info(htaccessp,name) $name } proc Ht-authuserfile {infoName file} { upvar #0 $infoName info set info(htaccessp,userfile) $file } proc Ht-authgroupfile {infoName file} { upvar #0 $infoName info set info(htaccessp,groupfile) $file } proc Ht-limit {infoName args} { upvar #0 $infoName info set info(htaccessp,limit) $args ;# List of operations, GET, POST, ... } proc Ht-/limit {infoName args} { upvar #0 $infoName info set info(htaccessp,limit) {} } proc Ht-require {infoName key list} { upvar #0 $infoName info if {![info exists info(htaccessp,limit)]} { set info(htaccessp,limit) {} } foreach op $info(htaccessp,limit) { if {![info exists info(htaccessp,require,$op,$key)]} { set info(htaccessp,require,$op,$key) {} } foreach a $list { lappend info(htaccessp,require,$op,$key) $a } } } proc Ht-order {infoName value} { upvar #0 $infoName info if {![info exists info(htaccessp,limit)]} { set info(htaccessp,limit) {} } foreach op $info(htaccessp,limit) { if {[info exists info(htaccessp,order,$op)]} { unset info(htaccessp,order,$op) } set info(htaccessp,order,$op) $value } } proc Ht-deny {infoName args} { HtByNet $infoName deny $args } proc Ht-allow {infoName args} { HtByNet $infoName allow $args } proc HtByNet {infoName how list} { upvar #0 $infoName info if {![info exists info(htaccessp,limit)]} { set info(htaccessp,limit) {} } if {[string compare [lindex $list 0] "from"] == 0} { set list [lrange $list 1 end] } foreach op $info(htaccessp,limit) { if {![info exists info(htaccessp,network,$how,$op)]} { set info(htaccessp,network,$how,$op) {} } foreach a $list { lappend info(htaccessp,network,$how,$op) [string tolower $a] } } } |
Added modules/httpd/cgi.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | # cgi.tcl # CGI support # Stephen Uhler / Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: cgi.tcl,v 1.31 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::cgi 1.1 package require httpd ;# Httpd_Date Httpd_Error Httpd_Port Httpd_SelfUrl Httpd_SockClose package require httpd::counter ;# Count package require httpd::doc ;# DocAccessHook Doc_RegisterRoot Doc_Root Doc_Virtual package require httpd::doc_error ;# Doc_NotFound package require httpd::log ;# Log package require httpd::threadmgr ;# Thread_Id Thread_Send Thread_SendAsync package require httpd::url ;# Url_Dispatch Url_Handle Url_PathCheck Url_PrefixInstall #package require httpd::utils ;# file # Cgi parameters # timeout Seconds before pipe to CGI program is closed # maxcgi Number of concurrent requests allowed # cgi Running total of cgi requests # ident If true, try to use the ident protocol # env-pass List of environment variables to preserve when setting # up the environment. The rest are deleted and then recreated # from information in the CGI request. # tclsh Pathname to a Tcl interpreter. If you preserve the env(PATH) # by listing PATH in env-pass, this can be "tclsh80.exe" # or "protclsh80.exe". Otherwise it has to be an absolute path. array set Cgi { timeout 300000 maxcgi 100 cgi 0 ident 0 env-pass {PATH LD_LIBRARY_PATH TZ} } if {"$tcl_platform(platform)" == "windows"} { # On windows we hard-code the interpreters for various script types regsub -nocase wish [info nameofexecutable] tclsh Cgi(tclsh) ;# For .tcl set Cgi(perl) "perl.exe" ;# For .pl set Cgi(cgiexe) $Cgi(tclsh) ;# For .cgi # More environment variables need to be passed through. # Windows NT Need Lib and SystemRoot so DLLs loaded by tcl are found. # Windows 95 needs more... so we just pass everything lappend Cgi(env-pass) * } # Register a cgi-bin directory. # This causes the server to pay attention to the extra path information # after the program name. proc Cgi_Directory {virtual {directory {}}} { # Set up the URL-directory mapping so that DocAccessHook works right. if {[string length $directory] == 0} { set directory [Doc_Virtual {} {} $virtual] } Doc_RegisterRoot $virtual $directory # Register the domain - not in a thread becaused we'll use another process anyway. # The CGI module will also read the post data itself so TclHttpd doesn't buffer # it all in memory before passing it to the CGI process. Url_PrefixInstall $virtual [list Cgi_Domain $virtual $directory] \ -thread 0 -readpost 0 } # Cgi_Domain is called from Url_Dispatch for URLs inside cgi-bin directories. proc Cgi_Domain {virtual directory sock suffix} { global Cgi env # Check the path and then find the part beyond the program name. # The trimleft avoids a buildup of extra / after the domain prefix. if {[catch {Url_PathCheck [string trimleft $suffix /]} pathlist]} { Doc_NotFound $sock return } # url is the logical name as viewed by a browser # path is a physical file system name as viewd by the server set url [string trimright $virtual /] set path $directory set i 0 foreach component $pathlist { incr i set path [file join $path $component] append url /$component if {[file isfile $path]} { # if {[file executable $path]} { # Don't bother testing execute permission here, # because it doens't test right on windows anyway. set extra [lrange $pathlist $i end] # } break } elseif {![file exists $path]} { Doc_NotFound $sock return } } if {![info exists extra]} { # Didn't find an executable file Httpd_Error $sock 403 return } elseif {[llength $extra]} { set extra /[join $extra /] } # The CGI needs the server-relative url of the script, # the extra part after the program name, # and the translated version of the whole pathname. Url_Handle [list CgiHandle $url $extra $path] $sock } proc CgiHandle {url extra path sock} { global Doc env Cgi_SetEnvAll $sock $path $extra $url env CgiSpawn $sock $path } # This gets called if there is no extra pathname after # the name of a cgi script, and the Doc module finds a .cgi file proc Doc_application/x-cgi {path suffix sock} { upvar #0 Httpd$sock data Url_Handle [list CgiHandle $data(url) {} $path] $sock } # Set the environment for the cgi scripts. This is passed implicitly to # the cgi script during the "open" call. proc Cgi_SetEnv {sock path {var env}} { upvar 1 $var env upvar #0 Httpd$sock data Cgi_SetEnvAll $sock $path {} $data(url) env } proc Cgi_SetEnvInterp {sock path interp} { upvar #0 Httpd$sock data Cgi_SetEnvAll $sock $path {} $data(url) env interp eval $interp [list uplevel #0 \ [list array set env [array get env]]] } proc Cgi_SetEnvAll {sock path extra url var} { upvar #0 Httpd$sock data upvar 1 $var env global Httpd Httpd_EnvMap Cgi # we can't "unset env" or it won't get passed to the CGI script foreach i [array names env] { set clear 1 foreach x $Cgi(env-pass) { if {[string match $x $i]} { # Preserve some path settings set clear 0 break } } if {$clear} { unset env($i) } } foreach name [array names Httpd_EnvMap] { set env($name) "" catch { set env($name) $data($Httpd_EnvMap($name)) } } set env(REQUEST_URI) [Httpd_SelfUrl $data(uri) $sock] set env(GATEWAY_INTERFACE) "CGI/1.1" set env(SERVER_PORT) [Httpd_Port $sock] if {[info exist Httpd(https_port)]} { set env(SERVER_HTTPS_PORT) $Httpd(https_port) } set env(SERVER_NAME) $Httpd(name) set env(SERVER_SOFTWARE) $Httpd(server) set env(SERVER_PROTOCOL) HTTP/1.0 set env(REMOTE_ADDR) $data(ipaddr) set env(SCRIPT_NAME) $url set env(PATH_INFO) $extra set env(PATH_TRANSLATED) [string trimright [Doc_Root] /]/[string trimleft $data(url) /] set env(DOCUMENT_ROOT) [Doc_Root] set env(HOME) [Doc_Root] if {$Cgi(ident)} { catch { set ident [::ident::get $sock] set env(REMOTE_IDENT) [lindex $ident 0] } } if {$data(proto) == "POST"} { set env(QUERY_STRING) "" } } # Enable/disable IDENT lookup. Disabled by default. proc Cgi_Ident state { global Cgi regsub {^(1|yes|true|on)$} $state 1 state regsub {^(0|no|false|off)$} $state 0 state if {$state} { package require ident } set Cgi(ident) $state } # Run a cgi script: # Our caller needs to set up the environment with Cgi_SetEnv. # Run the script, and copy the # output to the socket. # Set a timer to deal with invalid scripts. proc CgiSpawn {sock script} { upvar #0 Httpd$sock data global env Cgi if {$Cgi(cgi) >= $Cgi(maxcgi)} { Httpd_Error $sock 504 "Too many CGI's" return } incr Cgi(cgi) # for GET queries, pass the query as an argument to the cgi script if {$data(proto) == "POST"} { set arglist "" } else { set arglist $data(query) } set pwd [pwd] cd [file dirname $script] if {[catch {CgiExec $script $arglist} fd]} { cd $pwd Httpd_Error $sock 400 $fd incr Cgi(cgi) -1 return } cd $pwd Count cgihits set data(infile) $fd ;# So close happens in Httpd_SockClose set data(header) 0 ;# Have not read header yet set data(headerlist) {} ;# list of read headers set data(headercode) "200 data follows" ;# normal return fconfigure $fd -blocking 0 # Set up a timer in case it hangs catch {after cancel $data(cancel)} set data(cancel) [after $Cgi(timeout) CgiCancel $fd $sock] if {$data(proto) == "POST"} { # Read the pipe in auto mode to properly detect the end of # headers in Unix and Windows. Pump the POST data in # binary mode. fconfigure $fd -translation {auto binary} if {$data(count) == 0} { # Either there was no POST data, or we are inside a domain # that automatically read the POST data into data(query) already # Errors appear here because of the non-blocking writes. catch { puts -nonewline $fd $data(query) flush $fd } } else { # Pump the query data to the CGI process in the background # We set up fileevents after this finishes, so return now # fcopy bug in Tcl 8.3.2 and Tcl 8.4a2 and all previous versions # prevents this from working reliably on large amounts of POST data # fcopy $sock $fd -command [list CgiCopyDone $sock $fd] -size $data(count) fileevent $sock readable [list CgiCopyPost $sock $fd] return } } CgiCopyDone $sock $fd $data(count) "" } # CgiCopyPost -- # # Called to copy POST data down the pipe - need to avoid fcopy bug proc CgiCopyPost {sock fd} { upvar #0 Httpd$sock data global tcl_version set buf [read $sock $data(count)] puts -nonewline $fd $buf if {$tcl_version <= 8.0} { set len [string length $buf] } else { # Ensure we get byte count, not I18N character count set len [string bytelength $buf] } set data(count) [expr {$data(count) - $len}] if {$data(count) <= 0} { flush $fd CgiCopyDone $sock $fd dummy "" } } # CgiCopyDone -- # # Called when we have finished copying POST data to the CGI process proc CgiCopyDone {sock fd bytes {errmsg {}}} { upvar #0 Httpd$sock data # Reset this otherwise the Httpd module tries to read the # extra data set data(count) 0 if {[string length $errmsg]} { CgiCancel } else { # Wait for output from the CGI process (CgiRead) # Watch the socket (CgiCleanup) # In a worker thread, this is not really a socket, hence the catch. catch {fileevent $sock readable [list CgiCleanup $fd $sock]} fileevent $fd readable [list CgiRead $fd $sock] } } # Execute the CGI process. proc CgiExec {script arglist} { global tcl_platform global Cgi switch -- $tcl_platform(platform) { unix { if {[file exists /dev/stdout]} { # This trick "2> /dev/stdout" fails if you start the process in # the background under an xterm, then quit the xterm. In that case # the open raises an error. if { ! [catch {open "|[list $script] $arglist 2> /dev/stdout" r+} pipe]} { return $pipe } } # We use cat to merge the stderr and stdout return [open "|[list $script] $arglist |& cat" r+] } windows { switch -- [file extension $script] { .pl { return [open "|[list $Cgi(perl) $script] $arglist" r+] } .cgi { return [open "|[list $Cgi(cgiexe) $script] $arglist" r+] } .tcl { return [open "|[list $Cgi(tclsh) $script] $arglist" r+] } .exe { return [open "|[list $script] $arglist" r+] } default { error "Don't know how to execute CGI $script" } } } macintosh { error "CGI not supported on Macintosh" } } } # Read data from the CGI script, write to client. proc CgiRead {fd sock} { upvar #0 Httpd$sock data global Cgi Httpd if {[eof $fd]} { CgiClose $fd $sock } elseif {[catch { if {!$data(header)} { # Read and accumulate headers until we know what kind # of response to make set n [gets $fd line] if {$n < 0} { # Blocked or EOF - do nothing. # EOF will be caught on next fileevent. # Blocked means we have a partial line, just wait. } elseif {$n == 0} { set data(header) 1 append header "HTTP/1.0 $data(headercode)\n" append header "Server: $Httpd(server)\n" append header "Date: [Httpd_Date [clock seconds]]\n" append header "Connection: Close\n" foreach line $data(headerlist) { append header $line\n } append header "\n" CgiPutHeader $sock $header } else { lappend data(headerlist) $line if {[regexp -nocase ^(location|uri): $line]} { set data(headercode) "302 found" } } } else { CgiCopy $fd $sock } } oops]} { # Socket may have gone away CgiCancel $fd $sock } } # Emit the header, handling the case where we are in a worker thread. proc CgiPutHeader {sock header} { upvar #0 Httpd$sock data if {[info exist data(master_thread)] && $data(master_thread) != [Thread_Id]} { Thread_Send $data(master_thread) \ [list CgiCopyDirect $sock $header] Thread_Send $data(master_thread) \ [list fconfigure $sock -translation binary] } else { puts -nonewline $sock $header } } # Copy data from the pipe to the socket proc CgiCopy {fd sock} { upvar #0 Httpd$sock data global Httpd fconfigure $fd -translation binary if {[info exist data(master_thread)] && $data(master_thread) != [Thread_Id]} { # Read the data and copy it to the main thread for return. # Quick and dirty until we can transfer file descriptors. # The pipe is already non-blocking - read what we can Thread_SendAsync $data(master_thread) \ [list CgiCopyDirect $sock [read $fd]] return } # Normal one-thread case - set up to copy data from pipe to socket fconfigure $sock -translation binary fileevent $sock readable {} fileevent $fd readable {} fcopy $fd $sock -command [list CgiClose $fd $sock] } proc CgiCopyDirect {sock block} { puts -nonewline $sock $block flush $sock } # This is installed after running the sub-process to # check for eof on the socket before the processing is complete. proc CgiCleanup {fd sock} { fconfigure $sock -blocking 0 -translation auto set n [gets $sock line] if {[eof $sock]} { CgiCancel $fd $sock } } # Cancel a cgi script if it is taking too long. proc CgiCancel {fd sock} { upvar #0 Httpd$sock data if {[info exist data(url)]} { Log $sock CgiCancel $data(url) } catch {exec kill [pid $fd]} CgiClose $fd $sock } # Close down the CGI connection proc CgiClose {fd sock {bytes {}} {error {}}} { global Cgi upvar #0 Httpd$sock data catch {after cancel $data(cancel)} incr Cgi(cgi) -1 if {![info exists data(header)]} { Httpd_Error $sock 204 } else { Httpd_SockClose $sock 1 } if {[string length $error] > 0} { Log $sock CgiClose $error } } |
Added modules/httpd/config.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | # config.tcl # # This provides a simple module to manage configuration variables # # Brent Welch (c) 2000 Scriptics Corporation # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: config.tcl,v 1.4 2004/09/05 05:10:13 coldstore Exp $ package provide httpd::config 1.0 namespace eval config { # The main array holding the configuration information variable Config # The file containing the configuration information variable ConfigFile namespace export cget } # config::init -- # # Get the list of resources from disk. # # Arguments: # config The name of the configuration file (optional) # aname Name of array containing default configuration # values on input, and the new values after # processing the config file. # # Side Effects: # Defines the Config parameter array and records the name of # the configuration file in ConfigFile proc config::init {config aname} { upvar 1 $aname TheirConfig variable Config variable ConfigFile if {[catch {open $config} in]} { return -code error "Cannot read configuration file \"$config\"\nError: $in" } set X [read $in] close $in # Load the file into a safe interpreter that just creates Config array set i [interp create -safe] if {$::tcl_version >= 8.5} { namespace ensemble create -command ::SafeFile -map { isdirectory {::file isdirectory} exists {::file exists} join {::file join} dirname {::file dirname} } $i alias file SafeFile } else { interp expose $i file } $i alias fileutil::tempdir ::fileutil::tempdir # Create the slave's Config array, then source the config script interp eval $i [list array set Config [array get TheirConfig]] interp eval $i { proc Config {name {value {}}} { global Config if {![info exist Config($name)] || [string length $value]} { set Config($name) $value } else { set Config($name) } } } if {[catch {interp eval $i $X} err]} { return -code error "Error in configuration file \"$config\"\n:Error: $err" } array set Config [interp eval $i {array get Config}] interp delete $i set ConfigFile $config } # config::cget -- # # Get the value for an index in the Config array. # # Arguments: # index index in Config array to get. # # Results: # Returns the value of Config for the given index, or "" if # there is no such index. proc config::cget {index} { variable Config if {![info exists Config($index)]} { return "" } return $Config($index) } # config::setValue -- # # Set one or more values for an index(es) in the Config array, and store # the array's new contents in the configuration file. # # Arguments: # args A list of index, value pairs # # Results: # None. proc config::setValue {args} { variable Config variable ConfigFile if {![info exist ConfigFile]} { return -code error "config is not initialized" } set in "(original lost)" if {![file exists $ConfigFile] || [catch {open $ConfigFile} in]} { set note "# Emergency copy: $in\n" unset in } append note "# Last modified: [clock format [clock seconds]]\n" # Re-write config file if {![info exist in]} { # We've lost the original, just dump out the array if {[catch {open $ConfigFile w} out]} { return -code error "Cannot create configuration file: $out" } puts $out "# Server Configuration File\n$note\n" foreach name [lsort [array names Config]] { puts $out [list Config $name $Config($name)]\n } close $out } else { # Re-write the original, inserting the new values. # This code only supports values that fit on one line set X [read $in] close $in if {[catch {open $ConfigFile w} out]} { return -code error "Cannot re-write configuration file: $out" } regsub "^# Last modified:.*?\n" $X $note X foreach {name value} $args { if {[regsub -all "\n\\s*?Config\\s*?[list $name](\\s*?).*?\n" $X \ "\nConfig [list $name]\\1 [list $value]\n" X] == 0} { append X "\n[list Config $name $value]\n" } } puts -nonewline $out $X close $out } # Update in-memory information array set Config $args return } |
Added modules/httpd/cookie.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | # cookie.tcl #@c Cookie support # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: cookie.tcl,v 1.11 2005/01/02 03:36:38 coldstore Exp $ package provide httpd::cookie 1.0 package require httpd ;# Httpd_CurrentSocket Httpd_RemoveCookies Httpd_SetCookie package require httpd::utils ;# K file lassign # Cookie_Save # #@c instruct httpd to return cookies, if any, to the browser # # Arguments: #@a interp The interpreter in which to subst. proc Cookie_Save {sock {interp {}}} { global Cookie if {![catch { interp eval $interp {uplevel #0 {set Cookie(set-cookie)}} } cookie]} { foreach c $cookie { Httpd_SetCookie $sock $c } interp eval $interp {uplevel #0 {unset Cookie(set-cookie)}} } } # Cookie_Get # #@c Return a *list* of cookie values, if present, else "" #@c It is possible for multiple cookies with the same key #@c to be present, so we return a list. #@c WARNING: This uses the environment HTTP_COOKIE, which can #@c get stomped on if a request reenters the event loop #@c See also Cookie_GetSock that doesn't have this problem # # Arguments: #@a cookie The name of the cookie (the key) # Returns: #@r a list of cookie values matching argument proc Cookie_Get {cookie} { global env set result "" if {[info exist env(HTTP_COOKIE)]} { set rawcookie $env(HTTP_COOKIE) } else { # Try to find the connection if {[info exists env(HTTP_CHANNEL)]} { upvar #0 Httpd$env(HTTP_CHANNEL) data if {[info exist data(mime,cookie)]} { set rawcookie $data(mime,cookie) } } } if {[info exist rawcookie]} { foreach pair [split $rawcookie \;] { lassign [split [string trim $pair] =] key value if {[string compare $cookie $key] == 0} { lappend result $value } } } return $result } # Cookie_GetSock # #@c Return a *list* of cookie values, if present, else "" #@c It is possible for multiple cookies with the same key #@c to be present, so we return a list. #@c This always gets the cookie state associated with the specified #@c socket, unlike Cookie_Get that looks at the environment. # # Arguments: #@a cookie The name of the cookie (the key) #@a sock A handle on the socket connection # Returns: #@r a list of cookie values matching argument proc Cookie_GetSock {sock cookie} { upvar #0 Httpd$sock data set result "" set rawcookie "" if {[info exist data(mime,cookie)]} { set rawcookie $data(mime,cookie) } foreach pair [split $rawcookie \;] { lassign [split [string trim $pair] =] key value if {[string compare $cookie $key] == 0} { lappend result $value } } return $result } # Cookie_Make # #$c make a cookie from name value pairs # # Arguments: # args Name value pairs, where the names are: #@a -name Cookie name #@a -value Cookie value #@a -path Path restriction #@a -domain domain restriction #@a -expires Time restriction #@a -secure Append "secure" to cookie attributes #@r a formatted cookie proc Cookie_Make {args} { array set opt $args set line "$opt(-name)=$opt(-value) ;" foreach extra {path domain} { if {[info exist opt(-$extra)]} { append line " $extra=$opt(-$extra) ;" } } if {[info exist opt(-expires)]} { switch -glob -- $opt(-expires) { *GMT { set expires $opt(-expires) } default { set expires [clock format [clock scan $opt(-expires)] \ -format "%A, %d-%b-%Y %H:%M:%S GMT" -gmt 1] } } append line " expires=$expires ;" } if {[info exist opt(-secure)]} { append line " secure " } return $line } # Cookie_Set # #$c Set a return cookie # # Arguments: # args Name value pairs, where the names are: #@a -name Cookie name #@a -value Cookie value #@a -path Path restriction #@a -domain domain restriction #@a -expires Time restriction proc Cookie_Set {args} { global Cookie lappend Cookie(set-cookie) [Cookie_Make {*}$args] } # Cookie_UnSet # #$c Unset a return cookie # # Arguments: # args Name value pairs, where the names are: #@a -name Cookie name #@a -path Path restriction #@a -domain domain restriction proc Cookie_Unset {name args} { Httpd_RemoveCookies [Httpd_CurrentSocket] $name Cookie_Set -name $name -value "" -expires [clock format [clock scan "last year"] -format "%A, %d-%b-%Y %H:%M:%S GMT" -gmt 1] {*}$args } |
Added modules/httpd/counter.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # counter.tcl # # Global counters and histograms # # This module was generalized and moved into the Standard Tcl Library. # This code is now a thin layer over that more general package. # # We pre-declare any non-simple counters (e.g., the time-based # histogram for urlhits, and the interval-histogram for service times) # and everything else defaults to a basic counter. Once things # are declared, the counter::count function counts things for us. # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: counter.tcl,v 1.20 2004/09/05 05:10:13 coldstore Exp $ # Layer ourselves on top of the Standard Tcl Library counter package. package require counter 2.0 package provide httpd::counter 2.0 package require httpd ;# Httpd_RegisterShutdown package require httpd::log ;# Log package require httpd::utils ;# file parray proc Counter_Init {{secsPerMinute 60}} { global counter if {[info exists counter]} { unset counter } set counter(starttime) [clock seconds] # The Count procedure will be self-initializing because # the counter::count module is not. The knownTags list is # searched to determine if we need to initialize the counter. # Predefine well known counters here. # urlhits is the number of requests serviced. counter::init urlhits -timehist $secsPerMinute # This start/stop timer is used for connection service times. # The linear histogram has buckets of 5 msec. counter::init serviceTime -hist 0.005 # This log-scale histogram multiplies the seconds time by # 1000 to get milliseconds, and then plots the log of that. # The log-base histgram isn't useful #counter::init serviceTime -histlog 10 # These group counters are used for per-page hit, notfound, and error # statistics. If you auto-gen unique URLS, these are a memory leak # that you can plug by doing # # status::countInit hit -simple foreach g {domainHit hit notfound errors} { counter::init $g -group $g } # These are simple counters about each kind of connection event foreach c {accepts sockets connections urlreply keepalive connclose http1.0 http1.1 cgihits} { counter::init $c } Httpd_RegisterShutdown Counter_CheckPoint } proc Counter_CheckPoint {} { global Log if {[info exists Log(log)]} { set path $Log(log)counter catch {file rename -force $path $path.old} if {![catch {open $path w} out]} { puts $out \n[parray counter] puts $out \n[parray [counter::get urlhits -histVar]] puts $out \n[parray [counter::get urlhits -histHourVar]] puts $out \n[parray [counter::get urlhits -histDayVar]] close $out } } } proc Count {what {delta 1}} { if {![counter::exists $what]} { counter::init $what } counter::count $what $delta } proc CountName {instance tag} { if {![counter::exists $tag]} { counter::init $tag } counter::count $tag 1 $instance } proc Counter_Reset {what args} { counter::reset $what {*}$args } proc CountHist {what {delta 1}} { counter::count $what $delta } proc CountStart {what instance} { counter::start $what $instance } proc CountStop {what instance} { counter::stop $what $instance # counter::stop $what $instance CountMsec } proc CountMsec {x} { return [expr {$x * 1000}] } proc CountVarName {what} { return [counter::get $what -totalVar] } proc Counter_StartTime {} { return $counter::startTime } |
Added modules/httpd/debug.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | # debug.tcl -- # # Application-direct URLs to help debug the server. # Tcl procedures of the form Debug/hello implement URLS # of the form /debug/hello # # Copyright (c) 1998-2000 by Ajuba Solutions. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: debug.tcl,v 1.21 2004/09/05 05:10:13 coldstore Exp $ package provide httpd::debug 1.0 package require httpd ;# Httpd_Webmaster package require httpd::config ;# Config package require httpd::direct ;# Direct_Url Direct_UrlRemove package require httpd::status ;# Version package require httpd::threadmgr ;# Thread_List Thread_Send package require httpd::utils ;# Stderr file parray # Debug_Url # # Use this to register the URL prefix that corresponds to # the debug URLs implemented by this module # # Arguments: # dir The URL prefix proc Debug_Url {dir} { Direct_Url $dir Debug DebugSetRandomPassword $dir } # DebugSetRandomPassword # # Choose and save a random password used to secure the /debug domain proc DebugSetRandomPassword {dir} { set alphabet {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 0 1 2 3 4 5 6 7 8 9 . + - =} for {set i 0} {$i < 12} {incr i} { set c [lindex $alphabet [expr int(rand() * [llength $alphabet])]] append passwd $c } set ::DebugPassword $passwd # This lets the admin see this important password during startup. # It is also displayed by the Tk srvui interface. Stderr "$dir user \"debug\" password \"$passwd\"" } # DebugPasswordChecker # # This is called to verify the username and password # # Arguments: # sock Handle on the client connection # realm Should be the realm we define above # user The user name # pass The password # # Results: # 1 if access is allowed # 0 if access is denied proc DebugPasswordChecker {sock realm user pass} { # Any user will do, really, if you know the random password switch $user { tclhttpd - debug - default { return [DebugCheckRandomPassword $pass] } } return 0 } # DebugCheckRandomPassword # # Check that the input matches the random password proc DebugCheckRandomPassword {input} { if {![info exist ::DebugPassword]} { return 0 } return [expr {[string compare $::DebugPassword $input] == 0}] } # Debug/source -- # # Source the file into a server thread. First look for the file to # source in the dir specified by Httpd(library). If not found, use the # dir in Doc(templateLibrary) or Config(lib). # # Arguments: # source the file to source # # Results: # Returns HTML code that displays result of loading the file. proc Debug/source {source {thread main}} { global Httpd Doc Config set source [file tail $source] set dirlist $Httpd(library) if {[info exists Doc(templateLibrary)]} { lappend dirlist $Doc(templateLibrary) } if {[info exists Config(library)]} { lappend dirlist $Config(library) } if {[info exists Config(lib)]} { lappend dirlist $Config(lib) } foreach dir $dirlist { set file [file join $dir $source] if {[file exists $file]} { break } } if {![file exists $file]} { set html "<h1>Error sourcing $source</h1>" append html "Cannot find it in <br>[join $dirlist <br>]" return $html } set error [catch { switch -- $thread { main { uplevel #0 [list source $file] } all { foreach id [Thread_List] { Thread_Send $id [list source $file] } } default { Thread_Send $thread [list source $file] } } } result] set html "<title>Source $source</title>\n" if {$error} { global errorInfo append html "<H1>Error in $source</H1>\n" append html "<pre>$result<p>$errorInfo</pre>" } else { append html "<H1>Reloaded $source</H1>\n" append html "<pre>$result</pre>" } return $html } # Debug/package -- # # Forget, delete, and the reload a package into the server. # # Arguments: # name the package to reload. # # Results: # Returns HTML code that displays the result of reloading the package. proc Debug/package {name} { if {[catch { package forget $name catch {namespace delete $name} package require $name } result]} { set html "<title>Error</title> <H1>Error Reloading Package $name</H1> Unable to reload package \"$name\" due to: <PRE> $result </PRE> " } else { set html "<title>Package reloaded</title> <H1>Reloaded Package $name</H1> Version $result of package \"$name\" has been (re)loaded. " } return $html } # Debug/pvalue -- # # Generate HTML code that displays the contents of all existing arrays # and variables that match the glob pattern. # # Arguments: # aname the (fully qualified) glob pattern to match against existing # arrays and variables. # # Results: # Returns HTML code that displays the contents of the arrays and # variables that match the glob pattern. proc Debug/pvalue {aname} { set html "<title>$aname</title>\n" append html [DebugValue $aname] return $html } proc DebugValue {aname} { upvar #0 $aname var append html "<p><b><font size=+=>$aname</font></b><br>\n" if {[array exists var]} { global $aname append html "<pre>[parray $aname]</pre>" } elseif {[info exists var]} { append html "<pre>[list set $aname $var]</pre>" } else { # Undefined variable - see if it is a pattern. # Be careful about declared but undefined procedures # that used to blow the recursion stack here... set list [lsort [uplevel #0 [list info vars $aname]]] if {[llength $list] == 1 && [string compare [lindex $list 0] $aname] == 0} { append html "<pre># $aname undefined</pre>" } else { append html "<ul>" foreach n $list { append html [DebugValue $n] } append html "</ul>" } } return $html } # Debug/parray -- # # Generate HTML code that displays # # Arguments: # aname the name of the array whose contents will appear. # # Results: # Returns HTML code that displays proc Debug/parray {aname} { global $aname set html "<title>Array $aname</title>\n" append html "<H1>Array $aname</H1>\n" append html "<pre>[parray $aname]</pre>" return $html } # Debug/raise -- # # Generate HTML code that causes the Tcl error specified by args to be thrown. # # Arguments: # args (optional) the error string to throw. # # Side Effects: # An error is thrown. # # Results: # none. proc Debug/raise {args} { error $args } # Debug/goof -- # # Generate HTML code that causes the Tcl error: "can't read "goof": no # such variable". # # Arguments: # none. # # Side Effects: # An error is thrown. # # Results: # None. proc Debug/goof {} { set goof return } # Debug/after -- # # Generate HTML code that displays info regarding after events existing # on the server. # # Arguments: # none. # # Results: # Returns HTML. proc Debug/after {} { global tcl_version set html "<title>After Queue</title>\n" append html "<H1>After Queue</H1>\n" append html "<pre>" if {[catch {after info} afterlist]} { append html "\"after info\" not supported in Tcl $tcl_version" } else { foreach a $afterlist { append html "$a [after info $a]\n" } } append html </pre> return $html } # Debug/echo -- # # Generate HTML code that displays the attributes and values posted to # the URL. # # Arguments: # title (optional) title to display # args an even number of attrbutes and values to be displayed. # # Results: # Returns HTML. proc Debug/echo {title args} { set html "<title>$title</title>\n" append html "<H1>$title</H1>\n" append html "<table border=1>\n" foreach {name value} $args { append html "<tr><td>$name</td><td>$value</td></tr>\n" } append html </table> return $html } # Debug/errorInfo -- # # Generate HTML code that displays a title, some errorInfo, and the # contents of (the env) array. # # Arguments: # title (optional) page title to display # errorInfo (optional) error data to display # env (optional) the name of an array to display # # Results: # Returns HTML. proc Debug/errorInfo {title errorInfo {env {no environment}}} { set html "<title>$title</title>\n" append html "<H1>$title</H1>\n" append html "<p>[Version]" append html "<br>Webmaster: [Httpd_Webmaster]" append html <pre>$errorInfo</pre> append html "<p>Environment:</p>" append html "<table>" catch { array set X $env foreach n [lsort [array names X]] { append html "<tr><td>$n</td><td>$X($n)</td></tr>\n" } } append html "</table>" return $html } # Debug/dbg -- # # Initiate a connection with the tcldebugger. # # Arguments: # host the host where the debugger is running # port the port on which the debugger is listening # # Results: # Returns the result of initiating the connection in HTML. proc Debug/dbg {host port} { global debug_init Httpd # In case application-direct parameter bindings are broken, # use the local host and default prodebug port. if {$host == ""} { set host [info hostname] } if {$port == ""} { set port 2576 } if {![info exist debug_init]} { if {[info command debugger_init] == ""} { source [file join $Httpd(library) prodebug.tcl] } debugger_init $host $port set debug_init "$host $port" return "Contacted TclPro debugger at $host:$port" } return "Already connected to tclPro at $debug_init" } # Debug/showproc -- # # Generate HTML code that displays the args and body of a proc. # # Arguments: # proc the name of the procedure # # Results: # Returns HTML. proc Debug/showproc {proc} { global Debug/showproc set Debug/showproc text/plain set alist "" foreach arg [info args $proc] { if {[info default $proc $arg default]} { set arg [list $arg $default] } lappend alist $arg } return [list proc $proc $alist [info body $proc]] } # Debug/disable -- # # Disable debugging in tclhttpd. # # Side Effects: # Removes the /debug URL proc Debug/disable {} { Direct_UrlRemove Debug return "<title>Debugging disabled</title>\n <h1> Debugging disabled</h1>" } |
Added modules/httpd/digest.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | # digest.tcl # # Provides Digest Authentication, per http://www.ietf.org/rfc/rfc2617.txt # Works in conjunction with auth.tcl, requires tcllib. # Digest authentication is selectable in .htaccess. # No provision for dual Basic/Digest authentication. # # Supports only algorithm=MD5 and qop=auth # (which is more than most browsers support :) # # Copyright 2004 Colin McCormack. [email protected] # Licensed on terms identical to tclhttpd's license. package require base64 package provide httpd::digest 1.0 package require httpd::md5hex package require httpd::auth # generate private key if {[catch {package require Random}]} { # use the built in tcl random proc DigestRand {} { return [expr {rand() * 65536}] } } else { # use http://mini.net/tcl/random # cvs -d:pserver:[email protected]:/cvsroot/tclsoap co Random # generate a random seed if {[catch { # try for hardware support set r [open /dev/random] binary scan [read $r 4] I seed close $r }]} { set seed [clock clicks] } ::isaac::isaac seed $seed ;# seed random # get an integer secret proc DigestRand {} { return [::isaac::isaac integer] } } set DigestSecret [DigestRand] proc Digest_Passwd {username realm passwd} { return [string tolower [md5hex "$username:$realm:$passwd"]] } # calculate a digest key for a given session proc DigestA1 {sock} { upvar #0 Httpd$sock data upvar #0 Digest$data(digest,nonce) digest # create a digest for this socket set userstuff "$data(digest,username):$data(digest,realm):$digest(passwd)" #Stderr "DigestA1: $userstuff" switch -- [string tolower $data(digest,algorithm)] { md5 { set digest(A1) [md5hex $userstuff] } md5-sess { set digest(A1) [md5hex "[string tolower [md5hex $userstuff]]:$data(digest,nonce):$data(digest,cnonce)"] } default { error "unknown algorithm: $data(digest,algorithm)" } } set digest(A1) [string tolower $digest(A1)] return $digest(A1) } # per operation hash proc DigestA2 {sock} { upvar #0 Httpd$sock data set uri $data(digest,uri) regexp {[^?]+} $uri uri if {[info exists data(proto)]} { #Stderr "A2: op:$data(proto) uri:$data(digest,uri)" set result [string tolower [md5hex "[string toupper $data(proto)]:$data(digest,uri)"]] # nb: we don't offer auth-int } else { #Stderr "A2: uri:$data(digest,uri)" set result [string tolower [md5hex "GET:$data(digest,uri)"]] } return [string tolower $result] } # generate a nonce proc DigestNonce {} { #return "dcd98b7102dd2f0e8b11d0f600bfb0c093" ;# test global DigestSecret set time [clock clicks] return [string tolower [md5hex ${time}:${DigestSecret}]] } # calculate the digest value for a given operation and session proc DigestDigest {sock} { upvar #0 Httpd$sock data upvar #0 Digest$data(digest,nonce) digest if {![info exists digest(A1)]} { set digest(A1) [DigestA1 $sock] } set digest(A2) [DigestA2 $sock] #Stderr "DigestDigest A1:$digest(A1) A2:$digest(A2) nc:[format %08x $data(digest,nc)] cnonce:$data(digest,cnonce) qop:$data(digest,qop)" if {[info exists data(digest,qop)]} { set result [md5hex "$digest(A1):$data(digest,nonce):[format %08x $data(digest,nc)]:$data(digest,cnonce):$data(digest,qop):$digest(A2)"] } else { set result [md5hex "$digest(A1):$data(digest,nonce):$digest(A2)"] } return [string tolower $result] } # handle the client's Digest proc Digest_Request {sock realm file} { upvar #0 Httpd$sock data upvar #0 Digest$data(digest,nonce) digest set digest(last) [clock clicks] ;# remember the last use if {![info exists digest(A1)]} { set A1 [AuthGetPass $sock $file $data(digest,username)@$data(digest,realm)] if {$A1 != "*"} { set digest(A1) $A1 } else { # no digest password on record - use plaintext password if {![info exists digest(passwd)]} { set digest(passwd) [AuthGetPass $sock $file $data(digest,username)] } set digest(A1) [DigestA1 $sock] #Stderr "Plaintext password $digest(passwd)" } #Stderr "A1 Calc: $digest(A1)" } # check that realms match if {$realm != $data(digest,realm)} { #Stderr "realm" return 0 } #Stderr "Digest_Request: [array get digest] - [array get data digest,*]" if {[info exists digest(opaque)]} { if {$digest(opaque) != $data(digest,opaque)} { #Stderr "Digest Opaque $digest(opaque) ne $data(digest,opaque)" return 0 } } # check the nonce count set data(digest,nc) [scan $data(digest,nc) %08x] if {[info exists digest(nc)]} { if { $data(digest,nc) <= $digest(nc)} { set digest(stale) 1 #Stderr "Digest Stale $digest(nc) ne $data(digest,nc)" #return 0 ;# Mozilla doesn't implement nc } #Stderr "Digest nc $digest(nc) - $data(digest,nc)" } else { #Stderr "Digest New Nonce $data(digest,nc)" return 0 ;# this is new to us } set digest(nc) $data(digest,nc) # check the password set calc_digest [DigestDigest $sock] if {$calc_digest != $data(digest,response)} { #Stderr "Digest Response: $calc_digest ne $data(digest,response)" return 0 } # successful authentication # construct authentication args set a_args "qop=auth" if {[info exists data(digest,cnonce)]} { append a_args ", cnonce=\"$data(digest,cnonce)\"" append a_args ", rspauth=\"${calc_digest}\"" } if {[info exists data(digest,nc)]} { append auth_info [format ", nc=%08x" [expr 1 + $data(digest,nc)]] } # remember some data set digest(realm) $data(digest,realm) set digest(cnonce) $data(digest,cnonce) set digest(username) $data(digest,username) # associate nonce with realm,user global DigestByRealmName set DigestByRealmName($digest(realm),$digest(username)) $digest(nonce) Httpd_AddHeaders $sock Authentication-Info $auth_info #Stderr "Digest Request OK" return 1 } # decode an Authentication request # "parts" comes from the Authorization HTTP header. proc Digest_Get {sock parts} { upvar #0 Httpd$sock data #Stderr "Digest_Get $parts" # get the digest request args foreach el [lrange $parts 1 end] { set el [string trimright $el ,] #foreach {n v} [split $el =] break regexp {^[ ]*([^=]+)[ ]*=[ ]*(.*)$} $el junk n v #Stderr "Getting: '$el' -> $n $v" set data(digest,[string trim $n " "]) [string trim $v " \""] } #Stderr "Digest Got: [array get data digest,*]" # perform some desultory checks on credentials } # create and issue a Digest challenge to the client proc Digest_Challenge {sock realm user} { upvar #0 Httpd$sock data global DigestByRealmName if {[info exists DigestByRealmName($realm,$user)]} { # find an existing nonce for this realm,user pair set nonce $DigestByRealmName($realm,$user) upvar #0 Digest$nonce digest set digest(last) [clock clicks] ;# remember the last use } else { # get a new unique nonce # (redundant, really MD5 doesn't collide) set nonce [DigestNonce] while {[info exists ::Digest$nonce]} { set nonce [DigestNonce] } upvar #0 Digest$nonce digest set digest(last) [clock clicks] ;# remember the last use # initialise the digest state global DigestSecret set digest(nonce) $nonce set digest(opaque) [string tolower [md5hex "[clock clicks]${DigestSecret}"]] #set digest(opaque) 5ccc069c403ebaf9f0171e9517f40e41 ;# test set digest(nc) 0 #set digest(stale) 0 } # construct authentication args # minimally nonce, opaque, qop and algorithm set challenge [list nonce \"$digest(nonce)\" \ domain \"/" \ opaque \"$digest(opaque)\" \ qop \"auth\" \ algorithm MD5] # algorithm \"MD5,MD5-sess\" #if {$digest(stale)} { #lappend challenge stale true #} #Stderr "Digest Challenge: [array get digest] - $challenge" # issue Digest authentication challenge eval Httpd_RequestAuth $sock Digest $realm $challenge } if {0} { # test array set Httpd999 { digest,username Mufasa digest,realm [email protected] digest,nonce dcd98b7102dd2f0e8b11d0f600bfb0c093 uri /dir/index.html digest,uri /dir/index.html op GET digest,qop auth digest,nc 00000001 digest,cnonce 0a4f113b digest,response 6629fae49393a05397450978507c4ef1 digest,opaque 5ccc069c403ebaf9f0171e9517f40e41 digest,algorithm MD5 } array set Digest$Httpd999(digest,nonce) [list last [clock clicks] nc [format %08d 1] opaque $Httpd999(digest,opaque) nonce $Httpd999(digest,nonce) realm [email protected] qop auth,auth-int passwd "Circle Of Life"] AuthParseHtaccess 999 /usr/lib/tclhttpd4.0.0/testdigest if {[catch {Digest_Request 999 [email protected] /usr/lib/tclhttpd4.0.0/testdigest} DTest]} { error "Digest test error" } if {$DTest != 1} { error "Failed digest test" } } # nb: mozilla converts UCS2 to UTF8 for username and password |
Added modules/httpd/direct.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | # direct.tcl # # Support for application-direct URLs that result in Tcl procedures # being invoked inside the server. # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: direct.tcl,v 1.21 2004/11/20 07:10:04 coldstore Exp $ package provide httpd::direct 1.1 package require httpd ;# Httpd_Redirect Httpd_ReturnData package require httpd::cgi ;# Cgi_SetEnv package require httpd::cookie ;# Cookie_Save package require httpd::doc_error ;# Doc_NotFound package require httpd::url ;# Url_PrefixInstall Url_PrefixRemove Url_QuerySetup package require httpd::utils ;# file iscommand # Direct_Url # Define a subtree of the URL hierarchy that is implemented by # direct Tcl calls. # # Arguments # virtual The name of the subtree of the hierarchy, e.g., /device # prefix The Tcl command prefix to use when constructing calls, # e.g. Device # inThread True if this should be dispatched to a thread. # # Side Effects # Register a prefix proc Direct_Url {virtual {prefix {}} {inThread 0}} { global Direct if {[string length $prefix] == 0} { set prefix $virtual } set Direct($prefix) $virtual ;# So we can reconstruct URLs Url_PrefixInstall $virtual [list DirectDomain $prefix] $inThread } # Direct_UrlRemove # Remove a subtree of the URL hierarchy that is implemented by # direct Tcl calls. # # Arguments # prefix The Tcl command prefix used when constructing calls, # # Side Effects # proc Direct_UrlRemove {prefix} { global Direct catch { Url_PrefixRemove $Direct($prefix) } catch { unset Direct($prefix) } } # Main handler for Direct domains (i.e. tcl commands) # prefix: the Tcl command prefix of the domain registered with Direct_Url # sock: the socket back to the client # suffix: the part of the url after the domain prefix. # # This calls out to the Tcl procedure named "$prefix$suffix", # with arguments taken from the form parameters. # Example: # Direct_Url /device Device # if the URL is /device/a/b/c, then the Tcl command to handle it # should be # proc Device/a/b/c # You can define the content type for the results of your procedure by # defining a global variable with the same name as the procedure: # set Device/a/b/c text/plain # The default type is text/html proc DirectDomain {prefix sock suffix} { global Direct global env upvar #0 Httpd$sock data # Set up the environment a-la CGI. Cgi_SetEnv $sock $prefix$suffix # Prepare an argument data from the query data. Url_QuerySetup $sock set cmd [Direct_MarshallArguments $prefix $suffix] if {$cmd == ""} { Doc_NotFound $sock return } # Eval the command. Errors can be used to trigger redirects. set code [catch $cmd result] set type text/html upvar #0 $prefix$suffix aType if {[info exist aType]} { set type $aType } Direct_Respond $sock $code $result $type } # Direct_MarshallArguments -- # # Use the url prefix, suffix, and cgi values (set with the # ncgi package) to create a Tcl command line to invoke. # # Arguments: # prefix The Tcl command prefix of the domain registered # with Direct_Url. # suffix The part of the url after the domain prefix. # # Results: # Returns a Tcl command line. # # Side effects: # If the prefix and suffix do not map to a Tcl procedure, # returns empty string. proc Direct_MarshallArguments {prefix suffix} { global Direct set cmd $prefix$suffix if {![iscommand $cmd]} { return } # Compare built-in command's parameters with the form data. # Form fields with names that match arguments have that value # passed for the corresponding argument. # Form fields with no corresponding parameter are collected into args. set cmdOrig $cmd set params [info args $cmdOrig] foreach arg $params { if {[ncgi::empty $arg]} { if {[info default $cmdOrig $arg value]} { lappend cmd $value } elseif {[string compare $arg "args"] == 0} { set needargs yes } else { lappend cmd {} } } else { # The original semantics for Direct URLS is that if there # is only a single value for a parameter, then no list # structure is added. Otherwise the parameter gets a list # of all values. set vlist [ncgi::valueList $arg] if {[llength $vlist] == 1} { lappend cmd [ncgi::value $arg] } else { lappend cmd $vlist } } } if {[info exists needargs]} { foreach {name value} [ncgi::nvlist] { if {[lsearch $params $name] < 0} { lappend cmd $name $value } } } return $cmd } # Direct_Respond -- # # This function returns the result of evaluating the direct # url. Usually, this involves returning a page, but a redirect # could also occur. # # Arguments: # sock The socket back to the client. # code The return code from evaluating the direct url. # result The return string from evaluating the direct url. # type The mime type to use for the result. (Defaults to text/html). # # # Results: # None. # # Side effects: # If code 302 (redirect) is passed, calls Httpd_Redirect to # redirect the current request to the url in result. # If code 0 is passed, the result is returned to the client. # If any other code is passed, an exception is raised, which # will cause a stack trace to be returned to the client. # proc Direct_Respond {sock code result {type text/html}} { switch $code { 0 { # Fall through to Httpd_ReturnData. } 302 { # Redirect. Httpd_Redirect $result $sock return "" } default { # Exception will cause error page to be returned. global errorInfo errorCode return -code $code -errorinfo $errorInfo -errorcode $errorCode \ $result } } # See if a content type has been registered for the URL. # Save any return cookies which have been set. # This works with the Doc_SetCookie procedure that populates # the global cookie array. Cookie_Save $sock Httpd_ReturnData $sock $type $result return "" } |
Added modules/httpd/dirlist.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | # dirlist.tcl -- # # Create a HTML-formatted directory listing # # Steve Ball (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: dirlist.tcl,v 1.13 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::dirlist 1.1 package require httpd ;# Httpd_ReturnData package require httpd::doc ;# Doc_Handle package require httpd::doc_error ;# Doc_NotFound package require httpd::url ;# Url_Decode Url_DecodeQuery Url_Encode package require httpd::utils ;# file file_latest setmax # DirList_IndexFile -- # # Define the index file for a directory # # Arguments: # pat A glob pattern for index files in a directory. # # Results: # None # # Side Effects: # Sets the index file glob pattern. proc DirList_IndexFile {pat} { global dirlist set dirlist(indexpat) $pat } # DirList_Directory -- # # Handle a directory. Look for the index file, falling back to # the Directory Listing module, if necessary. If the Directory # Listing is hidden, then give the not-found page. # # Arguments: # prefix The URL domain prefix. # path The file system pathname of the directory. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Dispatches to the appropriate page handler. proc DirList_Directory {prefix path suffix sock} { upvar #0 Httpd$sock data global dirlist tcl_platform # Special case because glob doesn't work in wrapped files # Just set indexpat to "index.tml" or "index.html" set npath [file join $path $dirlist(indexpat)] if {[info exist tcl_platform(isWrapped)] && $tcl_platform(isWrapped)} { set newest $npath } else { set newest [file_latest [glob -directory $path -nocomplain -- $dirlist(indexpat)]] } if {[string length $newest]} { # Template hack. Ask for the corresponding .html file in # case that file should be cached when running the template. # If we ask for the .tml directly then its result is never cached. global Template if {[string compare $Template(tmlExt) [file extension $newest]] == 0} { set newest [file root $newest]$Template(htmlExt) } return [Doc_Handle $prefix $newest $suffix $sock] } if {[Dir_ListingIsHidden]} { # Directory listings are hidden, so give the not-found page. return [Doc_NotFound $sock] } # Listings are not hidden, so show it. Httpd_ReturnData $sock text/html [DirList $sock $path $data(url)] } # Dir_HideListings -- # # If a directory is viewed, hide the directory listing. # # Arguments: # None # # Results: # None # # Side Effects: # From now on, directory listings are hidden. proc Dir_HideListings {} { global Doc set Doc(HideDirListing) 1 return } # Dir_ShowListings -- # # If a directory is viewed, show the directory listing. # # Arguments: # None # # Results: # None # # Side Effects: # From now on, directory listings can be shown. proc Dir_ShowListings {} { global Doc set Doc(HideDirListing) 0 return } # Dir_ListingIsHidden -- # # Tell whether directory listings are currently hidden. # # Arguments: # None # # Results: # Returns 1 if listings are hidden, otherwise 0. # # Side Effects: # None proc Dir_ListingIsHidden {} { global Doc return $Doc(HideDirListing) } # By default, directory listings are shown. Dir_ShowListings proc DirListForm {dir urlpath {sort name} {pattern *}} { set what [DirListTerm] set namecheck "" set sizecheck "" set numcheck "" switch -- $sort { number { set numcheck checked } size { set sizecheck checked } default { set namecheck checked } } set listing " <H1>Listing of $what $urlpath</H1> <form action=$urlpath> Pattern <input type=text name=pattern value=$pattern><br> Sort by Modify Date <input type=radio name=sort value=number $numcheck> or Name <input type=radio name=sort value=name $namecheck> or Size <input type=radio name=sort value=size $sizecheck><br> <input type=submit name=submit value='Again'><p> " append listing [DirListInner $dir $urlpath $sort $pattern] append listing "</form>\n" return $listing } proc DirListInner {dir urlpath sort pattern} { set listing "<PRE>\n" set path [file split $dir] # Filter pattern to avoid leaking path information regsub -all {\.+/} $pattern {} pattern set pattern [string trimleft $pattern /] set list [glob -directory $dir -nocomplain -- $pattern] if {[llength $path] > 1} { append listing \ "<A HREF=\"..\">Up to parent [string tolower [DirListTerm]]</A>\n" } set timeformat "%b %e, %Y %X" if {[llength $list] > 0} { set max 0 foreach entry $list { setmax max [string length [file tail $entry]] } incr max [string length </a>] # Resort the list into list2 switch -- $sort { number { set mlist {} foreach entry $list { lappend mlist [list $entry [file mtime $entry]] } if {[catch {lsort -decreasing -integer -index 1 $mlist} list2]} { set list2 [lsort -command DateCompare $mlist] } set extra 1 } size { set slist {} foreach entry $list { lappend slist [list $entry [file size $entry]] } if {[catch {lsort -decreasing -integer -index 1 $slist} list2]} { set list2 [lsort -command SizeCompare $slist] } set extra 1 } default { if {[catch {lsort -dict $list} list2]} { set list2 [lsort -command DirlistCompare $list] } set extra 0 } } # Loop through list2, which may have an extra sorting field we ignore foreach entry $list2 { if {$extra} { set entry [lindex $entry 0] } file lstat $entry lst switch $lst(type) { file { # Should determine dingbat from file type append listing "<A HREF=\"[DirHref $entry]\">[format %-*s $max [file tail $entry]</a>] [format %8d $lst(size)] [format %-5s bytes] [clock format $lst(mtime) -format $timeformat]\n" } directory { append listing "<A HREF=\"[DirHref $entry]/\">[format %-*s $max [file tail $entry]/</a>] [format %8s {}] [format %-5s dir] [clock format $lst(mtime) -format $timeformat]\n" } link { append listing "<A HREF=\"[DirHref $entry]\">[format %-*s $max [file tail $entry]</a>] [format %8s {}] [format %-5s link] [clock format $lst(mtime) -format $timeformat] -> [file readlink $entry]\n" } characterSpecial - blockSpecial - fifo - socket { append listing "<A HREF=\"${urlpath}[file tail $entry]\">[format %-20s [file tail $entry]</a>] $lst(type)\n" } } } } else { append listing "[DirListTerm] is empty\n" } append listing " </PRE> " return $listing } proc DirHref {entry} { set entry [Url_Encode [file tail $entry]] # Decode ".", regsub -all -nocase {%2e} $entry . entry regsub -all -nocase {%5f} $entry _ entry return $entry } proc DirList {sock dir urlpath} { upvar #0 Httpd$sock data set sort name set pattern * if {[info exists data(query)]} { foreach {name value} [Url_DecodeQuery $data(query)] { switch $name { sort {set sort $value} pattern {set pattern $value} } } } return " <HTML> <HEAD> <TITLE>Listing of [DirListTerm] $urlpath</TITLE> </HEAD> <BODY> [DirListForm $dir $urlpath $sort $pattern] </BODY> </HTML>" } # DirlistCompare -- # # Utility procedure for case-insensitive filename comparison. # Suitable for use with lsort proc DirlistCompare {a b} { string compare [string tolower $a] [string tolower $b] } proc DateCompare {a b} { set a [lindex $a 1] set b [lindex $b 1] if {$a > $b} { return -1 } elseif {$a < $b} { return 1 } else { return 0 } } proc SizeCompare {a b} { set aa [lindex $a 1] set bb [lindex $b 1] set res [string compare $aa $bb] if { $res != 0 } { return $res } else { return [string compare $a $b] } } # DirListTerm -- # # Return "Folder" or "Directory" as appropriate proc DirListTerm {} { global tcl_platform if {[string compare macintosh $tcl_platform(platform)]} { set what Directory } else { set what Folder } return $what } |
Added modules/httpd/doc.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | # doc.tcl # # File system based URL support. # This calls out to the Auth module to check for access files. # Once a file is found, it checks for content-type handlers defined # by Tcl procs of the form Doc_$contentType. If those are present # then they are responsible for processing the file and returning it. # Otherwise the file is returned by Doc_Handle. # # If a file is not found then a limited form of content negotiation is # done based on the browser's Accept header. For example, this makes # it easy to transition between foo.shtml and foo.html. Just rename # the file and content negotiation will find it from old links. # # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: doc.tcl,v 1.59 2004/12/11 13:22:40 coldstore Exp $ package require uri package provide httpd::doc 1.1 package require httpd ;# Httpd_ReturnFile package require httpd::auth ;# Auth_Check Auth_Verify package require httpd::cgi ;# Cgi_Domain package require httpd::counter ;# Count CountName package require httpd::dirlist ;# DirList DirList_Directory package require httpd::doc_error ;# Doc_NotFound package require httpd::fallback ;# Fallback_Try package require httpd::mtype ;# Mtype package require httpd::redirect ;# Redirect_Dir Redirect_Self Redirect_To package require httpd::template ;# Template_Dynamic Template_Try package require httpd::url ;# Url_AccessInstall Url_PathCheck Url_PrefixInstall Url_PrefixMatch package require httpd::utils ;# file iscommand # Doc_Root -- # # Query or set the physical pathname of the document root # # Arguments: # real Optional. The name of the file system directory # containing the root of the URL tree. If this is empty, # then the current document root is returned instead. # args "real" followed by "args" for Url_PrefixInstall. # "real" is the name of the file system directory # containing the root of the URL tree. If no args are given, # then the current document root is returned instead. # # Results: # If querying, returns the name of the directory of the document root. # Otherwise returns nothing. # # Side Effects: # Sets the document root. proc Doc_Root {args} { global Doc if {[llength $args] > 0} { set real [lindex $args 0] set Doc(root) $real Doc_AddRoot / $real {*}[lrange $args 1 end] return } return $Doc(root) } # Doc_AddRoot # Add a file system to the virtual document hierarchy # # Arguments: # virtual The URL prefix of the document tree to add. # directory The file system directory containing the doc tree. # args Same as args for Url_PrefixInstall # # Results: # None # # Side Effects: # Sets up a document URL domain and the document-based access hook. proc Doc_AddRoot {virtual directory args} { Doc_RegisterRoot $virtual $directory Url_PrefixInstall $virtual [list DocDomain $virtual $directory] {*}$args Url_AccessInstall DocAccessHook return } # Doc_RegisterRoot # Add a file system managed by any Domain Handler (e.g. CGI) # This is necessary for Doc_AccessControl to search directories right. # # Arguments: # virtual The prefix of the URL # directory The directory that corresponds to $virtual # # Results: # None # # Side Effects: # Registers the URL to directory mapping proc Doc_RegisterRoot {virtual directory} { global Doc if {[info exist Doc(root,$virtual)] && [string compare $Doc(root,$virtual) $directory] != 0} { return -code error \ "Doc_RegisterRoot will not change an existing url to directory mapping" } set Doc(root,$virtual) [file normalize $directory] } # Doc_Include # # Read the contents of the file and substitute them at the stack level # at which this procedure was called. Relative paths will be joined # with the directory at the top of the include stack in global variable # page(includeStack). # # Arguments: # filename The relative path of the file to read. # # Results: # Returns the substituted contents of the file. # # Side Effects: # None. proc Doc_Include {filename} { global page # Use the path at the top of the include stack. set oldIncludeStack $page(includeStack) set path [file join [lindex $oldIncludeStack 0] $filename] # Read the data from the file. ::set f [open $path] ::set data [read -nonewline $f] close $f # Call subst on the data in the stack frame above this one. # To support nested includes, we use a uniquely named # variable to store incremental results. ::set resultVar "__result_[expr rand()]" # Create the script to eval in the stack frame above this one. ::set script "append $resultVar \[subst \{$data\}\]" # Create a temporary variable in the stack frame above this one, # and use it to store the incremental resutls of the multiple loop # iterations. Remove the temporary variable when we're done so there's # no trace of this loop left in that stack frame. upvar $resultVar tmp ::set tmp "" # Including of doc templates can be nested. # Push the directory of the file we are subst'ing onto the include stack. # Perform the substitution, and the pop that dir from the stack. set page(includeStack) [linsert $oldIncludeStack 0 [file dirname $path]] uplevel $script set page(includeStack) $oldIncludeStack ::set result $tmp unset tmp return $result } # Doc_PublicHtml -- # # Enable URLS of the form ~user/a/b/c and map those to # a subdirectory of that users account. # # Arguments: # homedir The directory under a user's home that is their # personal URL root. Defaults to public_html. # If this is empty, then user home directories # are disabled. # # Results: # None # # Side Effects: # Sets the per-user public_html directory name. proc Doc_PublicHtml {{homedir public_html}} { global Doc if {[string length $homedir] == 0} { catch {unset Doc(homedir)} } else { set Doc(homedir) [string trim $homedir /] } } # Doc_Virtual - return a real pathname corresponding to a # "virtual" path in an include # # Arguments: # sock The client connection. # curfile The pathname of the file that contains the # "virtual" URL spec. This is used to resolve # relative URLs. # virtual The URL we need the file name of. # # Results: # The file name corresponding to the URL. # If "" is returned, then the URL is invalid. # # Side Effects: # None proc Doc_Virtual {sock curfile virtual} { global Doc if {[regexp ^~ $virtual]} { # This is UNIX-specific, so we don't need file joins if {![info exists Doc(homedir)]} { return {} ;# Not allowed } set list [split $virtual /] set user [lindex $list 0] if {[catch {glob $user} homedir]} { return {} ;# No such user } return $homedir/$Doc(homedir)/[join [lrange $list 1 end] /] } # Try to hook up the pathname under the appropriate document root if {[regexp ^/ $virtual]} { Url_PrefixMatch $virtual prefix suffix if {[info exist Doc(root,$prefix)]} { return [file join $Doc(root,$prefix) [string trimleft $suffix /]] } else { # Not a document domain, so there cannot be a file behind this url. return {} } } # Non-absolute URL return [file join [file dirname $curfile] $virtual] } # DocAccessHook # # Access handle for Doc domains. # This looks for special files in the file system that # determine access control. This is registered via # Url_AccessInstall # # Arguments: # sock Client connection # url The full URL. We realy need the prefix/suffix, which # is stored for us in the connection state # # Results: # "denied", in which case an authorization challenge or # not found error has been returned. Otherwise "skip" # which means other access checkers could be run, but # most likely access will be granted. proc DocAccessHook {sock url} { global Doc upvar #0 Httpd$sock data # Make sure the path doesn't sneak out via .. # This turns the URL suffix into a list of pathname components if {[catch {Url_PathCheck $data(suffix)} data(pathlist)]} { Doc_NotFound $sock return denied } # Figure out the directory corresponding to the domain, taking # into account other document roots. if {[info exist Doc(root,$data(prefix))]} { set directory $Doc(root,$data(prefix)) } else { set directory [file join $Doc(root,/) [string trimleft $data(prefix) /]] } # Look for .htaccess and .tclaccess files along the path # If you wanted to have a time-limited cache of these # cookies you could save the cost of probing the file system # for these files on each URL. set cookie [Auth_Check $sock $directory $data(pathlist)] # Finally, check access if {![Auth_Verify $sock $cookie]} { return denied } else { return skip } } # DocDomain -- # # Main handler for Doc domains (i.e. file systems) # This looks around for a file and, if found, uses Doc_Handle # to return the contents. # # Arguments: # prefix The URL prefix of the domain. # directory The directory containing teh domain. # sock The socket connection. # suffix The URL after the prefix. # # Results: # None # # Side Effects: # Dispatch to the document handler that is in charge # of generating an HTTP response. proc DocDomain {prefix directory sock suffix} { global Doc upvar #0 Httpd$sock data # The pathlist has been checked and URL decoded by # DocAccess, so we ignore the suffix and recompute it. if {![info exists data(pathlist)]} { set data(pathlist) [Url_PathCheck $data(suffix)] } set pathlist $data(pathlist) set suffix [join $pathlist /] # Check for personal home pages if {[regexp ^~ $pathlist] && [info exists Doc(homedir)]} { set user [lindex $pathlist 0] if {[catch {glob $user} homedir]} { Doc_NotFound $sock return ;# No such user } set directory [file join $homedir $Doc(homedir)] if {![file isdirectory $directory]} { Doc_NotFound $sock return ;# No User's Public Directory } if {![file readable $directory]} { Doc_NotFound $sock return ;# No access to User's Public Directory } set pathlist [lrange $pathlist 1 end] set suffix [join $pathlist /] } # The file join here is subject to attacks that create absolute # pathnames outside the URL tree. We trim left the / and ~ # to prevent those attacks. set path [file join $directory [string trimleft $suffix /~]] set path [DocPathNormalize $path] set data(path) $path ;# record this path for not found handling set data(directory) $directory # Handle existing files return [Doc_Handle $prefix $path $suffix $sock] } # Doc_Return -- # # Return a document from a URL. Dispatch to the mime type handler, if defined. # # Arguments: # prefix The URL prefix of the domain. # path The file system pathname of the file. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Dispatch to the correct document handler. proc Doc_Return {prefix path suffix sock} { upvar #0 Httpd$sock data # precise match - return file or dispatch to mime type handler CountName $data(url) hit switch [file type $path] { directory { if {[string length $data(url)] && ![regexp /$ $data(url)]} { # Insist on the trailing slash Redirect_Dir $sock return } return [DirList_Directory $prefix $path $suffix $sock] } link { set link [file readlink $path] if {[file pathtype $link] == "relative"} { set link [file join [file dirname $path] $link] } return [Doc_Return $prefix $link $suffix $sock] } default { # Look for a Tcl procedure whose # name matches the MIME Content-Type if {[info exists data(contentType)]} { set ctype $data(contentType) ;# set by a template } else { set ctype [Mtype $path] } set cmd Doc_$ctype if {[iscommand $cmd]} { # call the Mime type handler return [$cmd $path $suffix $sock] } else { return [Httpd_ReturnFile $sock $ctype $path] } } } } # Doc_Handle -- # # Handle a document URL. Dispatch to the mime type handler, if defined. # # Arguments: # prefix The URL prefix of the domain. # path The file system pathname of the file. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Dispatch to the correct document handler. proc Doc_Handle {prefix path suffix sock} { upvar #0 Httpd$sock data # first we check if there's a template file to run, and run it # if there's a precise file match, we return it # otherwise we generate alternatives from the client's Accept # otherwise we leave it Cgi to try to satisfy the request # Look for a fresh template which generates the desired path if {[Template_Try $sock $path $suffix]} { # template has handled the request return 1 } # Template_Try hasn't satisfied the request, # Look for an exact match. if {[file exists $path] && [file readable $path]} { # we have a file precisely matching the request Doc_Return $prefix $path $suffix $sock return 1 } # Negotiate an Acceptable available alternative file # if one is found, a redirect is provoked # (FIXME: is this according to the spec?) if {[Fallback_Try $prefix $path $suffix $sock]} { # we have found an Accept-able alternative # Fallback_Try generates a redirect return 1 } # Couldn't find any matches # check for cgi script in the middle of the path # will generate Doc_Notfound if necessary Cgi_Domain $prefix $data(directory) $sock $suffix return 1 } # Doc_GetPath -- # # Return a list of unique directories from domain root to a given path # Adjusts for Document roots and user directories # # Arguments: # sock The client connection # file The file endpoint of the path # Results: # A list of directories from root to directory of $data(path) # # Side Effects: # None. proc Doc_GetPath {sock {file ""}} { global Doc upvar #0 Httpd$sock data if {$file == ""} { set file $data(path) } # Start at the Doc_AddRoot point if {[info exist Doc(root,$data(prefix))]} { set root [file normalize $Doc(root,$data(prefix))] # always start in the rootdir set dirs $Doc(root) } else { set root $Doc(root,/) set dirs {} } set dirsplit [file split [file dirname $file]] if {[string match ${root}* $file]} { # Normal case of pathname under domain prefix set path $root set extra [lrange $dirsplit [llength [file split $root]] end] } elseif {[set hindex [lsearch -exact $dirsplit $Doc(homedir)]] >= 0} { # "public_html" is in the path, so we have been warped # to a user's URL tree. set path [eval file join [lrange $dirsplit 0 $hindex]] incr hindex set extra [lrange $dirsplit $hindex end] } else { # Don't know where we are - just use the current directory set path [file dirname $file] set extra {} } foreach dir [concat [list {}] $extra] { set path [file join $path $dir] # Don't add duplicates to the list. if {[lsearch $dirs $path] == -1} { lappend dirs $path } } return $dirs } # Helper routine for cleaning up file names # Part of the context here is that "file exists" on Windows # ignores trailing . in a pathname, leading to cute attacks if {[catch {file normalize /a/b/../c/foo.tml.}]} { # No file normalize command if {$tcl_platform(platform) == "windows"} { proc DocPathNormalize {path} { return [string trimright $path .] } } else { proc DocPathNormalize {path} { return $path } } } else { proc DocPathNormalize {path} { return [file normalize $path] } } |
Added modules/httpd/doc_error.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | # doc_error.tcl #@c handlers for server errors and doc-not-found cases. # # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: doc_error.tcl,v 1.7 2004/09/05 05:10:13 coldstore Exp $ package provide httpd::doc_error 1.0 package require httpd ;# Httpd_Error package require httpd::counter ;# Count CountName package require httpd::doc ;# Doc_Virtual package require httpd::log ;# Log package require httpd::subst ;# Subst_ReturnFile package require httpd::utils ;# file lappendOnce protect_text # Doc_NotFoundPage -- # #@c Register a file not found error page. #@c This page always gets "subst'ed, but without the fancy #@c context of the ".tml" pages. #@c # Arguments: #@a virtual The URL of the not-found page, e.g., /notfound.html # # Results: #@r None # # Side Effects: #@e Sets the not-found page. proc Doc_NotFoundPage { virtual } { global Doc set Doc(page,notfound) [Doc_Virtual {} {} $virtual] } # Doc_ErrorPage -- # #@c Register a server error page. #@c This page always gets "subst'ed" # # Arguments: #@a virtual The URL of the error page, e.g., /error.html # # Results: #@r None # # Side Effects: #@e Sets the error page. proc Doc_ErrorPage { virtual } { global Doc set Doc(page,error) [Doc_Virtual {} {} $virtual] } # Doc_NotFound -- # #@c Called when a page is missing. This looks for a handler page #@c and sets up a small amount of context for it. # # Arguments: #@a sock The socket connection. # # Results: #@r None # # Side Effects: #@e Returns a page. proc Doc_NotFound { sock } { global Doc Referer upvar #0 Httpd$sock data CountName $data(url) notfound set Doc(url,notfound) $data(url) ;# For subst if {[info exists data(mime,referer)]} { # Record the referring URL so we can track down # bad links lappendOnce Referer($data(url)) $data(mime,referer) } DocSubstSystemFile $sock notfound 404 [protect_text $Doc(url,notfound)] } # Doc_Error -- # #@c Called when an error has occurred processing the page. # # Arguments: #@a sock The socket connection. # ei errorInfo # # Results: #@r None # # Side Effects: #@e Returns a page. proc Doc_Error { sock ei } { global Doc upvar #0 Httpd$sock data # Could have been reset!!! catch { set Doc(errorUrl) $data(url) set Doc(errorInfo) $ei ;# For subst CountName $Doc(errorUrl) errors } if {![info exists data(error_hook)] || [catch {$data(error_hook) $sock}]} { DocSubstSystemFile $sock error 500 [protect_text $ei] } } # DocSubstSystemFile -- # # Simple template processor for notfound and error pages. # # Arguments: # sock The socket connection # key Either "notfound" or "error" # code HTTP code # extra Optional string to include in return page. # interp Interp to use for Subst. # # Results: # None # # Side Effects: # Returns a page. proc DocSubstSystemFile {sock key code {extra {}} {interp {}}} { global Doc env if {![info exists Doc(page,$key)]} { set path [Doc_Virtual {} {} /$key.html] if {[file exists $path]} { set Doc(page,$key) $path } } if {![info exists Doc(page,$key)] || [catch {Subst_ReturnFile $sock $Doc(page,$key) $interp} err]} { if {[info exists err]} { Log $sock DocSubstSystemFile $err } Httpd_Error $sock $code $extra } } # Doc_ErrorInfo -- # #@c Return the error information raised by this page # # Arguments: # # Results: #@r $Doc(errorInfo) # # Side Effects: #@e None proc Doc_ErrorInfo {} { global Doc return $Doc(errorInfo) } # Doc_UrlNotFound -- # #@c Return the url which was not found (in notfound handler) # # Arguments: # # Results: #@r $Doc(url,notfound) # # Side Effects: #@e None proc Doc_UrlNotFound {} { global Doc return $Doc(url,notfound) } |
Added modules/httpd/doctools.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | # doctools.tcl # # tclllib doctools support package provide httpd::doctools 1.0 if {[catch {package require doctools}]} { # tcllib's doctools package must be available return } package require httpd ;# Httpd_PostDataSize Httpd_ReturnData Httpd_ReturnFile package require httpd::mtype ;# Mtype Mtype_Add package require httpd::url ;# Url_ReadPost #package require httpd::utils ;# file # register the man suffix as a doctool application set Doctools(suffix) .man Mtype_Add $Doctools(suffix) application/x-doctool # Doc_application/x-doctool -- # # use doctools to format up and return an html document # # Arguments: # path The file pathname. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Sets up the interpreter context and runs doctools over the page # if necessary, to generate a cached version which is returned to the client. proc Doc_application/x-doctool {path suffix sock} { # allow selection of doctool output types DoctoolsQuery $sock set format [ncgi::value format] if {$format == ""} { set format html } # check if a cached version exists and is newer if {[file exists ${path}.$format]} { set mtime [file mtime ${path}.$format] if {$mtime > [file mtime $path]} { return [Httpd_ReturnFile $sock text/$format ${path}.$format] } } # generate the requested format set fd [open $path] ::doctools::new doctool -format $format if {[catch {doctool format [read $fd]} result]} { } doctool destroy close $fd # write the cached version if {![catch {set fd [open ${path}.$format w]}]} { puts $fd $result close $fd # return the file return [Httpd_ReturnFile $sock text/$format ${path}.$format] } else { # can't cache - return as data Httpd_ReturnData $sock text/$format $result } } # this should be a global facility somewhere proc DoctoolsQuery {sock} { upvar #0 Httpd$sock data if {[Httpd_PostDataSize $sock] > 0 && ![info exists data(query)]} { set data(query) {} } if {[info exist data(query)]} { if {![info exist data(mime,content-type)] || $data(proto) == "GET"} { # The check against GET is because IE 5 has the following bug. # If it does a POST with content-type multipart/form-data and # keep-alive reuses the connection for a subsequent GET request, # then the GET request erroneously has a content-type header # that is a copy of the one from the previous POST! set type application/x-www-urlencoded } else { set type $data(mime,content-type) } # Read and append the pending post data to data(query). Url_ReadPost $sock data(query) # Initialize the Standard Tcl Library ncgi package so its # ncgi::value can be used to get the data. ncgi::reset $data(query) $type ncgi::parse ncgi::urlStub $data(url) } } |
Added modules/httpd/fallback.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | # fallback.tcl #@c Fallback does "content negotation" if a file isn't found #@c look around for files with different suffixes but the same root. # # NOTE: This feature is probably more trouble than it is worth. # It was originally used to be able to choose between different # iamge types (e.g., .gif and .jpg), but is now also used to # find templates (.tml files) that correspond to .html files. # # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: fallback.tcl,v 1.8 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::fallback 1.0 package require httpd::mtype ;# Mtype Mtype_Accept package require httpd::redirect ;# Redirect_QuerySelf package require httpd::template ;# Template_Choose #package require httpd::utils ;# file # Fallback_ExcludePat -- # # Define a pattern of files names to exclude in Fallback # # Arguments: # patlist A glob pattern of files to avoid when playing # games in FallBack to find an alternative file. # # Results: # None # # Side Effects: # Sets the exclude pattern. proc Fallback_ExcludePat {patlist} { global Fallback set Fallback(excludePat) $patlist } if {![info exists Fallback(excludePat)]} { set Fallback(excludePat) {*.bak *.swp *~} } # Fallback_Try # # Try to find an file which matches the HTTP Accept alternatives # given by the client. # # Arguments: # prefix The URL prefix of the domain. # path The pathname we were trying to find. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # This either triggers an HTTP redirect to switch the user # to the correct file name, or it calls out to the template-aware # text/html processor. proc Fallback_Try {virtual path suffix sock} { set root [file root $path] if {[string match */ $root]} { # Input is something like /a/b/.xyz return 0 } # Look for files indicated by any Accept headers. # Most browsers say */*, but they may provide some ordering info, too. # First generate a list of candidate files by ignoring extension global Template ;# we need the template extension here set ok {} foreach choice [glob -nocomplain $root.*] { # don't let "foo.html.old" match for "foo.html" # but let foo.*.tml match for foo.* if {[string equal $root [file root $choice]] || [string equal [file extension $choice] $Template(tmlExt)]} { # Filter on the exclude patterns if {![FallbackExclude $choice]} { lappend ok $choice } } } # Now we pick the best file from the files and templates that matched # Template_Choose will return us the best possible match # the best match might not yet exist, but may be able to be generated # from a template, which will be handled after the redirection we provoke set npath [Template_Choose [Mtype_Accept $sock] $ok] if {[string length $npath] == 0} { # there was no viable alternative return 0 } elseif {[string compare $path $npath] == 0} { # the best alternative was the original path requested # FIXME: this is bogus - we shouldn't even be called if there's a match return 0 } else { # A file matched with a different extension to that requested # (if the match was a template, we offer the untemplated name.) # Redirect_to/offer our best match. # Redirect so we don't mask spelling errors like john.osterhoot set new [file extension $npath] ;# candidate extension set old [file extension $suffix] ;# requested extension if {[string length $old] == 0} { append suffix $new ;# client request was without extension } else { # client requested foo.$old, we're offering foo.$new # Watch out for specials in $old, like .html) # FIXME: the following seems bogus and heavyweight # if there's an element in the path which happens to match the ext, # we will subst it too, which can't be a good thing. # we should really decompose the path and reconstruct it. regsub -all {[][$^|().*+?\\]} $old {\\&} old ;# quote special chars regsub $old\$ $suffix $new suffix ;# substitute $new for $old } # Offer alternative to the client by redirection, preserving query data Redirect_QuerySelf $sock "$virtual[string trimleft $suffix /~]" return 1 ;# we have completely handled the request. } } # FallbackExclude -- # # This is used to filter out files like "foo.bak" and foo~ # from the Fallback failover code # # Arguments: # name The filename to filter. # # Results: # 1 If the file should be excluded, 0 otherwise. # # Side Effects: # None proc FallbackExclude {name} { global Fallback foreach pat $Fallback(excludePat) { if {[string match $pat $name]} { return 1 } } return 0 } |
Added modules/httpd/fastcgi.tcl.
> > > > > > > | 1 2 3 4 5 6 7 | ### # This package adds fastCGI support for tclhttpd # While it's cool that tclhttpd *can* do a lot of things dynamically # it often needs to access external components ### package provide httpd::fastcgi 0.1 |
Added modules/httpd/fossil.tcl.
> > > > > > | 1 2 3 4 5 6 | ### # This package adds fastCGI support for fossil repositories ### package provide httpd::fossil 0.1 |
Added modules/httpd/httpd.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 | # httpd.tcl -- # # HTTP 1.0 protocol stack, plus connection keep-alive and 1.1 subset. # This accepts connections and calls out to Url_Dispatch once a request # has been recieved. There are several utilities for returning # different errors, redirects, challenges, files, and data. # # For binary data transfer this uses unsupported0 or fcopy. # Tcl8.0a2 was the last release with unsupported0. # Note that Tcl8.0b1 has a bug in fcopy where if an error occurs then # bgerror is called instead of the command callback to fcopy. This # causes file descriptor leaks, so don't use 8.0b1 for real servers. # # For async operation, such as long-lasting server-side operations use # Httpd_Suspend. # # Copyright # Matt Newman (c) 1999 Novadigm Inc. # Stephen Uhler / Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # Brent Welch (c) 2001-2004 Panasas Inc # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: httpd.tcl,v 1.90 2005/02/26 02:33:31 coldstore Exp $ package provide httpd 1.7 package require httpd::config ;# Config config::cget config::init package require httpd::counter ;# Count CountHist CountStart CountStop package require httpd::log ;# Log Log_Flush Log_FlushMinutes Log_SetFile package require httpd::logstd ;# LogValue package require httpd::redirect ;# Redirect_Dir package require httpd::threadmgr ;# Thread_Enabled Thread_Init Thread_Respond package require httpd::url ;# Url_Decode Url_DecodeQuery Url_Dispatch Url_PostHook package require httpd::utils ;# K Stderr file protect_text package require httpd::version ;# Httpd_Version # initialize all the global data # Location of this package set Httpd(library) [file dirname [info script]] # HTTP/1.0 error codes (the ones we use) array set Httpd_Errors { 200 {Data follows} 204 {No Content} 302 {Found} 304 {Not Modified} 400 {Bad Request} 401 {Authorization Required} 403 {Permission denied} 404 {Not Found} 408 {Request Timeout} 411 {Length Required} 419 {Expectation Failed} 500 {Server Internal Error} 501 {Server Busy} 503 {Service Unavailable} 504 {Service Temporarily Unavailable} } # Environment variables that are extracted from the mime header # by Cgi_SetEnv. The values are keys into the # per-connection state array (i.e. "data") array set Httpd_EnvMap { CONTENT_LENGTH mime,content-length CONTENT_TYPE mime,content-type HTTP_ACCEPT mime,accept HTTP_AUTHORIZATION mime,authorization HTTP_FROM mime,from HTTP_REFERER mime,referer HTTP_USER_AGENT mime,user-agent QUERY_STRING query REQUEST_METHOD proto HTTP_COOKIE mime,cookie HTTP_FORWARDED mime,forwarded HTTP_HOST mime,host HTTP_PROXY_CONNECTION mime,proxy-connection REMOTE_USER remote_user AUTH_TYPE auth_type } # The per-connection state is kept in the "data" array, which is # really an array named Httpd$sock - (note the upvar #0 trick throughout) # The elements of this array are documented here. URL implementations # are free to hang additional state off the data array so long as they # do not clobber the elements documented here: # These fields are semi-public, or "well known". There are a few # API's to access them, but URL implementations can rely on these: # # self A list of protocol (http or https), name, and port that # capture the server-side of the socket address # Available with Httpd_Protocol, Httpd_Name, and Httpd_Port API. # uri The complete URL, including proto, servername, and query # proto http or https # url The URL after the server name and before the ? # query The URL after the ? # ipaddr The remote client's IP address # cert Client certificate (The result of tls::status) # host The host specified in the URL, if any (proxy case) # port The port specified in the URL, if any # mime,* HTTP header request lines (e.g., mime,content-type) # count Content-Length # set-cookie List of Set-Cookie headers to stick into the response # Use Httpd_SetCookie to append to this. # headers List of http headers to stick into the response # Use Httpd_AddHeaders to append to this. # prefix (Set by Url_Dispatch to be the URL domain prefix) # suffix (Set by Url_Dispatch to be the URL domain suffix) # auth_type (Set by the auth.tcl module to "Basic", etc.) # remote_user (Set by the auth.tcl to username from Basic authentication) # session (Set by the auth.tcl to "realm,$username" from Basic auth) # You can overwrite this session ID with something more useful # Internal fields used by this module. # left The number of keep-alive connections allowed # cancel AfterID of event that will terminate the connection on timeout # state State of request processing # version 1.0 or 1.1 # line The current line of the HTTP request # mimeorder List indicating order of MIME header lines # key Current header key # checkNewLine State bit for Netscape SSL newline bug hack # callback Command to invoke when request has completed # file_size Size of file returned by ReturnFile # infile Open file used by fcopy to return a file, or CGI pipe # filter List of http post-generation filter procs to apply to content # path normalized path to Doc file (set by doc.tcl) # Httpd_Init # Initialize the httpd module. Call this early, before Httpd_Server. # # Arguments: # none # # Side Effects: # Initialize the global Httpd array. # bufsize: Chunk size for copies # initialized: True after server started. # ipaddr: Non-default ipaddr for the server (for multiple interfaces) # library: a directory containing the tcl scripts. # port: The port this server is serving # listen: the main listening socket id # server: The server ID for the HTTP protocol. # shutdown: A list of Tcl callbacks made when the server shuts down # sockblock: blocking mode value for sockets (normally this should be 0) # timeout1: Time before the server closes a kept-alive socket (msecs) # timeout2: Time before the server kills an in-progress transaction. (msecs) # timeout3: Time allowed to drain extra post data # version: The version number. # maxused: Max number of transactions per socket (keep alive) proc Httpd_Init {} { global Httpd array set Httpd { timeout1 120000 timeout2 120000 timeout3 2000 server "Tcl-Webserver/" initialized 1 shutdown "" sockblock 0 bufsize 16384 maxused 25 } if {![info exist Httpd(maxthreads)]} { set Httpd(maxthreads) 0 } Httpd_Version append Httpd(server) $Httpd(version) } # Httpd_Server -- # Start the server by listening for connections on the desired port. # This may be re-run to re-start the server. Call this late, # fter Httpd_Init and the init calls for the other modules. # # Arguments: # port The TCP listening port number # name The qualified host name returned in the Host field. Defaults # to [info hostname] # ipaddr Non-default interface address. Otherwise IP_ADDR_ANY is used # so the server can accept connections from any interface. # # Results: # none # # Side Effects: # This sets up a callback to HttpdAccept for new connections. proc Httpd_Server {{port 80} {name {}} {ipaddr {}}} { global Httpd if {![info exists Httpd(initialized)]} { Httpd_Init } catch {close $Httpd(listen)} set Httpd(name) $name set Httpd(ipaddr) $ipaddr set Httpd(port) $port if {[string length $name] == 0} { set Httpd(name) [info hostname] } set cmd [list socket -server [list HttpdAccept \ [list http $name $port]]] if {[string length $ipaddr] != 0} { lappend cmd -myaddr $ipaddr } lappend cmd $port if {[catch $cmd Httpd(listen)]} { return -code error "$Httpd(name):$port $Httpd(listen)\ncmd=$cmd" } } # Httpd_ServerShutdown -- # # Close the server's HTTP socket. # # Arguments: # none # # Results: # Returns "" if the socket was successfully closed, otherwise an error string. # # Side Effects: # Close the server's HTTP listening socket. proc Httpd_ServerShutdown {} { global Httpd Log {} ShutdownSocket catch {close $Httpd(listen)} err return $err } proc Httpd_VirtualHost {host file} { return [Httpd_VirtualHosts [list $host] $file] } proc Httpd_VirtualHosts {hostNames file} { variable virtual foreach host $hostNames { set host [string tolower $host] if {[info exists virtual($host)]} { error "Virtual host $host already exists" } } set slave [interp create] # Transfer the scalar global variables foreach var {::v ::auto_path} { $slave eval [list set $var [set $var]] } # Transfer the array global variables foreach arr {::Config ::Httpd} { $slave eval [list array set $arr [array get $arr]] } $slave eval [list array set ::Httpd [list name $host]] # Load the packages $slave eval package require httpd [package provide httpd] foreach pkg {version utils counter config} { $slave eval \ package require httpd::$pkg [package provide httpd::$pkg] } $slave eval [list array set Config [list config $file host $host]] $slave eval { config::init $Config(config) Config namespace import config::cget # This replaces the command line processing array set Config [array get config::Config] if {[string length $Config(library)] && [lsearch -exact $auto_path $Config(library)] == -1} { lappend auto_path $Config(library) } Httpd_Init if {$Config(threads) > 0} { package require Thread ;# C extension package require httpd::threadmgr ;# Tcl layer on top Thread_Init $Config(threads) } else { # Stub out Thread_Respond so threadmgr isn't required proc Thread_Respond {args} {return 0} proc Thread_Enabled {} {return 0} } source $Config(main) Log_SetFile [cget LogFile]$Config(port)_ Log_FlushMinutes [cget LogFlushMinutes] Log_Flush } foreach host $hostNames { set host [string tolower $host] set virtual($host) $slave } } # Httpd_SecureServer -- # # Like Httpd_Server, but with additional setup for SSL. # This requires the TLS extension. # # Arguments: # port The TCP listening port number # name The qualified host name returned in the Host field. Defaults # to [info hostname] # ipaddr Non-default interface address. Otherwise IP_ADDR_ANY is used # so the server can accept connections from any interface. # # Results: # none # # Side Effects: # This sets up a callback to HttpdAccept for new connections. proc Httpd_SecureServer {{port 443} {name {}} {ipaddr {}}} { global Httpd if {![info exists Httpd(initialized)]} { Httpd_Init } catch {close $Httpd(https_listen)} set Httpd(name) $name set Httpd(https_ipaddr) $ipaddr set Httpd(https_port) $port if {[string length $name] == 0} { set Httpd(name) [info hostname] } package require tls # This now depends on a call to tls::init being made elsewhere, typically # in the main startup script. That call sets all the various SSL parameters # based on the server's configuration file. set cmd [list tls::socket -server [list HttpdAccept \ [list https $name $port]]] if {[string length $ipaddr] != 0} { lappend cmd -myaddr $ipaddr } lappend cmd $port if {[catch $cmd Httpd(https_listen)]} { return -code error "$Httpd(name):$port $Httpd(https_listen)\ncmd=$cmd" } } # Httpd_SecureServerShutdown -- # # Close the server's secure socket. # # Arguments: # none # # Results: # Returns "" if the socket was successfully closed, otherwise an error string. # # Side Effects: # Close the server's HTTPS listening socket. proc Httpd_SecureServerShutdown {} { global Httpd Log {} ShutdownSecureSocket catch {close $Httpd(https_listen)} err return $err } # Httpd_Shutdown -- # # Kill the server gracefully # # Arguments: # none # # Results: # none # # Side Effects: # Close the server listening socket(s) # Invoke any registered shutdown procedures. proc Httpd_Shutdown {} { global Httpd variable virtual set ok 1 foreach host [array names virtual] { $virtual($host) eval Httpd_Shutdown } foreach handler $Httpd(shutdown) { if {[catch {eval $handler} err]} { Log "" "Shutdown: $handler" $err set ok 0 } } Log {} Shutdown Httpd_ServerShutdown Httpd_SecureServerShutdown return $ok } # Httpd_RegisterShutdown -- # # Register a Tcl command to be called by Httpd_Shutdown # # Arguments: # cmd The command to eval from Httpd_Shutdown # # Results: # none # # Side Effects: # Save the callback. proc Httpd_RegisterShutdown {cmd} { global Httpd if {[lsearch $Httpd(shutdown) $cmd] < 0} { lappend Httpd(shutdown) $cmd } } # HttpdAccept -- # # This is the socket accept callback invoked by Tcl when # clients connect to the server. # # Arguments: # self A list of {protocol name port} that identifies the server # sock The new socket connection # ipaddr The client's IP address # port The client's port # # Results: # none # # Side Effects: # Set up a handler, HttpdRead, to read the request from the client. # The per-connection state is kept in Httpd$sock, (e.g., Httpdsock6), # and upvar is used to create a local "data" alias for this global array. proc HttpdAccept {self sock ipaddr port} { global Httpd upvar #0 Httpd$sock data Count accepts Count sockets set data(self) $self set data(ipaddr) $ipaddr if {[Httpd_Protocol $sock] == "https"} { # There is still a lengthy handshake that must occur. # We do that by calling tls::handshake in a fileevent # until it is complete, or an error occurs. Count accept_https fconfigure $sock -blocking 0 fileevent $sock readable [list HttpdHandshake $sock] } else { HttpdReset $sock $Httpd(maxused) } } # HttpdHandshake -- # # Complete the SSL handshake. This is called from a fileevent # on a new https connection. It calls tls::handshake until done. # # Arguments: # sock The socket connection # # Results: # none # # Side Effects: # If the handshake fails, close the connection. # Otherwise, call HttpdReset to set up the normal HTTP protocol. proc HttpdHandshake {sock} { upvar #0 Httpd$sock data global Httpd errorCode if {[catch {tls::handshake $sock} complete]} { if {[lindex $errorCode 1] == "EAGAIN"} { # This seems to occur normally on UNIX systems return } Log $sock "HttpdHandshake" "\{$data(self)\} $sock \ $data(ipaddr) $complete" Httpd_SockClose $sock 1 "$complete" } elseif {$complete} { set data(cert) [tls::status $sock] HttpdReset $sock $Httpd(maxused) } } # HttpdReset -- # # Initialize or reset the socket state. # We allow multiple transactions per socket (keep alive). # # Arguments: # sock The socket connection # left (optional) The keepalive connection count. # # Results: # none # # Side Effects: # Resets the "data" array. # Cancels any after events. # Closes the socket upon error or if the reuse counter goes to 0. # Sets up the fileevent for HttpdRead proc HttpdReset {sock {left {}}} { global Httpd upvar #0 Httpd$sock data if {[catch { flush $sock } err]} { Httpd_SockClose $sock 1 $err return } Count connections # Count down transactions. if {[string length $left]} { set data(left) $left } else { set left [incr data(left) -1] } if {[info exists data(cancel)]} { after cancel $data(cancel) } # Clear out (most of) the data array. set ipaddr $data(ipaddr) set self $data(self) if {[info exist data(cert)]} { set cert $data(cert) } unset data array set data [list state start version 0 \ left $left ipaddr $ipaddr self $self] if {[info exist cert]} { set data(cert) $cert } # Set up a timer to close the socket if the next request # is not completed soon enough. The request has already # been started, but a bad URL domain might not finish. set data(cancel) [after $Httpd(timeout1) \ [list Httpd_SockClose $sock 1 "timeout"]] fconfigure $sock -blocking 0 -buffersize $Httpd(bufsize) \ -translation {auto crlf} fileevent $sock readable [list HttpdRead $sock] fileevent $sock writable {} } # Httpd_Peername -- # # Really need to fix the core to support DNS lookups. # This routine is not used anywhere. # # Arguments: # sock Socket connection # # Results: # The clients dns name. # # Side Effects: # None proc Httpd_Peername {sock} { # This is expensive! fconfigure $sock -peername } # HttpdRead -- # # Read request from a client. This is the main state machine # for the protocol. # # Arguments: # sock Socket connection # # Results: # None # # Side Effects: # Reads the request from the socket and dispatches the # URL request when ready. proc HttpdRead {sock} { global Httpd upvar #0 Httpd$sock data # Use line mode to read the request and the mime headers if {[catch {gets $sock line} readCount]} { Httpd_SockClose $sock 1 "read error: $readCount" return } # State machine is a function of our state variable: # start: the connection is new # mime: we are reading the protocol headers # and how much was read. Note that # [string compare $readCount 0] maps -1 to -1, 0 to 0, and > 0 to 1 set state [string compare $readCount 0],$data(state) switch -glob -- $state { 1,start { if {[regexp {^([^ ]+) +([^?]+)\??([^ ]*) +HTTP/(1.[01])} \ $line x data(proto) data(url) data(query) data(version)]} { # data(uri) is the complete URI set data(uri) $data(url) if {[string length $data(query)]} { append data(uri) ?$data(query) } # Strip leading http://server and look for the proxy case. if {[regexp {^https?://([^/:]+)(:([0-9]+))?(.*)$} $data(url) \ x xserv y xport urlstub]} { set myname [Httpd_Name $sock] set myport [Httpd_Port $sock] if {([string compare \ [string tolower $xserv] \ [string tolower $myname]] != 0) || ($myport != $xport)} { set data(host) $xserv set data(port) $xport } # Strip it out if it is for us (i.e., redundant) # This makes it easier for doc handlers to # look at the "url" set data(url) $urlstub } set data(state) mime set data(line) $line CountHist urlhits # Limit the time allowed to serve this request if {[info exists data(cancel)]} { after cancel $data(cancel) } set data(cancel) [after $Httpd(timeout2) \ [list HttpdCancel $sock]] } else { # Could check for FTP requests, here... Log $sock HttpError $line Httpd_SockClose $sock 1 } } 0,start { # This can happen in between requests. } 1,mime { # This regexp picks up # key: value # MIME headers. MIME headers may be continue with a line # that starts with spaces. if {[regexp {^([^ :]+):[ ]*(.*)} $line dummy key value]} { # The following allows something to # recreate the headers exactly lappend data(headerlist) $key $value # The rest of this makes it easier to pick out # headers from the data(mime,headername) array set key [string tolower $key] if {[info exists data(mime,$key)]} { append data(mime,$key) ,$value } else { set data(mime,$key) $value lappend data(mimeorder) $key } set data(key) $key } elseif {[regexp {^[ ]+(.*)} $line dummy value]} { # Are there really continuation lines in the spec? if {[info exists data(key)]} { append data(mime,$data(key)) " " $value } else { Httpd_Error $sock 400 $line } } else { Httpd_Error $sock 400 $line } # Check for virtual host variable virtual if {[string compare host $key]} {return} set host [lindex [split [string tolower $value] :] 0] if {[catch {set virtual($host)} i]} {return} # Transfer $sock to interp $i fileevent $sock readable {} interp transfer {} $sock $i set data(self) [list [Httpd_Protocol $sock] \ $host [Httpd_Port $sock]] if {[info exists data(cancel)]} { after cancel $data(cancel) unset data(cancel) } $i eval [list array set Httpd$sock [array get data]] unset data $i eval [list fileevent $sock readable [list HttpdRead $sock]] set tmp [$i eval [list \ after $Httpd(timeout2) [list HttpdCancel $sock]]] $i eval [list array set Httpd$sock [list cancel $tmp]] } 0,mime { if {$data(proto) == "POST"} { fconfigure $sock -translation {binary crlf} if {![info exists data(mime,content-length)]} { Httpd_Error $sock 411 return } set data(count) $data(mime,content-length) if {$data(version) >= 1.1 && [info exists data(mime,expect)]} { if {$data(mime,expect) == "100-continue"} { puts $sock "100 Continue HTTP/1.1\n" flush $sock } else { Httpd_Error $sock 419 $data(mime,expect) return } } # Flag the need to check for an extra newline # in SSL connections by some browsers. set data(checkNewline) 1 # Facilitate a backdoor hook between Url_DecodeQuery # where it will read the post data on behalf of the # domain handler in the case where the domain handler # doesn't use an Httpd call to read the post data itself. Url_PostHook $sock $data(count) } else { Url_PostHook $sock 0 ;# Clear any left-over hook set data(count) 0 } # Disabling this fileevent makes it possible to use # http::geturl in domain handlers reliably fileevent $sock readable {} # The use of HTTP_CHANNEL is a disgusting hack. set ::env(HTTP_CHANNEL) $sock # Do a different dispatch for proxies. By default, no proxy. if {[info exist data(host)]} { if {[catch { Proxy_Dispatch $sock } err]} { Httpd_Error $sock 400 "No proxy support\n$err" } } else { # Dispatch to the URL implementation. # As a service for domains that loose track of their # context (e.g., .tml pages) we save the socket in a global. # If a domain implementation would block and re-enter the # event loop, it must use Httpd_Suspend to clear this state, # and use Httpd_Resume later to restore it. set Httpd(currentSocket) $sock CountStart serviceTime $sock Url_Dispatch $sock } } -1,* { if {[fblocked $sock]} { # Blocked before getting a whole line return } if {[eof $sock]} { Httpd_SockClose $sock 1 "" return } } default { Httpd_Error $sock 404 "$state ?? [expr {[eof $sock] ? "EOF" : ""}]" } } } # Httpd_PostDataSize -- # # Arguments: # sock Client connection # # Results: # The amount of post data available. proc Httpd_PostDataSize {sock} { upvar #0 Httpd$sock data return $data(count) } # Httpd_GetPostData -- # # Arguments: # sock Client connection # varName Name of buffer variable to append post data to # size Amount of data to read this call. -1 to read all available. # # Results: # The amount of data left to read. When this goes to zero, you are done. proc Httpd_GetPostData {sock varName {size -1}} { global Httpd upvar #0 Httpd$sock data upvar 1 $varName buffer if {$size < 0} { set size $Httpd(bufsize) } HttpdReadPost $sock buffer $size return $data(count) } # Httpd_ReadPostDataAsync -- # # Convenience layer on Http-GetPostDataAsync to # read the POST data into a the data(query) variable. # # Arguments: # (Same as HttpdReadPost) # # Side Effects: # (See Httpd_GetPostDataAsync) proc Httpd_ReadPostDataAsync {sock cmd} { global Httpd upvar #0 Httpd$sock data if {[string length $data(query)]} { # This merges query data from the GET/POST URL append data(query) & } Httpd_Suspend $sock fileevent $sock readable [list HttpdReadPostGlobal $sock \ Httpd${sock}(query) $Httpd(bufsize) $cmd] return } # Httpd_GetPostDataAsync -- # # Read the POST data into a Tcl variable, but do it in the # background so the server doesn't block on the socket. # # Arguments: # (Same as HttpdReadPost) # # Side Effects: # This schedules a readable fileevent to read all the POST data # asynchronously. The data is appened to the named variable. # The callback is made proc Httpd_GetPostDataAsync {sock varName blockSize cmd} { Httpd_Suspend $sock fileevent $sock readable \ [list HttpdReadPostGlobal $sock $varName $blockSize $cmd] return } # HttpdReadPostGlobal -- # # This fileevent callback can only access a global variable. # But HttpdReadPost needs to affect a local variable in its # caller so it can be shared with Httpd_GetPostData. # So, the fileevent case has an extra procedure frame. # # Arguments: # (Same as HttpdReadPost) # # Results: # None # # Side Effects: # Accumulates POST data into the named variable proc HttpdReadPostGlobal {sock varName blockSize {cmd {}}} { upvar #0 $varName buffer HttpdReadPost $sock buffer $blockSize $cmd } # HttpdReadPost -- # # The core procedure that reads post data and accumulates it # into a Tcl variable. # # Arguments: # sock Client connection # varName Name of buffer variable to append post data to. This # must be a global or fully scoped namespace variable, or # this can be the empty string, in which case the data # is discarded. # blockSize Default read block size. # cmd Callback to make when the post data has been read. # It is called like this: # cmd $sock $varName $errorString # Where the errorString is only passed if an error occurred. # # Results: # None # # Side Effects: # Consumes post data and appends it to a variable. proc HttpdReadPost {sock varName blockSize {cmd {}}} { global Httpd upvar #0 Httpd$sock data # Ensure that the variable, if specified, exists by appending "" to it if {[string length $varName]} { upvar 1 $varName buffer append buffer "" } if {[eof $sock]} { if {$data(count)} { set doneMsg "Short read: got [string length $buffer] bytes,\ expected $data(count) more bytes" set data(count) 0 } else { set doneMsg "" } } else { if {[info exist data(checkNewline)]} { # Gobble a single leading \n from the POST data # This is generated by various versions of Netscape # when using https/SSL. This extra \n is not counted # in the content-length (thanks!) set nl [read $sock 1] if {[string compare $nl \n] != 0} { # It was not an extra newline. incr data(count) -1 if {[info exist buffer]} { append buffer $nl } } unset data(checkNewline) } set toRead [expr {$data(count) > $blockSize ? \ $blockSize : $data(count)}] if {[catch {read $sock $toRead} block]} { set doneMsg $block set data(count) 0 } else { if {[info exist buffer]} { append buffer $block } set data(count) [expr {$data(count) - [string length $block]}] if {$data(count) == 0} { set doneMsg "" } } } if {[info exist doneMsg]} { Url_PostHook $sock 0 catch {fileevent $sock readable {}} Httpd_Resume $sock if {[string length $cmd]} { eval $cmd [list $sock $varName $doneMsg] } return $doneMsg } else { return "" } } # Httpd_CopyPostData -- # # Copy the POST data to a channel and make a callback when that # has completed. # # Arguments: # sock Client connection # channel Channel, e.g., to a local file or to a proxy socket. # cmd Callback to make when the post data has been read. # It is called like this: # cmd $sock $channel $bytes $errorString # Bytes is the number of bytes transferred by fcopy. # errorString is only passed if an error occurred, # otherwise it is an empty string # # Side Effects: # This uses fcopy to transfer the data from the socket to the channel. proc Httpd_CopyPostData {sock channel cmd} { upvar #0 Httpd$sock data fcopy $sock $channel -size $data(count) \ -command [concat $cmd $sock $channel] Url_PostHook $sock 0 return } # Httpd_GetPostChannel -- # # Arguments: # sock Client connection # sizeName Name of variable to get the amount of post # data expected to be read from the channel # # Results: # The socket, as long as there is POST data to read proc Httpd_GetPostChannel {sock sizeName} { upvar #0 Httpd$sock data upvar 1 $sizeName size if {$data(count) == 0} { error "no post data" } set size $data(count) return $sock } # The following are several routines that return replies # HttpdCloseP -- # See if we should close the socket # # Arguments: # sock the connection handle # # Results: # 1 if the connection should be closed now, 0 if keep-alive proc HttpdCloseP {sock} { upvar #0 Httpd$sock data if {[info exists data(mime,connection)]} { if {[string tolower $data(mime,connection)] == "keep-alive"} { Count keepalive set close 0 } else { Count connclose set close 1 } } elseif {[info exists data(mime,proxy-connection)]} { if {[string tolower $data(mime,proxy-connection)] == "keep-alive"} { Count keepalive set close 0 } else { Count connclose set close 1 } } elseif {$data(version) >= 1.1} { Count http1.1 set close 0 } else { # HTTP/1.0 Count http1.0 set close 1 } if {[expr {$data(left) == 0}]} { # Exceeded transactions per connection Count noneleft set close 1 } return $close } # Httpd_CompletionCallback -- # # Register a procedure to be called when an HTTP request is # completed, either normally or forcibly closed. This gives a # URL implementation a guaranteed callback to clean up or log # requests. # # Arguments: # sock The connection handle # cmd The callback to make. These arguments are added: # sock - the connection # errmsg - An empty string, or an error message. # # Side Effects: # Registers the callback proc Httpd_CompletionCallback {sock cmd} { upvar #0 Httpd$sock data set data(callback) $cmd } # HttpdDoCallback -- # # Invoke the completion callback. # # Arguments: # sock The connection handle # errmsg The empty string, or an error message. # # Side Effects: # Invokes the callback proc HttpdDoCallback {sock {errmsg {}}} { upvar #0 Httpd$sock data if {[info exists data(callback)]} { catch {eval $data(callback) {$sock $errmsg}} # Ensure it is only called once unset data(callback) } CountStop serviceTime $sock } # Httpd_AddHeaders # Add http headers to be used in a reply # Call this before using Httpd_ReturnFile or # Httpd_ReturnData # # Arguments: # sock handle on the connection # args a list of header value ... proc Httpd_AddHeaders {sock args} { upvar #0 Httpd$sock data lappend data(headers) {*}$args } # Httpd_RemoveHeaders # Remove previously set headers from the reply. # Any headers that match the glob pattern are removed. # # Arguments: # sock handle on the connection # pattern glob pattern to match agains cookies. proc Httpd_RemoveHeaders {sock {pattern *}} { upvar #0 Httpd$sock data if {[info exists data(headers)] && $data(headers) != {}} { set tmp {} foreach {header value} $data(headers) { if {![string match $pattern $header]} { lappend tmp $header $value } } set data(headers) $tmp } return } # Httpd_NoCache # Insert header into http header to indicate that this page # should not be cached # # Arguments: # sock handle on the connection proc Httpd_NoCache {sock} { Httpd_RemoveHeaders $sock Cache-Control Httpd_AddHeaders $sock Cache-Control no-cache Httpd_AddHeaders $sock Expires content '-1' } # Httpd_Refresh # Insert header into http header to cause browser to refresh # after a delay, optionally to a different URL # # Arguments: # sock handle on the connection # time time in seconds before refresh # url optional: url to refresh to proc Httpd_Refresh {sock time {url ""}} { Httpd_RemoveHeaders $sock Cache-Control if {$url == ""} { Httpd_AddHeaders $sock Refresh $time } else { Httpd_AddHeaders $sock Refresh ${time}\;url=${url} } } # HttpdRespondHeader -- # # Utility routine for outputting response headers for normal data Does # not output the end of header markers so additional header lines can be # added # # Arguments: # sock The connection handle # type The mime type of this response # close If true, signal connection close headers. See HttpdCloseP # size The size "in bytes" of the response # code The return code - defualts to 200 # # Side Effects: # Outputs header lines proc HttpdRespondHeader {sock type close size {code 200}} { global Httpd upvar #0 Httpd$sock data set data(code) $code append reply "HTTP/$data(version) $code [HttpdErrorString $code]" \n append reply "Date: [Httpd_Date [clock seconds]]" \n append reply "Server: $Httpd(server)\n" if {$close} { append reply "Connection: Close" \n } elseif {$data(version) == 1.0 && !$close} { append reply "Connection: Keep-Alive" \n } append reply "Content-Type: $type" \n if {[string length $size]} { append reply "Content-Length: $size" \n } if {[info exists data(headers)]} { foreach {header value} $data(headers) { catch { append reply "[string trimright $header :]: " $value \n } } } puts -nonewline $sock $reply } # HttpdErrorString -- # # Map from an error code to a meaningful string. # # Arguments: # code An HTTP error code, e.g., 200 or 404 # # Results: # An error string, e.g. "Data follows" or "File Not Found" # # Side Effects: # None proc HttpdErrorString { code } { global Httpd_Errors if {[info exist Httpd_Errors($code)]} { return $Httpd_Errors($code) } else { return "Error $code" } } # Httpd_RemoveCookies # Remove previously set cookies from the reply. # Any cookies that match the glob pattern are removed. # This is useful for expiring a cookie that was previously set. # # Arguments: # sock handle on the connection # pattern glob pattern to match agains cookies. proc Httpd_RemoveCookies {sock pattern} { upvar #0 Httpd$sock data if {[info exists data(set-cookie)] && $data(set-cookie) != {}} { set tmp {} foreach c $data(set-cookie) { if {![string match $pattern $c]} { lappend tmp $c } } set data(set-cookie) $tmp } return } # Httpd_SetCookie # Define a cookie to be used in a reply # Call this before using Httpd_ReturnFile or # Httpd_ReturnData # # Arguments: # sock handle on the connection # cookie Set-Cookie line # modify (optional) If true, overwrite any preexisting # cookie that matches. This way you can change # the expiration time. proc Httpd_SetCookie {sock cookie {modify 0}} { upvar #0 Httpd$sock data lappend data(set-cookie) $cookie } # HttpdSetCookie # Generate the Set-Cookie headers in a reply # Use Httpd_SetCookie to register cookes eariler # # Arguments: # sock handle on the connection proc HttpdSetCookie {sock} { upvar #0 Httpd$sock data if {[info exist data(set-cookie)]} { foreach item $data(set-cookie) { puts $sock "Set-Cookie: $item" } # HttpdCookieLog $sock HttpdSetCookie unset data(set-cookie) } } # Httpd_ReturnFile # Return a file. # # Arguments: # sock handle on the connection # type is a Content-Type # path is the file pathname # offset amount to skip at the start of file # # Side Effects: # Sends the file contents back as the reply. proc Httpd_ReturnFile {sock type path {offset 0}} { global Httpd upvar #0 Httpd$sock data if {[Thread_Respond $sock \ [list Httpd_ReturnFile $sock $type $path $offset]]} { return } # Set file size early so it gets into all log records set data(file_size) [file size $path] set data(code) 200 Count urlreply if {[info exists data(mime,if-modified-since)]} { # No need for complicated date comparison, if they're identical then 304. if {$data(mime,if-modified-since) == [Httpd_Date [file mtime $path]]} { Httpd_NotModified $sock return } } # Some files have a duality, when the client sees X bytes but the # file is really X + n bytes (the first n bytes reserved for server # side accounting information. incr data(file_size) -$offset if {[catch { set close [HttpdCloseP $sock] HttpdRespondHeader $sock $type $close $data(file_size) 200 HttpdSetCookie $sock puts $sock "Last-Modified: [Httpd_Date [file mtime $path]]" puts $sock "" if {$data(proto) != "HEAD"} { set in [open $path] ;# checking should already be done fconfigure $in -translation binary -blocking 1 if {$offset != 0} { seek $in $offset } fconfigure $sock -translation binary -blocking $Httpd(sockblock) set data(infile) $in Httpd_Suspend $sock 0 fcopy $in $sock -command [list HttpdCopyDone $in $sock $close] } else { Httpd_SockClose $sock $close } } err]} { HttpdCloseFinal $sock $err } } # Httpd_ReturnData # Return data for a page. # # Arguments: # sock handle on the connection # type a Content-Type # content the data to return # code the HTTP reply code. # # Side Effects: # Send the data down the socket proc Httpd_ReturnData {sock type content {code 200} {close 0}} { global Httpd upvar #0 Httpd$sock data # process any filters if {[info exists data(filter)]} { while {[llength $data(filter)]} { set cmd [lindex $data(filter) end] set data(filter) [lrange $data(filter) 0 end-1] set content [eval $cmd $sock [list $content]] } } if {[Thread_Respond $sock \ [list Httpd_ReturnData $sock $type $content $code $close]]} { return } Count urlreply if {$close == 0} { set close [HttpdCloseP $sock] } if {[catch { HttpdRespondHeader $sock $type $close [string length $content] $code HttpdSetCookie $sock puts $sock "" if {$data(proto) != "HEAD"} { fconfigure $sock -translation binary -blocking $Httpd(sockblock) puts -nonewline $sock $content } Httpd_SockClose $sock $close } err]} { HttpdCloseFinal $sock $err } } # Httpd_ReturnCacheableData # Return data with a Last-Modified time so # that proxy servers can cache it. Or they seem to, anyway. # # Arguments: # sock Client connection # type a Content-Type # content the data to return # date Modify date of the date # code the HTTP reply code. # # Side Effects: # Send the data down the socket proc Httpd_ReturnCacheableData {sock type content date {code 200}} { global Httpd upvar #0 Httpd$sock data # process any filters if {[info exists data(filter)]} { while {[llength $data(filter)]} { set cmd [lindex $data(filter) end] set data(filter) [lrange $data(filter) 0 end-1] set content [eval $cmd $sock [list $content]] } } if {[Thread_Respond $sock \ [list Httpd_ReturnCacheableData $sock $type $content $date $code]]} { return } Count urlreply set close [HttpdCloseP $sock] if {[catch { HttpdRespondHeader $sock $type $close [string length $content] $code HttpdSetCookie $sock puts $sock "Last-Modified: [Httpd_Date $date]" puts $sock "" if {$data(proto) != "HEAD"} { fconfigure $sock -translation binary -blocking $Httpd(sockblock) puts -nonewline $sock $content } Httpd_SockClose $sock $close } err]} { HttpdCloseFinal $sock $err } } # Httpd_Filter # Add a post-generation filter to the socket # # Arguments: # sock Client connection # args filter proc or specs # # Side Effects: # Adds a filter to data(filter) proc Httpd_Filter {sock args} { upvar #0 Httpd$sock data lappend data(filter) $args } # HttpdCopyDone -- this is used with fcopy when the copy completes. # # Arguments: # in Input channel, typically a file # sock Socket connection # close If true, the socket is closed after the copy. # bytes How many bytes were copied # error Optional error string. # # Results: # None # # Side Effects: # See Httpd_SockClose proc HttpdCopyDone {in sock close bytes {error {}}} { if {$error == ""} { # This special value signals a normal close, # and triggers a log record so static files are counted set error Close } Httpd_SockClose $sock $close $error } # HttpdCancel -- # # Cancel a transaction if the client doesn't complete the request fast enough. # # Arguments: # sock Socket connection # # Results: # None # # Side Effects: # Terminates the connection by returning an error page. proc HttpdCancel {sock} { upvar #0 Httpd$sock data Count cancel Httpd_Error $sock 408 } # generic error response set Httpd_ErrorFormat { <title>Httpd_Error: %1$s</title> Got the error <b>%2$s</b><br> while trying to obtain <b>%3$s</b>. } # Httpd_Error -- # # send the error message, log it, and close the socket. # Note that the Doc module tries to present a more palatable # error display page, but falls back to this if necessary. # # Arguments: # sock Socket connection # code HTTP error code, e.g., 500 # detail Optional string to append to standard error message. # # Results: # None # # Side Effects: # Generates a HTTP response. proc Httpd_Error {sock code {detail ""}} { if {[Thread_Respond $sock [list Httpd_Error $sock $code $detail]]} { # We've passed the error back to the main thread return } upvar #0 Httpd$sock data global Httpd Httpd_ErrorFormat Count errors append data(url) "" set message [format $Httpd_ErrorFormat $code [HttpdErrorString $code] $data(url)] append message <br>$detail if {$code == 500} { append message "<h2>Tcl Call Trace</h2>" for {set l [expr [info level]-1]} {$l > 0} {incr l -1} { append message "$l: [protect_text [info level $l]]<br>" } } Log $sock Error $code $data(url) $detail # We know something is bad here, so we make the completion callback # and then unregister it so we don't get an extra call as a side # effect of trying to reply. HttpdDoCallback $sock $message if {[info exists data(infile)]} { # We've already started a reply, so just bail out Httpd_SockClose $sock 1 return } if {[catch { HttpdRespondHeader $sock text/html 1 [expr {[string length $message] + 4}] $code puts $sock "" puts $sock $message } err]} { Log $sock LostSocket $data(url) $err } Httpd_SockClose $sock 1 } set HttpdRedirectFormat { <html><head> <title>Found</title> </head><body> This document has moved to a new <a href="%s">location</a>. Please update your documents and hotlists accordingly. </body></html> } # Httpd_Redirect -- # # Generate a redirect reply (code 302) # # Arguments: # newurl New URL to redirect to. # sock Socket connection # # Results: # None # # Side Effects: # Generates an HTTP reply proc Httpd_Redirect {newurl sock} { upvar #0 Httpd$sock data global Httpd HttpdRedirectFormat if {[Thread_Respond $sock \ [list Httpd_Redirect $newurl $sock]]} { return } set message [format $HttpdRedirectFormat $newurl] set close [HttpdCloseP $sock] HttpdRespondHeader $sock text/html $close [string length $message] 302 HttpdSetCookie $sock puts $sock "Location: $newurl" puts $sock "URI: $newurl" puts $sock "" # The -nonewline is important here to work properly with # keep-alive connections puts -nonewline $sock $message Httpd_SockClose $sock $close } # Httpd_NotModified -- # # Generate a Not Modified reply (code 304) # # Arguments: # sock Socket connection # # Results: # None # # Side Effects: # Generates an HTTP reply proc Httpd_NotModified {sock} { upvar #0 Httpd$sock data if {[Thread_Respond $sock \ [list Httpd_NotModified $sock]]} { return } HttpdRespondHeader $sock text/html 0 0 304 HttpdSetCookie $sock puts $sock "" Httpd_SockClose $sock 0 } # Httpd_RedirectSelf -- # # Generate a redirect to another URL on this server. # # Arguments: # newurl Server-relative URL to redirect to. # sock Socket connection # # Results: # None # # Side Effects: # Generates an HTTP reply. proc Httpd_RedirectSelf {newurl sock} { Httpd_Redirect [Httpd_SelfUrl $newurl $sock] $sock } # Httpd_SelfUrl -- # # Create an absolute URL for this server # # Arguments: # url A server-relative URL on this server. # sock The current connection so we can tell if it # is the regular port or the secure port. # # Results: # An absolute URL. # # Side Effects: # None proc Httpd_SelfUrl {url {sock ""}} { global Httpd if {$sock == ""} { set sock $Httpd(currentSocket) } upvar #0 Httpd$sock data set type [Httpd_Protocol $sock] set port [Httpd_Port $sock] if {[info exists data(mime,host)]} { # Use in preference to our "true" name because # the client might not have a DNS entry for use. set name $data(mime,host) } else { set name [Httpd_Name $sock] } set newurl $type://$name if {[string first : $name] == -1} { # Add in the port number, which may or may not be present in # the name already. IE5 sticks the port into the Host: header, # while Tcl's own http package does not... if {$type == "http" && $port != 80} { append newurl :$port } if {$type == "https" && $port != 443} { append newurl :$port } } append newurl $url } # Httpd_Protocol -- # # Return the protocol for the connection # # Arguments: # sock Socket connection # # Results: # Either "http" or "https" # # Side Effects: # None proc Httpd_Protocol {sock} { upvar #0 Httpd$sock data return [lindex $data(self) 0] } # Httpd_Name -- # # Return the server name for the connection # # Arguments: # sock Socket connection # # Results: # The name of the server, e.g., www.tcltk.org # # Side Effects: # None proc Httpd_Name {sock} { upvar #0 Httpd$sock data return [lindex $data(self) 1] } # Httpd_Port -- # # Return the port for the connection # # Arguments: # sock The current connection. If empty, then the # regular (non-secure) port is returned. Otherwise # the port of this connection is returned. # # Results: # The server's port. # # Side Effects: # None proc Httpd_Port {{sock {}}} { if {[string length $sock]} { # Return the port for this connection upvar #0 Httpd$sock data return [lindex $data(self) 2] } else { # Return the non-secure listening port global Httpd if {[info exist Httpd(port)]} { return $Httpd(port) } else { return {} } } } # Httpd_SecurePort -- # # Return the secure port of this server # # Arguments: # # Results: # The server's secure port. # # Side Effects: # None proc Httpd_SecurePort {} { # Return the secure listening port global Httpd if {[info exist Httpd(https_port)]} { return $Httpd(https_port) } else { return {} } } set HttpdAuthorizationFormat { <HTML><HEAD> <TITLE>401 Authorization Required</TITLE> </HEAD><BODY> <H1>Authorization Required</H1> This server could not verify that you are authorized to access the document you requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.<P> </BODY></HTML> } # Httpd_RequestAuth -- # # Generate the (401) Authorization required reply # # Arguments: # sock Socket connection # type usually "Basic" # realm browsers use this to cache credentials # args additional name value pairs for request # # Results: # None # # Side Effects: # Generate an authorization challenge response. proc Httpd_RequestAuth {sock type realm args} { upvar #0 Httpd$sock data global Httpd HttpdAuthorizationFormat if {[Thread_Respond $sock \ [list Httpd_RequestAuth $sock $type $realm]]} { return } set additional "" foreach {name value} $args { append additional ", " ${name}=$value } set close [HttpdCloseP $sock] HttpdRespondHeader $sock text/html $close [string length $HttpdAuthorizationFormat] 401 puts $sock "Www-Authenticate: $type realm=\"$realm\" $additional" puts $sock "" puts -nonewline $sock $HttpdAuthorizationFormat Httpd_SockClose $sock $close } # Httpd_Date -- # # generate a date string in HTTP format # # Arguments: # seconds Clock seconds value # # Results: # A date string. # # Side Effects: # None proc Httpd_Date {seconds} { return [clock format $seconds -format {%a, %d %b %Y %T GMT} -gmt true] } # Httpd_SockClose -- # "Close" a connection, although the socket might actually # remain open for a keep-alive connection. # This means the HTTP transaction is fully complete. # # Arguments: # sock Identifies the client connection # closeit 1 if the socket should close no matter what # message Logging message. If this is "Close", which is the default, # then an entry is made to the standard log. Otherwise # an entry is made to the debug log. # # Side Effects: # Cleans up all state associated with the connection, including # after events for timeouts, the data array, and fileevents. proc Httpd_SockClose {sock closeit {message Close}} { global Httpd upvar #0 Httpd$sock data if {[string length $message]} { Log $sock $message if {$message == "Close"} { # This is a normal close. Any other message # is some sort of error. set message "" } } # Call back to the URL domain implementation so they are # sure to see the end of all their HTTP transactions. # There is a slight chance of an error reading any un-read # Post data, but if the URL domain didn't want to read it, # then they obviously don't care. HttpdDoCallback $sock $message Count connections -1 if {[info exist data(infile)]} { # Close file or CGI pipe. Still need catch because of CGI pipe. catch {close $data(infile)} } if {$closeit} { if {[info exists data(count)] && $data(count) > 0} { # There is unread POST data. To ensure that the client # can read our reply properly, we must read this data. # The empty variable name causes us to discard the POST data. if {[info exists data(cancel)]} { after cancel $data(cancel) } set data(cancel) [after $Httpd(timeout3) \ [list HttpdCloseFinal $sock "timeout reading extra POST data"]] Httpd_GetPostDataAsync $sock "" $data(count) HttpdReadPostDone } else { HttpdCloseFinal $sock } } else { HttpdReset $sock } } # HttpdReadPostDone -- # # Callback is made to this when we are done cleaning up any # unread post data. # # Arguments: # sock Socket connection # varname Name of variable with post data # errmsg If not empty, an error occurred on the socket. # # Results: # None # # Side Effects: # None here, but see HttpdCloseFinal. proc HttpdReadPostDone {sock var errmsg} { HttpdCloseFinal $sock $errmsg } # HttpdCloseFinal -- # # Central close procedure. All close operations should funnel # through here so that the right cleanup occurs. # # Arguments: # sock Socket connection # errmsg If non-empty, then something went wrong on the socket. # # Results: # None # # Side Effects: # Cleans up any after event associated with the connection. # Closes the socket. # Makes the callback to the URL domain implementation. proc HttpdCloseFinal {sock {errmsg {}}} { upvar #0 Httpd$sock data Count sockets -1 if {[info exists data(cancel)]} { after cancel $data(cancel) } if {[catch {close $sock} err]} { Log $sock CloseError $err if {[string length $errmsg] == 0} { set errmsg $err } } HttpdDoCallback $sock $errmsg if {[info exist data]} { unset data } } # Httpd_RequestComplete -- # # Detect if a request has been sent. The holder of a socket # might need to know of the URL request was completed with # one of the return-data commands, or is still lingering open. # # Arguments: # sock Socket connection # # Results: # 1 if the request was completed, 0 otherwise. # # Side Effects: # None. proc Httpd_RequestComplete {sock} { upvar #0 Httpd$sock data if {![info exist data(state)] || $data(state) == "start"} { # The connection was closed or reset in a keep-alive situation. return 1 } else { return 0 } } # server specific version of bgerror - indent to hide from indexer proc bgerror {msg} { global errorInfo set msg "[clock format [clock seconds]]\n$errorInfo" if {[catch {Log nosock bgerror $msg}]} { Stderr $msg } } # HttpdCookieLog -- # # Special loggin procedure to debug cookie implementation. # # Arguments: # sock Socket connection # what What procedure is doing the logging. # # Results: # None # # Side Effects: # Writes to the debug log. proc HttpdCookieLog {sock what} { global Log Httpd upvar #0 Httpd$sock data if {[info exist Log(log)] && ![info exist Httpd(cookie_log)]} { set Httpd(cookie_log) [open $Log(log)cookie a] } if {[info exist Httpd(cookie_log)]} { append result [LogValue data(ipaddr)] append result { } \[[clock format [clock seconds] -format %d/%h/%Y:%T] -0700\] append result { } $what switch $what { Httpd_Dispatch { if {![info exist data(mime,cookie)]} { return } append result { } \"$data(mime,cookie)\" } Httpd_SetCookie - HttpdSetCookie { append result { } \"[LogValue data(set-cookie)]\" } } catch { puts $Httpd(cookie_log) $result ; flush $Httpd(cookie_log)} } } # Httpd_Suspend -- # # Suspend Wire Callback - for async transactions # Use Httpd_Resume once you are back in business # Note: global page array is not preserved over suspend # # Arguments: # sock Socket connection # timeout Timeout period. After this the request is aborted. # # Results: # None # # Side Effects: # Disables fileevents and sets up a timer. proc Httpd_Suspend {sock {timeout ""}} { global Httpd upvar #0 Httpd$sock data fileevent $sock readable {} fileevent $sock writable {} if {[info exists data(cancel)]} { after cancel $data(cancel) unset data(cancel) } if {[info exists Httpd(currentSocket)]} { unset Httpd(currentSocket) } if {$timeout == ""} { set timeout $Httpd(timeout2) } if {$timeout != 0} { set data(cancel) [after $timeout [list HttpdCancel $sock]] } } # Httpd_Resume -- # # Resume processing of a request. Sets up a bit of global state that # has been cleared by Httpd_Suspend. # # Arguments: # sock Socket connection # timeout Timeout period. After this the request is aborted. # # Results: # None # # Side Effects: # Restores the Httpd(currentSocket) setting. proc Httpd_Resume {sock {timeout ""}} { upvar #0 Httpd$sock data global Httpd set Httpd(currentSocket) $sock if {[info exists data(cancel)]} { after cancel $data(cancel) } if {$timeout == ""} { set timeout $Httpd(timeout1) } set data(cancel) [after $timeout \ [list Httpd_SockClose $sock 1 "timeout"]] } # Httpd_CurrentSocket -- # # Return (or set) the handle to the current socket. # # Arguments: # sock Optional - if specified, set the current socket. # # Results: # A socket. # # Side Effects: # None. proc Httpd_CurrentSocket {{sock {}}} { global Httpd if {[string length $sock]} { set Httpd(currentSocket) $sock } return $Httpd(currentSocket) } # Httpd_Pair -- # # # Pair two fd's - typically for tunnelling # Close both if either one closes (or gets an error) # # # Arguments: # sock Socket connection # fd Any other I/O connection # # Results: # None # # Side Effects: # Sets up fileevents for proxy'ing data. proc Httpd_Pair {sock fd} { global Httpd upvar #0 Httpd$sock data syslog debug "HTTP: Pairing $sock and $fd" Httpd_Suspend $sock 0 fconfigure $sock -translation binary -blocking 0 fconfigure $fd -translation binary -blocking 0 fileevent $sock readable [list HttpdReflect $sock $fd] fileevent $fd readable [list HttpdReflect $fd $sock] } # HttpdReflect -- # # This is logically fcopy in both directions, but the core # prevents us from doing that so we do it by hand. # # Arguments: # in Input channel # out Output channel # # Results: # None # # Side Effects: # Copy data between channels. proc HttpdReflect {in out} { global Httpd if {[catch { set buf [read $in $Httpd(bufsize)] puts -nonewline $out $buf flush $out set buflen [string length $buf] if {$buflen > 0} { syslog debug "Tunnel: $in -> $out ($buflen bytes)" } } oops]} { Log $in Tunnel "Error: $oops" } elseif {![eof $in]} { return 1 } else { syslog debug "Tunnel: $in EOF" } fileevent $in readable {} fileevent $out readable {} catch {flush $in} catch {flush $out} catch {close $in} catch {close $out} return 0 } # Httpd_DumpHeaders -- # # Dump out the protocol headers so they can be saved for later. # # Arguments: # sock Client connection # # Results: # A list structure that alternates between names and values. # The names are header names without the trailing colon and # mapped to lower case (e.g., content-type). Two pseudo-headers # added: One that contains the original request URL; its name is "url" # Another that contains the request protocol; its name is "method" # There are no duplications in the header keys. If any headers # were repeated, their values were combined by separating them # with commas. proc Httpd_DumpHeaders {sock} { upvar #0 Httpd$sock data set result [list url $data(uri) method $data(proto) version $data(version)] if {[info exist data(mimeorder)]} { foreach key $data(mimeorder) { lappend result $key $data(mime,$key) } } return $result } # Httpd_Webmaster -- # # Define an email address for the webmaster # # Arguments: # email The email of the webmaster. If empty, the # current value is returned, which is handy in # web pages. # # Results: # Returns the webmaster email. # # Side Effects: # Sets the webmaster email. proc Httpd_Webmaster {{email {}}} { global Httpd if {[string length $email] == 0} { if {![info exists Httpd(webmaster)]} { set Httpd(webmaster) webmaster } return $Httpd(webmaster) } else { set Httpd(webmaster) $email } } |
Added modules/httpd/imagemap.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | # imagemap.tcl # based on imagemap.c, version 1.8 # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: imagemap.tcl,v 1.7 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::imagemap 1.0 package require httpd ;# Httpd_Redirect Httpd_ReturnData package require httpd::counter ;# Count package require httpd::utils ;# file parray # Doc_application/x-imagemap -- # # this is called by DocHandle to process .map files # # Arguments: # path The file name of the .map file. # suffix The URL suffix # sock The socket connection. # # Results: # None # # Side Effects: # Redirect to the URL indicated by the map. proc Doc_application/x-imagemap {path suffix sock} { upvar #0 Httpd$sock data if {![info exists data(query)]} { Httpd_ReturnData $sock text/plain "[parray Httpd$sock]" return } set url [Map_Lookup $path?$data(query)] Count maphits Httpd_Redirect $url $sock } proc MapPointInRect {X Y coordArray} { upvar $coordArray coords return [expr ($X >= $coords(0,X) && $X <= $coords(1,X)) && \ ($Y >= $coords(0,Y) && $Y <= $coords(1,Y))] } proc MapPointInCircle {X Y coordArray} { upvar $coordArray coords set radius1 [expr (($coords(0,Y) - $coords(1,Y)) * ($coords(0,Y) - \ $coords(1,Y))) + (($coords(0,X) - $coords(1,X)) * ($coords(0,X) - \ $coords(1,X)))] set radius2 [expr (($coords(0,Y) - $Y) * ($coords(0,Y) - $Y)) + \ (($coords(0,X) - $X) * ($coords(0,X) - $X))] return [expr $radius2 <= $radius1] } proc MapPointInPoly {tx ty pgonArray} { upvar $pgonArray pgon global MAXVERTS set numverts [expr [llength [array names pgon]] / 2] set lastvert [expr $numverts - 1] set crossings 0 set y pgon($lastvert,Y) set p pgon(0,Y) if {($y >= $ty) != ($p >= $ty)} { set xflag0 [expr $pgon($lastvert,X) >= $tx] if {$xflag0 == ($pgon(0,X) >= $tx)} { if $xflag0 { incr crossings } } else { incr crossings [expr {$pgon($lastvert,X) - ($y - $ty) * ($pgon(0,X) - $pgon($lastvert,X)) / ($p - $y) >= $tx}] } } for {set i 0} {$i < $numverts} {incr i} { set y $pgon($i,Y) if {$y >= $ty} { while {$i < $numverts && $pgon($i,Y) >= $ty} { incr i } } else { while {$i < $numverts && $pgon($i,Y) < $ty} { incr i } } if {$i >= $numverts} { break } set lasti [expr $i-1] set xflag0 [expr $pgon($lasti,X) >= $tx] if {$xflag0 == ($pgon($i,X) >= $tx)} { if $xflag0 { incr crossings } } else { incr crossings \ [expr ($pgon($lasti,X) - \ ($pgon($lasti,Y) - $ty) * \ ($pgon($i,X) - $pgon($lasti,X)) / \ ($pgon($i,Y) - $pgon($lasti,Y))) >= $tx] } } set inside_flag [expr $crossings & 0x01] return $inside_flag } proc MapTest {} { array set pgon { 0,X 0.0 0,Y 0.0 1,X 100.0 1,Y 0.0 2,X 100.0 2,Y 100.0 3,X 0.0 3,Y 100.0 } foreach {X Y} {50. 50. 1. 1. 0. 0. 200. 200.} { puts "($X,$Y) In Poly [pointinpoly $X $Y pgon]" } } |
Added modules/httpd/include.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | # include.tcl # # Stephen Uhler (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: include.tcl,v 1.7 2004/10/22 03:43:06 coldstore Exp $ # Process server side includes. # Look for comments of the form: # <!--#keyword args --> # Where "keyword" is one of: # ECHO FLASTMOD FSIZE INCLUDE EXEC # We do not implement # CONFIG # The input string is passed on the command line to Httpd_include, # and the result is returned. # Note: the included file is treated as text, which possibly has # other include files in it. We are not doing a full URL dispatch # on the included files, so they cannot be cgi scripts or other fancy # objects. package require html package provide httpd::include 1.0 package require httpd ;# Httpd_Error Httpd_ReturnData package require httpd::cgi ;# Cgi_SetEnv package require httpd::counter ;# Count package require httpd::doc ;# Doc_Virtual package require httpd::utils ;# file iscommand # Global state for this module # maxdepth controls recursively included files. array set Include { maxdepth 10 } # Process a file with server includes proc Doc_application/x-server-include {path suffix sock} { Count includes if {[catch {open $path} in]} { Httpd_Error $sock 404 $in } else { global env Cgi_SetEnv $sock $path set html [Include_Html $sock $path [read $in]] close $in Httpd_ReturnData $sock text/html $html } } # Process all the server includes. # sock: a token passed through to the include procedures # path: required to handle relative paths in recursive includes # html: The html to process # depth: A counter to detect include loops proc Include_Html {sock path html {depth 0}} { set token \x87 ;# this character never appears in an html stream regsub -all {([][$\\])} $html {\\\1} html ;# protect TCL special characters regsub -all -- --> $html $token html ;# convert end of comment to token regsub -all "<!--# *(\[^ ]+) *(\[^$token]+)$token" $html \ "\[IncludeInner $sock {$path} {\\1} {\\2} [incr depth]\]" html ;# find all includes regsub -all $token $html --> html ;# recover end of comment tokens return [subst $html] ;# process the includes } proc IncludeInner {sock path command params depth} { set command [string tolower $command] if {![iscommand include_$command]} { return "<!-- Server not configured to processes \"$command\" includes -->\n" } elseif {[catch {include_$command $sock $path $params $depth} result]} { return "<!-- Server error in include command $command: $result -->\n" } else { return $result } } # utility to extract the file name specified from the include parameters proc IncludeFile {sock op path params} { if {[html::extractParam $params virtual orig]} { set key virtual set npath [Doc_Virtual $sock $path $orig] } elseif {[html::extractParam $params file orig]} { set key file set npath [file join [file dirname $path] $orig] } else { error "<!-- Invalid $op parameter list: $params. -->\n" } return [list $key $npath $orig] } # Each server function has its own procedure, that returns the substituted value ############################################################################### # include another file # Params: # virtual=path # file=path proc include_include {sock path params depth} { global Include if {$depth > $Include(maxdepth)} { return "<!-- Include recursion depth exceeded ($depth) -->\n" } if {[catch {IncludeFile $sock include $path $params} info]} { return $info } set key [lindex $info 0] set npath [lindex $info 1] set orig [lindex $info 2] # now open the file and re-do substitutions. if {[catch {open $npath r} fd]} { return "<!-- invalid include $key path $orig: $fd -->\n" } set data [Include_Html $sock $npath [read $fd] $depth] close $fd return $data } proc include_echo {sock path params args} { global env set var "" if {[html::extractParam $params var]} { if {[info exists env($var)]} { return $env($var) } else { return "<!-- No such variable: $var. -->\n" } } return "<!-- Echo: No var parameter. -->\n" } proc include_fsize {sock path params args} { if {[catch {IncludeFile $sock fsize $path $params} info]} { return $info } set key [lindex $info 0] set npath [lindex $info 1] set orig [lindex $info 2] if {[file exists $npath]} { return [file size $npath] } else { return "<!-- File not found $key: $npath. -->\n" } } proc include_exec {sock path params args} { set cmd "" if {[html::extractParam $params cmd]} { if {[catch {eval exec $cmd} result]} { regsub -all -- --> $result {} result return "<!-- $cmd error: $result -->\n" } else { return $result } } } proc include_config {sock path params args} { return "<!-- include config not implemented -->\n" } proc include_flastmod {sock path params args} { if {[catch {IncludeFile $sock flastmod $path $params} info]} { return $info } set key [lindex $info 0] set npath [lindex $info 1] set orig [lindex $info 2] if {[file exists $npath]} { return [clock format [file mtime $npath]] } else { return "<!-- File not found $key: $npath. -->\n" } } |
Added modules/httpd/log.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | # log.tcl # # This is a file-based logging module for TclHttpd. # # This starts a new log file each day with Log_SetFile # It also maintains an error log file that is always appeneded to # so it grows over time even when you restart the server. # # Stephen Uhler / Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: log.tcl,v 1.14 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::log 1.1 package require httpd::config ;# Config package require httpd::counter ;# Count Counter_CheckPoint package require httpd::logstd ;# LogStandardData package require httpd::utils ;# Stderr file # log an Httpd transaction # This program is used to compress log files if {![info exists Log(compressProg)]} { set Log(compressProg) gzip } # Flush interval if {![info exists Log(flushInterval)]} { set Log(flushInterval) [expr {60 * 1000}] } # This is used to turn on an alternate debug log file if {![info exist Log(debug_log)]} { set Log(debug_log) 0 } # Log -- # # Log information about the activity of TclHttpd. There are two kinds of # log entries. One "normal" entry that goes into its own log, one line # for each HTTP transaction. All other log records are appended to an # error log file. # # Arguments: # sock The client connection. # reason If "Close", then this is the normal completion of a request. # Otherwise, this is some error tag and the record goes to # the error log. # args Additional information to put into the logs. # # Results: # None # # Side Effects: # Writes data to the log files. proc Log {sock reason args} { global Log upvar #0 Httpd$sock data # Log normal closes to the regular log. # Log everything else to the error log. switch -- $reason { "Close" { set now [clock seconds] set result [LogStandardData $sock $now] if {[catch {puts $Log(log_fd) $result} err]} { set urk ! } if {$Log(flushInterval) == 0} { catch {flush $Log(log_fd)} } } "Debug" { set now [clock seconds] append result { } \[[clock format $now -format %d/%h/%Y:%T]\] append result { } $sock { } $reason { } $args if {[info exists data(url)]} { append result { } $data(url) } catch { puts $Log(debug_fd) $result ; flush $Log(debug_fd) } } default { set now [clock seconds] append result { } \[[clock format $now -format %d/%h/%Y:%T]\] append result { } $sock { } $reason { } $args if {[info exists data(url)]} { append result { } $data(url) } catch { puts $Log(error_fd) $result ; flush $Log(error_fd) } } } } # Log_Configure -- # # Query/modify configuration settings for logging. # # Arguments: # args option/value pairs # # Results: # Configuration value(s) or empty string proc Log_Configure args { global Log switch [llength $args] { 0 { foreach {key value} [array get Log] { lappend result [list -$key $value] } return $result } 1 { return $Log(-[lindex $args 0]) } default { if {[llength $args] % 2} { error "no value specified for option \"[lindex $args end]\"" } else { foreach {option value} $args { switch -- $option { -lognames { lappend newOptions lognames [boolean $value] } default { # TODO: Other logging options, such as filenames, flush interval, etc error "unknown option \"$option\"" } } } array set Log $newOptions } } } return {} } # Log_FlushMinutes -- # # Set the interval at which the logs are flushed. # # Arguments: # min The minutes between flushes. If 0, # then the log is flushed on each write. # # Results: # None # # Side Effects: # None proc Log_FlushMinutes {min} { global Log set Log(flushInterval) [expr int($min*60*1000)] if {[info exist Log(flushID)]} { Log_Flush } } # Log_CompressProg -- # # Set log compression program # # Arguments: # prog the program used to compress logs # # Results: # None # # Side Effects: # None proc Log_CompressProg {prog} { global Log set Log(compressProg) $prog } # Log_SetFile -- # automatically change log files every midnight # # Arguments: # basename The name of a base filename # including its directory, # e.g. /logs/www # This will create files like: # /logs/www80_00.09.23 # # Results: # None # # Side Effects: # Closes and opens files, creating new files # each time through. proc Log_SetFile {{basename {}}} { global Log if {[string length $basename]} { set Log(log) $basename } if {![info exists Log(log)]} { catch {close $Log(log_fd)} catch {close $Log(error_fd)} catch {close $Log(debug_fd)} return } catch {Counter_CheckPoint} ;# Save counter data # set after event to switch files after midnight set now [clock seconds] set next [expr {([clock scan 23:59:59 -base $now] -$now + 1000) * 1000}] after cancel Log_SetFile after $next Log_SetFile # set the log file and error file. # Log files rotate, error files don't if {[info exists Log(log_file)] && [file exists $Log(log_file)]} { set lastlog $Log(log_file) } set Log(log_file) $Log(log)[clock format $now -format %y.%m.%d] catch {close $Log(log_fd)} # Create log directory, if neccesary, then open the log file catch {file mkdir [file dirname $Log(log_file)]} if {[catch {set Log(log_fd) [open $Log(log_file) a]} err]} { Stderr $err } if {[info exists lastlog]} { # compress log files as we go if {[file executable $Log(compressProg)] && [catch {exec $Log(compressProg) $lastlog &} err]} { Stderr $err } } catch {close $Log(error_fd)} if {[catch {set Log(error_fd) [open $Log(log)error a]} err]} { Stderr $err } # This debug log gets reset daily catch {close $Log(debug_fd)} if {[info exists Log(debug_file)] && [file exists $Log(debug_file)]} { catch {file rename -force $Log(debug_file) $Log(debug_file).old} } if {[info exist Log(debug_log)] && $Log(debug_log)} { set Log(debug_file) $Log(log)debug if {[catch {set Log(debug_fd) [open $Log(debug_file) w]} err]} { Stderr $err } } } # Log_Flush -- # flush the output to the log file. Do this periodically, rather than # for every transaction, for better performance # # Arguments: # # Results: # None # # Side Effects: # Flushes the logs to disk. proc Log_Flush {} { global Log catch {flush $Log(log_fd)} catch {flush $Log(error_fd)} catch {after cancel $Log(flushID)} if {$Log(flushInterval) > 0} { set Log(flushID) [after $Log(flushInterval) Log_Flush] } } |
Added modules/httpd/logstd.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | # logstd.tcl # # Standard Web Log file format support. # # Stephen Uhler / Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: logstd.tcl,v 1.5 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::logstd 1.0 package require httpd ;# Httpd_Peername package require httpd::log ;# Log package require httpd::utils ;# file # Use IP address, or domain name? # Default is IP address, because looking up names is expensive if {![info exists Log(lognames)]} { set Log(lognames) 0 } # If true, we append cookie values to the log if {![info exists Log(cookie)]} { set Log(cookie) 0 } # LogStandardData -- # # Generate a standard web log file record for the current connection. # This records the client address, the URL, the time, the error # code, and so forth. # # Arguments: # sock The client connection. # now The timestamp for the connection, in seconds # # Results: # A string containing the log fie record. # # Side Effects: # None proc LogStandardData {sock now} { return [LogStandardPrint [LogStandardList $sock $now]] } # LogStandardPrint -- # # Generate a standard web log file record for the current connection. # This records the client address, the URL, the time, the error # code, and so forth. # # Arguments: # sock The client connection. # now The timestamp for the connection, in seconds # # Results: # A string containing the log fie record. # # Side Effects: # None proc LogStandardPrint {data} { set sep "" set result "" foreach {n v} $data { if {$v == "" || $v == "-"} { append result ${sep}- continue } switch -- $n { time { append result $sep\[[clock format $v -format "%d/%h/%Y:%T %Z"]\] } http - referer - useragent - cookie { append result $sep"$v" } default { append result $sep$v } } set sep " " } return $result } # LogStandardList -- # # Like LogStandardData, but return the data in a name, value list # suitable for use in foreach loops, array get, or long term # storage. # # Arguments: # sock The client connection # now The timestamp for the connection, in seconds # # Results: # A name, value list of the fields in a standard web log entry. # # Side Effects: # None proc LogStandardList {sock now} { global Log upvar #0 Httpd$sock data if {$Log(lognames)} { if {[catch {lappend result ipaddr [Httpd_Peername $sock]}]} { lappend result ipaddr [LogValue data(ipaddr)] } } else { lappend result ipaddr [LogValue data(ipaddr)] } lappend result authuser [LogValue data(mime,auth-user)] lappend result username [LogValue data(mime,username)] lappend result time $now lappend result http [LogValue data(line)] lappend result status [LogValue data(code)] lappend result filesize [LogValue data(file_size)] lappend result referer [LogValue data(mime,referer)] lappend result useragent [LogValue data(mime,user-agent)] if {$Log(cookie)} { # This field is not always present in logs lappend result cookie [LogValue data(mime,cookie)] } return $result } # LogValue -- # # Generate a field or the default "null field" representation. # # Arguments: # var The variable whose value to use, if any # # Results: # The value of the variable, or - as the default. # # Side Effects: # None proc LogValue {var} { upvar $var data if {[info exists data]} { return $data } else { return - } } |
Added modules/httpd/mail.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | # mail.tcl # mail support using tcllib's smtp and mime packages # # The /mail URL is registered as a direct url that maps to procedures # in this file that begin with Mail. # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: mail.tcl,v 1.16 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::mail 1.0 package require httpd ;# Httpd_Webmaster package require httpd::config ;# Config package require httpd::direct ;# Direct_Url package require httpd::utils ;# file protect_text # No useful default, but we define procedures so the vanilla server # can start up. # Config(mail) seems to be an old usage # MailServer is defined in tclhttpd.rc if {[info exists Config(mail)] && ($Config(mail) != {})} { set Mail(server) $Config(mail) } elseif {[config::cget MailServer] ne ""} { set Mail(server) [config::cget MailServer] } package require smtp package require mime # Mail_Send # Send email to recipients using tcllib's smtp client. # # Arguments: # recipients list of email addresses to which to send the mail # subject subject line for email # from email address of email sender # type mime type of body ("text/plain" for normal email) # body the body of the email # # Results: # return the tcllib smtp client's return, {} if successful else: # A list indicating which recipients were unacceptable to the SMTP server. # Each element of the list is another list, containing the address, # an SMTP error code, and a textual diagnostic. # # Side Effects: # Email is sent to each of the recipients proc Mail_Send {recipients subject from type body} { global Mail set token [mime::initialize -canonical $type -string $body] mime::setheader $token Subject $subject set result [smtp::sendmessage $token \ -recipients $recipients \ -originator $from \ -servers $Mail(server)] mime::finalize $token return $result } # Mail_Result # convert tcllib smtp server result to a table suitable for display proc Mail_Result {mail_err} { set html "" if {$result != {}} { set html <table> foreach el $result { append html <tr> foreach {addr errcode diagnostic} $el { append html <th> [protect_text $addr] </th> append html <td> [protect_text $errcode] </td> append html <td> [protect_text $diagnostic] </td> } append html </tr> } append html </table> } return $html } proc MailSend {recipients subject from type body} { set result [Mail_Send $recipients $subject $from $type $body] if {$result == ""} { set html "<b>Thank You!</b><br>Mailed report to <b>[protect_text $recipients]</b>" } else { return [Mail_Result $result] } } proc Mail_Url {dir} { Direct_Url $dir Mail } proc Mail/bugreport {email errorInfo args} { global Httpd set html "<pre>" foreach {name value} $args { if {([string compare $name "env"] == 0) && ([catch {array set X $value}] == 0)} { # add this later continue } else { append html "$name: $value\n" } } append html $Httpd(server)\n append html [protect_text $errorInfo] if {[info exist X]} { append html "\n\nEnvironment:\n" foreach n [lsort [array names X]] { append html " $n: $X($n)\n" } } append html "</pre>" if {$email == ""} { set email [Httpd_Webmaster] } MailSend $email "$Httpd(name):$Httpd(port) error" "" text/html $html } # If your form action is /mail/forminfo, then this procedure # sends the results to the address specified by "sendto" proc Mail/forminfo {sendto subject href label args} { set from "" foreach {name value} $args { # If the value has unbalanced braces, we will do base64 # encoding to avoid a huge jumble of backslashes and # a long line that will not survive the email transport set blob [list $value] if {[regsub -all \\\\ $blob {} _] > 0} { append message "[list Data64 $name] \\\n" append message [list [base64::encode $value]]\n } else { append message [list Data $name $value]\n } if {[string compare $name "email"] == 0} { set from $value } } set html [MailSend $sendto $subject $from text/plain $message] if {[string length $href]} { if {[string length $label] == 0} { set label Back } append html "<p><a href=\"$href\">$label</a>" } return $html } # This form is designed to be embedded into a page # that handles form data. proc Mail_FormInfo {} { global page set html {<!-- Mail_FormInfo -->} if {[info exist page(query)]} { array set q $page(query) if {[info exist q(sendto)] && [info exist q(subject)]} { eval {Mail/forminfo $q(sendto) $q(subject) {} {}} $page(query) set html {<!-- Mail_FormInfo sent email -->} } } return $html } # Older version of mail/forminfo proc Mail/formdata {email subject args} { foreach {name value} $args { append message "$name: $value\n" } MailSend $email $subject {} text/plain $message } |
Added modules/httpd/maptcl.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | # maptcl.tcl # Pure Tcl imagemap handling. # # read in an image map file, and generate the appropriate canvas # # sample image map # circle /sun-on-net/internet.sol/access.html 664,311 686,311 # default http://www.hal.com/ # default /sunsoft/index.html # point /sunworldonline/common/swol-subscribe.html 45,134 # poly / 182,11 184,88 301,77 365,86 393,57 393,10 # rect /sunsoft/index.html 1,1 119,34 # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: maptcl.tcl,v 1.7 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::ismaptcl 1.0 package require httpd::imagemap 1.0 ;# MapPointInCircle MapPointInPoly MapPointInRect package require httpd::log ;# Log #package require httpd::utils ;# file # translate an x/y coordinate into a url proc Map_Lookup {request} { global ImageMaps if {[regexp {([^?]+)\?([0-9]+),([0-9]+)} $request {} map x y]} { if {[catch {file mtime $map} mtime]} { return "" } if {![info exists ImageMaps($map)] || ($mtime > $ImageMaps(mtime,$map))} { set ImageMaps($map) [MapRead $map] set ImageMaps(mtime,$map) $mtime } return [MapHit $ImageMaps($map) $x $y] } else { return "" } } # MapRead - this parses a map data file and converts it to # a Tcl array that contains state about each region. # This parser is another famous regsub-subst combo by Steve Uhler proc MapRead {file} { if {[catch {open $file} fd]} { Log "" "file open" $fd return {} } regsub -all {\.} $file _ cookie set data [read $fd] close $fd regsub -all "(^|\n+)#\[^\n]*" $data {} data regsub -all {([][$\\])} $data {\\\1} data set types circle|default|point|poly|rect append exp {[ ]*(} $types {)[ ]+([^ } append exp \n { ]+)[ ]*([^} \n\r {]*)} \[\n\r]+ regsub -nocase -all $exp $data "\[MapInsert [list $cookie] \\1 {\\2} {\\3}]" cmd upvar #0 $cookie map catch {unset map} subst $cmd return $cookie } # helper proc for generating the data structure proc MapInsert {cookie type href coords} { upvar #0 $cookie map if {![info exists map]} { set map(N) 0 } else { incr map(N) } regsub -all , $coords { } coords set c {} set i 0 foreach {X Y} $coords { lappend c $i,X $X $i,Y $Y incr i } set map($map(N),type) $type set map($map(N),coords) $c set map($map(N),href) $href if {$type == "default"} { set map(default) $href } } # MapHit looks up coordinates in a map proc MapHit {cookie x y} { upvar #0 $cookie map set sawpoint 0 for {set i 0} {$i < $map(N)} {incr i} { array set pgon $map($i,coords) switch $map($i,type) { poly { if {[MapPointInPoly $x $y pgon]} { return $map($i,href) } } circle { if {[MapPointInCircle $x $y pgon]} { return $map($i,href) } } rect { if {[MapPointInRect $x $y pgon]} { return $map($i,href) } } point { set dist [expr ($x - $pgon(0,X)) * ($x - $pgon(0,X)) + \ ($y - $pgon(0,Y)) * ($y - $pgon(0,Y))] if {!$sawpoint || ($dist < $mindist)} { set mindist $dist set default $map($i,href) } } } } if {[info exists default]} { return $default } if {[info exists map(default)]} { return $map(default) } return {} } |
Added modules/httpd/maptk.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # maptk.tcl # simple sample image map resolver # uses Netscape map files # # This version uses a Tk canvas to do hit detection. # # Stephen Uhler (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: maptk.tcl,v 1.6 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::ismaptk 1.0 package require httpd::log ;# Log #package require httpd::utils ;# file # read in an image map file, and generate the appropriate canvas # # sample image map # circle /sun-on-net/internet.sol/access.html 664,311 686,311 # default http://www.hal.com/ # default /sunsoft/index.html # point /sunworldonline/common/swol-subscribe.html 45,134 # poly / 182,11 184,88 301,77 365,86 393,57 393,10 # rect /sunsoft/index.html 1,1 119,34 # translate an x/y coordinate into a url proc Map_Lookup {request} { if {[regexp {([^?]+)\?([0-9]+),([0-9]+)} $request {} map x y]} { if {[catch {file mtime $map} mtime]} { return "" } if {![info exists ImageMaps($map)] || ($mtime > $ImageMaps(mtime,$map))} { set ImageMaps($map) [MapRead $map] set ImageMaps(mtime,$map) $mtime } return [MapHit $ImageMaps($map) $x $y] } else { return "" } } # Resolve hits by building a canvas (which is never mapped), # with the map objects. Use the file name as the canvas tag. proc MapRead {file} { if {[catch {open $file} fd]} { Log "" "file open" $fd return {} } regsub -all {\.} $file _ cookie set data [read $fd] close $fd catch {destroy .image$cookie} set can [canvas .image$cookie] regsub -all "(^|\n+)#\[^\n]*" $data {} data regsub -all {([][$\\])} $data {\\\1} data set types circle|default|point|poly|rect append exp {[ ]*(} $types {)[ ]+([^ } append exp \n { ]+)[ ]*([^} \n\r {]*)} \[\n\r]+ regsub -nocase -all $exp $data "\[MapInsert [list $can] \\1 {\\2} {\\3}]" cmd $can lower default set tags [$can itemconfigure default -tags] $can itemconfigure default -tags [lindex $tags 0] subst $cmd return $can } # helper proc for generating the canvas proc MapInsert {can type href coords} { regsub -all , $coords { } coords if {[catch { switch -- $type { default { upvar #0 $can default set default $href # $can create rectangle 0 0 1000 1000 -fill white -tags [list $href default] } circle { # The coords are the center and one point on the edge. # Tk ovals are defined by two corner points. foreach {x1 y1 x2 y2} $coords {break} set r [expr int(sqrt(($y2 - $y1) * ($y2 - $y1) + \ ($x2 - $x1) * ($x2 - $x1)))] set x1 [expr $x1 - $r] set x2 [expr $x1 + 2*$r] set y1 [expr $y1 - $r] set y2 [expr $y1 + 2 * $r] $can create oval $x1 $y1 $x2 $y2 -fill black -tags $href } rect { eval {$can create rectangle} $coords -fill black -tags {$href} } poly { eval {$can create polygon} $coords -fill black -tags {$href} } point { eval {$can create oval} $coords $coords -width 2 -fill black \ -tags {$href} } }} err]} { Log $can $href $err } } proc MapHit {map x y} { if {[catch { $map gettags [lindex [$map find overlapping $x $y $x $y] 0] } result]} { set result {} } if {[string length $result] == 0} { upvar #0 $map default catch {set result $default} } return $result } |
Added modules/httpd/md5hex.tcl.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # This is a shim layer to deal with the inconsistencies # between md5 1 and md5 2 (grr) package provide httpd::md5hex 1.0 catch { # for some reason pkg_mkIndex barfs on this ... hide it. package require md5 2 # md5hex always returns a hex version of the md5 hash if {[package vcompare [package present md5] 2.0] > -1} { # we have md5 v2 - it needs to be told to return hex interp alias {} md5hex {} ::md5::md5 -hex -- } else { # we have md5 v1 - it returns hex anyway interp alias {} md5hex {} ::md5::md5 } } |
Added modules/httpd/mime.types.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | # # Thanks to [email protected] # This is the mime.types shipped with the NCSA http server application/activemessage application/andrew-inset application/applefile application/atomicmail application/dca-rft application/dec-dx application/mac-binhex40 hqx application/macwriteii application/msword doc dot application/ms-excel xls xlw xla xlc xlm xlt application/ms-powerpoint ppt pps pot application/ms-project mpp application/x-msaccess mdb application/x-msmetafile wmf application/x-mswrite wri application/x-msschedule scd application/news-message-id application/news-transmission application/octet-stream bin core exe tgz gz Z zip application/octet-stream sun4 i86pc application/oda oda application/pdf pdf application/postscript ai eps ps application/remote-printing application/rtf rtf application/slate application/x-mif mif application/x-javascript js application/wita application/wordperfect5.1 application/x-cgi cgi application/x-csh csh application/x-dvi dvi application/x-hdf hdf application/x-latex latex application/x-netcdf nc cdf application/x-ns-proxy-autoconfig pac application/x-safetcl thtml application/x-server-include shtml application/x-sh sh application/x-tcl tcl application/x-tcl-subst subst application/x-tcl-template tml application/x-tcl-auth auth application/x-tcl-snmp snmp application/x-tcl-connect xtcl application/x-tex tex application/x-texinfo texinfo texi application/x-troff t tr roff application/x-troff-man man application/x-troff-me me application/x-troff-ms ms application/x-wais-source src application/x-imagemap map application/zip zip application/x-bcpio bcpio application/x-cpio cpio application/x-gtar gtar application/x-shar shar application/x-sv4cpio sv4cpio application/x-sv4crc sv4crc application/x-tar tar application/x-ustar ustar application/x-patch patch application/x-shockwave-flash swf audio/basic au snd audio/x-aiff aif aiff aifc audio/x-wav wav image/gif gif GIF image/ief ief image/jpeg jpeg jpg jpe image/tiff tiff tif image/x-cmu-raster ras image/x-portable-anymap pnm image/x-portable-bitmap pbm image/x-portable-graymap pgm image/x-portable-pixmap ppm image/x-rgb rgb image/x-xbitmap xbm image/x-xpixmap xpm image/x-xwindowdump xwd message/external-body message/news message/partial message/rfc822 multipart/alternative multipart/appledouble multipart/digest multipart/mixed multipart/parallel text/html html htm text/plain txt text/richtext rtx text/tab-separated-values tsv text/x-setext etx text/xml xml application/xhtml+xml xhtml text/css css video/mpeg mpeg mpg mpe video/quicktime qt mov video/x-msvideo avi video/x-sgi-movie movie text/vnd.wap.wml wml text/vnd.wap.wmlscript wmls application/vnd.wap.wmlc wmlc application/vnd.wap.wmscriptc wmlsc image/vnd.wap.wbmp wbmp audio/mpeg mp3 |
Added modules/httpd/mtype.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | # mimetype.tcl -- # Code to deal with mime types # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: mtype.tcl,v 1.9 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::mtype 1.1 #package require httpd::utils ;# file # Convert the file suffix into a mime type # global MimeType is a mapping from file extension to mime-type proc Mtype {path} { global MimeType set ext [string tolower [file extension $path]] if {[info exist MimeType($ext)]} { return $MimeType($ext) } else { return text/plain } } # Read a mime types file into the mimeType array. # Set up some minimal defaults if no file is available. proc Mtype_ReadTypes {file} { global MimeType array set MimeType { {} text/plain .txt text/plain .htm text/html .html text/html .tml application/x-tcl-template .gif image/gif .thtml application/x-safetcl .shtml application/x-server-include .cgi application/x-cgi .map application/x-imagemap .subst application/x-tcl-subst } if {[catch {open $file} in]} { return } while {[gets $in line] >= 0} { if {[regexp {^( )*$} $line]} { continue } if {[regexp {^( )*#} $line]} { continue } if {[regexp {([^ ]+)[ ]+(.+)$} $line match type rest]} { foreach item [split $rest] { if {[string length $item]} { set MimeType([string tolower .$item]) $type } } } } close $in } # Mtype_Accept -- # # This returns the Accept specification from the HTTP headers. # These are a list of MIME types that the browser favors. # # Arguments: # sock The socket connection # # Results: # The Accept header, or a default. # # Side Effects: # None proc Mtype_Accept {sock} { upvar #0 Httpd$sock data if {![info exist data(mime,accept)]} { return */* } else { return $data(mime,accept) } } # Mtype_Match -- # # This compares a document type with the Accept values. # # Arguments: # accept The results of Mtype_Accept # type A MIME Content-Type. # # Results: # 1 If the content-type matches the accept spec, 0 otherwise. # # Side Effects: # None proc Mtype_Match {accept type} { foreach t [split $accept ,] { regsub {;.*} $t {} t ;# Nuke quality parameters set t [string trim [string tolower $t]] if {[string match $t $type]} { return 1 } } return 0 } # Mtype_Add -- # # Add a MIME type mapping # # Arguments: # suffix A file suffix # type The corresponding MIME Content-Type. # # Results: # None proc Mtype_Add {suffix type} { global MimeType set suffix [string trimleft $suffix .] set MimeType([string tolower .$suffix]) $type } # Mtype_Reset -- # # Clear all MIME type mappings # # Arguments: # None # # Side Effects: # Unsets the MimeType array proc Mtype_Reset {} { global MimeType if {[info exist MimeType]} { unset MimeType } } |
Added modules/httpd/objects.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | # objects.tcl # # Provides a hook for objects to process URLs # Object that are connected are expected to expose the method: # # httpdMarshallArguments [suffix] [cgiList] # # Returns a command that is immediately evaluated, usually in the # form of [object] [method] [key/value list] # # For an example of this system in action, see custom/objects.tcl # in the distribution # # Copyright # Sean Woods (c) 2008 # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: objects.tcl,v 1.1 2008/05/06 00:17:47 eviltwinskippy Exp $ package provide httpd::objects 1.0 # Object_Url # Define a subtree of the URL hierarchy that is implemented by # direct Tcl calls to a Tao Object. # # Arguments # virtual The name of the subtree of the hierarchy, e.g., /device # object The Tcl object to use when constructing calls, # e.g. Device # inThread True if this should be dispatched to a thread. # # Side Effects # Register an object proc ::Object_Url {virtual object {inThread 0}} { global Direct set Direct($object) $virtual ;# So we can reconstruct URLs Url_PrefixInstall $virtual [list ObjectDomain $object] $inThread } # Object_UrlRemove # Remove a subtree of the URL hierarchy that is implemented by # direct Tcl calls. # # Arguments # object The Tcl object used when constructing calls, # # Side Effects # proc ::Object_UrlRemove {object} { global Direct catch { Url_PrefixRemove $Direct($object) } catch { unset Direct($object) } } # Main handler for Object domains (i.e. tcl commands) # object: the object registered with Object_Url # sock: the socket back to the client # suffix: the part of the url after the object. # # This calls out to the Object with the suffix being either # a direct method to this object, a reference to an object # and a method to call to the referered object. # # All parameters from the form are fed into a Dict # All object method called must be prefixed with "httpd" # # Example: # Object_Url /device Device # if the URL is /device/a/display, then the Tcl command to handle it # should be # proc [Device /node a] httpdDisplay # # You can define the content type for the results of your procedure by # modifying the global ::page(content-type) field # # ::page(content-type) is reset to text/html every pageview proc ::ObjectDomain {object sock suffix} { global Direct global env upvar #0 Httpd$sock data global page set page(content-type) text/html # Set up the environment a-la CGI. Cgi_SetEnv $sock $object #$suffix # Prepare an argument data from the query data. Url_QuerySetup $sock set cmd [$object httpdMarshallArguments $suffix [::ncgi::nvlist]] if {$cmd == ""} { Doc_NotFound $sock return } set code [catch $cmd result] ::Object_Respond $sock $code $result $page(content-type) } # Object_Respond -- # # This function returns the result of evaluating the object # url. Usually, this involves returning a page, but a redirect # could also occur. # # Arguments: # sock The socket back to the client. # code The return code from evaluating the direct url. # result The return string from evaluating the direct url. # type The mime type to use for the result. (Defaults to text/html). # # Notes: Cargo Culted from Direct_Url Code. May start to differ later. # # Results: # None. # # Side effects: # If code 302 (redirect) is passed, calls Httpd_Redirect to # redirect the current request to the url in result. # If code 0 is passed, the result is returned to the client. # If any other code is passed, an exception is raised, which # will cause a stack trace to be returned to the client. # proc ::Object_Respond {sock code result {type text/html}} { switch $code { 0 { # Fall through to Httpd_ReturnData. } 302 { # Redirect. Httpd_Redirect $result $sock return "" } default { # Exception will cause error page to be returned. global errorInfo errorCode return -code $code -errorinfo $errorInfo -errorcode $errorCode \ $result } } # See if a content type has been registered for the URL. # Save any return cookies which have been set. # This works with the Doc_SetCookie procedure that populates # the global cookie array. ::Cookie_Save $sock ::Httpd_ReturnData $sock $type $result return "" } |
Added modules/httpd/open.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # opentrace.tcl -- # # This is a wrapper around the open command that keeps track of what # file (or pipe) was opened for a particular channel. Useful for # debugging file descriptor leaks. # # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: open.tcl,v 1.3 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::opentrace 1.0 #package require httpd::utils ;# file if {[info commands "open-orig"] == ""} { rename open open-orig proc open {path {mode r} {perms {}}} { global OpenFiles if {[catch { if {[string length $perms]} { set io [open-orig $path $mode $perms] } else { set io [open-orig $path $mode] } } err]} { return -code error $err } set OpenFiles($io) $path return $io } } if {[info commands "close-orig"] == ""} { rename close close-orig proc close {io} { global OpenFiles if {[info exist OpenFiles($io)]} { set OpenFiles($io) "CLOSED $OpenFiles($io)" } close-orig $io } } |
Added modules/httpd/passcheck.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | # passcheck.tcl # package provide httpd::passcheck 1.0 namespace eval passcheck { } # Copyright(c) Genesys Software Romania srl., 2000 # # License is granted here to use this code for any purpose, # No warranties included. # # # # Provides password checking against various systems. # Useful with TCLHTTPD server, available from http://www.tcl.tk/ # # The purpose is to avoid maintaining duplicate password tables # for tclhttpd, and re-use instead existing systems available in your local net. # This way users dont need to remember many passwords - just use known passwords. # # # Currently implemented are pop3 and odbc checkers. # # Use pop3 pass checker to authenticate users against an pop mail server # it requires pop3 package # # Use odbc pass checker to perform authentication against a ODBC datasource # available locally to the web server. # # # You can add your passcheckers by providing procedures with the following # syntax and name conventioni: (we consider thi will authenticate against LDAP: # # proc ::passcheck::verify_ldap {sock realm user pass {config {}}} { .... return 1 or 0 } # # the sock, realm, user, pass arguments are the same as received by a .tclaccess "callback" # command. # # the config argument should provide significant configuration options for the checker. # e.g. for pop3 it should be a mail server machine name, running pop3 service, # and for odbc - a datasource name. # # Other usefull commands are here - to see wich types of checkers are available, # to clear password caches # for specific or all realms, to see wich realms and how are configured. # Author: Cezar Totth <[email protected]> # set ::passcheck::comment { # # You'll probably need to add these in your tclhttpd.rc file.. # package require httpd::passcheck # ################# POP3 example # Configure checker to use pop3 authentication for the realm named "LocalMail" against # an existing local pop server. set pop3server 192.168.50.5 ::passcheck::setChecker LocalMail pop3 $pop3server # ######################## #Then you can specify within any .tclaccess file: realm LocalMail callback ::passcheck::Verify ######################## ################# ODBC example ########################## # Configure it to authenticate against a datasource. # The realm will be named "DbServer" ::passcheck::setChecker DbServer odbc $datasource ###### and in .tclaccess files: realm DbServer callback ::passcheck::Verify } ################################ End of comment here ... proc ::passcheck::setChecker {realm passcheckerName {confopt {}}} { set ::passcheck::_Config($realm) [list verify_$passcheckerName $confopt] } proc ::passcheck::unsetConf {realm} { catch {unset ::passcheck::_Config($realm)} } # # The pass checker configuration for all realms. # set ::passcheck::DefaultChecker [list verify_deny {}] proc ::passcheck::getChecker realm { upvar #0 ::passcheck::_Config($realm) myConf if {[info exists myConf]} { return $myConf } return ${::passcheck::DefaultChecker} } proc ::passcheck::getCheckerConf {realm} { return [lindex [::passcheck::getChecker $realm] 1] } proc ::passcheck::getCheckerName {realm} { return [lindex [::passcheck::getChecker $realm] 0] } # # Returns the available types of passcheckers (e.g. pop3, odbc, never, allways..) proc ::passcheck::getCheckerTypes {} { set toR {} foreach cname [info commands ::passcheck::verify_*] { lappend toR [lindex [split $cname _] 1] } return $toR } # # returns wich realms are controlled by our pass checkers proc ::passcheck::getRealms {} { return [array names ::passcheck::_Config] } # # Use this to clear password caches. Needed after users changed their passwords. # No realm specified means to clear all caches of all realms. proc ::passcheck::clearCache {{realm {}}} { if {![llength $realm]} { set rlist [info vars ::passcheck::_passCache_*] } else { set rlist ::passcheck::_passCache_$realm } foreach carr $rlist { catch { unset $carr } } } # # this is to be specified from .tclaccess files on tclhttpd. # add lines: # # set realm ARealmName # set callback ::passcheck::Verify # proc ::passcheck::Verify {socket realm user pass} { upvar #0 ::passcheck::_passCache_$realm pcache set kpass [crypt $pass 91] if {[info exists pcache($user)]} { if { "$kpass" == "$pcache($user)" } { set ::env(REMOTE_USER) $user return 1 } else { unset pcache($user) } } set pcheck [::passcheck::getChecker $realm] set tocall [list [lindex $pcheck 0] $socket $realm $user $pass [lindex $pcheck 1]] # puts "will call: $tocall" set rez 0 catch { set rez [eval $tocall] } if {$rez} { set pcache($user) $kpass set ::env(REMOTE_USER) $user } return $rez } ############################## Basic Auth --> Pop3 authentication ###################### # # By default the tcl server is considered to run on the email server. # On most Unix-like systems this means authentication is made against # the local system proc ::passcheck::verify_pop3 {socket realm user pass {conf localhost}} { if {[catch {::pop3::close [::pop3::open $conf $user $pass]}] } { return 0 } return 1 } ############################# TCLODBC Datasource authentication ####################### proc ::passcheck::verify_odbc {socket realm user pass {conf passcheck}} { if {[catch { database _passCheck_db$conf$user $conf $user $pass } ] } { return 0 } _passCheck_db$conf$user disconnect return 1 } # ############################ Dummy pass checkers ###################################### # These are dummy pass checkers. Usefull in automated tests, or to temporarly lock/unlock # realms proc ::passcheck::verify_deny {socket realm user pass {conf {}}} { return 0 } proc ::passcheck::verify_allow {socket realm user pass {conf {}}} { return 1 } ########################### external packages availability ####################### # # warning messages. Shall it go to server's log too? proc ::passcheck::warning message { puts "passcheck: $message" } # # # Is better to have crypt handy to cache passwords with more confidence. if { [catch { package require crypt } ] } { # we provide a dummy crypt... package require tclcrypt #::passcheck::warning {no crypt package available! passwords cached in cleartext!} #proc crypt {word salt} { return "${word}$salt" } } # # checking for POP3 if { [catch { package require pop3 } ] } { ::passcheck::warning {no POP3 pass check available! verify pop3 package} # rename pop3_verify pop3_notAvail } # # checking for TCLODBC if { [catch { package require tclodbc } ] } { ::passcheck::warning {no ODBC pass check available! verify tclodbc package} # rename odbc_verify odbc_notAvail } |
Added modules/httpd/passgen.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | # password generator # generate a password according to the passgen_rules array # # Source: http://mini.net/tcl/Password%20Generator # Author: Mark Oakden http:/wiki.tcl.tk/MNO # Version: 1.0 # no sanity checks on the supplied rules are done. package provide httpd::passgen 1.0 # datasets for password generation:- # separate lowercase and UPPERCASE letters so we can demand minimum # number of each separately. array set passgen { letters "abcdefghijklmnopqrstuvwxyz" LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" numbers "0123456789" punctuation "!\"\x{00A3}$%^&*()_+-={};':@#~<>,.?/\\|" } # a simpler set might be, for example:- # # set passgen(letters) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" # set passgen(numbers) "0123456789" # set passgen(punctuation) "!\"\x{00A3}$%^&*()_+-={};':@#~<>,.?/\\|" # the rules determine characteristics of the randomly generated passwords # presently available are:- # passgen_rules(len) password length # passgen_rules(<dataset_name>,min) minimum number of characters from <dataset_name> # entry on the passgen array # example rules:- # password 7 chars long, with at least one U/C char, one l/c char, # one number and one punctuation. array set passgen_rules { len 7 letters,min 1 LETTERS,min 1 numbers,min 1 punctuation,min 1 } # example rules appropriate to the commented "simpler" datasets above:- # # set passgen_rules(len) 7 # set passgen_rules(numbers,min) 1 # set passgen_rules(punctuation,min) 1 # picks a (pseudo)random char from str proc PassgenOneCharFrom { str } { set len [string length $str] set indx [expr int(rand()*$len)] return [string index $str $indx] } # given a string, and integers i and j, swap the ith and jth chars of str # return the result proc PassgenSwap { str i j } { if { $i == $j } { return $str } if { $i > $j } { set t $j set j $i set i $t } set pre [string range $str 0 [expr $i - 1]] set chari [string index $str $i] set mid [string range $str [expr $i + 1] [expr $j - 1]] set charj [string index $str $j] set end [string range $str [expr $j + 1] end] set ret ${pre}${charj}${mid}${chari}${end} return $ret } # for a string of length n, swap random pairs of chars n times # and return the result proc PassgenShuffle { str } { set len [string length $str] for { set i 1 } { $i <= $len } { incr i 1 } { set indx1 [expr int(rand()*$len)] set indx2 [expr int(rand()*$len)] set str [PassgenSwap $str $indx1 $indx2] } return $str } # generate a password proc Passgen_Generate {} { variable passgen variable passgen_rules # Algorithm # 1. foreach dataset with a min parameter, choose exactly min # random chars from it # 2. concatenate results of above into password # 3. concatenate all datasets into large dataset # 4. choose desired_length-password_length chars from large # 5. concatenate (4) and (2) # 6. shuffle (5) set password {} foreach indx [array names passgen_rules *,min] { set ds_name [lindex [split $indx ,] 0] set num $passgen_rules($indx) for {set i 1} {$i <= $num} {incr i 1} { append password [PassgenOneCharFrom $passgen($ds_name)] } } set all_data {} foreach set [array names passgen] { append all_data $passgen($set) } set rem_len [expr $passgen_rules(len) - [string length $password]] for {set i 1} {$i <= $rem_len} {incr i 1} { append password [PassgenOneCharFrom $all_data] } return [PassgenShuffle $password] } set passgen(saltstr) "$passgen(LETTERS)$passgen(letters)$passgen(numbers)" proc Passgen_Salt {} { global passgen set slen [string len $passgen(saltstr)] return "[string index $passgen(saltstr) [expr round(rand() * $slen)]][string index $passgen(saltstr) [expr round(rand() * $slen)]]" } |
Added modules/httpd/pkgIndex.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex -direct" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd 1.7 [list source [file join $dir httpd.tcl]] package ifneeded httpd::admin 1.0 [list source [file join $dir admin.tcl]] package ifneeded httpd::auth 2.0 [list source [file join $dir auth.tcl]] package ifneeded httpd::cgi 1.1 [list source [file join $dir cgi.tcl]] package ifneeded httpd::config 1.0 [list source [file join $dir config.tcl]] package ifneeded httpd::cookie 1.0 [list source [file join $dir cookie.tcl]] package ifneeded httpd::counter 2.0 [list source [file join $dir counter.tcl]] package ifneeded httpd::debug 1.0 [list source [file join $dir debug.tcl]] package ifneeded httpd::digest 1.0 [list source [file join $dir digest.tcl]] package ifneeded httpd::direct 1.1 [list source [file join $dir direct.tcl]] package ifneeded httpd::dirlist 1.1 [list source [file join $dir dirlist.tcl]] package ifneeded httpd::doc 1.1 [list source [file join $dir doc.tcl]] package ifneeded httpd::doc_error 1.0 [list source [file join $dir doc_error.tcl]] package ifneeded httpd::doctools 1.0 [list source [file join $dir doctools.tcl]] package ifneeded httpd::fallback 1.0 [list source [file join $dir fallback.tcl]] package ifneeded httpd::imagemap 1.0 [list source [file join $dir imagemap.tcl]] package ifneeded httpd::include 1.0 [list source [file join $dir include.tcl]] package ifneeded httpd::ismaptcl 1.0 [list source [file join $dir maptcl.tcl]] package ifneeded httpd::ismaptk 1.0 [list source [file join $dir maptk.tcl]] package ifneeded httpd::log 1.1 [list source [file join $dir log.tcl]] package ifneeded httpd::logstd 1.0 [list source [file join $dir logstd.tcl]] package ifneeded httpd::mail 1.0 [list source [file join $dir mail.tcl]] package ifneeded httpd::md5hex 1.0 [list source [file join $dir md5hex.tcl]] package ifneeded httpd::mtype 1.1 [list source [file join $dir mtype.tcl]] package ifneeded httpd::opentrace 1.0 [list source [file join $dir open.tcl]] package ifneeded httpd::passcheck 1.0 [list source [file join $dir passcheck.tcl]] package ifneeded httpd::passgen 1.0 [list source [file join $dir passgen.tcl]] package ifneeded httpd::redirect 1.0 [list source [file join $dir redirect.tcl]] package ifneeded httpd::safecgio 1.0 [list source [file join $dir safecgio.tcl]] package ifneeded httpd::session 1.0 [list source [file join $dir session.tcl]] package ifneeded httpd::srvui 1.0 [list source [file join $dir srvui.tcl]] package ifneeded httpd::status 1.0 [list source [file join $dir status.tcl]] package ifneeded httpd::stdin 1.1 [list source [file join $dir stdin.tcl]] package ifneeded httpd::subst 1.0 [list source [file join $dir subst.tcl]] package ifneeded httpd::template 1.0 [list source [file join $dir template.tcl]] package ifneeded httpd::threadmgr 1.0 [list source [file join $dir thread.tcl]] package ifneeded httpd::upload 1.0 [list source [file join $dir upload.tcl]] package ifneeded httpd::url 1.2 [list source [file join $dir url.tcl]] package ifneeded httpd::utils 1.0 [list source [file join $dir utils.tcl]] package ifneeded httpd::version 4.0 [list source [file join $dir version.tcl]] package ifneeded tclcrypt 1.0 [list source [file join $dir tclcrypt.tcl]] |
Added modules/httpd/prodebug.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # prodebug.tcl -- # # This file contains the public routines used to start debugging user # code in a remote application. # # Copyright (c) 1998-2000 by Ajuba Solutions # All rights reserved. # # RCS: @(#) $Id: prodebug.tcl,v 1.1 2000/08/02 07:06:53 welch Exp $ # # This file comprises the public interface to the TclPro Debugger for use # by applications that are not launched directly from the debugger. The # public interface consists of the two commands "debugger_init" and # "debugger_eval". A typical application will source this file then invoke # "debugger_init" to initiate the connection to the debugger. Once # connected, the application can use the "debugger_eval" command to # evaluate scripts that the debugger will be able to step through. # Additionally, various other Tcl commands including "source" and "proc" # will automatically instrument code. Any blocks of code (e.g. procedure # bodies) that existed before "debugger_init" was invoked will execute # without any instrumentation. # # debugger_init -- # # This function initiates a connection to the TclPro Debugger. Files # that are sourced and procedures that are defined after this # function completes will be instrumented by the debugger. # # Arguments: # host Name of the host running the debugger. # port TCP port that the debugger is using. # # Results: # Returns 1 on success and 0 on failure. proc debugger_init {{host 127.0.0.1} {port 2756}} { global tcl_version if {[catch {set socket [socket $host $port]}] != 0} { return 0 } fconfigure $socket -blocking 1 -translation binary # Send the loader and tcl library version set msg [list HELLO 1.0 $tcl_version] puts $socket [string length $msg] puts -nonewline $socket $msg flush $socket # Get the rest of the nub library and evaluate it in the current scope. # Note that the nub code assumes there will be a "socket" variable that # contains the debugger socket channel. if {[gets $socket bytes] == -1} { close $socket return 0 } set msg [read $socket $bytes] eval [lindex $msg 1] return 1 } # debugger_eval -- # # Instrument and evaluate a script. This routine is a trivial # implementation that is replaced when the nub is downloaded. # # Arguments: # args One or more arguments, the last of which must # be the script to evaluate. # # Results: # Returns the result of evaluating the script. proc debugger_eval {args} { global errorInfo errorCode set length [llength $args] if {$length < 1} { error "wrong # args: should be \"debugger_eval ?options? script\"" } set code [catch {uplevel 1 [lindex $args [expr {$length - 1}]]} result] return -code $code -errorcode $errorCode -errorinfo $errorInfo $result } |
Added modules/httpd/redirect.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | # redirect.tcl # # Support for redirecting URLs. # You can either do a single redirect (Redirect_Url) # or you can redirect a whole subtree elsewhere (Redirect_UrlTree) # # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: redirect.tcl,v 1.7 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::redirect 1.0 package require httpd ;# Httpd_Redirect Httpd_RedirectSelf Httpd_SelfUrl package require httpd::direct ;# Direct_Url package require httpd::url ;# Url_AccessInstall Url_Dispatch Url_PrefixInstall Url_Unwind #package require httpd::utils ;# file # Redirect_To -- # # Trigger a page redirect # # Arguments: # newurl The new URL # # Results: # None # # Side Effects: # Raises a special error that is caught by Url_Unwind proc Redirect_To {newurl} { return -code error \ -errorcode [list HTTPD_REDIRECT $newurl] \ "Redirect to $newurl" } # Redirect_Self -- # # Like Redirect_To, but to a URL that is relative to this server. # # Arguments: # newurl Server-relative URL # # Results: # None # # Side Effects: # See Redirect_To proc Redirect_Self {newurl} { set thispage [ncgi::urlStub] set thisurl [Httpd_SelfUrl $thispage] set newurl [uri::resolve $thisurl $newurl] Redirect_To $newurl } # Redirect_QuerySelf -- # # Like Redirect_Self, but preserves query data # # Arguments: # newurl Server-relative URL # # Results: # None # # Side Effects: # See Redirect_To proc Redirect_QuerySelf {sock newurl} { upvar #0 Httpd$sock data # Preserve query data when bouncing among pages. if {[info exist data(query)] && [string length $data(query)]} { append newurl ? $data(query) } Redirect_Self $newurl ;# offer what we have to the client } # Redirect_Dir -- # # Generate a redirect because the trailing slash isn't present # on a URL that corresponds to a directory. # # Arguments: # sock Socket connection # # Results: # None # # Side Effects: # Generate a redirect page. proc Redirect_Dir {sock} { global Httpd upvar #0 Httpd$sock data set url $data(url)/ if {[info exist data(query)] && [string length $data(query)]} { # maintain the query data append url ? $data(query) } Httpd_Redirect $url $sock } # Redirect_Init # # Initialize the redirect module. # # Arguments: # url (optional) Direct URL for redirect control. # # Side Effects: # Registers access hook to implement redirects. # May register direct domain proc Redirect_Init {{url {}}} { if {[string length $url]} { Direct_Url $url Redirect } # The [list] makes the eval in Url_Dispatch run slightly faster Url_AccessInstall [list RedirectAccess] # Load the default redirect file Redirect/reload } # Redirect_UrlTree # # Map a whole URL hierarchy to a new place # # Arguments: # old Old location, (e.g., /olddir) # new New location, (e.g., /newdir) # # Side Effects: # Future requests to old/a/b/c will redirect to new/a/b/c proc Redirect_UrlTree {old new} { Url_PrefixInstall $old [list RedirectDomain $new] } # RedirectDomain # # Set up a domain that redirects requests elsewhere # To use, make a call like this: # # Url_PrefixInstall /olddir [list RedirectDomain /newdir] # # Arguments: # prefix The Prefix of the domain # url The other URL to which to redirect # # Results: # This always raises a redirect error proc RedirectDomain {url sock suffix} { set newurl $url$suffix Httpd_Redirect $newurl $sock } # Redirect_Url # # Redirect a single URL to another, fully-qualified URL. # # Arguments: # old Old location, (e.g., /olddir/file.html) # new New location, (e.g., http://www.foo.bar/newdir/newfile.html) # # Side Effects: # Future requests to $old will redirect to $new proc Redirect_Url {old new} { global Redirect set Redirect($old) $new } # Redirect_UrlSelf # # Redirect a single URL to another location on the same server. # # Arguments: # old Old location, (e.g., /olddir/file.html) # new New location, (e.g., /newdir/newfile.html) # # Side Effects: # Future requests to $old will redirect to $new proc Redirect_UrlSelf {old new} { global RedirectSelf # Cannot make the "self" computation until we have # a socket and know the protocol and server name for sure set RedirectSelf($old) $new } # RedirectAccess # # This is invoked as an "access checker" that will simply # redirect a URL to another location. # # Arguments: # sock Current connection # url The url of the connection # # Results: # Returns "denied" if it triggered a redirect. This stops URL processing. # Returns "skip" otherwise, so other access control checks can be made. proc RedirectAccess {sock url} { global Redirect global RedirectSelf if {[info exist RedirectSelf($url)]} { # Note - this is not an "internal" redirect, but in this case # the server simply qualifies the url with its own name Httpd_RedirectSelf $RedirectSelf($url) $sock return denied } if {[info exist Redirect($url)]} { Httpd_Redirect $Redirect($url) $sock return denied } return skip } # Redirect/reload # # Direct URL to reload the redirect configuration file. # # Arguments: # none # # Side Effects: # Sources "redirect" from the document root. proc Redirect/reload {} { global Doc set path [file join $Doc(root) redirect] if { ! [file exists $path]} { return } source $path set html "<h3>Reloaded redirect file</h3>" append html [Redirect/status] return $html } # Redirect/status # # Display the Redirection tables # # Arguments: # none # # Results: # An HTML table proc Redirect/status {} { global Redirect global RedirectSelf global Url ;# hack alert append html "<h3>Redirect Table</h3>\n" append html "<table>\n" append html "<tr><th colspan=2>Single URLs</th></tr>\n" foreach old [lsort [array names RedirectSelf]] { append html "<tr><td>$old</td><td>$RedirectSelf($old)</td></tr>\n" } foreach old [lsort [array names Redirect]] { append html "<tr><td>$old</td><td>$Redirect($old)</td></tr>\n" } append html "<tr><th colspan=2>URL Subtrees</th></tr>\n" foreach prefix [lsort [array names Url command,*]] { if {[string match RedirectDomain* $Url($prefix)]} { set new [lindex $Url($prefix) 1] regsub command, $prefix {} prefix append html "<tr><td>$prefix</td><td>$new</td></tr>\n" } } append html </table>\n return $html } |
Added modules/httpd/safecgio.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | # safecgio.tcl # Brent Welch (c) 1996 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # # RCS: @(#) $Id: safecgio.tcl,v 1.8 2004/10/22 03:43:06 coldstore Exp $ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # Safe Tcl security policy for server-side CGI-like processing. # The HTTPD will "subst" an html page in the context of a safecgio interpreter # in order to efficiently compute a page. This security policy gives the # safe interpreter limited access to files within a specified directory. # # The script has access to the "env" array, which contains the same # information as for a CGI bin script. # # Any query information, either from a POST or GET query is available # as a name-value list in the "Query" variable. package provide httpd::safecgio 1.0 package require httpd::log ;# Log package require httpd::utils ;# Stderr file # start a safe CGI server proc SafeCGI_Server {port} { if {[catch {socket -server SafeCGI_Accept $port} oops]} { Stderr "SafeCGI_Server: $oops" exit 1 } } # Accept a connection from Httpd server. proc SafeCGI_Accept {sock addr port} { fconfigure $sock -blocking off fileevent $sock readable [list SafeCGIRead $sock] } # Read and execute commands from the Http server proc SafeCGIRead {sock} { global Env Query if {[eof $sock]} { close $sock } else { set command {} foreach {command value} [gets $sock] break switch -- $command { SetEnv { catch {array set Env $value} } SetQuery { set Query $value } DoFile { SafeCGIDo $sock $value } Exit { exit } } } } # Create a safe interpreter to "subst" a data file. proc SafeCGIDo {sock filename} { global Query Env argv0 if {![catch {open $filename} fd]} { append Query {} set child child$sock ;# Name of child interpreter SafeCGI_Create $child interp transfer {} $fd $child interp eval $child { proc DoCGI {fd Query envlist} { global env array set env $envlist subst [read $fd] } } if {![catch { interp eval $child [list DoCGI $fd $Query [array get Env]] } result]} { puts -nonewline $sock $result } else { Log $sock SafeCGIDo "$argv0 Error in $filename\n\t<$result>" } interp delete $child ;# Does close of transferred fd } close $sock } # security policy defined below. ##################################################################### # # Create a child that is limted to a few open files within # a given directory. If they open for writing, limit the size # of the output file. proc SafeCGI_Create {name {directory .} {maxopen 4} {maxsize 4096}} { global interpState interp create -safe $name interp alias $name open {} SafeCGI_Open $name $maxopen $directory interp eval $name {rename puts {}} interp alias $name puts {} SafeCGI_Puts $name $maxsize interp eval $name {rename close _close} ;# would rather "hide" this interp alias $name close {} SafeCGI_Close $name interp alias $name exit {} SafeCGI_Cleanup $name set interpState(channels,$name) {} } # Open files in a given directory. # Paramters set by the definition of the alias: # interp is a child interperter # maxopen is the max number of open files for the child # directory is the directory # Parameters from the child's call # file is the name of the file # access is the I/O mode proc SafeCGI_Open {interp maxopen directory file {access r}} { global interpState if {[llength $interpState(channels,$interp)] >= $maxopen} { error "couldn't open \"$file\": too many open files" } if {[regexp "^\[ \t\]*|" $file]} { error "no pipes allowed" } # Constrain the pathname to a one-component relative name if {([llength [file split $file]] != 1) || [file pathtype $file] != "relative"} { error "couldn't open \"$file\": permission denied" } # Disallow symbolic links and other non-file types set path [file join $directory $file] if {[file exists $path]} { file lstat $path stat ;# lstat here prevents symlinks if {$stat(type) != "file"} { error "couldn't open \"$file\": not a plain file" } } set out [open $path $access] lappend interpState(channels,$interp) $out interp share {} $out $interp return $out } # This is an alias to clean up children that exit # interp is the exiting child # interpState records open files for the child # We share them, so we must close our references. proc SafeCGI_Cleanup {interp} { global interpState interp delete $interp foreach out $interpState(channels,$interp) { catch {close $out} } unset interpState(channels,$interp) } # This is an alias for puts that limits file size # Parameters set by the alias definition: # interp is the child interpreter # max is the file size limit, in bytes # Parameters set in the call to the alias # args is ?-nonewline? chan string # chan is the I/O channel # string is the output data proc SafeCGI_Puts {interp max args} { if {[string match "-nonewline" [lindex $args 0]]} { set flag -nonewline set args [lrange $args 1 end] } else { set flag "" } if {[llength $args] == 1} { # Flag output to stdout as coming from the unsafe interpreter set chan stdout set string "Untrusted code $name says: [lindex $args 0]" } elseif {[llength $args] == 2} { set chan [lindex $args 0] set string [lindex $args 1] } else { error "wrong # args: should be \"puts ?-nonewline? ?channelId? string\"" } if {[string match "stdout" $chan"]} { set size [string length $string] ;# Tell makes no sense } else { set size [expr [tell $chan] + [string length $string]] } if {$size > $max} { interp eval $interp [list close $chan] error "File size exceeded" } else { eval puts $flag {$chan $string} } } # An alias for close that lets the parent clean up its reference proc SafeCGI_Close {interp chan} { global interpState set ix [lsearch $interpState(channels,$interp) $chan] if {$ix >= 0} { catch {close $chan} set interpState(channels,$interp) \ [lreplace $interpState(channels,$interp) $ix $ix] } $interp eval _close $chan ;# Need "invoke" hidden close } proc bgerror {msg} { global errorInfo Stderr $errorInfo } |
Added modules/httpd/session.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | # session.tcl -- # Session management support. # # A session is implemented as a safe slave interpreter that holds its state. # # Creating a session with Session_Create returns either a 4 character ID # (if MD5 is missing or Session(short) is true) or an unforgeable MD5 # hash. # # Use Session_Match to find and/or create a session based on query data. # # Use Session_Destroy to delete one session, and Session_Reap to # clean up "old" sessions. # # A session has a type, which is used to automatically create aliases for # the slave. If the type is Foo, then every Tcl procedure named Foo_* # in the master will be created as an alias. The Foo_ prefix gets # stripped off the alias name in the slave. # # Certain first arguments are treated specially for the aliases: # if the first argument is "session", then the alias automatically # gets called with the current session ID as the first argument. # if the first argument is "interp", then the alias automatically # gets called with the interp name as the first argument. # (From a session you get also get the interp name). # # In addition, a few aliases are defined for all types: # session - returns the session identifier # sequence - returns an increasing sequence number used to chain together # pages and detect bookmarks and "backs" that screw things up. # group - set or get the current session "group". # value - get a value from the current "group", or a default value # # Session state can be organized in "groups", which are just Tcl arrays # in the safe interpreters. The master keeps track of the current group # for a session, and the slave can change the group and query group # values with the "value" alias. There is no standard for setting # group values, but typically query data is copied into them by # the module that uses the sessions. # # Stephen Uhler (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: session.tcl,v 1.16 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::session 1.0 package require httpd::cookie ;# Cookie_GetSock Cookie_Make package require httpd::doc ;# Doc_Root package require httpd::utils ;# Stderr file iscommand randomx # use long session IDs if {![info exists Session(short)]} { set Session(short) 0 } # how long do session cookies last? if {![info exists Session(expires)]} { set Session(expires) "now + 10 years" ;# should be long enough } # if an MD5 package is available, we use it to make # an unforgeable session ID, otherwise default to # the old 4-digit session ID if {($Session(short) == 1) || [catch {package require httpd::md5hex}]} { # we have no usable md5 or have elected short session IDs proc SessionGenId {} { return [randomx] } } else { # generate a long and unforgeable session id proc SessionGenId {} { return [md5hex [randomx]] } } proc Session_Authorized {id} { upvar #0 Session:$id session if {![info exists session(interp)]} { set interp [SessionCreate $id] SessionAuthorizedAliases $interp $id } return $session(interp) } proc SessionAuthorizedAliases {interp id} { upvar #0 Session:$id session interp alias $interp require {} Session_Require $id interp alias $interp exit {} Session_Destroy $id } proc Session_Require {id tag} { upvar #0 Session:$id session if {![info exists session(init)]} { if {![iscommand ${tag}_Init]} { set html " <h4>No ${tag}_Init proc</h4> " } else { set html [${tag}_Init Session:$id] } } else { set html "<-- Session $id -->" } return $html } proc Dummy_Init {name} { upvar #0 $name session return "<-- Dummy_Init was here -->" } # Create a new session as a safe slave interpreter. # Populate it with the useful aliases. # Type: An arbitrary session type, used for automatic alias creation. proc Session_Create {type {isSafe 1}} { # Pick a unique session id, create the interpreter and global state. while {[info globals *[set id [SessionGenId]]*] != ""} {} Session_CreateWithID $type $id $isSafe } proc Session_CreateWithID {type id {isSafe 1}} { set interp [SessionCreate $id $isSafe] SessionTypeAliases $interp $id $type } proc SessionCreate {id {isSafe 1}} { upvar #0 Session:$id session if {$isSafe} then { set interp [interp create -safe interp$id] } else { set interp [interp create interp$id] } set session(start) [clock seconds] set session(current) $session(start) set session(count) 0 set session(interp) $interp return $interp } proc SessionTypeAliases {interp id type} { upvar #0 Session:$id session set session(type) $type # Set up the document specific aliases for this interp This # looks for all procedures in the master interpreter that start # with "<type>_". Since some of them might be auto-loaded, look # in the auto index array. The names get stored in an array to # remove duplicates. global auto_index foreach name "[info commands ${type}_*] [array names auto_index ${type}_*]" { set procs($name) {} } # Look at the *name* of the first argument to each alias-able proc. # Some names are treated specally. foreach proc [array names procs] { regexp -- ${type}_(.*) $proc {} alias catch {lindex [info args $proc] 0} arg0 switch -- $arg0 { session {interp alias $interp $alias {} $proc $id} interp {interp alias $interp $alias {} $proc $interp} default {interp alias $interp $alias {} $proc} } } # Set up the common aliases for all session interpreters. interp alias $interp session {} Session_Session $id interp alias $interp sequence {} Session_Sequence $id interp alias $interp group {} Session_Value $id group interp alias $interp value {} Session_Variable $id return $id } # Destroy all sessions older than a certain age (in seconds) # age: time (in seconds) since the most recent access # type: a regexp to mach session types with (defaults to all) proc Session_Reap {age {type .*}} { foreach id [info globals Session:*] { upvar #0 $id session set old [expr {[clock seconds] - $age}] if {[regexp -- $type $session(type)] && $session(current) < $old} { catch {interp delete $session(interp)} Stderr "Reaping session $id" unset session } } } # Destroy a single session proc Session_Destroy {id} { upvar #0 Session:$id session if {[info exists session]} { interp delete $session(interp) unset session SessionDiscard $id return 1 } else { return 0 } } # Find the correct session, and return the proper interp or error. # This is identical to Session_Match, but uses cookies to store # session id. # If the session is "new", then create a new one. # - query: optional alist containing the form and/or url query # - type: The type of this session # - error_name: The variable holding the error result (if any) proc Session_Cookie {{querylist {}} {type {}} {error_name error} {isSafe 1}} { upvar $error_name error global Httpd set sock $Httpd(currentSocket) # fetch cookies pertaining to session set old 0 foreach {key var} {session session session_sequence sequence} { set x [Cookie_GetSock $sock ${type}_$key] if {$x != ""} { incr old lappend querylist $var [lindex $x 0] } } # try to find an existing or saved session set error "" array set query $querylist set id [Session_Match [array get query] $type error $isSafe] # we must have lost the old session. lose the cookies and try again if {$error == "Session: Invalid session id."} { set query(session) new set error "" set id [Session_Match [array get query] $type error $isSafe] set old 0 } # set the session cookies if {!$old} { global Session upvar #0 Session:$id session foreach {key var} {session id session_sequence session(sequence) session_type session(type)} { if {[info exists $var]} { Httpd_SetCookie $sock [Cookie_Make -expires $Session(expires) -path / -name ${type}_$key -value [set $var]] 1 } } } # we accept an additional session_cmd argument to manipulate sessions if {[info exists query(session_cmd)]} { switch $query(session_cmd) { save { Session_Save $id } } } return $id } # Create and return the session directory for saved sessions proc SessionDir {} { if {![info exists Session(dir)]} { # I'm not keen on this default location, as it could # be exposed to URL fetches set Session(dir) [file join [Doc_Root] .sessions] } file mkdir $Session(dir) return $Session(dir) } # Destroy the session cookie for this type # note, this won't take immediate effect, # you may have to reload the page to get the new cookies proc Session_CookieDestroy {{type {}}} { global Httpd set sock $Httpd(currentSocket) foreach key {session session_sequence} { Httpd_RemoveCookies $sock ${type}_* } } # Save session state in a file under $Session(dir), # for later reconstruction proc Session_Save {id} { upvar #0 Session:$id session # create a session save file, write state set sfile [file join [SessionDir] ${id}.sess] set fd [open $sfile w] puts $fd $session(type) puts $fd [interp issafe interp$id] puts $fd [array get session] # add Self Vars set vars "" set arrays "" foreach sv [interp eval $session(interp) info vars] { switch -regexp -- $sv { tcl_* - env - errorCode - errorInfo - arg[cv] - auto_* {} default { if {[interp eval $session(interp) array exists $sv]} { append arrays "array set $sv [list [interp eval $session(interp) array get $sv]]" \n } else { append vars "set $sv [list [interp eval $session(interp) set $sv]]" \n } } } } puts $fd $vars puts $fd $arrays close $fd } # SessionDiscard - destroy persistent record of session $id proc SessionDiscard {id} { set sfile [file join [SessionDir] ${id}.sess] if {[file exists $sfile]} { # delete the session save file file delete $sfile } } # SessionFetch - fetch persistent record of session $id proc SessionFetch {id} { upvar #0 Session:$id session set sfile [file join [SessionDir] ${id}.sess] if {[file exists $sfile]} { # open a session save file, read state set fd [open $sfile r] set type [gets $fd] set isSafe [gets $fd] set sarray [gets $fd] set script [read $fd] close $fd # create the interpreter Session_CreateWithID $type $id $isSafe array set session $sarray ;# set session vars interp eval $session(interp) $script # consistency check if {$type != {} && $type != $session(type)} { return "Session: Invalid session type." } return "" } else { # there's no stored session return "Session: Invalid session id." } } # Find the correct session, and return the proper interp or error. # If the session is "new", then create a new one. # - query: The array containing the form and/or url query # session: Either an ID or "new". # an ID will return that ID to confirm that the session is valid # or will return an empty string if session is invalid. # "new" will create a new session. # sequence: Sequence position if this is a sequential set of pages. # - type: The type of this session # - error_name: The variable holding the error result (if any) # - isSafe: True to create a safe interp, false for normal. proc Session_Match {querylist {type {}} {error_name error} {isSafe 1}} { upvar $error_name error # Check the session informatioin provided in the query data. if {[catch { array set query $querylist }]} { Stderr "Bogus querylist\n$querylist" } if {![info exists query(session)]} { set error "Session: no session id provided." return {} } set id $query(session) if {$id == "new"} { set id [Session_Create $type $isSafe] } elseif {[regexp "kill(.+)" $id x id]} { Session_Destroy $id set id [Session_Create $type $isSafe] } elseif {[regexp "save(.+)" $id x id]} { Session_Save $id } upvar #0 Session:$id session if {![array exists session]} { # see if there's a session to be instantiated set error [SessionFetch $id] if {$error != ""} { return {} } } else { # session's already instantiated } # Check sequence number (if any). if {[info exists session(sequence)]} { if {![info exists query(sequence)]} { set error "Session: Sequence number required, not provided." return $id } if {$query(sequence) != $session(sequence)} { set error "Session: Sequence number invalid." return $id } unset session(sequence) } # Update the session access time and count, and return the session id. set session(current) [clock seconds] incr session(count) return $id } # Import variables from a global array into the local scope. # valid: The array containing the legal values to import. If valid # is {}, then all names in "array" will be imported. # array: The name of the global array in "Interp" to import from. # Interp: The interpreter to import it from. proc Session_Import {valid array {interp {}}} { upvar $valid ok foreach {name value} [interp eval $interp [list array get $array]] { if {$valid == {} || [info exists ok(-$name)]} { upvar $name var set var $value } } } ################################### # Common Aliases for interpreters # Return the (constant) session id. The id is a constant created at # alias time. proc Session_Session {arg} { return $arg } # set up a sequence number. Id is the session id, passed in at alias time. proc Session_Sequence {id} { upvar #0 Session:$id session set session(sequence) $session(count) } # Set or return a session variable. The slave alias may be set up to allow # read access only. proc Session_Variable {id var {value ""}} { upvar #0 Session:$id state if {$value != {}} { set state($var) $value } if {[info exists state($var)]} { return $state($var) } else { return "" } } # Get a group variable, specify a default if not set proc Session_Value {id var {default {}}} { upvar #0 Session:$id session set group $session(group) if {[catch {interp eval $session(interp) set ${group}($var)} value]} { set value $default } return $value } |
Added modules/httpd/srvui.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # srvui.tcl # Trivial Tk control panel for the server. # # Brent Welch (c) 1997 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: srvui.tcl,v 1.9 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::srvui 1.0 package require httpd ;# Httpd_Shutdown package require httpd::counter ;# Count CountVarName package require httpd::utils ;# file proc SrvUI_Init {title} { global Httpd Doc option add *font 9x15 wm title . $Httpd(name):$Httpd(port) wm protocol . WM_DELETE_WINDOW {Httpd_Shutdown; exit} wm iconname . $Httpd(name):$Httpd(port) set msgText "$title\n$Httpd(name):$Httpd(port)" if {[info exists Httpd(https_listen)]} { append msgText "\n$Httpd(name):$Httpd(https_port) (Secure Server)" } append msgText "\n$Doc(root)" message .msg -text $msgText -aspect 1000 grid .msg -columnspan 2 -sticky news foreach {url label} { / "Home Page" } { label .l$url -text $label label .n$url -textvariable counterhit($url) -width 0 grid .l$url .n$url -sticky w grid configure .n$url -sticky e } foreach {counter label} { urlhits "URL Requests" urlreply "URL Replies" cgihits "CGI Hits" maphits "Image Map Hits" errors "Errors" } { label .l$counter -text $label label .n$counter -textvariable [CountVarName $counter] -width 0 grid .l$counter .n$counter -sticky w grid configure .n$counter -sticky e } # Expose webmaster and debug passwords foreach {varname label} { webmaster_password "webmaster Password" DebugPassword "debug Password" } { label .l$varname -text $label label .n$varname -textvariable $varname -width 0 grid .l$varname .n$varname -sticky w grid configure .n$varname -sticky e } button .quit -text Quit -command {Httpd_Shutdown ; exit} grid .quit -columnspan 2 } |
Added modules/httpd/status.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | # status.tcl -- # # Application-direct URLs to give out status of the server. # Tcl procedures of the form Status/hello implement URLS # of the form /status/hello # # Brent Welch (c) Copyright 1997 Sun Microsystems, Inc. # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: status.tcl,v 1.29 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::status 1.0 package require httpd ;# Httpd_ReturnData Httpd_ReturnFile package require httpd::counter ;# Count Counter_StartTime package require httpd::direct ;# Direct_Url package require httpd::log ;# Log package require httpd::subst ;# Subst_ReturnFile package require httpd::threadmgr ;# Thread_Enabled Thread_Id Thread_IsFree Thread_List Thread_Send Thread_SendAsync package require httpd::url ;# Url_Decode Url_DecodeQuery Url_Dispatch package require httpd::utils ;# K file setmax proc Status_Url {dir {imgdir /images}} { global _status set _status(dir) $dir set _status(images) $imgdir Direct_Url $dir Status } # Status/hello -- # # Show the string "hello". # # Arguments: # args arguments are ignored. # # Results: # Returns the string "hello". proc Status/hello {args} {return hello} # StatusHeader -- # # Standard HTML header for status pages. # # Arguments: # title - also used as <h1> # # Results: # Html for head and <body> proc StatusHeader {title} { return "<html><head> <title>$title</title> </head> <body bgcolor=white text=black> <h1>$title</h1> " } # Status/threads -- # # Show the list of threads running in the server. # # Arguments: # args arguments are ignored. # # Results: # Returns the list of threads running in the server. proc Status/threads {args} { append html [StatusHeader "Thread List"] append html [StatusMenu]\n if {[catch {Thread_List} x]} { append html "No thread support\n" } else { append html $x } return $html } proc StatusSortForm {action label {pattern *} {sort number}} { if {[string compare $sort "number"] == 0} { set numcheck checked set namecheck "" } else { set numcheck "" set namecheck checked } append result "<form action=$action>" append result "Pattern <input type=text name=pattern value=$pattern><br>" append result "Sort by $label <input type=radio name=sort value=number $numcheck> or Name <input type=radio name=sort value=name $namecheck><br>" append result "<input type=submit name=submit value=\"Again\">" append result "</form>" } proc StatusMenu {} { global _status set sep "" set html "<p>\n" foreach {url label} [list \ / "Home" \ $_status(dir)/ "Graphical Status" \ $_status(dir)/text "Text Status" \ $_status(dir)/domain "Domains" \ $_status(dir)/doc "Documents" \ $_status(dir)/notfound "Not Found" \ $_status(dir)/threads "Threads" \ $_status(dir)/size "Memory Size" \ ] { append html "$sep<a href=$url>$label</a>\n" set sep " | " } append html "</p>\n" return $html } # Status/doc -- # # Show the number of hits for documents matching the pattern. # # Arguments: # pattern (optional) the glob pattern of the URL to report on. # sort (optional) how to sort the output. If the default "number" is # not given, output is sorted by url alphabetically. # # Results: # Returns HTML code that displays document hit info. proc Status/doc {{pattern *} {sort number}} { global _status set result "" append result [StatusHeader "Document Hits"] append result [StatusMenu] append result [StatusSortForm $_status(dir)/doc "Hit Count" $pattern $sort] append result [StatusPrintArray [counter::get hit -histVar] * $sort Hits Url] } # Status/domain -- # # Show the number of hits for documents in different domains. # # Arguments: # pattern (optional) the glob pattern of the domain to report on. # sort (optional) how to sort the output. If the default "number" is # not given, output is sorted by url alphabetically. # # Results: # Returns HTML code that displays document hit info. proc Status/domain {{pattern *} {sort number}} { global _status set result "" append result [StatusHeader "Domain Hits"] append result [StatusMenu] append result [StatusSortForm $_status(dir)/domain "Hit Count" $pattern $sort] append result [StatusPrintArray [counter::get domainHit -histVar] * $sort Hits Domain] } proc StatusPrintArray {aname pattern sort col1 col2} { upvar #0 $aname a set result "" append result <pre>\n append result [format "%6s %s\n" $col1 $col2] set list {} set total 0 foreach name [lsort [array names a $pattern]] { set value $a($name) lappend list [list $value $name] incr total $value } if {[string compare $sort "number"] == 0} { if {[catch {lsort -index 0 -integer -decreasing $list} newlist]} { set newlist [lsort -command StatusSort $list] } } else { if {[catch {lsort -index 1 -integer -decreasing $list} newlist]} { set newlist [lsort -command StatusSortName $list] } } append result [format "%6d %s\n" $total Total] foreach k $newlist { set url [lindex $k 1] append result [format "%6d %s\n" [lindex $k 0] $url] } append result </pre>\n return $result } proc StatusSort {a b} { set 1 [lindex $a 0] set 2 [lindex $b 0] if {$1 == $2} { return [string compare $a $b] } elseif {$1 < $2} { return 1 } else { return -1 } } proc StatusSortName {a b} { set 1 [lindex $a 1] set 2 [lindex $b 1] return [string compare $1 $2] } # Status/notfound -- # # Show the number of hits for nonexistent documents matching the pattern. # # Arguments: # pattern (optional) the glob pattern of the URL to report on. # sort (optional) how to sort the output. If the default "number" is # not given, output is sorted by url alphabetically. # # Results: # Returns HTML code that displays document hit info for docs that were # not found. proc Status/notfound {{pattern *} {sort number}} { global Doc Referer _status set result "" append result [StatusHeader "Documents Not Found"] append result [StatusMenu] append result [StatusSortForm $_status(dir)/notfound "Hit Count" $pattern $sort] append result [StatusPrintNotFound $pattern $sort] } proc StatusPrintNotFound {{pattern *} {sort number}} { global Doc Referer _status upvar #0 [counter::get notfound -histVar] histogram append result <pre>\n append result [format "%6s %s\n" Miss Url] set list {} foreach i [lsort [array names histogram $pattern]] { lappend list [list $histogram($i) $i] } if {[catch {lsort -index 0 -integer -decreasing $list} newlist]} { set newlist [lsort -command StatusSort $list] } foreach k $newlist { set url [lindex $k 1] append result [format "%6d <a href=%s>%s</a>\n" \ [lindex $k 0] [lindex $k 1] [lindex $k 1]] if {[info exists Referer($url)]} { set i 0 append result <ul> foreach r $Referer($url) { append result "<li> <a href=\"$r\">$r</a>\n" } append result </ul>\n } } append result </pre>\n # append result "<a href=$_status(dir)/notfound/reset>Reset counters</a>" return $result } # Status/notfound/reset -- # # Reset the number of hits for nonexistent documents to 0. # # Arguments: # args arguments are ignored. # # Results: # Returns HTML code that confirms that the reset occurred. proc Status/notfound/reset {args} { global Referer counter::reset notfound catch {unset Referer} return [StatusHeader "Reset Notfound Counters"] } # Status/size -- # # Show both the code size and data size. # # Arguments: # args arguments are ignored. # # Results: # Returns HTML. proc Status/size {args} { global StatusDataSize StatusCodeSize append top_html [StatusHeader "Memory Size"] append top_html [StatusMenu]\n append html [Status/datasize]\n append html [Status/codesize]\n append top_html "<h2>Grand Total</h3>" append top_html "Bytes [expr $StatusDataSize(bytes) + $StatusCodeSize(bytes)]" return $top_html$html } # Status/datasize -- # # Show the data size for the entire server or for a particular namespace. # # Arguments: # ns (optional) if given, show the data size for this namespace # # Results: # Returns HTML. proc Status/datasize {{ns ::}} { global StatusDataSize array set StatusDataSize { vars 0 values 0 bytes 0 } append html [StatusHeader "Data Size"] append html [StatusDataSize $ns] append top_html "<h2>Total Data Size</h2>\n Num Variables $StatusDataSize(vars)<br>\n\ Num Values $StatusDataSize(values)<br>\n\ Data Bytes $StatusDataSize(bytes)" return $top_html$html } proc StatusDataSize {ns} { global StatusDataSize set ng 0 set nv 0 set size 0 foreach g [info vars ${ns}::*] { incr ng if {[array exists $g]} { foreach {name value} [array get $g] { set size [expr {$size + [string length $name] + [string length $value]}] incr nv } } elseif {[info exist $g]} { # info vars returns declared but undefined namespace vars set size [expr {$size + [string length $g] + [string length [set $g]]}] incr nv } } set html "<h3>$ns</h3>\n\ Num Variables $ng<br>\n\ Num Values $nv<br>\n\ Data Bytes $size" incr StatusDataSize(vars) $ng incr StatusDataSize(values) $nv incr StatusDataSize(bytes) $size append html "<ul>" foreach child [namespace children $ns] { append html [StatusDataSize $child] } append html "</ul>" return $html } # Status/codesize -- # # Show the code size for the entire server or for a particular namespace. # # Arguments: # ns (optional) if given, show the code size for this namespace # # Results: # Returns HTML. proc Status/codesize {{ns ::}} { global StatusCodeSize array set StatusCodeSize { procs 0 bytes 0 } set html [StatusHeader "Code Size"] append html [StatusCodeSize $ns] append top_html "<h2>Total Code Size</h2>\n Num Procs $StatusCodeSize(procs)<br>\n\ Code Bytes $StatusCodeSize(bytes)" return $top_html$html } proc StatusCodeSize {{ns ::}} { global StatusCodeSize set np 0 set size 0 foreach g [info procs ${ns}::*] { incr np set size [expr {$size + [string length $g] + [string length [info args $g]] + [string length [info body $g]]}] } set html "<h3>$ns</h3>\n\ Num Procs $np<br>\n\ Code Bytes $size" incr StatusCodeSize(procs) $np incr StatusCodeSize(bytes) $size append html "<ul>" foreach child [namespace children $ns] { append html [StatusCodeSize $child] } append html "</ul>" } # StatusMainTable -- # # Display the main status counters. This gathers information # from worker threads, if possible. # # Arguments # None # # Results # Html proc StatusMainTable {} { global Httpd Doc status tcl_patchLevel tcl_platform Thread global StatusThreadTable set html "<H1>$Httpd(name):$Httpd(port)</h1>\n" append html "<H2>Server Info</h2>" append html "<table border=0>" append html "<tr><td>Start Time</td><td>[clock format [Counter_StartTime]]</td></tr>\n" append html "<tr><td>Current Time</td><td>[clock format [clock seconds]]</td></tr>\n" append html "<tr><td>Server</td><td>$Httpd(server)</td></tr>\n" append html "<tr><td>Tcl Version</td><td>$tcl_patchLevel</td></tr>" switch $tcl_platform(platform) { unix { append html "<tr><td colspan=2>[exec uname -a]</td></tr>" } macintosh - windows { append html "<tr><td colspan=2>$tcl_platform(os) $tcl_platform(osVersion)</td></tr>" } } append html </table> append html "<br><br><br>\n" append html "<p>[StatusTable]<p>\n" # Per thread stats if {[Thread_Enabled]} { set self [Thread_Id] foreach id [lsort -integer [Thread_List]] { if {$id == $self} { continue } append html "<h4>Thread $id</h4>\n" global counter_thread_$id if {[Thread_IsFree $id]} { set StatusThreadTable($id) \ [Thread_Send $id StatusTable] } else { # Use cached version of the other threads counters, # but update our stats for next time. append html "<i>busy, using cached values</i>\n" Thread_SendAsync $id [list StatusThreadUpdate $id $self] } if {[info exist StatusThreadTable($id)]} { append html $StatusThreadTable($id) } } } return $html } proc StatusThreadUpdate {self master} { Thread_SendAsync $master [list array set ::counter_thread_$self \ [array get ::counter]] } proc StatusTable {} { append html "<table bgcolor=#eeeeee>\n" set hit 0 foreach {c label} { / "Home Page Hits" } { set N [counter::get hit -hist $c] if {$N > 0} { append html "<tr><td>$label</td><td>$N</td>\n" set hit 1 append html </tr>\n } } foreach {c label} { urlhits "URL Requests" Url_Dispatch "URL Dispatch" UrlToThread "Thread Dispatch" UrlEval "Direct Dispatch" UrlCacheHit "UrlCache eval" urlreply "URL Replies" accepts "Total Connections" accept_https "HTTPS Connections" keepalive "KeepAlive Requests" http1.0 "OneShot Connections" http1.1 "Http1.1 Connections" threads "Worker Threads" sockets "Open Sockets" cgihits "CGI Hits" tclhits "Tcl Safe-CGIO Hits" maphits "Image Map Hits" cancel "Timeouts" notfound "Not Found" errors "Errors" Status "Status" } { if {[counter::exists $c]} { set t [counter::get $c -total] if {$t > 0} { append html "<tr><td>$label</td><td>$t</td>\n" set hit 1 set resetDate [counter::get $c -resetDate] if {[string length $resetDate]} { append html "<td>[clock format $resetDate -format "%B %d, %Y"]</td>" } append html </tr>\n } } } if {!$hit} { foreach c [counter::get "" -allTagNames] { append html "<tr><td>$name</td><td>[counter::get $c -total]</td>\n" set resetDate [counter::get $c -resetDate] if {[string length $resetDate]} { append html "<td>[clock format $resetDate -format "%B %d, %Y"]</td>" } append html </tr>\n } } append html </table>\n return $html } proc StatusTclPower {{align left}} { global _status set html "<img src=$_status(images)/pwrdLogo150.gif align=$align width=97 height=150>\n" } # Status/all -- # # Show the page hist per minute, hour, and day using images. # # Arguments: # args arguments are ignored # # Results: # Returns HTML. proc Status/all {args} { global _status page set html [StatusHeader "Tcl HTTPD Status"] append html [StatusMenu] append html [StatusTclPower left] append html [StatusMainTable] append html "<br><a href=/status/text>Text only view.</a>\n" append html "<p>\n<table border=0 cellpadding=0 cellspacing=0>\n" append html [counter::histHtmlDisplayRow serviceTime \ -title "Service Time" -unit seconds \ -width 1 -skip 10 -min 0 -max 400 \ -images $_status(images)] append html [counter::histHtmlDisplayRow urlhits \ -title "Url Hits" -unit minutes \ -min 0 -max 60 \ -images $_status(images)] append html [counter::histHtmlDisplayRow urlhits \ -title "Url Hits" -unit hours \ -min 0 -max 24 \ -images $_status(images)] append html [counter::histHtmlDisplayRow urlhits \ -title "Url Hits" -unit days \ -images $_status(images)] append html </table> return $html } # Status/text -- # # Show the page hist per minute, hour, and day in text format. # # Arguments: # args arguments are ignored # # Results: # Returns HTML. proc Status/text {args} { global _status set html [StatusHeader "Tcl HTTPD Status"] append html [StatusMenu] append html [StatusTclPower left] append html [StatusMainTable] append html "<p><a href=$_status(dir)/all>Bar Chart View.</a>" catch { append html [counter::histHtmlDisplay serviceTime \ -title "Service Time" -unit seconds -max 100 -text 1] } catch { append html [counter::histHtmlDisplay urlhits \ -title "Per Minute Url Hits" -unit minutes -text 1] append html [counter::histHtmlDisplay urlhits \ -title "Hourly Url Hits" -unit hours -text 1] append html [counter::histHtmlDisplay urlhits \ -title "Daily Url Hits" -unit days -text 1] } return $html } # Status/ -- # # Same as Status/all. # # Arguments: # args arguments are ignored # # Results: # Returns HTML. proc Status/ {args} { Status/all {*}$args } # Status -- # # Same as Status/all. # # Arguments: # args arguments are ignored # # Results: # Returns HTML. proc Status {args} { Status/all {*}$args } proc Version {} { global tcl_patchLevel Httpd append html "$Httpd(server)" append html "<br>Tcl version $tcl_patchLevel" return $html } # NOTUSED proc StatusTimeText {array title unit what time} { global counter upvar #0 $array data regsub ^Cnt $array Age agebitName upvar #0 $agebitName agebit set total 0 set max 0 set base 100 foreach {name value} [array get data] { setmax max $value } switch $unit { Min {set delta 60 ; set fmt %R} Hour {set delta 3600 ; set fmt "%h %e %R"} Day {set delta 86400 ; set fmt %D} } append result "<h3>$title ($max max)</h3>" append result <ul> append result "<h4>Starting at [clock format $time]</h4>" append result "<table cellpadding=2 cellspacing=2 border><tr>\n" append result "<tr><th>$unit</th><th>$what</th></tr>" foreach t [lsort -integer [array names data]] { set value $data($t) # Minutes time we infer from the starting time and the agebits, # which indicate minute buckets for the previous hour. if {[info exists agebit($t)]} { set tt [expr $time - 3600] } else { set tt $time } # Hours have their own base time in counter(hour,$hour) if {$unit == "Hour"} { set tt $counter(hour,$t) } # Wrap separator if {[info exists lasttime] && ($lasttime > $tt)} { append result "<tr><td><hr></td><td><hr></td></tr>" } set lasttime $tt append result "<tr><td>[clock format $tt -format $fmt]</td><td>$value</td></tr>" incr time $delta } append result "</table>" append result </ul> return $result } # Handle .stat templates. (NOTUSED) # First process the incoming form data in an Status-specific way, # then do a normal Subst into a safe interpreter # path: The path name of the document # suffix: The file suffix # sock: The name of the socket, and a handle for the socket state # It turns out this is not used, but you could use it as a template # for your own application's template processor. proc Doc_application/x-tcl-status {path suffix sock} { global status upvar #0 Httpd$sock data append data(query) "" set queryList [Url_DecodeQuery $data(query)] # Put the query data into an array. # If a key appears multiple times, the resultant array value will # be a list of all the values. foreach {name value} $queryList { lappend query($name) $value } if {![info exists status(session)]} { set status(session) [session_create Status] } # Process the query data from the previous page. if {[catch {StatusProcess $session $queryList} result]} { Httpd_ReturnData $sock text/html $result return } # Expand the page in the correct session interpreter, or treat # the page as ordinary html if the session has ended. if {$result} { Subst_ReturnFile $sock $path interp$session } else { Httpd_ReturnFile $sock text/html $path } } if {0} { proc StatusPrintHits {aname {pattern *} {sort number}} { append result [StatusPrintArray [counter::get hit -histVar] *\ $sort Hits Url] } } |
Added modules/httpd/stdin.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # stdin.tcl # # (c) 1997 Sun Microsystems Laboratories (Stephen Uhler) # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: stdin.tcl,v 1.5 2004/10/22 03:43:06 coldstore Exp $ # The following is an event-driven command loop for testing with tclsh # with command history: # !<pattern> run 1st command matching pattern # !<pattern>/xxx/yyy/ as above, but substitute yyy for xxx # Nb: history doesn't work, too many changes to the tcl api to track. package provide httpd::stdin 1.1 package require httpd::log ;# Log Log_Flush #package require httpd::utils ;# file set Stdin(maxHistory) 100 append Stdin(history) {} proc StdinRead {prompt} { global Stdin if {[eof stdin]} { set Stdin(Wait) 1 fileevent stdin readable {} return } append Stdin(command) [gets stdin] if {[info complete $Stdin(command)]} { set s1 ""; set s2 "" if {[regexp {^!([^/]+)(/([^/]+)/([^/]*))?} $Stdin(command) \ {} history {} s1 s2]} { set match [lsearch -regexp $Stdin(history) "^ *$history"] if {$match >= 0} { set Stdin(command) [lindex $Stdin(history) $match] if {$s1 != ""} { catch {regsub -- $s1 $Stdin(command) $s2 Stdin(command)} } puts stderr $Stdin(command) } else { puts -nonewline "No \"$history\" in history list\n$prompt" set Stdin(command) "" flush stdout return } } if {$Stdin(command) != "" && \ $Stdin(command) != [lindex $Stdin(history) 0]} { set Stdin(history) [lrange "[list $Stdin(command)] \ $Stdin(history)" 0 $Stdin(maxHistory)] } catch {uplevel #0 $Stdin(command)} result puts -nonewline "$result\n$prompt" flush stdout set Stdin(command) "" } else { append Stdin(command) \n } } proc Stdin_Start {{prompt "% "}} { global Stdin set Stdin(command) "" puts -nonewline $prompt flush stdout fileevent stdin readable [list StdinRead $prompt] vwait Stdin(wait) } if {[info procs bgerror] == ""} { proc bgerror {args} { global errorInfo Log {} bgerror $errorInfo ; Log_Flush puts stderr $errorInfo } } |
Added modules/httpd/subst.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | # subst.tcl #@c Subst support # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: subst.tcl,v 1.10 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::subst 1.0 package require httpd ;# Httpd_RequestAuth Httpd_ReturnData package require httpd::cgi ;# Cgi_SetEnv package require httpd::session ;# Session_Authorized #package require httpd::utils ;# file # Subst_ReturnFile -- # # Subst a file and return the result to the HTTP client. # Note that ReturnData has no Modification-Date so the result is not cached. # # Arguments: # sock The socket connection. # path The template file pathname. # interp The Tcl intepreter in which to subst. # # Results: # None # # Side Effects: # Returns a page to the client. proc Subst_ReturnFile {sock path {interp {}}} { Httpd_ReturnData $sock text/html [Subst_File $path $interp] } # SubstCleanScope -- # # Substitute the data in this clean (no vars set) scope. # # Arguments: # _html_data The data to substitute. # # Results: # The subst'ed data. # # Side Effects: # None proc SubstCleanScope {_html_data} { return [subst $_html_data] } # Subst_Scope -- # # When processing templates in the current interpreter, decide whether to # use the global or local scope (that of DocSubst) to process templates. # # Arguments: # scope 0 means global and non-zero means local. # # Results: # None # # Side Effects: # Sets the scope for all Doc domain substs. proc Subst_Scope {scope} { global Subst set Subst(templateScope) $scope } if {![info exists Subst(templateScope)]} { set Subst(templateScope) 0 } # SubstFile -- # # Subst a file in an interpreter context. If no interp is given, use the # current interp. If using the current interp, use the scope # variable to decide whether to use the global or current scope. # # Arguments: # path The file pathname of the template. # interp The interpreter in which to subst. # # Results: # The subst'ed page. # # Side Effects: # None proc SubstFile {path {interp {}}} { global Subst set in [open $path] set script [read $in] close $in if {[string length $interp] == 0} { # Substitution occurs in the current interp. if {$Subst(templateScope) == 0} { # Substitution occurs at the global level. set result [uplevel #0 [list subst $script]] } else { # Substitution occurs at a clean level, one-off from global. set result [uplevel [list SubstCleanScope $script]] } } else { # Substitution occurs in the given interp. set result [interp eval $interp [list subst $script]] } # Perform the post-processing of the output, as installed via Subst_Install. foreach hook $Subst(substHooks) { set result [$hook $result] } return $result } # Subst_File -- # # Subst a file or directory in an interpreter context. # As SubstFile except that a path which is a directory is evaluated # by evaluating a file $path/index.tml, and returning that as the substituted # value of the $path directory. # proc Subst_File {path {interp {}}} { global Subst switch [file type $path] { file { return [uplevel 1 [list SubstFile $path $interp]] } link { set link [file readlink $path] if {[file pathtype $link] == "relative"} { set link [file join [file dirname $path] $link] } return [uplevel 1 [list Subst_File $link $interp]] } directory { return [uplevel 1 [list SubstFile [file join $path index.tml] $interp]] } default { error "Can't process [file type $path] files." } } } # Subst_Install # # Install a subst hook. Each installed hook will be performed over the # substituted template. # # Arguments # proc This is a command prefix that is invoked with one additional # arguments to process: # text The text to process. # The subst hook returns the HTML that will be returned by the server. # # Results: # None # # Side Effects # Save the subst hook. proc Subst_Install {proc} { global Subst if {[lsearch $Subst(substHooks) $proc] < 0} { lappend Subst(substHooks) $proc } return } if {![info exist Subst(substHooks)]} { set Subst(substHooks) {} } # Doc_application/x-tcl-auth -- # # Like tcl-subst, but a basic authentication cookie is used for session state # # Arguments: # path The file pathname. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Returns a page to the client. proc Doc_application/x-tcl-auth {path suffix sock} { upvar #0 Httpd$sock data if {![info exists data(session)]} { Httpd_RequestAuth $sock Basic "Random Password" return } set interp [Session_Authorized $data(session)] # Need to make everything look like a GET so the Cgi parser # doesn't read post data from stdin. We've already read it. set data(proto) GET Doc_application/x-tcl-subst $path $suffix $sock } # Doc_application/x-tcl-subst -- # # Tcl-subst a template that mixes HTML and Tcl. # This subst is just done in the context of the specified # interpreter with not much other support. # See x-tcl-template for something more sophisticated # # Arguments: # path The file pathname. # suffix The URL suffix. # sock The socket connection. # interp The interp to use for subst'ing. # # Results: # None # # Side Effects: # Sets the env array in interp and calls Subst_ReturnFile. proc Doc_application/x-tcl-subst {path suffix sock {interp {}}} { upvar #0 Httpd$sock data Cgi_SetEnv $sock $path pass interp eval $interp [list uplevel #0 [list array set env [array get pass]]] Subst_ReturnFile $sock $path $interp } |
Added modules/httpd/tclcrypt.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 | # tclcrypt.tcl # # Unix crypt in pure tcl # From http://mini.net/tcl/crypt by Michael A. Cleverly (23/Nov/2000) # # Used as a fallback for installations without libcrypt.so compiled. # It's always better to have the compiled C version available, of course # This package provides two implementations of crypt, and will choose # the fastest possible depending upon Tcl version package provide tclcrypt 1.0 proc crypt {password salt} { array set IP { 0 58 1 50 2 42 3 34 4 26 5 18 6 10 7 2 8 60 9 52 10 44 11 36 12 28 13 20 14 12 15 4 16 62 17 54 18 46 19 38 20 30 21 22 22 14 23 6 24 64 25 56 26 48 27 40 28 32 29 24 30 16 31 8 32 57 33 49 34 41 35 33 36 25 37 17 38 9 39 1 40 59 41 51 42 43 43 35 44 27 45 19 46 11 47 3 48 61 49 53 50 45 51 37 52 29 53 21 54 13 55 5 56 63 57 55 58 47 59 39 60 31 61 23 62 15 63 7} array set FP { 0 40 1 8 2 48 3 16 4 56 5 24 6 64 7 32 8 39 9 7 10 47 11 15 12 55 13 23 14 63 15 31 16 38 17 6 18 46 19 14 20 54 21 22 22 62 23 30 24 37 25 5 26 45 27 13 28 53 29 21 30 61 31 29 32 36 33 4 34 44 35 12 36 52 37 20 38 60 39 28 40 35 41 3 42 43 43 11 44 51 45 19 46 59 47 27 48 34 49 2 50 42 51 10 52 50 53 18 54 58 55 26 56 33 57 1 58 41 59 9 60 49 61 17 62 57 63 25} array set PC1_C { 0 57 1 49 2 41 3 33 4 25 5 17 6 9 7 1 8 58 9 50 10 42 11 34 12 26 13 18 14 10 15 2 16 59 17 51 18 43 19 35 20 27 21 19 22 11 23 3 24 60 25 52 26 44 27 36} array set PC1_D { 0 63 1 55 2 47 3 39 4 31 5 23 6 15 7 7 8 62 9 54 10 46 11 38 12 30 13 22 14 14 15 6 16 61 17 53 18 45 19 37 20 29 21 21 22 13 23 5 24 28 25 20 26 12 27 4} array set shifts { 0 1 1 1 2 2 3 2 4 2 5 2 6 2 7 2 8 1 9 2 10 2 11 2 12 2 13 2 14 2 15 1} array set PC2_C { 0 14 1 17 2 11 3 24 4 1 5 5 6 3 7 28 8 15 9 6 10 21 11 10 12 23 13 19 14 12 15 4 16 26 17 8 18 16 19 7 20 27 21 20 22 13 23 2} array set PC2_D { 0 41 1 52 2 31 3 37 4 47 5 55 6 30 7 40 8 51 9 45 10 33 11 48 12 44 13 49 14 39 15 56 16 34 17 53 18 46 19 42 20 50 21 36 22 29 23 32} array set e { 0 32 1 1 2 2 3 3 4 4 5 5 6 4 7 5 8 6 9 7 10 8 11 9 12 8 13 9 14 10 15 11 16 12 17 13 18 12 19 13 20 14 21 15 22 16 23 17 24 16 25 17 26 18 27 19 28 20 29 21 30 20 31 21 32 22 33 23 34 24 35 25 36 24 37 25 38 26 39 27 40 28 41 29 42 28 43 29 44 30 45 31 46 32 47 1} array set S { 0,0 14 0,1 4 0,2 13 0,3 1 0,4 2 0,5 15 0,6 11 0,7 8 0,8 3 0,9 10 0,10 6 0,11 12 0,12 5 0,13 9 0,14 0 0,15 7 0,16 0 0,17 15 0,18 7 0,19 4 0,20 14 0,21 2 0,22 13 0,23 1 0,24 10 0,25 6 0,26 12 0,27 11 0,28 9 0,29 5 0,30 3 0,31 8 0,32 4 0,33 1 0,34 14 0,35 8 0,36 13 0,37 6 0,38 2 0,39 11 0,40 15 0,41 12 0,42 9 0,43 7 0,44 3 0,45 10 0,46 5 0,47 0 0,48 15 0,49 12 0,50 8 0,51 2 0,52 4 0,53 9 0,54 1 0,55 7 0,56 5 0,57 11 0,58 3 0,59 14 0,60 10 0,61 0 0,62 6 0,63 13 1,0 15 1,1 1 1,2 8 1,3 14 1,4 6 1,5 11 1,6 3 1,7 4 1,8 9 1,9 7 1,10 2 1,11 13 1,12 12 1,13 0 1,14 5 1,15 10 1,16 3 1,17 13 1,18 4 1,19 7 1,20 15 1,21 2 1,22 8 1,23 14 1,24 12 1,25 0 1,26 1 1,27 10 1,28 6 1,29 9 1,30 11 1,31 5 1,32 0 1,33 14 1,34 7 1,35 11 1,36 10 1,37 4 1,38 13 1,39 1 1,40 5 1,41 8 1,42 12 1,43 6 1,44 9 1,45 3 1,46 2 1,47 15 1,48 13 1,49 8 1,50 10 1,51 1 1,52 3 1,53 15 1,54 4 1,55 2 1,56 11 1,57 6 1,58 7 1,59 12 1,60 0 1,61 5 1,62 14 1,63 9 2,0 10 2,1 0 2,2 9 2,3 14 2,4 6 2,5 3 2,6 15 2,7 5 2,8 1 2,9 13 2,10 12 2,11 7 2,12 11 2,13 4 2,14 2 2,15 8 2,16 13 2,17 7 2,18 0 2,19 9 2,20 3 2,21 4 2,22 6 2,23 10 2,24 2 2,25 8 2,26 5 2,27 14 2,28 12 2,29 11 2,30 15 2,31 1 2,32 13 2,33 6 2,34 4 2,35 9 2,36 8 2,37 15 2,38 3 2,39 0 2,40 11 2,41 1 2,42 2 2,43 12 2,44 5 2,45 10 2,46 14 2,47 7 2,48 1 2,49 10 2,50 13 2,51 0 2,52 6 2,53 9 2,54 8 2,55 7 2,56 4 2,57 15 2,58 14 2,59 3 2,60 11 2,61 5 2,62 2 2,63 12 3,0 7 3,1 13 3,2 14 3,3 3 3,4 0 3,5 6 3,6 9 3,7 10 3,8 1 3,9 2 3,10 8 3,11 5 3,12 11 3,13 12 3,14 4 3,15 15 3,16 13 3,17 8 3,18 11 3,19 5 3,20 6 3,21 15 3,22 0 3,23 3 3,24 4 3,25 7 3,26 2 3,27 12 3,28 1 3,29 10 3,30 14 3,31 9 3,32 10 3,33 6 3,34 9 3,35 0 3,36 12 3,37 11 3,38 7 3,39 13 3,40 15 3,41 1 3,42 3 3,43 14 3,44 5 3,45 2 3,46 8 3,47 4 3,48 3 3,49 15 3,50 0 3,51 6 3,52 10 3,53 1 3,54 13 3,55 8 3,56 9 3,57 4 3,58 5 3,59 11 3,60 12 3,61 7 3,62 2 3,63 14 4,0 2 4,1 12 4,2 4 4,3 1 4,4 7 4,5 10 4,6 11 4,7 6 4,8 8 4,9 5 4,10 3 4,11 15 4,12 13 4,13 0 4,14 14 4,15 9 4,16 14 4,17 11 4,18 2 4,19 12 4,20 4 4,21 7 4,22 13 4,23 1 4,24 5 4,25 0 4,26 15 4,27 10 4,28 3 4,29 9 4,30 8 4,31 6 4,32 4 4,33 2 4,34 1 4,35 11 4,36 10 4,37 13 4,38 7 4,39 8 4,40 15 4,41 9 4,42 12 4,43 5 4,44 6 4,45 3 4,46 0 4,47 14 4,48 11 4,49 8 4,50 12 4,51 7 4,52 1 4,53 14 4,54 2 4,55 13 4,56 6 4,57 15 4,58 0 4,59 9 4,60 10 4,61 4 4,62 5 4,63 3 5,0 12 5,1 1 5,2 10 5,3 15 5,4 9 5,5 2 5,6 6 5,7 8 5,8 0 5,9 13 5,10 3 5,11 4 5,12 14 5,13 7 5,14 5 5,15 11 5,16 10 5,17 15 5,18 4 5,19 2 5,20 7 5,21 12 5,22 9 5,23 5 5,24 6 5,25 1 5,26 13 5,27 14 5,28 0 5,29 11 5,30 3 5,31 8 5,32 9 5,33 14 5,34 15 5,35 5 5,36 2 5,37 8 5,38 12 5,39 3 5,40 7 5,41 0 5,42 4 5,43 10 5,44 1 5,45 13 5,46 11 5,47 6 5,48 4 5,49 3 5,50 2 5,51 12 5,52 9 5,53 5 5,54 15 5,55 10 5,56 11 5,57 14 5,58 1 5,59 7 5,60 6 5,61 0 5,62 8 5,63 13 6,0 4 6,1 11 6,2 2 6,3 14 6,4 15 6,5 0 6,6 8 6,7 13 6,8 3 6,9 12 6,10 9 6,11 7 6,12 5 6,13 10 6,14 6 6,15 1 6,16 13 6,17 0 6,18 11 6,19 7 6,20 4 6,21 9 6,22 1 6,23 10 6,24 14 6,25 3 6,26 5 6,27 12 6,28 2 6,29 15 6,30 8 6,31 6 6,32 1 6,33 4 6,34 11 6,35 13 6,36 12 6,37 3 6,38 7 6,39 14 6,40 10 6,41 15 6,42 6 6,43 8 6,44 0 6,45 5 6,46 9 6,47 2 6,48 6 6,49 11 6,50 13 6,51 8 6,52 1 6,53 4 6,54 10 6,55 7 6,56 9 6,57 5 6,58 0 6,59 15 6,60 14 6,61 2 6,62 3 6,63 12 7,0 13 7,1 2 7,2 8 7,3 4 7,4 6 7,5 15 7,6 11 7,7 1 7,8 10 7,9 9 7,10 3 7,11 14 7,12 5 7,13 0 7,14 12 7,15 7 7,16 1 7,17 15 7,18 13 7,19 8 7,20 10 7,21 3 7,22 7 7,23 4 7,24 12 7,25 5 7,26 6 7,27 11 7,28 0 7,29 14 7,30 9 7,31 2 7,32 7 7,33 11 7,34 4 7,35 1 7,36 9 7,37 12 7,38 14 7,39 2 7,40 0 7,41 6 7,42 10 7,43 13 7,44 15 7,45 3 7,46 5 7,47 8 7,48 2 7,49 1 7,50 14 7,51 7 7,52 4 7,53 10 7,54 8 7,55 13 7,56 15 7,57 12 7,58 9 7,59 0 7,60 3 7,61 5 7,62 6 7,63 11} array set P { 0 16 1 7 2 20 3 21 4 29 5 12 6 28 7 17 8 1 9 15 10 23 11 26 12 5 13 18 14 31 15 10 16 2 17 8 18 24 19 14 20 32 21 27 22 3 23 9 24 19 25 13 26 30 27 6 28 22 29 11 30 4 31 25} for {set i 0} {$i < 66} {incr i} { set block($i) 0 } set pw [split $password ""] set pw_pos 0 for {set i 0} \ {[scan [lindex $pw $pw_pos] %c c] != -1 && $i < 64} \ {incr pw_pos} { for {set j 0} {$j < 7} {incr j ; incr i} { set block($i) [expr {($c >> (6 - $j)) & 01}] } incr i } for {set i 0} {$i < 28} {incr i} { set C($i) $block([expr {$PC1_C($i) - 1}]) set D($i) $block([expr {$PC1_D($i) - 1}]) } for {set i 0} {$i < 16} {incr i} { for {set k 0} {$k < $shifts($i)} {incr k} { set t $C(0) for {set j 0} {$j < 27} {incr j} { set C($j) $C([expr {$j + 1}]) } set C(27) $t set t $D(0) for {set j 0} {$j < 27} {incr j} { set D($j) $D([expr {$j + 1}]) } set D(27) $t } for {set j 0} {$j < 24} {incr j} { set KS($i,$j) $C([expr {$PC2_C($j) - 1}]) set KS($i,[expr {$j + 24}]) $D([expr {$PC2_D($j) - 28 - 1}]) } } for {set i 0} {$i < 48} {incr i} { set E($i) $e($i) } for {set i 0} {$i < 66} {incr i} { set block($i) 0 } set salt [split $salt ""] set salt_pos 0 set val_Z 90 set val_9 57 set val_period 46 for {set i 0} {$i < 2} {incr i} { scan [lindex $salt $salt_pos] %c c incr salt_pos set iobuf($i) $c if {$c > $val_Z} { incr c -6 } if {$c > $val_9} { incr c -7 } incr c -$val_period for {set j 0} {$j < 6} {incr j} { if {[expr {($c >> $j) & 01}]} { set temp $E([expr {6 * $i + $j}]) set E([expr {6 * $i + $j}]) $E([expr {6 * $i + $j + 24}]) set E([expr {6 * $i + $j + 24}]) $temp } } } set edflag 0 for {set h 0} {$h < 25} {incr h} { for {set j 0} {$j < 64} {incr j} { set L($j) $block([expr {$IP($j) - 1}]) } for {set ii 0} {$ii < 16} {incr ii} { if {$edflag} { set i [expr {15 - $ii}] } else { set i $ii } for {set j 0} {$j < 32} {incr j} { set tempL($j) $L([expr {$j + 32}]) } for {set j 0} {$j < 48} {incr j} { set preS($j) [expr {$L([expr {$E($j) - 1 + 32}]) ^ $KS($i,$j)}] } for {set j 0} {$j < 8} {incr j} { set t [expr {6 * $j}] set k $S($j, [expr { ($preS($t) << 5) + ($preS([expr {$t + 1}]) << 3) + ($preS([expr {$t + 2}]) << 2) + ($preS([expr {$t + 3}]) << 1) + $preS([expr {$t + 4}]) + ($preS([expr {$t + 5}]) << 4) }]) set t [expr {4 * $j}] set f($t) [expr {($k >> 3) & 01}] set f([expr {$t + 1}]) [expr {($k >> 2) & 01}] set f([expr {$t + 2}]) [expr {($k >> 1) & 01}] set f([expr {$t + 3}]) [expr { $k & 01}] } for {set j 0} {$j < 32} {incr j} { set L([expr {$j + 32}]) [expr {$L($j) ^ $f([expr {$P($j) - 1}])}] } for {set j 0} {$j < 32} {incr j} { set L($j) $tempL($j) } } for {set j 0} {$j < 32} {incr j} { set t $L($j) set L($j) $L([expr {$j + 32}]) set L([expr {$j + 32}]) $t } for {set j 0} {$j < 64} {incr j} { set block($j) $L([expr {$FP($j) - 1}]) } } for {set i 0} {$i < 11} {incr i} { set c 0 for {set j 0} {$j < 6} {incr j} { set c [expr {$c << 1}] set c [expr {$c | $block([expr {6 * $i + $j}])}] } incr c $val_period if {$c > $val_9} { incr c 7 } if {$c > $val_Z} { incr c 6 } set iobuf([expr {$i + 2}]) $c } if {$iobuf(1) == 0} { set iobuf(1) $iobuf(0) } set elements [lsort -integer [array names iobuf]] set encrypted "" foreach element $elements { append encrypted [format %c $iobuf($element)] } return $encrypted } if {[package present Tcl] < 8.4} { # we must use the slower non lset version return } #This version uses the [lset] command introduced in Tcl 8.4. #It seems to result in a 40-45% improvement in speed over the original version which uses [array]s. proc crypt {password salt} { set IP {58 50 42 34 26 18 10 2 60 52 44 36 28 20 12 4 62 54 46 38 30 22 14 6 64 56 48 40 32 24 16 8 57 49 41 33 25 17 9 1 59 51 43 35 27 19 11 3 61 53 45 37 29 21 13 5 63 55 47 39 31 23 15 7} set FP {40 8 48 16 56 24 64 32 39 7 47 15 55 23 63 31 38 6 46 14 54 22 62 30 37 5 45 13 53 21 61 29 36 4 44 12 52 20 60 28 35 3 43 11 51 19 59 27 34 2 42 10 50 18 58 26 33 1 41 9 49 17 57 25} set PC1_C {57 49 41 33 25 17 9 1 58 50 42 34 26 18 10 2 59 51 43 35 27 19 11 3 60 52 44 36} set PC1_D {63 55 47 39 31 23 15 7 62 54 46 38 30 22 14 6 61 53 45 37 29 21 13 5 28 20 12 4} set shifts {1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1} set PC2_C {14 17 11 24 1 5 3 28 15 6 21 10 23 19 12 4 26 8 16 7 27 20 13 2} set PC2_D {41 52 31 37 47 55 30 40 51 45 33 48 44 49 39 56 34 53 46 42 50 36 29 32} set e {32 1 2 3 4 5 4 5 6 7 8 9 8 9 10 11 12 13 12 13 14 15 16 17 16 17 18 19 20 21 20 21 22 23 24 25 24 25 26 27 28 29 28 29 30 31 32 1} set S {{14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13} {15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10 3 13 4 7 15 2 8 14 12 0 1 10 6 9 11 5 0 14 7 11 10 4 13 1 5 8 12 6 9 3 2 15 13 8 10 1 3 15 4 2 11 6 7 12 0 5 14 9} {10 0 9 14 6 3 15 5 1 13 12 7 11 4 2 8 13 7 0 9 3 4 6 10 2 8 5 14 12 11 15 1 13 6 4 9 8 15 3 0 11 1 2 12 5 10 14 7 1 10 13 0 6 9 8 7 4 15 14 3 11 5 2 12} { 7 13 14 3 0 6 9 10 1 2 8 5 11 12 4 15 13 8 11 5 6 15 0 3 4 7 2 12 1 10 14 9 10 6 9 0 12 11 7 13 15 1 3 14 5 2 8 4 3 15 0 6 10 1 13 8 9 4 5 11 12 7 2 14} { 2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9 14 11 2 12 4 7 13 1 5 0 15 10 3 9 8 6 4 2 1 11 10 13 7 8 15 9 12 5 6 3 0 14 11 8 12 7 1 14 2 13 6 15 0 9 10 4 5 3} {12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11 10 15 4 2 7 12 9 5 6 1 13 14 0 11 3 8 9 14 15 5 2 8 12 3 7 0 4 10 1 13 11 6 4 3 2 12 9 5 15 10 11 14 1 7 6 0 8 13} { 4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1 13 0 11 7 4 9 1 10 14 3 5 12 2 15 8 6 1 4 11 13 12 3 7 14 10 15 6 8 0 5 9 2 6 11 13 8 1 4 10 7 9 5 0 15 14 2 3 12} {13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7 1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2 7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8 2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11}} set P {16 7 20 21 29 12 28 17 1 15 23 26 5 18 31 10 2 8 24 14 32 27 3 9 19 13 30 6 22 11 4 25} set block {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} set KS {{0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}} set iobuf {0 0 0 0 0 0 0 0 0 0 0 0 0} set f {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} set pw [split $password ""] set pw_pos 0 for {set i 0} {[scan [lindex $pw $pw_pos] %c c] != -1 && $i < 64} \ {incr pw_pos} { for {set j 0} {$j < 7} {incr j ; incr i} { lset block $i [expr {($c >> (6 - $j)) & 01}] } incr i } set C [list] set D [list] for {set i 0} {$i < 28} {incr i} { lappend C [lindex $block [expr {[lindex $PC1_C $i] - 1}]] lappend D [lindex $block [expr {[lindex $PC1_D $i] - 1}]] } for {set i 0} {$i < 16} {incr i} { for {set k 0} {$k < [lindex $shifts $i]} {incr k} { set t [lindex $C 0] for {set j 0} {$j < 27} {incr j} { lset C $j [lindex $C [expr {$j + 1}]] } lset C 27 $t set t [lindex $D 0] for {set j 0} {$j < 27} {incr j} { lset D $j [lindex $D [expr {$j + 1}]] } lset D 27 $t } for {set j 0} {$j < 24} {incr j} { lset KS $i $j [lindex $C [expr {[lindex $PC2_C $j] - 1}]] lset KS $i [expr {$j + 24}] \ [lindex $D [expr {[lindex $PC2_D $j] - 28 - 1}]] } } set E [list] for {set i 0} {$i < 48} {incr i} { lappend E [lindex $e $i] } for {set i 0} {$i < 66} {incr i} { lset block $i 0 } set salt [split $salt ""] set salt_pos 0 set val_Z 90 set val_9 57 set val_period 46 for {set i 0} {$i < 2} {incr i} { scan [lindex $salt $salt_pos] %c c incr salt_pos lset iobuf $i $c if {$c > $val_Z} { incr c -6 } if {$c > $val_9} { incr c -7 } incr c -$val_period for {set j 0} {$j < 6} {incr j} { if {[expr {($c >> $j) & 01}]} { set temp [lindex $E [expr {6 * $i + $j}]] lset E [expr {6 * $i + $j}] \ [lindex $E [expr {6 * $i + $j + 24}]] lset E [expr {6 * $i + $j + 24}] $temp } } } set edflag 0 for {set h 0} {$h < 25} {incr h} { set L [list] for {set j 0} {$j < 64} {incr j} { lappend L [lindex $block [expr {[lindex $IP $j] - 1}]] } for {set ii 0} {$ii < 16} {incr ii} { if {$edflag} { set i [expr {15 - $ii}] } else { set i $ii } set tempL [list] for {set j 0} {$j < 32} {incr j} { lappend tempL [lindex $L [expr {$j + 32}]] } set preS [list] for {set j 0} {$j < 48} {incr j} { lappend preS \ [expr {[lindex $L [expr {[lindex $E $j] - 1 + 32}]] ^ [lindex $KS $i $j]}] } for {set j 0} {$j < 8} {incr j} { set t [expr {6 * $j}] set k [lindex $S $j [expr { ([lindex $preS $t] << 5) + ([lindex $preS [expr {$t + 1}]] << 3) + ([lindex $preS [expr {$t + 2}]] << 2) + ([lindex $preS [expr {$t + 3}]] << 1) + [lindex $preS [expr {$t + 4}]] + ([lindex $preS [expr {$t + 5}]] << 4) }]] set t [expr {4 * $j}] lset f $t [expr {($k >> 3) & 01}] lset f [expr {$t + 1}] [expr {($k >> 2) & 01}] lset f [expr {$t + 2}] [expr {($k >> 1) & 01}] lset f [expr {$t + 3}] [expr { $k & 01}] } for {set j 0} {$j < 32} {incr j} { lset L [expr {$j + 32}] \ [expr {[lindex $L $j] ^ [lindex $f [expr {[lindex $P $j] - 1}]]}] } for {set j 0} {$j < 32} {incr j} { lset L $j [lindex $tempL $j] } } for {set j 0} {$j < 32} {incr j} { set t [lindex $L $j] lset L $j [lindex $L [expr {$j + 32}]] lset L [expr {$j + 32}] $t } for {set j 0} {$j < 64} {incr j} { lset block $j [lindex $L [expr {[lindex $FP $j] - 1}]] } } for {set i 0} {$i < 11} {incr i} { set c 0 for {set j 0} {$j < 6} {incr j} { set c [expr {$c << 1}] set c [expr {$c | [lindex $block [expr {6 * $i + $j}]]}] } incr c $val_period if {$c > $val_9} { incr c 7 } if {$c > $val_Z} { incr c 6 } lset iobuf [expr {$i + 2}] $c } if {[lindex $iobuf 1] == 0} { lset iobuf 1 [lindex $iobuf 0] } set encrypted "" foreach element $iobuf { append encrypted [format %c $element] } return $encrypted } |
Added modules/httpd/template.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | # template.tcl #@c Template support # # Derived from doc.tcl # Stephen Uhler / Brent Welch (c) 1997-1998 Sun Microsystems # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: template.tcl,v 1.20 2004/10/22 08:32:56 coldstore Exp $ package provide httpd::template 1.0 package require httpd ;# Httpd_PostDataSize Httpd_ReturnData package require httpd::cgi ;# Cgi_SetEnv Cgi_SetEnvInterp package require httpd::cookie ;# Cookie_Save package require httpd::doc ;# Doc_GetPath package require httpd::log ;# Log package require httpd::mtype ;# Mtype package require httpd::subst ;# Subst_File package require httpd::url ;# Url_Decode Url_DecodeQuery Url_ReadPost package require httpd::utils ;# file file_latest lappendOnce package require Markdown ;# Markdown handler # Set the file extension for templates if {![info exists Template(mdExt)]} { set Template(mdExt) .md } if {![info exists Template(tmlExt)]} { set Template(tmlExt) .tml } if {![info exists Template(env)]} { set Template(env) 1 } if {![info exists Template(htmlExt)]} { switch $tcl_platform(platform) { windows { set Template(htmlExt) .htm } default { set Template(htmlExt) .html } } } set Template(htmlMatch) {([.]html?)} # Template_Check -- # # Allow or disable automatic template checking # # Arguments: # how A boolen that enables or disables template handling. # # Results: # None # # Side Effects: # Sets the checkTemplates variable. proc Template_Check {{how 1}} { global Template set Template(checkTemplates) $how } if {![info exists Template(checkTemplates)]} { set Template(checkTemplates) 0 } # Template_Interp -- # # Choose an alternate interpreter in which to process templates # # Arguments: # interp The Tcl interpreter in which to process templates. # # Results: # None # # Side Effects: # Sets the interpreter for all Doc domain templates. proc Template_Interp {interp} { global Template if {[string length $interp] && ![interp exists $interp]} { interp create $interp } set Template(templateInterp) $interp } if {![info exists Template(templateInterp)]} { set Template(templateInterp) {} } # Template_Library -- # # Define the auto_load library for template support # # Arguments: # dir The directory to add to the auto_path # # Results: # None # # Side Effects: # Updates the auto_path variable in the interpreter used # for templates. proc Template_Library {dir} { global Template auto_path set Template(templateLibrary) $dir if {$Template(templateInterp) != {}} { interp eval $Template(templateInterp) [list lappendOnce ::auto_path $dir] } else { lappendOnce auto_path $dir } } # Doc_application/x-tcl-template -- # # Tcl-subst a template that mixes HTML and Tcl. # # Arguments: # path The file pathname. # suffix The URL suffix. # sock The socket connection. # # Results: # None # # Side Effects: # Sets up the interpreter context and subst's the page, # which is returned to the client. proc Doc_application/x-tcl-template {path suffix sock} { upvar #0 Httpd$sock data global Template # This is always dynamic (ReturnData has no modification date) # so the result is not cached at the remote end, nor is a local # .html file cached. set content [TemplateInstantiate $sock $path {} $suffix {} $Template(templateInterp)] # If the content type was set, use it. Otherwise, use the default. if {[info exists data(contentType)]} { set ctype $data(contentType) } else { set ctype text/html } return [Httpd_ReturnData $sock $ctype $content] } # TemplateInstantiate -- # # Generate a .html file from a template # and from any .tml files in directories leading up to the root. # The processing is done in the specified interpreter. # State set in the global array "page": # url The URL past the document root # template The filename of the template file # filename The filename of the associated htmlfile # root The ../ path up to the root # dynamic If 1, then this page is dynamically generated # on every fetch. Otherwise the page has a cached # static representation. # # Arguments: # sock The client socket. # template The file name of the template. # htmlfile The file name of the corresponding .html file. # suffix The URL suffix. # dynamicVar Name of var to set to dynamic property of the page. # interp The interp to use for substing. # # Results: # html, or an error generated by the template # # Side Effects: # Generates a page. Will set up the CGI environment via the ncgi # module, and will do environment variable settings. # data(contentType) contains the mime type of generated content. proc TemplateInstantiate {sock template htmlfile suffix dynamicVar {interp {}}} { upvar #0 Httpd$sock data upvar $dynamicVar dynamic global Template # Compute a relative path back to the root. set dirs [lreplace [split [string trimleft $data(url) /] /] end end] set root "" foreach d $dirs { append root ../ } # Populate the global "page" array with state about this page if {[string length $htmlfile]} { set filename $htmlfile set dynamic 0 } else { set filename $template set dynamic 1 } interp eval $interp {uplevel #0 {catch {unset page}}} interp eval $interp [list uplevel #0 [list array set page [list \ url $data(url) \ template $template \ includeStack [list [file dirname $template]] \ filename $filename \ root $root \ dynamic $dynamic \ ]]] # Populate the global "env" array similarly to the CGI environment if {$Template(env)} { Cgi_SetEnvInterp $sock $filename $interp } # Check query data. if {[Httpd_PostDataSize $sock] > 0 && ![info exists data(query)]} { set data(query) {} } if {[info exist data(query)]} { if {![info exist data(mime,content-type)] || $data(proto) == "GET"} { # The check against GET is because IE 5 has the following bug. # If it does a POST with content-type multipart/form-data and # keep-alive reuses the connection for a subsequent GET request, # then the GET request erroneously has a content-type header # that is a copy of the one from the previous POST! set type application/x-www-urlencoded } else { set type $data(mime,content-type) } # Read and append the pending post data to data(query). Url_ReadPost $sock data(query) # Initialize the Standard Tcl Library ncgi package so its # ncgi::value can be used to get the data. This replaces # the old Url_DecodeQuery interface. interp eval $interp [list ncgi::reset $data(query) $type] interp eval $interp [list ncgi::parse] interp eval $interp [list ncgi::urlStub $data(url)] # Define page(query) and page(querytype) # for compatibility with older versions of TclHttpd # This is a bit hideous because it reaches inside ::ncgi # to avoid parsing the data twice. interp eval $interp [list uplevel #0 [list set page(querytype) \ [string trim [lindex [split $type \;] 0]]]] interp eval $interp [list uplevel #0 { set page(query) {} foreach n $ncgi::varlist { foreach v $ncgi::value($n) { lappend page(query) $n $v } } }] } else { interp eval $interp [list ncgi::reset ""] interp eval $interp [list uplevel #0 [list set page(query) {}]] interp eval $interp [list uplevel #0 [list set page(querytype) {}]] } # Source the .tml files from the root downward. foreach libdir [Doc_GetPath $sock $template] { set libfile [file join $libdir $Template(tmlExt)] if {[file exists $libfile]} { interp eval $interp [list uplevel #0 [list source $libfile]] } } # Process the template itself set code [catch {Subst_File $template $interp} html] if {$code != 0} { # pass errors up - specifically Redirect return code # stash error information so Cookie_Save doesn't interfere global errorCode errorInfo set ec $errorCode set ei $errorInfo # Save return cookies, if any Cookie_Save $sock $interp return -code $code -errorcode $ec -errorinfo $ei } # Save return cookies, if any Cookie_Save $sock $interp set dynamic [interp eval $interp {uplevel #0 {set page(dynamic)}}] if {!$dynamic} { # Cache the result catch {file delete -force $htmlfile} # process any filters if {[info exists data(filter)]} { while {[llength $data(filter)]} { set cmd [lindex $data(filter) end] set data(filter) [lrange $data(filter) 0 end-1] catch { set html [eval $cmd $sock [list $html]] } } } if {[catch {open $htmlfile w} out]} { set dynamic 1 Log $sock "Template" "no write permission" } else { puts -nonewline $out $html close $out } } return $html } # Template_Dynamic # Supress generation of HTML cache # # Arguments: # # Results: # None # # Side Effects: # Sets the dynamic bit so the page is not cached. proc Template_Dynamic {} { global page set page(dynamic) 1 return "<!-- DynamicOnly -->\n" } # TemplateCheck -- # # Check modify times on all templates that affect a page # # Arguments: # sock The client connection # template The file pathname of the template. # htmlfile The file pathname of the cached .html file. # # Results: # 1 if the template or any dependent .tml file are newer than # the cached .html file. # # Side Effects: # None proc TemplateCheck {sock template htmlfile} { global Template if {[file exists $htmlfile]} { set mtime [file mtime $htmlfile] } else { return 1 } # Look for .tml library files down the hierarchy. global Doc set rlen [llength [file split $Doc(root)]] set dirs [lrange [file split [file dirname $template]] $rlen end] foreach libdir [Doc_GetPath $sock $template] { set mdfile [file join $libdir $Template(mdExt)] if {[file exists $mdfile] && ([file mtime $mdfile] > $mtime)} { return 1 } set libfile [file join $libdir $Template(tmlExt)] if {[file exists $libfile] && ([file mtime $libfile] > $mtime)} { return 1 } } # make index.html regeneration depend upon the whole directory's # modification time, not just the modification time of index.tml global dirlist if {[file root [file tail $htmlfile]] == [file root $dirlist(indexpat)]} { if {[file mtime [file dirname $htmlfile]] > $mtime} { return 1 } } return [expr {[file mtime $template] > $mtime}] } # Template_try -- # process a template file which is newer than the path (if path exists). # # Arguments: # sock The client connection # path The file system pathname of the file. # suffix The URL suffix. # # Results: # 1 if the request has been completed (by a dynamic template) # 0 if the request hasn't been handled, either because there is # no template, or because cache file is (now) newer and can be # handled by caller # # Side Effects: # May have generated a page - # data(contentType) contains the mime type of generated content. proc Template_Try {sock path suffix} { upvar #0 Httpd$sock data global Template if {!$Template(checkTemplates)} { return 0 } set mdtemplate ${path}$Template(mdExt) if {[file exists $mdtemplate]} { # we have a matching template and extension for path # See if the cached result is up-to-date set dynamic 0 if {[TemplateCheck $sock $mdtemplate $path]} { # Template file is newer than its cached version # Do the subst and cache the result in the .html file # We set a provisional type based on the file extension, but # the template processing can override that set data(contentType) text/html set fin [open $mdtemplate r] set mdtxt [read $fin] close $fin set html [::Markdown::convert $mdtxt] if {$dynamic} { # return the data directly Httpd_ReturnData $sock $data(contentType) $html return 1 } else { set fout [open $path w] puts $fout $html close $fout # we have generated a cached file from the template. # leave it to caller to return newly generated file return 0 } } else { # cache file is newer return 0 } } else { set template ${path}$Template(tmlExt) if {![file exists $template]} { # special case, x.tml generates x.html set template [file root $path]$Template(tmlExt) # ensure request was for *.htm[l]? and .tml exists if {![regexp $Template(htmlMatch) [file extension $path]] || ![file exists $template]} { # no template found return 0 } } # we have a matching template and extension for path # See if the cached result is up-to-date if {[TemplateCheck $sock $template $path]} { # Template file is newer than its cached version # Do the subst and cache the result in the .html file # We set a provisional type based on the file extension, but # the template processing can override that set data(contentType) [Mtype $path] set html [TemplateInstantiate $sock $template $path $suffix dynamic \ $Template(templateInterp)] if {$dynamic} { # return the data directly Httpd_ReturnData $sock $data(contentType) $html return 1 } else { # we have generated a cached file from the template. # leave it to caller to return newly generated file return 0 } } else { # cache file is newer return 0 } } } # Template_Choose - what mime-type does this file # represent, or generate? # a.x.tml is considered to return/match .x proc Template_Choose {accept choices} { global Template # generate a map map from mime_type -> choices foreach f $choices { # get first of two extensions eg .css.tml set type [file extension [file root $f]] ;# use .css in .css.tml if {$type == ""} { set type [file extension $f] ;# path has only a single extension if {$type == $Template(tmlExt)} { # we've found a .tml file - x.tml matches x.html set type $Template(htmlExt) } } lappend mtype([Mtype $type]) $f } # array mtype is now a mapping from mime types to files # for the collection of files we can offer. # look at what mime types the client accepts, in order of presentation # (nb FIXME: the spec says we should accept them in q= order) foreach t [split $accept ,] { # find something that matches regsub {;.*} $t {} t ;# Nuke quality parameters set t [string trim [string tolower $t]] # collect string-matching mtypes we can offer set hits {} foreach {mime files} [array get mtype $t] { set hits [concat $hits $files] } # if some file choices match on type, choose the most recent if {[llength $hits] > 1} { set hit [file_latest $hits] } else { set hit [lindex $hits 0] } if {[string length $hit]} { # we have a matching file if {[file extension $hit] == $Template(tmlExt)} { # our candidate is a template file # return the name of the file as it will be. if {[file extension [file root $hit]] == ""} { # we're about to offer a .tml - as an .html return "[file root $hit]$Template(htmlExt)" } else { # strip the .tml and return for redirection return [file root $hit] } } return $hit ;# not a templated match } } return {} ;# no acceptable matches } |
Added modules/httpd/thread.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | # threadmgr.tcl # Wrappers around basic thread commands # # "Thread" is the C-based Tcl extension # "threadmgr" is the TclHttpd thread manager # # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: thread.tcl,v 1.16 2004/09/05 05:10:14 coldstore Exp $ package provide httpd::threadmgr 1.0 package require httpd ;# Httpd_GetPostData package require httpd::config ;# Config package require httpd::counter ;# Count package require httpd::log ;# Log package require httpd::url ;# Url_Unwind package require httpd::utils ;# Stderr file ldelete # The "Thread" package is implemented by a C extension. # We let the main .rc script do the appropriate package # require, and then fall back to the testthread command if necessary. # Default is no threading until Thread_Init is called if {![info exist Thread(enable)]} { set Thread(enable) 0 } # Thread_Init # # Initialize the thread dispatcher # # Arguments # max Maximum number of threads to create. # # Side Effects # Initializes variables used by the thread dispatcher proc Thread_Init {{max 4}} { global Thread package require Thread 2.0 set Thread(maxthreads) $max ;# Number of threads we can create set Thread(threadlist) {} ;# List of threads we have created set Thread(freelist) {} ;# List of available threads set Thread(deletelist) {} ;# List of running threads to delete when done set Thread(queue) {} ;# List of queued requests, ?socket? cmd set Thread(enable) 1 } # Thread_IsMaster # # Find out if this thread is the master. # # Arguments # none # # Results # Returns true iff this thread is the master. proc Thread_IsMaster {} { return [expr {![info exists ::Thread_MasterId]}] } # Thread_Enabled # # Find out if the threading system is turned on # # Arguments # none # # Results # none proc Thread_Enabled {} { global Thread return $Thread(enable) } # Thread_List # # Return the list of threads # # Arguments # none # # Results # a list proc Thread_List {} { global Thread if {$Thread(enable)} { return [thread::names] } return "" } # Thread_Start -- # This starts a worker thread. The big pain here is that a # virgin thread has none of our Tcl scripts, so we have to # bootstrap into a useful state. # # Arguments: # None # # Results: # The ID of the created thread proc Thread_Start {} { global auto_path tcl_library set id [Thread_Create] Thread_Send $id \ {puts stderr "Thread starting."} # Set up auto_loading. These steps may become redundent once the # TclpSetLibraryPath code works correctly in threads. Thread_Send $id \ [list set tcl_library $tcl_library] Thread_Send $id \ {source $tcl_library/init.tcl} Thread_Send $id \ [list set auto_path $auto_path] # Suck up all the necessary packages # Most state comes from the initialization in the config file. # There is just a bit of info in the Httpd array that is set up # when the main server is started, which we need (e.g., the name) global Httpd Config Thread_Send $id \ [list array set Httpd [array get Httpd]] Thread_Send $id \ [list array set Config [array get Config]] # Let the new thread know its master's Id. Only slave threads have # the "Thread_MasterId" global varaible set. Thread_Send $id [list set Thread_MasterId [Thread_Id]] Thread_Send $id [list source $Config(main)] return $id } # Thread_Dispatch -- # This dispatches the HTTP request to a worker thread. # That thread should use Thread_Respond or raise an error # to complete the request. # # Arguments: # sock Client connection # cmd Command to invoke in a worker # # Side Effects: # Allocate a thread or queue the command/sock for later execution proc Thread_Dispatch {sock cmd} { global Thread Url upvar #0 Httpd$sock data if {!$Thread(enable) || $Thread(maxthreads) == 0} { eval $cmd } else { if {[llength $Thread(freelist)] == 0} { if {[llength $Thread(threadlist)] < $Thread(maxthreads)} { # Add a thread to the free pool set id [Thread_Start] lappend Thread(threadlist) $id lappend Thread(freelist) $id } else { # Queue the request until a thread is available lappend Thread(queue) [list $sock $cmd] Count threadqueue return } } set id [lindex $Thread(freelist) 0] set Thread(freelist) [lrange $Thread(freelist) 1 end] set data(master_thread) [Thread_Id] # Until we can pass sockets, read the post data here if {[info exist Url(postlength)]} { while {$Url(postlength) > 0} { set Url(postlength) [Httpd_GetPostData $sock data(query)] } unset Url(postlength) } Thread_SendAsync $id [list Thread_Invoke $sock [array get data] $cmd] } } # Thread_Dispatch_General -- # This dispatches the command to a worker thread. # That thread should use Thread_Respond_General or raise an error # to complete the request. # # Arguments: # cmd Command to invoke in a worker # # Side Effects: # Allocate a thread or queue the command/sock for later execution proc Thread_Dispatch_General {cmd} { global Thread Url if {!$Thread(enable) || $Thread(maxthreads) == 0} { eval $cmd } else { if {[llength $Thread(freelist)] == 0} { if {[llength $Thread(threadlist)] < $Thread(maxthreads)} { # Add a thread to the free pool set id [Thread_Start] lappend Thread(threadlist) $id lappend Thread(freelist) $id } else { # Queue the request until a thread is available lappend Thread(queue) [list $cmd] Count threadqueue return } } set id [lindex $Thread(freelist) 0] set Thread(freelist) [lrange $Thread(freelist) 1 end] Thread_SendAsync $id [list Thread_Invoke_General $cmd] } } # Thread_Invoke -- # This is invoked in a worker thread to handle an HTTP request. # # Arguments: # sock The name of the socket connection. Probably is not # an actual I/O socket. # datalist The contents of the connection state in array get format # cmd Tcl command to eval in this thread # # Results: # None proc Thread_Invoke {sock datalist cmd} { upvar #0 Httpd$sock data if {[info exist data]} { unset data } Count urlhits array set data $datalist # Make sure the thread knows which socket it's currently processing. # This is needed for redirects from within doc templates. set ::Httpd(currentSocket) $sock if {[catch $cmd result]} { global errorInfo errorCode Count errors Thread_Respond $sock [list Url_Unwind $sock $errorInfo $errorCode] } else { return $result } } # Thread_Invoke_General -- # This is invoked in a worker thread to handle general eval request. # # Arguments: # cmd Tcl command to eval in this thread # # Results: # None proc Thread_Invoke_General {cmd} { if {[catch $cmd result]} { global errorInfo errorCode Count errors # An error occurred, so log it. Log {} bgerror "Error with code $errorCode in thread [Thread_Id]:\n$errorInfo" } Thread_MasterEvalAsync [list Thread_Free [Thread_Id]] return } # Thread_Respond -- # This is invoked in a worker thread to respond to a request # # Arguments: # sock Client connection # cmd Command to invoke to complete the request # # Results: # 1 if the request was passed to the master thread, else 0 proc Thread_Respond {sock cmd} { upvar #0 Httpd$sock data if {[info exist data(master_thread)] && $data(master_thread) != [Thread_Id]} { # Pass request back to the master thread # This includes a copy of the Httpd state (e.g., cookies) Thread_SendAsync $data(master_thread) [list Thread_Unwind \ [Thread_Id] $sock [array get data] $cmd] # The next iteration of the thread should not have access to # past connection data. unset data return 1 } else { return 0 } } # Thread_Unwind -- # Invoke a response handler for a thread that handled an HTTP request. # This cleans up the connection in the main thread. # # Arguments: # id The ID of the worker thread. # sock The ID of the socket connection # datalist name, value list for the Httpd state array # cmd The command to eval in the main thread # # Side Effects: # Invoke the response handler. proc Thread_Unwind {id sock datalist cmd} { upvar #0 Httpd$sock data array set data $datalist if {[catch $cmd err]} { global errorCode errorInfo Url_Unwind $sock $errorInfo $errorCode } Thread_Free $id } # Thread_Free -- # Mark a thread as available # # Arguments: # id The ID of the worker thread. # # Side Effects: # Reap the thread, put it on the freelist, or perhaps handle # a queued request. proc Thread_Free {id} { global Thread if {[ldelete Thread(deletelist) $id]} { # This thread was marked for deletion, so tell it to exit. Thread_SendAsync $t thread::exit ldelete Thread(threadlist) $id } elseif {[llength $Thread(queue)] > 0} { set state [lindex $Thread(queue) 0] set Thread(queue) [lrange $Thread(queue) 1 end] if {[llength $state] == 1} { # No socket was given, so just eval the command in the thread. set cmd [lindex $state 0] Thread_SendAsync $id [list Thread_Invoke_General $cmd] } else { set sock [lindex $state 0] set cmd [lindex $state 1] upvar #0 Httpd$sock data set data(master_thread) [Thread_Id] Thread_SendAsync $id [list Thread_Invoke $sock [array get data] $cmd] } } else { lappend Thread(freelist) $id } } # Thread_Create -- # thread create # # Arguments: # Optional startup script # # Results: # The ID of the created thread proc Thread_Create {{script {}}} { Count threads if {[string length $script]} { return [thread::create $script] } else { return [thread::create] } } # Thread_Send -- # thread send # # Arguments: # id Target thread # script Script to send # # Results: # The results of the script proc Thread_Send {id script} { if {[catch {thread::send $id $script} result]} { return -code error $result } else { return $result } } # Thread_MasterEval # # Evaluate the given script synchronously in the master thread. # # Arguments # script The script to evaluate. # # Results # Returns the result of evaluating the script in the master. proc Thread_MasterEval {script} { if {[info exists ::Thread_MasterId]} { return [Thread_Send $::Thread_MasterId $script] } else { return [eval $script] } } # Thread_SendAsync -- # thread send -async # # Arguments: # id Target thread # script Script to send # # Results: # The results of the script proc Thread_SendAsync {id script} { if {[catch {thread::send -async $id $script} result]} { return -code error $result } else { return $result } } # Thread_MasterEvalAsync # # Evaluate the given script asynchronously in the master thread. # # Arguments # script The script to evaluate. # # Results # none. proc Thread_MasterEvalAsync {script} { if {[info exists ::Thread_MasterId]} { return [Thread_SendAsync $::Thread_MasterId $script] } else { after 0 [list eval $script] return } } # Thread_Id -- # thread::id # # Arguments: # none # # Results: # The thread ID proc Thread_Id {} { thread::id } # Thread_IsFree -- # Find out if a thread is on the free list. # # Arguments: # id The thread ID # # Results: # 1 or 0 proc Thread_IsFree {id} { global Thread return [expr {[lsearch $Thread(freelist) $id] >= 0}] } # Thread_ReapAll -- # The master thread should reap all free threads and mark all busy # threads for deletion upon completion of their task. # # Arguments: # None. # # Results: # None. proc Thread_ReapAll {} { if {![Thread_IsMaster]} { # This proc should only be called by the master thread. return } global Thread set Thread(deletelist) {} foreach id $Thread(threadlist) { if {[lsearch $Thread(freelist) $id] != -1} { # Free threads are told to exit and removed from the freelist. Thread_SendAsync $id thread::exit } else { # Busy threads are marked for deletion upon completion of their task. lappend Thread(deletelist) $id } } set Thread(threadlist) $Thread(deletelist) set Thread(freelist) {} return } # Thread_SendAll -- # The master thread serially sends this script to all free threads, # including itself. # # Arguments: # cmd The script to send to all threads. # # Results: # Returns the list of alternating thread id and result, or {} if # this thread is not the master. proc Thread_SendAll {cmd} { if {![Thread_IsMaster]} { # This proc should only be called by the master thread. return {} } global Thread foreach id $Thread(threadlist) { if {[lsearch $Thread(freelist) $id] != -1} { # Send the same script to all free threads. lappend result $id [Thread_Send $id $cmd] } } # Also eval the script in this thread. catch {eval $cmd} res lappend result [thread::id] $res return $result } |
Added modules/httpd/upload.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | # upload.tcl # # File upload domain. This implements a domain handler that # specializes in file uploading of multipart/form-data. # It uploads files into a particular directory and enforces # limits on the number of files, their size, etc. # It invokes handler procedures similar to application-direct # handlers after doing the file upload. # # Brent Welch (c) 2001 # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: upload.tcl,v 1.13 2004/09/05 05:10:14 coldstore Exp $ package require ncgi package provide httpd::upload 1.0 package require httpd ;# Httpd_Error Httpd_Redirect Httpd_ReturnData Httpd_Suspend package require httpd::url ;# Url_PostHook Url_PrefixInstall package require httpd::utils ;# Incr K Stderr file # Upload_Url # Define a subtree of the URL hierarchy that handles # file uploads. # # Arguments # virtual The URL prefix of the upload domain. # dir The upload directory - files get placed here. # command The Tcl command to invoke after an upload. # args option-value flags described below. # -thread <boolean> # If true, dispatch domain in a thread # -maxfiles <integer> # Maximum files in upload directory # -maxbytes <integer> # Maximum number of bytes in a file # -totalbytes <integer> # Limit on total bytes in all files # in the upload directory # -unique <boolean> # Give uploads unique names # # Side Effects # Register a prefix proc Upload_Url {virtual dir command args} { global Upload array set opt { -inThread 0 -maxfiles -1 -maxbytes -1 -totalbytes -1 -unique 0 } array set opt $args Url_PrefixInstall $virtual [list UploadDomain $dir $command \ $opt(-maxfiles) $opt(-maxbytes) $opt(-totalbytes) $opt(-unique)] \ -thread $opt(-inThread) \ -callback [list UploadTidyUp] \ -readpost 0 } # UploadDomain # Main handler for Upload domains # This uploads the file, if it does not exceed the byte # and file limits, then invokes the callback. # # Arguments # dir Upload directory # cmd Tcl command to call after upload # maxfiles Max files per upload diretory # maxbytes File byte limit # totalbytes Total bytes per upload directory # sock The socket back to the client # suffix The part of the url after the domain prefix. # proc UploadDomain {dir cmd maxfiles maxbytes totalbytes unique sock suffix} { upvar #0 Httpd$sock data upvar #0 Upload$sock upload # Testing if {[string match *test* $suffix]} { set fd [open $dir/test w] fconfigure $fd -trans binary puts -nonewline $fd [read $sock $data(mime,content-length)] close $fd Httpd_ReturnData $sock text/html $dir/test } # Extract multi-part boundary from the headers if {![info exist data(mime,content-type)] || $data(proto) == "GET"} { set type application/x-www-urlencoded } else { set type $data(mime,content-type) } set parsedType [ncgi::parseMimeValue $type] if {![string match multipart/* [lindex $parsedType 0]]} { return -code error "Not a multipart Content-Type: [lindex $parsedType 0]" } array set options [lindex $parsedType 1] if {![info exists options(boundary)]} { return -code error "No boundary given for multipart document" } # Record upload instance data and set up a read event handler # so we can read large files without blocking. if {[info exist upload]} { unset upload } set upload(boundary) $options(boundary) set upload(dir) $dir set upload(cmd) $cmd set upload(maxfiles) $maxfiles set upload(totalbytes) $totalbytes set upload(maxbytes) $maxbytes set upload(suffix) $suffix set upload(count) $data(count) set upload(unique) $unique # These are temporary storage used when parsing the headers of each part set upload(headers) {} set upload(formName) {} set upload(formNames) {} if {$upload(maxfiles) != -1} { set files [glob -nocomplain -- [file join $upload(dir) *]] if {[llength $files] >= $upload(maxfiles)} { Httpd_Error $sock 503 "Max files ($upload(maxfiles)) exceeded.<br>Unable to upload" return } } if {$upload(maxbytes) != -1} { if {$upload(count) >= $upload(maxbytes)} { Httpd_Error $sock 503 "File size limit ($upload(maxbytes) bytes) exceeded.<br>Unable to upload." return } } if {$upload(totalbytes) != -1} { set tot $upload(count) foreach f [glob -nocomplain -- [file join $upload(dir) 0]] { incr tot [file size $f] } if {$tot >= $upload(totalbytes)} { Httpd_Error $sock 503 "Total size limit ($upload(totalbytes) bytes) exceeded.<br>Unable to upload." return } } # Now that we are going to read the post data, clear out the # hook and the data count so noone else tries to read it Url_PostHook $sock 0 set data(count) 0 # Accept cr-lf endings in the headers fconfigure $sock -trans auto fileevent $sock readable [list UploadFindBoundary $sock] } # Look for the first boundary - should be the first line read, # but done in a fileevent to avoid blocking. proc UploadFindBoundary {sock} { upvar #0 Upload$sock upload if {[eof $sock]} { UploadDone $sock return } if {[gets $sock line] > 0} { if {[regexp ^--$upload(boundary) $line]} { fileevent $sock readable [list UploadReadHeader $sock] } else { Stderr "UploadFindBoundary Unexpected line $line" } } } # UploadReadHeader -- # This is a fileeventhandler used to read the header # of each part in a multipart POST payload. proc UploadReadHeader {sock} { upvar #0 Upload$sock upload if {[eof $sock]} { UploadDone $sock return } # Read through the POST data line-by-line looking for the # boundary and diverting file content into files in the # upload directory. We read in binary mode to preserve whatever # line-ending mode is in the uploaded file. while {[gets $sock line] >= 0} { # Check for an empty or white-space only line. if {[string length [string trim $line]] == 0} { # End of headers. We should have seen a name header # that is now in formName. Keep a list of those, and # store the other headers under that key. lappend upload(formNames) $upload(formName) set upload(hdrs,$upload(formName)) $upload(headers) # Now switch to reading the content of that part. # Use binary mode so we don't corrupt the file fconfigure $sock -trans binary -encoding binary if {[info exist upload(fd)]} { fileevent $sock readable [list UploadReadFile $sock] } else { fileevent $sock readable [list UploadReadPart $sock] } return } if {[regexp {([^: ]+):(.*)$} $line x hdrname value]} { set hdrname [string tolower $hdrname] set valueList [ncgi::parseMimeValue $value] if {[string equal $hdrname "content-disposition"]} { # Promote Conent-Disposition parameters up to headers, # and look for the "name" that identifies the form element lappend upload(headers) $hdrname [lindex $valueList 0] foreach {n v} [lindex $valueList 1] { lappend upload(headers) $n $v switch -- $n { "name" { set upload(formName) $v } "filename" { # Open the upload file # If the uploade file is empty string, # then use a temporary name--this request # will fail later. Netscape allows you # to upload dirnames like /a/b/, which # end up as empty string here. if {$v == ""} { set v "directory" } # I'm a bit suprised that "file tail" # when run on a Unix box will not deal # with c:\a\b\c.txt correctly... regsub -all {\\} $v / v set tail [file tail $v] if {$upload(unique)} { # make the file a unique name set path [file join $upload(dir) ${tail}.[clock clicks]] } else { set path [file join $upload(dir) $tail] } set upload(fd) [open $path w] set upload(lastLineExists) 0 # always do binary transfers fconfigure $upload(fd) -trans binary set upload(file,$upload(formName)) $path } } } } else { lappend upload(headers) $hdrname $valueList } } } if {[fblocked $sock]} { return } } # Look for the boundary at the end of a content part. proc UploadReadPart {sock} { upvar #0 Upload$sock upload if {[eof $sock]} { UploadDone $sock return } if {[gets $sock line] > 0} { if {[regexp ^--$upload(boundary)(--)? $line x end]} { if {$end == "--"} { UploadDone $sock } else { set upload(formName) "" set upload(headers) "" fileevent $sock readable [list UploadReadHeader $sock] } } else { # Trim the string to remove carriage returns. append upload(data,$upload(formName)) [string trim $line] } } } # Read a content part and copy it to a file. # Because the server is non-blocking, this may be called multiple times to # process a file. proc UploadReadFile {sock} { upvar #0 Upload$sock upload # Maximum size of the buffer, in characters, before we schedule # another read and update other waiting tasks. Increasing this # number will probably make uploads a little faster at the expense # of some responsiveness on the part of other clients attempting # to connect to the server. set maxbuffersize 1000 set buffersize 0 if {[eof $sock]} { UploadDone $sock return } while {[gets $sock line] >= 0} { if {[regexp ^--$upload(boundary)(--)? $line x end]} { if {$upload(lastLineExists)} { # At least 1 line was read. Write the last line to the # file without the trailing newline character. puts -nonewline $upload(fd) [string range $upload(lastLine) 0 end-1] } set buffersize 0 close $upload(fd) unset upload(fd) if {$end == "--"} { UploadDone $sock } else { set upload(formName) "" set upload(headers) "" fileevent $sock readable [list UploadReadHeader $sock] } return } else { # Delay the writing of each line to make sure we don't add an # extra trailing newline to the last line. if {$upload(lastLineExists)} { puts $upload(fd) $upload(lastLine) } else { set upload(lastLineExists) 1 } set upload(lastLine) $line } incr buffersize [string bytelength $line] if { $buffersize > $maxbuffersize } { set buffersize 0 fileevent $sock readable [list UploadReadFile $sock] update idletasks break } } } proc UploadDone {sock} { upvar #0 Upload$sock upload if {[catch { # The first argument is a list of file names that were uploaded # The second argument is a name-value list of the other data set flist {} set vlist {} foreach x $upload(formNames) { if {[info exist upload(file,$x)]} { lappend flist $x $upload(file,$x) } else { lappend vlist $x $upload(data,$x) } } eval $upload(cmd) [list $flist $vlist] } result] == 1} { # handle special error codes set ec $::errorCode switch -- [lindex $ec 0] { HTTPD_REDIRECT { Httpd_Redirect [lindex $ec 1] $sock return } HTTPD_SUSPEND { Httpd_Suspend $sock return } } } Httpd_ReturnData $sock text/html $result } # This is called as the "final" completion callback to clean up proc UploadTidyUp {sock errmsg} { upvar #0 Upload$sock upload unset upload } # UploadTest -- # Sample callback procedure for an upload domain proc UploadTest {flist vlist} { set html "<title>Upload Test</title>\n" append html "<h1>Upload Test</h1>\n" append html "<h2>File List</h2>\n" append html [html::tableFromList $flist]\n append html "<h2>Data List</h2>\n" append html [html::tableFromList $vlist]\n return $html } |
Added modules/httpd/url.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | # url.tcl # # This is the URL dispatcher. The URL hierarchy is divided into "domains" # that are subtrees of the URL space with a particular type. A domain is # identified by the name of its root, which is a prefix of the URLs in # that domain. The dispatcher selects a domain by the longest matching # prefix, and then calls a domain handler to process the URL. Different # domain handlers correspond to files (Doc), cgi-bin directories (Cgi), # and things built right into the application (Direct). # # URL processing is divided into two parts: access control and # url implementation. You register access hooks with # Url_AccessInstall, and you register URL implementations with # Url_PrefixInstall. # # Brent Welch (c) 1997 Sun Microsystems, 1998-2000 Scriptics Corporation. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # SCCS: @(#) url.tcl 1.7 97/08/20 11:50:13 package provide httpd::url 1.2 package require httpd ;# Httpd_CompletionCallback Httpd_Error Httpd_Filter Httpd_GetPostData Httpd_ReadPostDataAsync Httpd_Redirect Httpd_RequestComplete Httpd_SockClose Httpd_Suspend package require httpd::counter ;# Count CountName package require httpd::doc_error ;# Doc_Error package require httpd::threadmgr ;# Thread_Dispatch Thread_Enabled package require httpd::utils ;# File_Reset file ldelete # This pattern cannot occur inside a URL path component # On windows we disallow : to avoid drive-letter attacks switch $tcl_platform(platform) { windows { set Url(fsSep) {[/\\:]} } macintosh { set Url(fsSep) : } unix - default { set Url(fsSep) / } } # Url_Dispatch # # Dispatch to a type-specific handler for a URL # # Arguments # sock THe client socket connection # # Side Effects # Handle the request proc Url_Dispatch {sock} { global Url UrlCache upvar #0 Httpd$sock data catch {after cancel $data(cancel)} set url $data(url) CountName $url hit if {[catch { # INLINE VERSION OF Url_PrefixMatch # Collapse multiple // to avoid tricks like //cgi-bin that fail # to match the /cgi-bin prefix regsub -all /+ $url / url if {![regexp ^($Url(prefixset))(.*) $url x prefix suffix] || ([string length $suffix] && ![string match /* $suffix])} { # Fall back and assume it is under the root if {[string match /* $url]} { set suffix [string trimleft $url /] set prefix / } else { # Requested URL doesn't start with slash - bad request Httpd_Error $sock 400 return } } # END INLINE # Do access control before dispatch, # but after prefix/suffix determination set data(prefix) $prefix set data(suffix) $suffix CountName $prefix domainHit foreach hook $Url(accessHooks) { switch -- [eval $hook [list $sock $url]] { ok { break } return - denied { # A URL implementation should have generated the # appropriate response, such as a 403, to request # a retry. But, if it hasn't, we generate a default. if {![Httpd_RequestComplete $sock]} { Httpd_Error $sock 403 } return } skip { continue } } } # Register a callback with the Httpd layer if {[info exist Url(callback,$prefix)]} { Httpd_CompletionCallback $sock $Url(callback,$prefix) } if {[info exist Url(filter,$prefix)]} { Httpd_Filter $sock $Url(filter,$prefix) } # Pre-read the post data, if the domain wants that if {$Url(readpost,$prefix) && $data(count) > 0} { Httpd_ReadPostDataAsync $sock \ [list Url_DeferredDispatch $prefix $suffix] return } # Invoke the URL domain handler either in this main thread # or in a worker thread if {[info exists Url(dispatch,$prefix)]} { Count UrlCustom $Url(dispatch,$prefix) $sock \ [concat $Url(command,$prefix) [list $sock $suffix]] } elseif {$Url(thread,$prefix)} { Count UrlToThread Thread_Dispatch $sock \ [concat $Url(command,$prefix) [list $sock $suffix]] } else { Count UrlEval eval $Url(command,$prefix) [list $sock $suffix] } } error] == 1} { # Only do this on uncaught errors. # Note that the return statement for the "denied" case of the # access hook will result in catch returning code == 2, not 1 (or zero) global errorInfo global errorCode Url_Unwind $sock $errorInfo $errorCode } } # Url_DeferredDispatch # # Dispatch to a type-specific handler for a URL after the # post data has been read. # # Arguments # sock The client socket connection # # Side Effects # Handle the request proc Url_DeferredDispatch {prefix suffix sock varname errmsg} { global Url if {[string length $errmsg]} { Httpd_SockClose $sock 1 $errmsg return } Url_PostHook $sock 0 ;# Turn of Url_ReadPost if {[catch { # Invoke the URL domain handler either in this main thread # or in a worker thread if {$Url(thread,$prefix)} { Count UrlToThread Thread_Dispatch $sock \ [concat $Url(command,$prefix) [list $sock $suffix]] } else { Count UrlEval eval $Url(command,$prefix) [list $sock $suffix] } } error] == 1} { global errorInfo global errorCode Url_Unwind $sock $errorInfo $errorCode } } # Url_PrefixMatch # Match the domain prefix of a URL # # Arguments # url The input URL # suffixVar Output variable, the suffix # prefixVar Output variable, the prefix # # Results # Fills in prefix and suffix result variables proc Url_PrefixMatch {url prefixVar suffixVar} { global Url upvar 1 $prefixVar prefix upvar 1 $suffixVar suffix # Prefix match the URL to get a domain handler # Fast check on domain prefixes with regexp # Check that the suffix starts with /, otherwise the prefix # is not a complete component. E.g., "/tcl" vs "/tclhttpd" # where /tcl is a domain prefix but /tclhttpd is a directory # in the / domain. # IF YOU CHANGE THIS - FIX in-line CODE IN URL_DISPATCH # Collapse multiple // to avoid tricks like //cgi-bin that fail # to match the /cgi-bin prefix regsub -all /+ $url / url if {![info exist Url(prefixset)] || ![regexp ^($Url(prefixset))(.*) $url x prefix suffix] || ([string length $suffix] && ![string match /* $suffix])} { # Fall back and assume it is under the root # We assume that Url_Dispatch has filtered out bad urls already set suffix [string trimleft $url /] set prefix / } } # Url_PrefixExists # Determine if a prefix has been registered. # # Arguments # prefix The input URL # # Results # 0 or 1 proc Url_PrefixExists {prefix} { global Url return [info exist Url(command,$prefix)] } # Url_Unwind # Do common error handling after a URL request # # Arguments # sock The client connection # ei The errorInfo from the command # ec The errorCode from the command # # Side Effects # Clean up the connection and ensure a reply proc Url_Unwind {sock ei ec} { # URL implementations can raise special errors to unwind their processing. set key [lindex $ec 0] set error [lindex [split $ei \n] 0] switch -- $key { HTTPD_REDIRECT { # URL implementations can raise an error and put redirect info # into the errorCode variable, which should be of the form # HTTPD_REDIRECT $newurl Httpd_Redirect [lindex $ec 1] $sock return } HTTPD_SUSPEND { # The domain handler has until Httpd(timeout2) to complete this request Httpd_Suspend $sock return } } switch -glob -- $ei { "*can not find channel*" { Httpd_SockClose $sock 1 $error } "*too many open files*" { # this is lame and probably not necessary. # Early bugs lead to file descriptor leaks, but # these are all plugged up. Count numfiles Httpd_SockClose $sock 1 $error File_Reset } default { Doc_Error $sock $ei } } } # Url_AccessInstall # # Install an access check hook. # # Arguments # proc This is a command prefix that is invoked with two additional # arguments to check permissions: # sock The handle on the connection # url The url being accessed # The access hook should return: # "ok" Meaning access is allowed # "denied" Access is denied and the hook is responsible # for generating the Authenticate challenge # "skip" Meaning the hook doesn't care about the URL, # but perhaps another access control hook does. # # Side Effects # Save the access control hook proc Url_AccessInstall {proc} { global Url if {[lsearch $Url(accessHooks) $proc] < 0} { lappend Url(accessHooks) $proc } return } # Url_AccessInstallPrepend # # Exactly like AccessInstall, but puts the hook first in the list proc Url_AccessInstallPrepend {proc} { global Url if {[lsearch $Url(accessHooks) $proc] < 0} { set Url(accessHooks) [concat $proc $Url(accessHooks)] } return } # Url_AccessUnInstall # # Remove an access control hook # # Arguments # proc A procedure previously registered with Url_AccessInstall # # Side Effects # Remove the access control hook proc Url_AccessUnInstall {proc} { global Url set ix [lsearch $Url(accessHooks) $proc] if {$ix >= 0} { set Url(accessHooks) [lreplace $Url(accessHooks) $ix $ix] } return } if {![info exist Url(accessHooks)]} { set Url(accessHooks) {} } # Url_PrefixInstall # Declare that a handler exists for a point in the URL tree # identified by the prefix of all URLs below that point. # # Arguments: # prefix The leadin part of the URL, (e.., /foo/bar) # command THe Domain handler command. This is invoked with one # additional arument, $sock, that is the handle identifier # A well-known state array is available at # upvar #0 Httpd$sock # args This is either a single boolean that, for backwards # compatibility, indicates if the domain handler runs # in a thread, or an option-value list of: # -thread boolean # To indicate the domain handler runs in a thread # -callback cmd # A callback to make when the request completes # with or without error, timeout, etc. # -readpost boolean # To indicate we should pre-read POST data. # -filter cmd # A command filter to be run on dynamic content # -dispatch cmd # A custom dispatcher. The receiving command should # accept arguments similar to Thread_Dispatch. proc Url_PrefixInstall {prefix command args} { global Url # Add the url to the prefixset, which is a regular expression used # to pick off the prefix from the URL regsub -all {([][\\().*+?$|])} $prefix {\\\1} prefixquoted if {[string compare $prefix "/"] == 0} { # / is not in the prefixset because of some special cases. # See Url_Dispatch } elseif {![info exists Url(prefixset)]} { set Url(prefixset) $prefixquoted } else { set list [split $Url(prefixset) |] if {[lsearch $list $prefixquoted] < 0} { lappend list $prefixquoted } set Url(prefixset) [join [lsort -command UrlSort $list] |] } # Install the unquoted prefix so the Url dispatch works right set Url(command,$prefix) $command # Most domains have small amounts of POST data so we read it # by default for them. If you post massive amounts, create # a special domain that handles the post data specially. set readpost 1 # Check for options on the domain if {[llength $args] == 1} { # Compatibility with early 3.* versions that didn't take # arbitrary flags set tothread [lindex $args 0] } else { set tothread 0 foreach {n v} $args { switch -- $n { -thread { set tothread $v } -callback { set Url(callback,$prefix) $v } -readpost { set readpost $v } -filter { set Url(filter,$prefix) $v } -dispatch { set Url(dispatch,$prefix) $v } default { return -code error "Unknown option $n.\ Must be -callback, -dispatch, -filter, -readpost or -thread" } } } } set Url(readpost,$prefix) $readpost # The decision to use worker threads is done on a domain-by-domain basis # # Do the check against Thread_Enabled here instead of inside # Url_Dispatch. This means you cannot easily turn # threading on and off without restarting the server. set Url(thread,$prefix) [expr {[Thread_Enabled] ? $tothread : 0}] } # Url_PrefixRemove # # Undo a prefix registration # # Arguments: # prefix The leadin part of the URL, (e.., /foo/bar) # # Side Effects: # Remove the prefix from the dispatch set. proc Url_PrefixRemove {prefix} { global Url # Delete the prefix from the regular expression used to match URLs regsub -all {([][\\().*+?$|])} $prefix {\\\1} prefixquoted set list [split $Url(prefixset) |] ldelete list $prefixquoted set Url(prefixset) [join [lsort -command UrlSort $list] |] if {[info exist Url(command,$prefix)]} { unset Url(command,$prefix) unset Url(thread,$prefix) } if {[info exist Url(callback,$prefix)]} { unset Url(callback,$prefix) } if {[info exist Url(filter,$prefix)]} { unset Url(filter,$prefix) } } # UrlSort # # Sort the URL prefixes so the longest ones are first. # The makes the regular expression match the longest # matching prefix. # # Arguments: # a, b To URL prefixes # # Results: # 1 if b should sort before a, -1 if a should sort before b, else 0 proc UrlSort {a b} { set la [string length $a] set lb [string length $b] if {$la == $lb} { return [string compare $a $b] } elseif {$la < $lb} { return 1 } else { return -1 } } # Url_Handle # # Cache the handler for the url, then invoke it # # Arguments: # cmd The command to eval to handle a URL # sock The socket for the current connection. # # Side Effects: # None - used to "Caches the command used to handle the URL" proc Url_Handle {cmd sock} { # upvar #0 Httpd$sock data # global UrlCache # set UrlCache($data(url)) $cmd eval $cmd [list $sock] } # Url_UnCache # # Deleted the cached handler for a URL # # Arguments: # sock The socket for the current connection. # force If set, there is no special case for the redirect hack # # Side Effects: # Deletes the cached handler proc Url_UnCache {sock {force 0}} { upvar #0 Httpd$sock data global UrlCache if {[info exists UrlCache($data(url))]} { set redirect [regexp Redirect $UrlCache($data(url))] if {$force || !$redirect} { unset UrlCache($data(url)) } } } # Url_PathCheck # # Validate a pathname. Make sure it doesn't sneak out of its domain. # # Arguments: # urlsuffix The URL after the domain prefix # # Results: # Raises an error, or returns a list of components in the pathname proc Url_PathCheck {urlsuffix} { global Url set pathlist "" foreach part [split $urlsuffix /] { if {[string length $part] == 0} { # It is important *not* to "continue" here and skip # an empty component because it could be the last thing, # /a/b/c/ # which indicates a directory. In this case you want # Auth_Check to recurse into the directory in the last step. } set part [Url_Decode $part] # Disallow Mac and UNIX path separators in components # Windows drive-letters are bad, too if {[regexp $Url(fsSep) $part]} { error "URL components cannot include $Url(fsSep)" } switch -- $part { . { } .. { set len [llength $pathlist] if {[incr len -1] < 0} { error "URL out of range" } set pathlist [lrange $pathlist 0 [incr len -1]] } default { lappend pathlist $part } } } return $pathlist } proc Url_PostHook {sock length} { global Url # Backdoor hack for Url_DecodeQuery compatibility # We remember the current connection so that Url_DecodeQuery # can read the post data if it has not already been read by # the time it is called. set Url(sock) $sock set Url(postlength) $length } # convert a x-www-urlencoded string into a list of name/value pairs proc Url_DecodeQuery {query args} { global Url if {[info exist Url(sock)]} { Url_ReadPost $Url(sock) query } Url_DecodeQueryOnly $query {*}$args } # Url_QuerySetup -- # # Grab any query data and pass it to the ncgi:: module. # # Arguments: # sock The socket back to the client. # # Results: # None # # Side effects: # ncgi::reset, ncgi::parse, ncgi::urlstup proc Url_QuerySetup {sock} { upvar #0 Httpd$sock data set valuelist {} # search for comma separeted pair of numbers # as generated from server side map # e.g 190,202 # Bjorn Ruff. if { [regexp {^([0-9]+),([0-9]+)$} $data(query) match x y]} { set data(query) x=$x&y=$y } # Honor content type of the query data # Some browsers leave junk Content-Type lines in # non-post requests as a side effect of keep alive. if {[info exist data(mime,content-type)] && ("$data(proto)" != "GET")} { set type $data(mime,content-type) } else { set type application/x-www-urlencoded } # Grab POST data, if any, and initialize the ncgi:: interface Url_ReadPost $sock data(query) ncgi::reset $data(query) $type ncgi::parse ncgi::urlStub $data(url) return } proc Url_ReadPost {sock varname} { upvar 1 $varname query global Url append query "" if {[info exist Url(postlength)] && ($Url(postlength) > 0)} { # For compatibility with older versions of the Httpd module # that used to read all the post data for us, we read it now # if it hasn't already been read set result $Url(postlength) if {[string length $query]} { # This merges query data from the GET/POST URL append query & } while {$Url(postlength) > 0} { set Url(postlength) [Httpd_GetPostData $sock query] } unset Url(postlength) return $result } else { return 0 } } proc Url_DecodeQueryOnly {query args} { array set options {-type application/x-www-urlencoded -qualifiers {}} catch {array set options $args} if {[string length [info command Url_DecodeQuery_$options(-type)]] == 0} { set options(-type) application/x-www-urlencoded } return [Url_DecodeQuery_$options(-type) $query $options(-qualifiers)] } proc Url_DecodeQuery_application/x-www-urlencoded {query qualifiers} { # These foreach loops are structured this way to ensure there are matched # name/value pairs. Sometimes query data gets garbled. set result {} foreach pair [split $query "&"] { foreach {name value} [split $pair "="] { lappend result [Url_Decode $name] [Url_Decode $value] } } return $result } proc Url_Decode {data} { regsub -all {\+} $data " " data regsub -all {([][$\\])} $data {\\\1} data regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data {[format %c 0x\1]} data return [subst $data] } if 0 { proc UrlDecodeData {data} { regsub -all {([][$\\])} $data {\\\1} data regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data {[format %c 0x\1]} data return [subst $data] } } # Sharing procedure bodies doesn't work with compiled procs, # so these call each other instead of doing # proc xprime [info args x] [info body x] proc Url_DecodeQuery_application/x-www-form-urlencoded {query qualifiers} { Url_DecodeQuery_application/x-www-urlencoded $query $qualifiers } # steve: 5/8/98: This is a very crude start at parsing MIME documents # Return filename/content pairs proc Url_DecodeQuery_multipart/form-data {query qualifiers} { array set options {} catch {array set options $qualifiers} if {![info exists options(boundary)]} { return -code error "no boundary given for multipart document" } # Filter query into a list # Protect Tcl special characters # regsub -all {([\\{}])} $query {\\\\\\1} query regsub -all {(\\)} $query {\\\\\\001} query regsub -all {(\{)} $query {\\\\\\002} query regsub -all {(\})} $query {\\\\\\003} query regsub -all -- "(\r?\n?--)?$options(boundary)\r?\n?" $query "\} \{" data set data [subst -nocommands -novariables "\{$data\}"] # Remove first and last list elements, which will be empty set data [lrange [lreplace $data end end] 1 end] set result {} foreach element $data { # Get the headers from the element. Look for the first empty line. set headers {} set elementData {} # Protect Tcl special characters # regsub -all {([\\{}])} $element {\\\\\\1} element regsub -all {(\\)} $element {\\\\\\001} element regsub -all {(\{)} $element {\\\\\\002} element regsub -all {(\})} $element {\\\\\\003} element regsub \r?\n\r?\n $element "\} \{" element foreach {headers elementData} [subst -nocommands -novariables "\{$element\}"] break set headerList {} set parameterName {} regsub -all \r $headers {} headers foreach hdr [split $headers \n] { if {[string length $hdr]} { set headerName {} set headerData {} if {![regexp {[ ]*([^: ]+)[ ]*:[ ]*(.*)} $hdr discard headerName headerData]} { return -code error "malformed MIME header \"$hdr\"" } set headerName [string tolower $headerName] foreach {major minor quals} [Url_DecodeMIMEField $headerData] break # restore Tcl special characters regsub -all {(\\\001\001)} $quals {\\} quals regsub -all {(\\\001\002)} $quals {\{} quals regsub -all {(\\\001\003)} $quals {\}} quals switch -glob -- [string compare content-disposition $headerName],[string compare form-data $major] { 0,0 { # This is the name for this query parameter catch {unset param} array set param $quals set parameterName $param(name) # Include the remaining parameters, if any unset param(name) if {[llength [array names param]]} { lappend headerList [list $headerName $major [array get param]] } } default { lappend headerList [list $headerName $major/$minor $quals] } } } else { break } } # restore Tcl special characters regsub -all {(\\\001\001)} $elementData {\\} elementData regsub -all {(\\\001\002)} $elementData "{" elementData regsub -all {(\\\001\003)} $elementData "}" elementData lappend result $parameterName [list $headerList $elementData] } return $result } # Decode a MIME type # This could possibly move into the MIME module proc Url_DecodeMIMEField type { set qualList {} if {[regexp {([^;]+)[ ]*;[ ]*(.+)} $type discard type qualifiers]} { foreach qualifier [split $qualifiers \;] { if {[regexp {[ ]*([^=]+)="([^"]*)"} $qualifier discard name value]} { } elseif {[regexp {[ ]*([^=]+)='([^']*)'} $qualifier discard name value]} { } elseif {[regexp {[ ]*([^=]+)=([^ ]*)} $qualifier discard name value]} { } else { continue } lappend qualList $name $value } } foreach {major minor} [split $type /] break return [list [string trim $major] [string trim $minor] $qualList] } # do x-www-urlencoded character mapping # The spec says: "non-alphanumeric characters are replaced by '%HH'" for {set i 1} {$i <= 256} {incr i} { set c [format %c $i] if {![string match \[a-zA-Z0-9\] $c]} { set UrlEncodeMap($c) %[format %.2x $i] } } # These are handled specially array set UrlEncodeMap { " " + \n %0d%0a } # 1 leave alphanumerics characters alone # 2 Convert every other character to an array lookup # 3 Escape constructs that are "special" to the tcl parser # 4 "subst" the result, doing all the array substitutions proc Url_Encode {string} { global UrlEncodeMap regsub -all \[^a-zA-Z0-9\] $string {$UrlEncodeMap(&)} string regsub -all \n $string {\\n} string regsub -all \t $string {\\t} string regsub -all {[][{})\\]\)} $string {\\&} string return [subst $string] } # Url_IsLinkToSelf # Compare the link to the URL of the current page. # If they seem to be the same thing, return 1 # # Arguments: # url The URL to compare with. # # Results: # 1 if the input URL seems to be equivalent to the page's URL. # # Side Effects: # None proc Url_IsLinkToSelf {url} { global page return [expr {[string compare $url $page(url)] == 0}] } |
Added modules/httpd/utils.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | # utils.tcl # # Brent Welch (c) 1998-2000 Ajuba Solutions # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: utils.tcl,v 1.14 2004/10/22 03:43:06 coldstore Exp $ package provide httpd::utils 1.0 package require httpd::log ;# Log_SetFile # Stderr - print to standard error proc Stderr {string} { catch {puts stderr $string} } # iscommand - returns true if the command is defined or lives in auto_index. proc iscommand {name} { expr {([string length [info command $name]] > 0) || [auto_load $name]} } # lappendOnce - add to a list if not already there proc lappendOnce {listName value} { upvar $listName list if {![info exists list]} { lappend list $value } else { set ix [lsearch $list $value] if {$ix < 0} { lappend list $value } } } # setmax - set the variable to the maximum of its current value # or the value of the second argument # return 1 if the variable's value was changed. proc setmax {varName value} { upvar $varName var if {![info exists var] || ($value > $var)} { set var $value return 1 } return 0 } # setmin - set the variable to the minimum of its current value # or the value of the second argument # return 1 if the variable's value was changed. proc setmin {varName value} { upvar $varName var if {![info exists var] || ($value < $var)} { set var $value return 1 } return 0 } # Incr - version of incr that handles undefined variables. proc Incr {varName {value 1}} { upvar $varName var if {![info exists var]} { set var $value } else { set var [expr $var + $value] } } # Delete a list item by value. Returns 1 if the item was present, else 0 proc ldelete {varList value} { upvar $varList list if {![info exist list]} { return 0 } set ix [lsearch $list $value] if {$ix >= 0} { set list [lreplace $list $ix $ix] return 1 } else { return 0 } } # see if an option matches a list of options # return full option name if it does, otherwise "" # option: the name of the option (or unique prefix) # list: the list of valid options (e.g. -foo -bar ...) proc matchOption {option list} { if {![regexp -- {-[a-zA-Z0-9:_-]+} $option]} { error "Invalid option: \"$option\"" } if {[regsub -all -- "$option\[^ \]*" $list {} {}] == 1} { regexp -- "$option\[^ \]*" $list result return $result } else { return "" } } # Set local variables based on defaults - passed in as an array, and # a set of name value pairs. The "params" always override the current setting # of the local variables; the defaults only get set if no vars exist. # array: name of the array (with default values) # params: The "-name value" pairs to set proc optionSet {array params} { upvar $array options set list [array names options -*] foreach {option value} $params { set realoption [matchOption $option $list] if {$realoption != ""} { regexp -- {-(.*)} $realoption {} var uplevel [list set $var $value] } } foreach {name value} [array get options -*] { regexp -- {-(.*)} $name {} var upvar $var set if {![info exists set]} { uplevel [list set $var $value] } } } # "configure" for options in an array # name: The name of the array containing the options # args: The name value pairs proc optionConfigure {name args} { upvar $name data set len [llength $args] set list [array names data -*] if {$len > 1 && ($len % 2) == 1} { return -code error "optionConfigure Must have 1 or even number of arguments" } set result "" # return entire configuration list if {$len == 0} { foreach option [lsort $list] { lappend result $option $data($option) } # return a single configuration value } elseif {$len == 1} { set option [matchOption $args $list] if {$option == ""} { return -code error "$args is an invalid option, should be one of: [join $list ", "]." } set result $data($option) # Set a bunch of options } else { foreach {option value} $args { set realoption [matchOption $option $list] if {$realoption == ""} { return -code error "$option is an invalid option, should be one of: [join $list ", "]." } if {[info exists data(validate$realoption)]} { eval $data(validate$realoption) {data $realoption $value} } else { set data($realoption) $value } } } return $result } # print an import array proc poptions {array args} { upvar $array data puts "*** $array *** $args" foreach name [array names data] { regexp -- {-(.*)} $name {} var upvar $var value if {[info exists value]} { puts "${array}($var) = $value" } else { puts "${array}($var) = <unset>" } } } # simple random number generator snagged from the net set RNseed [pid] proc randomx {} { global RNseed set RNseed [expr 30903*($RNseed&65535)+($RNseed>>16)] return [format %.4x [expr int(32767*($RNseed & 65535)/65535.0)]] } # escape html characters (simple version) proc protect_text {text} { array set Map { < lt > gt & amp \" quot} regsub -all {[\\$]} $text {\\&} text regsub -all {[><&"]} $text {\&$Map(&);} text subst -nocommands $text } # File_Reset - hack to close files after a leak has sprung proc File_Reset {} { for {set i 5} {$i <= 1025} {incr i} { if {! [catch {close file$i}]} { append result file$i\n } } for {set i 10} {$i <= 1025} {incr i} { if {! [catch {close sock$i}]} { append result sock$i\n } } Log_SetFile return $result } # File_List - report which files are open. proc File_List {} { global OpenFiles for {set i 1} {$i <= 1025} {incr i} { if {! [catch {fconfigure file$i} conf]} { append result "file$i $conf\n" if {[info exist OpenFiles(file$i)]} { append result "file$i: $OpenFiles(file$i)\n" } } if {! [catch {fconfigure sock$i} conf]} { array set c {-peername {} -sockname {}} array set c $conf append result "sock$i $c(-peername) $c(-sockname)\n" } } return $result } # parray - version of parray that returns the result instead # of printing it out. proc parray {aname {pat *}} { upvar $aname a foreach name [array names a $pat] { setmax max [string length $name] } if {![info exists max]} { return {} } incr max [string length $aname] incr max 2 set result {} foreach name [lsort [array names a $pat]] { append result [list set ${aname}($name) $a($name)] append result \n } return $result } # # Example 27-3 # Listbox with optional scrollbars. # proc Scrolled_Listbox { f args } { frame $f listbox $f.list \ -xscrollcommand [list Scroll_Set $f.xscroll \ [list grid $f.xscroll -row 1 -column 0 -sticky we]] \ -yscrollcommand [list Scroll_Set $f.yscroll \ [list grid $f.yscroll -row 0 -column 1 -sticky ns]] $f.list configure {*}$args scrollbar $f.xscroll -orient horizontal \ -command [list $f.list xview] scrollbar $f.yscroll -orient vertical \ -command [list $f.list yview] grid $f.list $f.yscroll -sticky news grid $f.xscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 return $f.list } # # Example 27-1 # A text widget and two scrollbars. # proc Scrolled_Text { f args } { frame $f eval {text $f.text \ -xscrollcommand [list $f.xscroll set] \ -yscrollcommand [list $f.yscroll set]} $args scrollbar $f.xscroll -orient horizontal \ -command [list $f.text xview] scrollbar $f.yscroll -orient vertical \ -command [list $f.text yview] grid $f.text $f.yscroll -sticky news grid $f.xscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 return $f.text } # # Example 27-2 # Scroll_Set manages optional scrollbars. # proc Scroll_Set {scrollbar geoCmd offset size} { if {$offset != 0.0 || $size != 1.0} { eval $geoCmd ;# Make sure it is visible $scrollbar set $offset $size } else { set manager [lindex $geoCmd 0] $manager forget $scrollbar ;# hide it } } # # Example 31-1 # A large scrolling canvas. # proc Scrolled_Canvas { c args } { frame $c eval {canvas $c.canvas \ -xscrollcommand [list $c.xscroll set] \ -yscrollcommand [list $c.yscroll set] \ -highlightthickness 0 \ -borderwidth 0} $args scrollbar $c.xscroll -orient horizontal \ -command [list $c.canvas xview] scrollbar $c.yscroll -orient vertical \ -command [list $c.canvas yview] grid $c.canvas $c.yscroll -sticky news grid $c.xscroll -sticky ew grid rowconfigure $c 0 -weight 1 grid columnconfigure $c 0 -weight 1 return $c.canvas } proc ChopLine {line {limit 72}} { regsub -all " *\n" $line " " line set new {} while {[string length $line] > $limit} { set hit 0 for {set c $limit} {$c >= 0} {incr c -1} { set char [string index $line $c] if {[regexp \[\ \t\n>/\] $char]} { set hit 1 break } } if !$hit { set c $limit } append new [string trimright [string range $line 0 $c]]\n incr c set line [string range $line $c end] } append new "$line" return $new } # boolean -- # # Convert boolean values to 0/1 # # Arguments: # value boolean value: true/false, on/off, yes/no, etc # # Results: # Returns 0 or 1. proc boolean value { if {!([regsub -nocase {^(1|yes|true|on)$} $value 1 value] || \ [regsub -nocase {^(0|no|false|off)$} $value 0 value])} { error "boolean value expected" } return $value } # file_latest -- # # Return the newest file from the list. # # Arguments: # files A list of filenames. # # Results: # None # # Side Effects: # The name of the newest file. proc file_latest {files} { set newest {} foreach file $files { if {[file readable $file]} { set m [file mtime $file] if {![info exist mtime] || ($m > $mtime)} { set mtime $m set newest $file } } } return $newest } if {([package vcompare [package provide Tcl] 7.6] < 0) && [string match unix $tcl_platform(platform)]} { # The subcommands copy, delete, rename, and mkdir were added to # the Tcl command 'file' in Tcl version 7.6. The following command # approximates them on Unix platforms. It may not agree with # the Tcl 7.6+ command 'file' in all of its functionality (notably # the way it reports errors). Further refinements should be made as # needed. rename file Tcl7.5_file proc file {option args} { switch -glob -- $option { c* { if {[string first $option copy] != 0} { return [uplevel [list Tcl7.5_file $option] $args] } # Translate -force into -f if {[string match -force [lindex $args 0]]} { set args [lreplace $args 0 0 -f] } uplevel exec cp $args } de* { if {[string first $option delete] != 0} { return [uplevel [list Tcl7.5_file $option] $args] } if {[string match -force [lindex $args 0]]} { set args [lreplace $args 0 0 -f] } catch {uplevel exec rm $args} } mk* { if {[string first $option mkdir] != 0} { return [uplevel [list Tcl7.5_file $option] $args] } uplevel exec mkdir $args } ren* { if {[string first $option rename] != 0} { return [uplevel [list Tcl7.5_file $option] $args] } if {[string match -force [lindex $args 0]]} { set args [lreplace $args 0 0 -f] } uplevel exec mv $args } default { uplevel [list Tcl7.5_file $option] $args } } } } if {[package vcompare [package provide Tcl] 8] < 0} { # The subcommands nativename and attributes were added to # the Tcl command 'file' in Tcl version 8.0. Here is an approximation # for earlier Tcl versions: rename file Tcl7.6_file ;proc file {option args} { switch -glob -- $option { att* { if {[string first $option attributes] != 0} { uplevel [list Tcl7.6_file $option] $args } return -code error "Tcl [package provide Tcl] does not support\ \[file attributes\].\n\tUpgrade to Tcl 8.0 to use it." } n* { if {[string first $option nativename] != 0} { uplevel [list Tcl7.6_file $option] $args } if {![llength $args]} { return -code error "wrong # args: should be\ \"file nativename name ?arg ...?\"" } set fcomps [file split [lindex $args 0]] # Take care of tilde substitution set first [lindex $fcomps 0] if {[string match ~* $first]} { set first [file join [file dirname $first] [file tail $first]] } set result [eval file join [list $first] [lrange $fcomps 1 end]] global tcl_platform if {[string match windows $tcl_platform(platform)]} { regsub -all -- / $result \\ result } return $result } default { uplevel [list Tcl7.6_file $option] $args } } } } if {[package vcompare [package provide Tcl] 8.4] < 0} { # The subcommands nativename and attributes were added to # the Tcl command 'file' in Tcl version 8.0. Here is an approximation # for earlier Tcl versions: rename file Tcl8.0_file ;proc file {option args} { switch -glob -- $option { norm* { set sp [file split [lindex $args 0]] if {[file pathtype [lindex $sp 0]] == "relative"} { set sp [file split [eval [list file join [pwd]] $sp]] } set np {} foreach ele $sp { if {$ele != ".."} { if {$ele != "."} { lappend np $ele } } elseif {[llength $np]> 1} { set np [lrange $np 0 [expr {[llength $np] - 2}]] } } if {[llength $np] > 0} { return [eval file join $np] } } default { uplevel [list Tcl8.0_file $option] $args } } } } # see http://mini.net/tcl/lambda proc K {a b} {set a} proc lambda {argl body} {K [info level 0] [proc [info level 0] $argl $body]} |
Added modules/httpd/version.tcl.
> > > > > | 1 2 3 4 5 | package provide httpd::version 4.0 proc Httpd_Version {} { global Httpd set Httpd(version) "4.0.0 FOS" } |
Added modules/jshash/js/md5-min.js.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ var hexcase=0;function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}function hex_hmac_md5(a,b){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a),str2rstr_utf8(b)))}function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}function rstr_md5(a){return binl2rstr(binl_md5(rstr2binl(a),a.length*8))}function rstr_hmac_md5(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_md5(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_md5(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_md5(d.concat(g),512+128))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_md5(p,k){p[k>>5]|=128<<((k)%32);p[(((k+64)>>>9)<<4)+14]=k;var o=1732584193;var n=-271733879;var m=-1732584194;var l=271733878;for(var g=0;g<p.length;g+=16){var j=o;var h=n;var f=m;var e=l;o=md5_ff(o,n,m,l,p[g+0],7,-680876936);l=md5_ff(l,o,n,m,p[g+1],12,-389564586);m=md5_ff(m,l,o,n,p[g+2],17,606105819);n=md5_ff(n,m,l,o,p[g+3],22,-1044525330);o=md5_ff(o,n,m,l,p[g+4],7,-176418897);l=md5_ff(l,o,n,m,p[g+5],12,1200080426);m=md5_ff(m,l,o,n,p[g+6],17,-1473231341);n=md5_ff(n,m,l,o,p[g+7],22,-45705983);o=md5_ff(o,n,m,l,p[g+8],7,1770035416);l=md5_ff(l,o,n,m,p[g+9],12,-1958414417);m=md5_ff(m,l,o,n,p[g+10],17,-42063);n=md5_ff(n,m,l,o,p[g+11],22,-1990404162);o=md5_ff(o,n,m,l,p[g+12],7,1804603682);l=md5_ff(l,o,n,m,p[g+13],12,-40341101);m=md5_ff(m,l,o,n,p[g+14],17,-1502002290);n=md5_ff(n,m,l,o,p[g+15],22,1236535329);o=md5_gg(o,n,m,l,p[g+1],5,-165796510);l=md5_gg(l,o,n,m,p[g+6],9,-1069501632);m=md5_gg(m,l,o,n,p[g+11],14,643717713);n=md5_gg(n,m,l,o,p[g+0],20,-373897302);o=md5_gg(o,n,m,l,p[g+5],5,-701558691);l=md5_gg(l,o,n,m,p[g+10],9,38016083);m=md5_gg(m,l,o,n,p[g+15],14,-660478335);n=md5_gg(n,m,l,o,p[g+4],20,-405537848);o=md5_gg(o,n,m,l,p[g+9],5,568446438);l=md5_gg(l,o,n,m,p[g+14],9,-1019803690);m=md5_gg(m,l,o,n,p[g+3],14,-187363961);n=md5_gg(n,m,l,o,p[g+8],20,1163531501);o=md5_gg(o,n,m,l,p[g+13],5,-1444681467);l=md5_gg(l,o,n,m,p[g+2],9,-51403784);m=md5_gg(m,l,o,n,p[g+7],14,1735328473);n=md5_gg(n,m,l,o,p[g+12],20,-1926607734);o=md5_hh(o,n,m,l,p[g+5],4,-378558);l=md5_hh(l,o,n,m,p[g+8],11,-2022574463);m=md5_hh(m,l,o,n,p[g+11],16,1839030562);n=md5_hh(n,m,l,o,p[g+14],23,-35309556);o=md5_hh(o,n,m,l,p[g+1],4,-1530992060);l=md5_hh(l,o,n,m,p[g+4],11,1272893353);m=md5_hh(m,l,o,n,p[g+7],16,-155497632);n=md5_hh(n,m,l,o,p[g+10],23,-1094730640);o=md5_hh(o,n,m,l,p[g+13],4,681279174);l=md5_hh(l,o,n,m,p[g+0],11,-358537222);m=md5_hh(m,l,o,n,p[g+3],16,-722521979);n=md5_hh(n,m,l,o,p[g+6],23,76029189);o=md5_hh(o,n,m,l,p[g+9],4,-640364487);l=md5_hh(l,o,n,m,p[g+12],11,-421815835);m=md5_hh(m,l,o,n,p[g+15],16,530742520);n=md5_hh(n,m,l,o,p[g+2],23,-995338651);o=md5_ii(o,n,m,l,p[g+0],6,-198630844);l=md5_ii(l,o,n,m,p[g+7],10,1126891415);m=md5_ii(m,l,o,n,p[g+14],15,-1416354905);n=md5_ii(n,m,l,o,p[g+5],21,-57434055);o=md5_ii(o,n,m,l,p[g+12],6,1700485571);l=md5_ii(l,o,n,m,p[g+3],10,-1894986606);m=md5_ii(m,l,o,n,p[g+10],15,-1051523);n=md5_ii(n,m,l,o,p[g+1],21,-2054922799);o=md5_ii(o,n,m,l,p[g+8],6,1873313359);l=md5_ii(l,o,n,m,p[g+15],10,-30611744);m=md5_ii(m,l,o,n,p[g+6],15,-1560198380);n=md5_ii(n,m,l,o,p[g+13],21,1309151649);o=md5_ii(o,n,m,l,p[g+4],6,-145523070);l=md5_ii(l,o,n,m,p[g+11],10,-1120210379);m=md5_ii(m,l,o,n,p[g+2],15,718787259);n=md5_ii(n,m,l,o,p[g+9],21,-343485551);o=safe_add(o,j);n=safe_add(n,h);m=safe_add(m,f);l=safe_add(l,e)}return Array(o,n,m,l)}function md5_cmn(h,e,d,c,g,f){return safe_add(bit_rol(safe_add(safe_add(e,h),safe_add(c,f)),g),d)}function md5_ff(g,f,k,j,e,i,h){return md5_cmn((f&k)|((~f)&j),g,f,e,i,h)}function md5_gg(g,f,k,j,e,i,h){return md5_cmn((f&j)|(k&(~j)),g,f,e,i,h)}function md5_hh(g,f,k,j,e,i,h){return md5_cmn(f^k^j,g,f,e,i,h)}function md5_ii(g,f,k,j,e,i,h){return md5_cmn(k^(f|(~j)),g,f,e,i,h)}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))}; |
Added modules/jshash/js/md5.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } function hex_hmac_md5(k, d) { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_md5(k, d) { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_md5(k, d, e) { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } /* * Perform a simple self-test to see if the VM is working */ function md5_vm_test() { return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72"; } /* * Calculate the MD5 of a raw string */ function rstr_md5(s) { return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); } /* * Calculate the HMAC-MD5, of a key and some data (raw strings) */ function rstr_hmac_md5(key, data) { var bkey = rstr2binl(key); if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { try { hexcase } catch(e) { hexcase=0; } var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var output = ""; var x; for(var i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt( x & 0x0F); } return output; } /* * Convert a raw string to a base-64 string */ function rstr2b64(input) { try { b64pad } catch(e) { b64pad=''; } var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var output = ""; var len = input.length; for(var i = 0; i < len; i += 3) { var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i+2) : 0); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); } } return output; } /* * Convert a raw string to an arbitrary string encoding */ function rstr2any(input, encoding) { var divisor = encoding.length; var i, j, q, x, quotient; /* Convert to an array of 16-bit big-endian values, forming the dividend */ var dividend = Array(Math.ceil(input.length / 2)); for(i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. All remainders are stored for later * use. */ var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); var remainders = Array(full_length); for(j = 0; j < full_length; j++) { quotient = Array(); x = 0; for(i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if(quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[j] = x; dividend = quotient; } /* Convert the remainders to the output string */ var output = ""; for(i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); return output; } /* * Encode a string as utf-8. * For efficiency, this assumes the input is valid utf-16. */ function str2rstr_utf8(input) { var output = ""; var i = -1; var x, y; while(++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); i++; } /* Encode output as utf-8 */ if(x <= 0x7F) output += String.fromCharCode(x); else if(x <= 0x7FF) output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F)); else if(x <= 0xFFFF) output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); else if(x <= 0x1FFFFF) output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); } return output; } /* * Encode a string as utf-16 */ function str2rstr_utf16le(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); return output; } function str2rstr_utf16be(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); return output; } /* * Convert a raw string to an array of little-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binl(input) { var output = Array(input.length >> 2); for(var i = 0; i < output.length; i++) output[i] = 0; for(var i = 0; i < input.length * 8; i += 8) output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); return output; } /* * Convert an array of little-endian words to a string */ function binl2rstr(input) { var output = ""; for(var i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); return output; } /* * Calculate the MD5 of an array of little-endian words, and a bit length. */ function binl_md5(x, len) { /* append padding */ x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i+10], 17, -42063); b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); } /* * These functions implement the four basic operations the algorithm uses. */ function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); } function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); } function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); } function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } |
Added modules/jshash/js/ripemd160-min.js.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | /* * A JavaScript implementation of the RIPEMD-160 Algorithm * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. * Also http://www.esat.kuleuven.ac.be/~cosicart/pdf/AB-9601/ */ var hexcase=0;function hex_rmd160(a){return rstr2hex(rstr_rmd160(str2rstr_utf8(a)))}function hex_hmac_rmd160(a,b){return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(a),str2rstr_utf8(b)))}function rmd160_vm_test(){return hex_rmd160("abc").toLowerCase()=="8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"}function rstr_rmd160(a){return binl2rstr(binl_rmd160(rstr2binl(a),a.length*8))}function rstr_hmac_rmd160(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_rmd160(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_rmd160(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_rmd160(d.concat(g),512+160))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_rmd160(q,v){q[v>>5]|=128<<(v%32);q[(((v+64)>>>9)<<4)+14]=v;var l=1732584193;var k=4023233417;var h=2562383102;var g=271733878;var f=3285377520;for(var u=0;u<q.length;u+=16){var e;var c=l,o=k,t=h,d=g,p=f;var a=l,m=k,s=h,b=g,n=f;for(var r=0;r<=79;++r){e=safe_add(c,rmd160_f(r,o,t,d));e=safe_add(e,q[u+rmd160_r1[r]]);e=safe_add(e,rmd160_K1(r));e=safe_add(bit_rol(e,rmd160_s1[r]),p);c=p;p=d;d=bit_rol(t,10);t=o;o=e;e=safe_add(a,rmd160_f(79-r,m,s,b));e=safe_add(e,q[u+rmd160_r2[r]]);e=safe_add(e,rmd160_K2(r));e=safe_add(bit_rol(e,rmd160_s2[r]),n);a=n;n=b;b=bit_rol(s,10);s=m;m=e}e=safe_add(k,safe_add(t,b));k=safe_add(h,safe_add(d,n));h=safe_add(g,safe_add(p,a));g=safe_add(f,safe_add(c,m));f=safe_add(l,safe_add(o,s));l=e}return[l,k,h,g,f]}function rmd160_f(b,a,d,c){return(0<=b&&b<=15)?(a^d^c):(16<=b&&b<=31)?(a&d)|(~a&c):(32<=b&&b<=47)?(a|~d)^c:(48<=b&&b<=63)?(a&c)|(d&~c):(64<=b&&b<=79)?a^(d|~c):"rmd160_f: j out of range"}function rmd160_K1(a){return(0<=a&&a<=15)?0:(16<=a&&a<=31)?1518500249:(32<=a&&a<=47)?1859775393:(48<=a&&a<=63)?2400959708:(64<=a&&a<=79)?2840853838:"rmd160_K1: j out of range"}function rmd160_K2(a){return(0<=a&&a<=15)?1352829926:(16<=a&&a<=31)?1548603684:(32<=a&&a<=47)?1836072691:(48<=a&&a<=63)?2053994217:(64<=a&&a<=79)?0:"rmd160_K2: j out of range"}var rmd160_r1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13];var rmd160_r2=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11];var rmd160_s1=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6];var rmd160_s2=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11];function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))}; |
Added modules/jshash/js/ripemd160.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | /* * A JavaScript implementation of the RIPEMD-160 Algorithm * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/ */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_rmd160(s) { return rstr2hex(rstr_rmd160(str2rstr_utf8(s))); } function b64_rmd160(s) { return rstr2b64(rstr_rmd160(str2rstr_utf8(s))); } function any_rmd160(s, e) { return rstr2any(rstr_rmd160(str2rstr_utf8(s)), e); } function hex_hmac_rmd160(k, d) { return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_rmd160(k, d) { return rstr2b64(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_rmd160(k, d, e) { return rstr2any(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d)), e); } /* * Perform a simple self-test to see if the VM is working */ function rmd160_vm_test() { return hex_rmd160("abc").toLowerCase() == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"; } /* * Calculate the rmd160 of a raw string */ function rstr_rmd160(s) { return binl2rstr(binl_rmd160(rstr2binl(s), s.length * 8)); } /* * Calculate the HMAC-rmd160 of a key and some data (raw strings) */ function rstr_hmac_rmd160(key, data) { var bkey = rstr2binl(key); if(bkey.length > 16) bkey = binl_rmd160(bkey, key.length * 8); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = binl_rmd160(ipad.concat(rstr2binl(data)), 512 + data.length * 8); return binl2rstr(binl_rmd160(opad.concat(hash), 512 + 160)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { try { hexcase } catch(e) { hexcase=0; } var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var output = ""; var x; for(var i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt( x & 0x0F); } return output; } /* * Convert a raw string to a base-64 string */ function rstr2b64(input) { try { b64pad } catch(e) { b64pad=''; } var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var output = ""; var len = input.length; for(var i = 0; i < len; i += 3) { var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i+2) : 0); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); } } return output; } /* * Convert a raw string to an arbitrary string encoding */ function rstr2any(input, encoding) { var divisor = encoding.length; var remainders = Array(); var i, q, x, quotient; /* Convert to an array of 16-bit big-endian values, forming the dividend */ var dividend = Array(Math.ceil(input.length / 2)); for(i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. We stop when the dividend is zero. * All remainders are stored for later use. */ while(dividend.length > 0) { quotient = Array(); x = 0; for(i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if(quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[remainders.length] = x; dividend = quotient; } /* Convert the remainders to the output string */ var output = ""; for(i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); /* Append leading zero equivalents */ var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))) for(i = output.length; i < full_length; i++) output = encoding[0] + output; return output; } /* * Encode a string as utf-8. * For efficiency, this assumes the input is valid utf-16. */ function str2rstr_utf8(input) { var output = ""; var i = -1; var x, y; while(++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); i++; } /* Encode output as utf-8 */ if(x <= 0x7F) output += String.fromCharCode(x); else if(x <= 0x7FF) output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F)); else if(x <= 0xFFFF) output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); else if(x <= 0x1FFFFF) output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); } return output; } /* * Encode a string as utf-16 */ function str2rstr_utf16le(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); return output; } function str2rstr_utf16be(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); return output; } /* * Convert a raw string to an array of little-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binl(input) { var output = Array(input.length >> 2); for(var i = 0; i < output.length; i++) output[i] = 0; for(var i = 0; i < input.length * 8; i += 8) output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); return output; } /* * Convert an array of little-endian words to a string */ function binl2rstr(input) { var output = ""; for(var i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); return output; } /* * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length. */ function binl_rmd160(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (len % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var h0 = 0x67452301; var h1 = 0xefcdab89; var h2 = 0x98badcfe; var h3 = 0x10325476; var h4 = 0xc3d2e1f0; for (var i = 0; i < x.length; i += 16) { var T; var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4; var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4; for (var j = 0; j <= 79; ++j) { T = safe_add(A1, rmd160_f(j, B1, C1, D1)); T = safe_add(T, x[i + rmd160_r1[j]]); T = safe_add(T, rmd160_K1(j)); T = safe_add(bit_rol(T, rmd160_s1[j]), E1); A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T; T = safe_add(A2, rmd160_f(79-j, B2, C2, D2)); T = safe_add(T, x[i + rmd160_r2[j]]); T = safe_add(T, rmd160_K2(j)); T = safe_add(bit_rol(T, rmd160_s2[j]), E2); A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T; } T = safe_add(h1, safe_add(C1, D2)); h1 = safe_add(h2, safe_add(D1, E2)); h2 = safe_add(h3, safe_add(E1, A2)); h3 = safe_add(h4, safe_add(A1, B2)); h4 = safe_add(h0, safe_add(B1, C2)); h0 = T; } return [h0, h1, h2, h3, h4]; } function rmd160_f(j, x, y, z) { return ( 0 <= j && j <= 15) ? (x ^ y ^ z) : (16 <= j && j <= 31) ? (x & y) | (~x & z) : (32 <= j && j <= 47) ? (x | ~y) ^ z : (48 <= j && j <= 63) ? (x & z) | (y & ~z) : (64 <= j && j <= 79) ? x ^ (y | ~z) : "rmd160_f: j out of range"; } function rmd160_K1(j) { return ( 0 <= j && j <= 15) ? 0x00000000 : (16 <= j && j <= 31) ? 0x5a827999 : (32 <= j && j <= 47) ? 0x6ed9eba1 : (48 <= j && j <= 63) ? 0x8f1bbcdc : (64 <= j && j <= 79) ? 0xa953fd4e : "rmd160_K1: j out of range"; } function rmd160_K2(j) { return ( 0 <= j && j <= 15) ? 0x50a28be6 : (16 <= j && j <= 31) ? 0x5c4dd124 : (32 <= j && j <= 47) ? 0x6d703ef3 : (48 <= j && j <= 63) ? 0x7a6d76e9 : (64 <= j && j <= 79) ? 0x00000000 : "rmd160_K2: j out of range"; } var rmd160_r1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ]; var rmd160_r2 = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ]; var rmd160_s1 = [ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]; var rmd160_s2 = [ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]; /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } |
Added modules/jshash/js/sha1-min.js.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS 180-1 * Version 2.2 Copyright Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ var hexcase=0;var b64pad="";function hex_sha1(a){return rstr2hex(rstr_sha1(str2rstr_utf8(a)))}function hex_hmac_sha1(a,b){return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha1_vm_test(){return hex_sha1("abc").toLowerCase()=="a9993e364706816aba3e25717850c26c9cd0d89d"}function rstr_sha1(a){return binb2rstr(binb_sha1(rstr2binb(a),a.length*8))}function rstr_hmac_sha1(c,f){var e=rstr2binb(c);if(e.length>16){e=binb_sha1(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha1(a.concat(rstr2binb(f)),512+f.length*8);return binb2rstr(binb_sha1(d.concat(g),512+160))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}function binb_sha1(v,o){v[o>>5]|=128<<(24-o%32);v[((o+64>>9)<<4)+15]=o;var y=Array(80);var u=1732584193;var s=-271733879;var r=-1732584194;var q=271733878;var p=-1009589776;for(var l=0;l<v.length;l+=16){var n=u;var m=s;var k=r;var h=q;var f=p;for(var g=0;g<80;g++){if(g<16){y[g]=v[l+g]}else{y[g]=bit_rol(y[g-3]^y[g-8]^y[g-14]^y[g-16],1)}var z=safe_add(safe_add(bit_rol(u,5),sha1_ft(g,s,r,q)),safe_add(safe_add(p,y[g]),sha1_kt(g)));p=q;q=r;r=bit_rol(s,30);s=u;u=z}u=safe_add(u,n);s=safe_add(s,m);r=safe_add(r,k);q=safe_add(q,h);p=safe_add(p,f)}return Array(u,s,r,q,p)}function sha1_ft(e,a,g,f){if(e<20){return(a&g)|((~a)&f)}if(e<40){return a^g^f}if(e<60){return(a&g)|(a&f)|(g&f)}return a^g^f}function sha1_kt(a){return(a<20)?1518500249:(a<40)?1859775393:(a<60)?-1894007588:-899497514}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))}; |
Added modules/jshash/js/sha1.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS 180-1 * Version 2.2 Copyright Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); } function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); } function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); } function hex_hmac_sha1(k, d) { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_sha1(k, d) { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_sha1(k, d, e) { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); } /* * Perform a simple self-test to see if the VM is working */ function sha1_vm_test() { return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d"; } /* * Calculate the SHA1 of a raw string */ function rstr_sha1(s) { return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8)); } /* * Calculate the HMAC-SHA1 of a key and some data (raw strings) */ function rstr_hmac_sha1(key, data) { var bkey = rstr2binb(key); if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8); return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { try { hexcase } catch(e) { hexcase=0; } var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var output = ""; var x; for(var i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt( x & 0x0F); } return output; } /* * Convert a raw string to a base-64 string */ function rstr2b64(input) { try { b64pad } catch(e) { b64pad=''; } var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var output = ""; var len = input.length; for(var i = 0; i < len; i += 3) { var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i+2) : 0); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); } } return output; } /* * Convert a raw string to an arbitrary string encoding */ function rstr2any(input, encoding) { var divisor = encoding.length; var remainders = Array(); var i, q, x, quotient; /* Convert to an array of 16-bit big-endian values, forming the dividend */ var dividend = Array(Math.ceil(input.length / 2)); for(i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. We stop when the dividend is zero. * All remainders are stored for later use. */ while(dividend.length > 0) { quotient = Array(); x = 0; for(i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if(quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[remainders.length] = x; dividend = quotient; } /* Convert the remainders to the output string */ var output = ""; for(i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); /* Append leading zero equivalents */ var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))) for(i = output.length; i < full_length; i++) output = encoding[0] + output; return output; } /* * Encode a string as utf-8. * For efficiency, this assumes the input is valid utf-16. */ function str2rstr_utf8(input) { var output = ""; var i = -1; var x, y; while(++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); i++; } /* Encode output as utf-8 */ if(x <= 0x7F) output += String.fromCharCode(x); else if(x <= 0x7FF) output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F)); else if(x <= 0xFFFF) output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); else if(x <= 0x1FFFFF) output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); } return output; } /* * Encode a string as utf-16 */ function str2rstr_utf16le(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); return output; } function str2rstr_utf16be(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); return output; } /* * Convert a raw string to an array of big-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binb(input) { var output = Array(input.length >> 2); for(var i = 0; i < output.length; i++) output[i] = 0; for(var i = 0; i < input.length * 8; i += 8) output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); return output; } /* * Convert an array of big-endian words to a string */ function binb2rstr(input) { var output = ""; for(var i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); return output; } /* * Calculate the SHA-1 of an array of big-endian words, and a bit length */ function binb_sha1(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (24 - len % 32); x[((len + 64 >> 9) << 4) + 15] = len; var w = Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; for(var j = 0; j < 80; j++) { if(j < 16) w[j] = x[i + j]; else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); e = d; d = c; c = bit_rol(b, 30); b = a; a = t; } a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); e = safe_add(e, olde); } return Array(a, b, c, d, e); } /* * Perform the appropriate triplet combination function for the current * iteration */ function sha1_ft(t, b, c, d) { if(t < 20) return (b & c) | ((~b) & d); if(t < 40) return b ^ c ^ d; if(t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d; } /* * Determine the appropriate additive constant for the current iteration */ function sha1_kt(t) { return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } |
Added modules/jshash/js/sha256-min.js.
> > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. * Also http://anmar.eu.org/projects/jssha2/ */ var hexcase=0;function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha256_vm_test(){return hex_sha256("abc").toLowerCase()=="ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),a.length*8))}function rstr_hmac_sha256(c,f){var e=rstr2binb(c);if(e.length>16){e=binb_sha256(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha256(a.concat(rstr2binb(f)),512+f.length*8);return binb2rstr(binb_sha256(d.concat(g),512+256))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}function sha256_S(b,a){return(b>>>a)|(b<<(32-a))}function sha256_R(b,a){return(b>>>a)}function sha256_Ch(a,c,b){return((a&c)^((~a)&b))}function sha256_Maj(a,c,b){return((a&c)^(a&b)^(c&b))}function sha256_Sigma0256(a){return(sha256_S(a,2)^sha256_S(a,13)^sha256_S(a,22))}function sha256_Sigma1256(a){return(sha256_S(a,6)^sha256_S(a,11)^sha256_S(a,25))}function sha256_Gamma0256(a){return(sha256_S(a,7)^sha256_S(a,18)^sha256_R(a,3))}function sha256_Gamma1256(a){return(sha256_S(a,17)^sha256_S(a,19)^sha256_R(a,10))}function sha256_Sigma0512(a){return(sha256_S(a,28)^sha256_S(a,34)^sha256_S(a,39))}function sha256_Sigma1512(a){return(sha256_S(a,14)^sha256_S(a,18)^sha256_S(a,41))}function sha256_Gamma0512(a){return(sha256_S(a,1)^sha256_S(a,8)^sha256_R(a,7))}function sha256_Gamma1512(a){return(sha256_S(a,19)^sha256_S(a,61)^sha256_R(a,6))}var sha256_K=new Array(1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998);function binb_sha256(n,o){var p=new Array(1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225);var k=new Array(64);var B,A,z,y,w,u,t,s;var r,q,x,v;n[o>>5]|=128<<(24-o%32);n[((o+64>>9)<<4)+15]=o;for(r=0;r<n.length;r+=16){B=p[0];A=p[1];z=p[2];y=p[3];w=p[4];u=p[5];t=p[6];s=p[7];for(q=0;q<64;q++){if(q<16){k[q]=n[q+r]}else{k[q]=safe_add(safe_add(safe_add(sha256_Gamma1256(k[q-2]),k[q-7]),sha256_Gamma0256(k[q-15])),k[q-16])}x=safe_add(safe_add(safe_add(safe_add(s,sha256_Sigma1256(w)),sha256_Ch(w,u,t)),sha256_K[q]),k[q]);v=safe_add(sha256_Sigma0256(B),sha256_Maj(B,A,z));s=t;t=u;u=w;w=safe_add(y,x);y=z;z=A;A=B;B=safe_add(x,v)}p[0]=safe_add(B,p[0]);p[1]=safe_add(A,p[1]);p[2]=safe_add(z,p[2]);p[3]=safe_add(y,p[3]);p[4]=safe_add(w,p[4]);p[5]=safe_add(u,p[5]);p[6]=safe_add(t,p[6]);p[7]=safe_add(s,p[7])}return p}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}; |
Added modules/jshash/js/sha256.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. * Also http://anmar.eu.org/projects/jssha2/ */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_sha256(s) { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); } function b64_sha256(s) { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); } function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); } function hex_hmac_sha256(k, d) { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_sha256(k, d) { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_sha256(k, d, e) { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); } /* * Perform a simple self-test to see if the VM is working */ function sha256_vm_test() { return hex_sha256("abc").toLowerCase() == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"; } /* * Calculate the sha256 of a raw string */ function rstr_sha256(s) { return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8)); } /* * Calculate the HMAC-sha256 of a key and some data (raw strings) */ function rstr_hmac_sha256(key, data) { var bkey = rstr2binb(key); if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8); return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { try { hexcase } catch(e) { hexcase=0; } var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var output = ""; var x; for(var i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt( x & 0x0F); } return output; } /* * Convert a raw string to a base-64 string */ function rstr2b64(input) { try { b64pad } catch(e) { b64pad=''; } var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var output = ""; var len = input.length; for(var i = 0; i < len; i += 3) { var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i+2) : 0); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); } } return output; } /* * Convert a raw string to an arbitrary string encoding */ function rstr2any(input, encoding) { var divisor = encoding.length; var remainders = Array(); var i, q, x, quotient; /* Convert to an array of 16-bit big-endian values, forming the dividend */ var dividend = Array(Math.ceil(input.length / 2)); for(i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. We stop when the dividend is zero. * All remainders are stored for later use. */ while(dividend.length > 0) { quotient = Array(); x = 0; for(i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if(quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[remainders.length] = x; dividend = quotient; } /* Convert the remainders to the output string */ var output = ""; for(i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); /* Append leading zero equivalents */ var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))) for(i = output.length; i < full_length; i++) output = encoding[0] + output; return output; } /* * Encode a string as utf-8. * For efficiency, this assumes the input is valid utf-16. */ function str2rstr_utf8(input) { var output = ""; var i = -1; var x, y; while(++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); i++; } /* Encode output as utf-8 */ if(x <= 0x7F) output += String.fromCharCode(x); else if(x <= 0x7FF) output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F)); else if(x <= 0xFFFF) output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); else if(x <= 0x1FFFFF) output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); } return output; } /* * Encode a string as utf-16 */ function str2rstr_utf16le(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); return output; } function str2rstr_utf16be(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); return output; } /* * Convert a raw string to an array of big-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binb(input) { var output = Array(input.length >> 2); for(var i = 0; i < output.length; i++) output[i] = 0; for(var i = 0; i < input.length * 8; i += 8) output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); return output; } /* * Convert an array of big-endian words to a string */ function binb2rstr(input) { var output = ""; for(var i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); return output; } /* * Main sha256 function, with its support functions */ function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));} function sha256_R (X, n) {return ( X >>> n );} function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));} function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));} function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));} function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));} function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));} function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));} function sha256_Gamma0512(x) {return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));} function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));} var sha256_K = new Array ( 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998 ); function binb_sha256(m, l) { var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, 1359893119, -1694144372, 528734635, 1541459225); var W = new Array(64); var a, b, c, d, e, f, g, h; var i, j, T1, T2; /* append padding */ m[l >> 5] |= 0x80 << (24 - l % 32); m[((l + 64 >> 9) << 4) + 15] = l; for(i = 0; i < m.length; i += 16) { a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; for(j = 0; j < 64; j++) { if (j < 16) W[j] = m[j + i]; else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), sha256_Gamma0256(W[j - 15])), W[j - 16]); T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), sha256_K[j]), W[j]); T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); } HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); } return HASH; } function safe_add (x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } |
Added modules/jshash/js/sha512-min.js.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined * in FIPS 180-2 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ var hexcase=0;function hex_sha512(a){return rstr2hex(rstr_sha512(str2rstr_utf8(a)))}function hex_hmac_sha512(a,b){return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha512_vm_test(){return hex_sha512("abc").toLowerCase()=="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"}function rstr_sha512(a){return binb2rstr(binb_sha512(rstr2binb(a),a.length*8))}function rstr_hmac_sha512(c,f){var e=rstr2binb(c);if(e.length>32){e=binb_sha512(e,c.length*8)}var a=Array(32),d=Array(32);for(var b=0;b<32;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha512(a.concat(rstr2binb(f)),1024+f.length*8);return binb2rstr(binb_sha512(d.concat(g),1024+512))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}var sha512_k;function binb_sha512(p,A){if(sha512_k==undefined){sha512_k=new Array(new int64(1116352408,-685199838),new int64(1899447441,602891725),new int64(-1245643825,-330482897),new int64(-373957723,-2121671748),new int64(961987163,-213338824),new int64(1508970993,-1241133031),new int64(-1841331548,-1357295717),new int64(-1424204075,-630357736),new int64(-670586216,-1560083902),new int64(310598401,1164996542),new int64(607225278,1323610764),new int64(1426881987,-704662302),new int64(1925078388,-226784913),new int64(-2132889090,991336113),new int64(-1680079193,633803317),new int64(-1046744716,-815192428),new int64(-459576895,-1628353838),new int64(-272742522,944711139),new int64(264347078,-1953704523),new int64(604807628,2007800933),new int64(770255983,1495990901),new int64(1249150122,1856431235),new int64(1555081692,-1119749164),new int64(1996064986,-2096016459),new int64(-1740746414,-295247957),new int64(-1473132947,766784016),new int64(-1341970488,-1728372417),new int64(-1084653625,-1091629340),new int64(-958395405,1034457026),new int64(-710438585,-1828018395),new int64(113926993,-536640913),new int64(338241895,168717936),new int64(666307205,1188179964),new int64(773529912,1546045734),new int64(1294757372,1522805485),new int64(1396182291,-1651133473),new int64(1695183700,-1951439906),new int64(1986661051,1014477480),new int64(-2117940946,1206759142),new int64(-1838011259,344077627),new int64(-1564481375,1290863460),new int64(-1474664885,-1136513023),new int64(-1035236496,-789014639),new int64(-949202525,106217008),new int64(-778901479,-688958952),new int64(-694614492,1432725776),new int64(-200395387,1467031594),new int64(275423344,851169720),new int64(430227734,-1194143544),new int64(506948616,1363258195),new int64(659060556,-544281703),new int64(883997877,-509917016),new int64(958139571,-976659869),new int64(1322822218,-482243893),new int64(1537002063,2003034995),new int64(1747873779,-692930397),new int64(1955562222,1575990012),new int64(2024104815,1125592928),new int64(-2067236844,-1578062990),new int64(-1933114872,442776044),new int64(-1866530822,593698344),new int64(-1538233109,-561857047),new int64(-1090935817,-1295615723),new int64(-965641998,-479046869),new int64(-903397682,-366583396),new int64(-779700025,566280711),new int64(-354779690,-840897762),new int64(-176337025,-294727304),new int64(116418474,1914138554),new int64(174292421,-1563912026),new int64(289380356,-1090974290),new int64(460393269,320620315),new int64(685471733,587496836),new int64(852142971,1086792851),new int64(1017036298,365543100),new int64(1126000580,-1676669620),new int64(1288033470,-885112138),new int64(1501505948,-60457430),new int64(1607167915,987167468),new int64(1816402316,1246189591))}var q=new Array(new int64(1779033703,-205731576),new int64(-1150833019,-2067093701),new int64(1013904242,-23791573),new int64(-1521486534,1595750129),new int64(1359893119,-1377402159),new int64(-1694144372,725511199),new int64(528734635,-79577749),new int64(1541459225,327033209));var s=new int64(0,0),r=new int64(0,0),J=new int64(0,0),I=new int64(0,0),G=new int64(0,0),F=new int64(0,0),E=new int64(0,0),D=new int64(0,0),C=new int64(0,0),B=new int64(0,0),m=new int64(0,0),l=new int64(0,0),t=new int64(0,0),o=new int64(0,0),z=new int64(0,0),w=new int64(0,0),u=new int64(0,0);var v,y;var n=new Array(80);for(y=0;y<80;y++){n[y]=new int64(0,0)}p[A>>5]|=128<<(24-(A&31));p[((A+128>>10)<<5)+31]=A;for(y=0;y<p.length;y+=32){int64copy(J,q[0]);int64copy(I,q[1]);int64copy(G,q[2]);int64copy(F,q[3]);int64copy(E,q[4]);int64copy(D,q[5]);int64copy(C,q[6]);int64copy(B,q[7]);for(v=0;v<16;v++){n[v].h=p[y+2*v];n[v].l=p[y+2*v+1]}for(v=16;v<80;v++){int64rrot(z,n[v-2],19);int64revrrot(w,n[v-2],29);int64shr(u,n[v-2],6);l.l=z.l^w.l^u.l;l.h=z.h^w.h^u.h;int64rrot(z,n[v-15],1);int64rrot(w,n[v-15],8);int64shr(u,n[v-15],7);m.l=z.l^w.l^u.l;m.h=z.h^w.h^u.h;int64add4(n[v],l,n[v-7],m,n[v-16])}for(v=0;v<80;v++){t.l=(E.l&D.l)^(~E.l&C.l);t.h=(E.h&D.h)^(~E.h&C.h);int64rrot(z,E,14);int64rrot(w,E,18);int64revrrot(u,E,9);l.l=z.l^w.l^u.l;l.h=z.h^w.h^u.h;int64rrot(z,J,28);int64revrrot(w,J,2);int64revrrot(u,J,7);m.l=z.l^w.l^u.l;m.h=z.h^w.h^u.h;o.l=(J.l&I.l)^(J.l&G.l)^(I.l&G.l);o.h=(J.h&I.h)^(J.h&G.h)^(I.h&G.h);int64add5(s,B,l,t,sha512_k[v],n[v]);int64add(r,m,o);int64copy(B,C);int64copy(C,D);int64copy(D,E);int64add(E,F,s);int64copy(F,G);int64copy(G,I);int64copy(I,J);int64add(J,s,r)}int64add(q[0],q[0],J);int64add(q[1],q[1],I);int64add(q[2],q[2],G);int64add(q[3],q[3],F);int64add(q[4],q[4],E);int64add(q[5],q[5],D);int64add(q[6],q[6],C);int64add(q[7],q[7],B)}var k=new Array(16);for(y=0;y<8;y++){k[2*y]=q[y].h;k[2*y+1]=q[y].l}return k}function int64(b,a){this.h=b;this.l=a}function int64copy(b,a){b.h=a.h;b.l=a.l}function int64rrot(c,a,b){c.l=(a.l>>>b)|(a.h<<(32-b));c.h=(a.h>>>b)|(a.l<<(32-b))}function int64revrrot(c,a,b){c.l=(a.h>>>b)|(a.l<<(32-b));c.h=(a.l>>>b)|(a.h<<(32-b))}function int64shr(c,a,b){c.l=(a.l>>>b)|(a.h<<(32-b));c.h=(a.h>>>b)}function int64add(g,b,f){var d=(b.l&65535)+(f.l&65535);var c=(b.l>>>16)+(f.l>>>16)+(d>>>16);var a=(b.h&65535)+(f.h&65535)+(c>>>16);var e=(b.h>>>16)+(f.h>>>16)+(a>>>16);g.l=(d&65535)|(c<<16);g.h=(a&65535)|(e<<16)}function int64add4(j,m,l,k,i){var h=(m.l&65535)+(l.l&65535)+(k.l&65535)+(i.l&65535);var g=(m.l>>>16)+(l.l>>>16)+(k.l>>>16)+(i.l>>>16)+(h>>>16);var f=(m.h&65535)+(l.h&65535)+(k.h&65535)+(i.h&65535)+(g>>>16);var e=(m.h>>>16)+(l.h>>>16)+(k.h>>>16)+(i.h>>>16)+(f>>>16);j.l=(h&65535)|(g<<16);j.h=(f&65535)|(e<<16)}function int64add5(l,o,n,m,k,j){var i=(o.l&65535)+(n.l&65535)+(m.l&65535)+(k.l&65535)+(j.l&65535);var h=(o.l>>>16)+(n.l>>>16)+(m.l>>>16)+(k.l>>>16)+(j.l>>>16)+(i>>>16);var g=(o.h&65535)+(n.h&65535)+(m.h&65535)+(k.h&65535)+(j.h&65535)+(h>>>16);var f=(o.h>>>16)+(n.h>>>16)+(m.h>>>16)+(k.h>>>16)+(j.h>>>16)+(g>>>16);l.l=(i&65535)|(h<<16);l.h=(g&65535)|(f<<16)}; |
Added modules/jshash/js/sha512.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined * in FIPS 180-2 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_sha512(s) { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); } function b64_sha512(s) { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); } function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);} function hex_hmac_sha512(k, d) { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_sha512(k, d) { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_sha512(k, d, e) { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);} /* * Perform a simple self-test to see if the VM is working */ function sha512_vm_test() { return hex_sha512("abc").toLowerCase() == "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; } /* * Calculate the SHA-512 of a raw string */ function rstr_sha512(s) { return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8)); } /* * Calculate the HMAC-SHA-512 of a key and some data (raw strings) */ function rstr_hmac_sha512(key, data) { var bkey = rstr2binb(key); if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8); var ipad = Array(32), opad = Array(32); for(var i = 0; i < 32; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8); return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { try { hexcase } catch(e) { hexcase=0; } var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var output = ""; var x; for(var i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt( x & 0x0F); } return output; } /* * Convert a raw string to a base-64 string */ function rstr2b64(input) { try { b64pad } catch(e) { b64pad=''; } var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var output = ""; var len = input.length; for(var i = 0; i < len; i += 3) { var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i+2) : 0); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); } } return output; } /* * Convert a raw string to an arbitrary string encoding */ function rstr2any(input, encoding) { var divisor = encoding.length; var i, j, q, x, quotient; /* Convert to an array of 16-bit big-endian values, forming the dividend */ var dividend = Array(Math.ceil(input.length / 2)); for(i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. All remainders are stored for later * use. */ var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); var remainders = Array(full_length); for(j = 0; j < full_length; j++) { quotient = Array(); x = 0; for(i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if(quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[j] = x; dividend = quotient; } /* Convert the remainders to the output string */ var output = ""; for(i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); return output; } /* * Encode a string as utf-8. * For efficiency, this assumes the input is valid utf-16. */ function str2rstr_utf8(input) { var output = ""; var i = -1; var x, y; while(++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); i++; } /* Encode output as utf-8 */ if(x <= 0x7F) output += String.fromCharCode(x); else if(x <= 0x7FF) output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F)); else if(x <= 0xFFFF) output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); else if(x <= 0x1FFFFF) output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6 ) & 0x3F), 0x80 | ( x & 0x3F)); } return output; } /* * Encode a string as utf-16 */ function str2rstr_utf16le(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode( input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); return output; } function str2rstr_utf16be(input) { var output = ""; for(var i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); return output; } /* * Convert a raw string to an array of big-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binb(input) { var output = Array(input.length >> 2); for(var i = 0; i < output.length; i++) output[i] = 0; for(var i = 0; i < input.length * 8; i += 8) output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); return output; } /* * Convert an array of big-endian words to a string */ function binb2rstr(input) { var output = ""; for(var i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); return output; } /* * Calculate the SHA-512 of an array of big-endian dwords, and a bit length */ var sha512_k; function binb_sha512(x, len) { if(sha512_k == undefined) { //SHA512 constants sha512_k = new Array( new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd), new int64(-1245643825, -330482897), new int64(-373957723, -2121671748), new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031), new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736), new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe), new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302), new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1), new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428), new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3), new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65), new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483), new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459), new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210), new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340), new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395), new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70), new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926), new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473), new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8), new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b), new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023), new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30), new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910), new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8), new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53), new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016), new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893), new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397), new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60), new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec), new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047), new int64(-1090935817, -1295615723), new int64(-965641998, -479046869), new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207), new int64(-354779690, -840897762), new int64(-176337025, -294727304), new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026), new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b), new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493), new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620), new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430), new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)); } //Initial hash values var H = new Array( new int64(0x6a09e667, -205731576), new int64(-1150833019, -2067093701), new int64(0x3c6ef372, -23791573), new int64(-1521486534, 0x5f1d36f1), new int64(0x510e527f, -1377402159), new int64(-1694144372, 0x2b3e6c1f), new int64(0x1f83d9ab, -79577749), new int64(0x5be0cd19, 0x137e2179)); var T1 = new int64(0, 0), T2 = new int64(0, 0), a = new int64(0,0), b = new int64(0,0), c = new int64(0,0), d = new int64(0,0), e = new int64(0,0), f = new int64(0,0), g = new int64(0,0), h = new int64(0,0), //Temporary variables not specified by the document s0 = new int64(0, 0), s1 = new int64(0, 0), Ch = new int64(0, 0), Maj = new int64(0, 0), r1 = new int64(0, 0), r2 = new int64(0, 0), r3 = new int64(0, 0); var j, i; var W = new Array(80); for(i=0; i<80; i++) W[i] = new int64(0, 0); // append padding to the source string. The format is described in the FIPS. x[len >> 5] |= 0x80 << (24 - (len & 0x1f)); x[((len + 128 >> 10)<< 5) + 31] = len; for(i = 0; i<x.length; i+=32) //32 dwords is the block size { int64copy(a, H[0]); int64copy(b, H[1]); int64copy(c, H[2]); int64copy(d, H[3]); int64copy(e, H[4]); int64copy(f, H[5]); int64copy(g, H[6]); int64copy(h, H[7]); for(j=0; j<16; j++) { W[j].h = x[i + 2*j]; W[j].l = x[i + 2*j + 1]; } for(j=16; j<80; j++) { //sigma1 int64rrot(r1, W[j-2], 19); int64revrrot(r2, W[j-2], 29); int64shr(r3, W[j-2], 6); s1.l = r1.l ^ r2.l ^ r3.l; s1.h = r1.h ^ r2.h ^ r3.h; //sigma0 int64rrot(r1, W[j-15], 1); int64rrot(r2, W[j-15], 8); int64shr(r3, W[j-15], 7); s0.l = r1.l ^ r2.l ^ r3.l; s0.h = r1.h ^ r2.h ^ r3.h; int64add4(W[j], s1, W[j-7], s0, W[j-16]); } for(j = 0; j < 80; j++) { //Ch Ch.l = (e.l & f.l) ^ (~e.l & g.l); Ch.h = (e.h & f.h) ^ (~e.h & g.h); //Sigma1 int64rrot(r1, e, 14); int64rrot(r2, e, 18); int64revrrot(r3, e, 9); s1.l = r1.l ^ r2.l ^ r3.l; s1.h = r1.h ^ r2.h ^ r3.h; //Sigma0 int64rrot(r1, a, 28); int64revrrot(r2, a, 2); int64revrrot(r3, a, 7); s0.l = r1.l ^ r2.l ^ r3.l; s0.h = r1.h ^ r2.h ^ r3.h; //Maj Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l); Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h); int64add5(T1, h, s1, Ch, sha512_k[j], W[j]); int64add(T2, s0, Maj); int64copy(h, g); int64copy(g, f); int64copy(f, e); int64add(e, d, T1); int64copy(d, c); int64copy(c, b); int64copy(b, a); int64add(a, T1, T2); } int64add(H[0], H[0], a); int64add(H[1], H[1], b); int64add(H[2], H[2], c); int64add(H[3], H[3], d); int64add(H[4], H[4], e); int64add(H[5], H[5], f); int64add(H[6], H[6], g); int64add(H[7], H[7], h); } //represent the hash as an array of 32-bit dwords var hash = new Array(16); for(i=0; i<8; i++) { hash[2*i] = H[i].h; hash[2*i + 1] = H[i].l; } return hash; } //A constructor for 64-bit numbers function int64(h, l) { this.h = h; this.l = l; //this.toString = int64toString; } //Copies src into dst, assuming both are 64-bit numbers function int64copy(dst, src) { dst.h = src.h; dst.l = src.l; } //Right-rotates a 64-bit number by shift //Won't handle cases of shift>=32 //The function revrrot() is for that function int64rrot(dst, x, shift) { dst.l = (x.l >>> shift) | (x.h << (32-shift)); dst.h = (x.h >>> shift) | (x.l << (32-shift)); } //Reverses the dwords of the source and then rotates right by shift. //This is equivalent to rotation by 32+shift function int64revrrot(dst, x, shift) { dst.l = (x.h >>> shift) | (x.l << (32-shift)); dst.h = (x.l >>> shift) | (x.h << (32-shift)); } //Bitwise-shifts right a 64-bit number by shift //Won't handle shift>=32, but it's never needed in SHA512 function int64shr(dst, x, shift) { dst.l = (x.l >>> shift) | (x.h << (32-shift)); dst.h = (x.h >>> shift); } //Adds two 64-bit numbers //Like the original implementation, does not rely on 32-bit operations function int64add(dst, x, y) { var w0 = (x.l & 0xffff) + (y.l & 0xffff); var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16); var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16); var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16); dst.l = (w0 & 0xffff) | (w1 << 16); dst.h = (w2 & 0xffff) | (w3 << 16); } //Same, except with 4 addends. Works faster than adding them one by one. function int64add4(dst, a, b, c, d) { var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff); var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16); var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16); var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16); dst.l = (w0 & 0xffff) | (w1 << 16); dst.h = (w2 & 0xffff) | (w3 << 16); } //Same, except with 5 addends function int64add5(dst, a, b, c, d, e) { var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff); var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16); var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16); var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16); dst.l = (w0 & 0xffff) | (w1 << 16); dst.h = (w2 & 0xffff) | (w3 << 16); } |
Added modules/jshash/js/test-min.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #-- # Script to test the JavaScript hash algorithms # This produces an HTML file, that you load in a browser to run the tests #-- import hashlib, base64, hmac all_algs = ['md5', 'sha1', 'ripemd160', 'sha256', 'sha512'] short = {'ripemd160': 'rmd160'} test_strings = ['hello', 'world', u'fred\u1234'.encode('utf-8'), 'this is a longer test message to confirm that multiple blocks are handled correctly by the hashing algorithm'] print """<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/></head><body>""" for alg in all_algs: algs = short.get(alg, alg) print """<script src="%s-min.js"></script> <script> var pass = 0; fail = 0; function check(a, b) { if(a != b) { document.write('Test fail: ' + a + ' != ' + b + '<br/>'); fail += 1; } else pass += 1; } document.write("Testing %s...<br/>"); """ % (alg, alg) for t in test_strings: h = hashlib.new(alg) h.update(t) print "check(hex_%s('%s'), '%s');" % (algs, t, h.hexdigest()) h = hmac.new('key', t, lambda: hashlib.new(alg)) print "check(hex_hmac_%s('key', '%s'), '%s');" % (algs, t, h.hexdigest()) print """ document.write('Tests competed - ' + pass + ' passed; ' + fail + ' failed.<br/><br/>'); </script> """ print "</body></html>" |
Added modules/jshash/js/test.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #-- # Script to test the JavaScript hash algorithms # This produces an HTML file, that you load in a browser to run the tests #-- import hashlib, base64, hmac all_algs = ['md5', 'sha1', 'ripemd160', 'sha256', 'sha512'] short = {'ripemd160': 'rmd160'} test_strings = ['hello', 'world', u'fred\u1234'.encode('utf-8'), 'this is a longer test message to confirm that multiple blocks are handled correctly by the hashing algorithm'] print """<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/></head><body>""" for alg in all_algs: algs = short.get(alg, alg) print """<script src="%s.js"></script> <script> var pass = 0; fail = 0; function check(a, b) { if(a != b) { document.write('Test fail: ' + a + ' != ' + b + '<br/>'); fail += 1; } else pass += 1; } document.write("Testing %s...<br/>"); """ % (alg, alg) for t in test_strings: h = hashlib.new(alg) h.update(t) print "check(hex_%s('%s'), '%s');" % (algs, t, h.hexdigest()) print "check(b64_%s('%s'), '%s');" % (algs, t, base64.b64encode(h.digest()).rstrip('=')) h = hmac.new('key', t, lambda: hashlib.new(alg)) print "check(hex_hmac_%s('key', '%s'), '%s');" % (algs, t, h.hexdigest()) print "check(b64_hmac_%s('key', '%s'), '%s');" % (algs, t, base64.b64encode(h.digest()).rstrip('=')) print """ document.write('Tests competed - ' + pass + ' passed; ' + fail + ' failed.<br/><br/>'); </script> """ print "</body></html>" |
Added modules/jshash/jshash.md.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | A JavaScript implementation of the Secure Hash Algorithm Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet Distributed under the BSD License See <http://pajhome.org.uk/crypt/md5> for details. This package adds javascripts capable of performing md5 and sha1 hashes, and makes them available at /jshash on the local webserver. To use them add the following block of code to your pages: <script type="text/javascript" src="/jshash/sha1.js"></script> |
Added modules/jshash/jshash.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | ### # Add hooks for jshash ### package require httpd::doc ;# Httpd_Redirect Httpd_ReturnData set PWD [file dirname [file normalize [info script]]] Doc_AddRoot /jshash $PWD/js package provide httpd::jshash 0.1 |
Added modules/jshash/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::jshash 0.1 [list source [file join $dir jshash.tcl]] |
Added modules/markdown/markdown.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | # # The MIT License (MIT) # # Copyright (c) 2014 Caius Project # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # package require textutil ## \file # \brief Functions for converting markdown to HTML. ## # \brief Functions for converting markdown to HTML. # namespace eval Markdown { namespace export convert ## # # Converts text written in markdown to HTML. # # @param markdown currently takes as a single argument the text in markdown # # The output of this function is only a fragment, not a complete HTML # document. The format of the output is generic XHTML. # proc convert {markdown} { set markdown [regsub {\r\n?} $markdown {\n}] set markdown [::textutil::untabify2 $markdown 4] set markdown [string trimright $markdown] # COLLECT REFERENCES array unset ::Markdown::_references array set ::Markdown::_references [collect_references markdown] # PROCESS return [apply_templates markdown] } ## \private proc collect_references {markdown_var} { upvar $markdown_var markdown set lines [split $markdown \n] set no_lines [llength $lines] set index 0 array set references {} while {$index < $no_lines} { set line [lindex $lines $index] if {[regexp \ {^[ ]{0,3}\[((?:[^\]]|\[[^\]]*?\])+)\]:\s*(\S+)(?:\s+(([\"\']).*\4|\(.*\))\s*$)?} \ $line match ref link title]} \ { set title [string trim [string range $title 1 end-1]] if {$title eq {}} { set next_line [lindex $lines [expr $index + 1]] if {[regexp \ {^(?:\s+(?:([\"\']).*\1|\(.*\))\s*$)} \ $next_line]} \ { set title [string range [string trim $next_line] 1 end-1] incr index } } set ref [string tolower $ref] set link [string trim $link {<>}] set references($ref) [list $link $title] } incr index } return [array get references] } ## \private proc apply_templates {markdown_var {parent {}}} { upvar $markdown_var markdown set lines [split $markdown \n] set no_lines [llength $lines] set index 0 set result {} set ul_match {^[ ]{0,3}(?:\*(?!\s*\*\s*\*\s*$)|-(?!\s*-\s*-\s*$)|\+) } set ol_match {^[ ]{0,3}\d+\. } # PROCESS MARKDOWN while {$index < $no_lines} { set line [lindex $lines $index] switch -regexp $line { {^\s*$} { # EMPTY LINES if {![regexp {^\s*$} [lindex $lines [expr $index - 1]]]} { append result "\n\n" } incr index } {^[ ]{0,3}\[(?:[^\]]|\[[^\]]*?\])+\]:\s*\S+(?:\s+(?:([\"\']).*\1|\(.*\))\s*$)?} { # SKIP REFERENCES set next_line [lindex $lines [expr $index + 1]] if {[regexp \ {^(?:\s+(?:([\"\']).*\1|\(.*\))\s*$)} \ $next_line]} \ { incr index } incr index } {^[ ]{0,3}-[ ]*-[ ]*-[- ]*$} - {^[ ]{0,3}_[ ]*_[ ]*_[_ ]*$} - {^[ ]{0,3}\*[ ]*\*[ ]*\*[\* ]*$} { # HORIZONTAL RULES append result "<hr/>" incr index } {^[ ]{0,3}#{1,6}} { # ATX STYLE HEADINGS set h_level 0 set h_result {} while {$index < $no_lines && ![is_empty_line $line]} { incr index if {!$h_level} { regexp {^\s*#+} $line m set h_level [string length [string trim $m]] } lappend h_result $line set line [lindex $lines $index] } set h_result [\ parse_inline [\ regsub -all {^\s*#+\s*|\s*#+\s*$} [join $h_result \n] {} \ ]\ ] append result "<h$h_level>$h_result</h$h_level>" } {^[ ]{0,3}\>} { # BLOCK QUOTES set bq_result {} while {$index < $no_lines} { incr index lappend bq_result [regsub {^[ ]{0,3}\>[ ]?} $line {}] if {[is_empty_line [lindex $lines $index]]} { set eoq 0 for {set peek $index} {$peek < $no_lines} {incr peek} { set line [lindex $lines $peek] if {![is_empty_line $line]} { if {![regexp {^[ ]{0,3}\>} $line]} { set eoq 1 } break } } if {$eoq} { break } } set line [lindex $lines $index] } set bq_result [string trim [join $bq_result \n]] append result <blockquote>\n \ [apply_templates bq_result] \ \n</blockquote> } {^\s{4,}\S+} { # CODE BLOCKS set code_result {} while {$index < $no_lines} { incr index lappend code_result [html_escape [\ regsub {^ } $line {}]\ ] set eoc 0 for {set peek $index} {$peek < $no_lines} {incr peek} { set line [lindex $lines $peek] if {![is_empty_line $line]} { if {![regexp {^\s{4,}} $line]} { set eoc 1 } break } } if {$eoc} { break } set line [lindex $lines $index] } set code_result [join $code_result \n] append result <pre><code> $code_result \n </code></pre> } {^(?:(?:`{3,})|(?:~{3,}))(?:\{?\S+\}?)?\s*$} { # FENCED CODE BLOCKS set code_result {} if {[string index $line 0] eq {`}} { set end_match {^`{3,}\s*$} } else { set end_match {^~{3,}\s*$} } while {$index < $no_lines} { incr index set line [lindex $lines $index] if {[regexp $end_match $line]} { incr index break } lappend code_result [html_escape $line] } set code_result [join $code_result \n] append result <pre><code> $code_result </code></pre> } {^[ ]{0,3}(?:\*|-|\+) |^[ ]{0,3}\d+\. } { # LISTS set list_result {} # continue matching same list type if {[regexp $ol_match $line]} { set list_type ol set list_match $ol_match } else { set list_type ul set list_match $ul_match } set last_line AAA while {$index < $no_lines} \ { if {![regexp $list_match [lindex $lines $index]]} { break } set item_result {} set in_p 1 set p_count 1 if {[is_empty_line $last_line]} { incr p_count } set last_line $line set line [regsub "$list_match\\s*" $line {}] # prevent recursion on same line set line [regsub {\A(\d+)\.(\s+)} $line {\1\\.\2}] set line [regsub {\A(\*|\+|-)(\s+)} $line {\\\1\2}] lappend item_result $line for {set peek [expr $index + 1]} {$peek < $no_lines} {incr peek} { set line [lindex $lines $peek] if {[is_empty_line $line]} { set in_p 0 }\ elseif {[regexp {^ } $line]} { if {!$in_p} { incr p_count } set in_p 1 }\ elseif {[regexp $list_match $line]} { if {!$in_p} { incr p_count } break }\ elseif {!$in_p} { break } set last_line $line lappend item_result [regsub {^ } $line {}] } set item_result [join $item_result \n] if {$p_count > 1} { set item_result [apply_templates item_result li] } else { if {[regexp -lineanchor \ {(\A.*?)((?:^[ ]{0,3}(?:\*|-|\+) |^[ ]{0,3}\d+\. ).*\Z)} \ $item_result \ match para rest]} \ { set item_result [parse_inline $para] append item_result [apply_templates rest] } else { set item_result [parse_inline $item_result] } } lappend list_result "<li>$item_result</li>" set index $peek } append result <$list_type>\n \ [join $list_result \n] \ </$list_type>\n\n } {^<(?:p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)} { # HTML BLOCKS set re_htmltag {<(/?)(\w+)(?:\s+\w+=(?:\"[^\"]+\"|'[^']+'))*\s*>} set buffer {} while {$index < $no_lines} \ { while {$index < $no_lines} \ { incr index append buffer $line \n if {[is_empty_line $line]} { break } set line [lindex $lines $index] } set tags [regexp -inline -all $re_htmltag $buffer] set stack_count 0 foreach {match type name} $tags { if {$type eq {}} { incr stack_count +1 } else { incr stack_count -1 } } if {$stack_count == 0} { break } } append result $buffer } {(?:^\s{0,3}|[^\\]+)\|} { # SIMPLE TABLES set cell_align {} set row_count 0 while {$index < $no_lines} \ { # insert a space between || to handle empty cells set row_cols [regexp -inline -all {(?:[^|]|\\\|)+} \ [regsub -all {\|(?=\|)} [string trim $line] {| }] \ ] if {$row_count == 0} \ { set sep_cols [lindex $lines [expr $index + 1]] # check if we have a separator row if {[regexp {^\s{0,3}\|?(?:\s*:?-+:?(?:\s*$|\s*\|))+} $sep_cols]} \ { set sep_cols [regexp -inline -all {(?:[^|]|\\\|)+} \ [string trim $sep_cols]] foreach {cell_data} $sep_cols \ { switch -regexp $cell_data { {:-*:} { lappend cell_align center } {:-+} { lappend cell_align left } {-+:} { lappend cell_align right } default { lappend cell_align {} } } } incr index } append result "<table class=\"table\">\n" append result "<thead>\n" append result " <tr>\n" if {$cell_align ne {}} { set num_cols [llength $cell_align] } else { set num_cols [llength $row_cols] } for {set i 0} {$i < $num_cols} {incr i} \ { if {[set align [lindex $cell_align $i]] ne {}} { append result " <th style=\"text-align: $align\">" } else { append result " <th>" } append result [parse_inline [string trim \ [lindex $row_cols $i]]] </th> "\n" } append result " </tr>\n" append result "</thead>\n" } else { if {$row_count == 1} { append result "<tbody>\n" } append result " <tr>\n" if {$cell_align ne {}} { set num_cols [llength $cell_align] } else { set num_cols [llength $row_cols] } for {set i 0} {$i < $num_cols} {incr i} \ { if {[set align [lindex $cell_align $i]] ne {}} { append result " <td style=\"text-align: $align\">" } else { append result " <td>" } append result [parse_inline [string trim \ [lindex $row_cols $i]]] </td> "\n" } append result " </tr>\n" } incr row_count set line [lindex $lines [incr index]] if {![regexp {(?:^\s{0,3}|[^\\]+)\|} $line]} { switch $row_count { 1 { append result "</table>\n" } default { append result "</tbody>\n" append result "</table>\n" } } break } } } default { # PARAGRAPHS AND SETTEXT STYLE HEADERS set p_type p set p_result {} while {($index < $no_lines) && ![is_empty_line $line]} \ { incr index switch -regexp $line { {^[ ]{0,3}=+$} { set p_type h1 break } {^[ ]{0,3}-+$} { set p_type h2 break } {^[ ]{0,3}(?:\*|-|\+) |^[ ]{0,3}\d+\. } { if {$parent eq {li}} { incr index -1 break } else { lappend p_result $line } } {^[ ]{0,3}-[ ]*-[ ]*-[- ]*$} - {^[ ]{0,3}_[ ]*_[ ]*_[_ ]*$} - {^[ ]{0,3}\*[ ]*\*[ ]*\*[\* ]*$} - {^[ ]{0,3}#{1,6}} \ { incr index -1 break } default { lappend p_result $line } } set line [lindex $lines $index] } set p_result [\ parse_inline [\ string trim [join $p_result \n]\ ]\ ] if {[is_empty_line [regsub -all {<!--.*?-->} $p_result {}]]} { # Do not make a new paragraph for just comments. append result $p_result } else { append result "<$p_type>$p_result</$p_type>" } } } } return $result } ## \private proc parse_inline {text} { set text [regsub -all -lineanchor {[ ]{2,}$} $text <br/>] set index 0 set result {} set re_backticks {\A`+} set re_whitespace {\s} set re_inlinelink {\A\!?\[((?:[^\]]|\[[^\]]*?\])+)\]\s*\(\s*((?:[^\s\)]+|\([^\s\)]+\))+)?(\s+([\"'])(.*)?\4)?\s*\)} set re_reflink {\A\!?\[((?:[^\]]|\[[^\]]*?\])+)\](?:\s*\[((?:[^\]]|\[[^\]]*?\])*)\])?} set re_htmltag {\A</?\w+\s*>|\A<\w+(?:\s+\w+=(?:\"[^\"]+\"|\'[^\']+\'))*\s*/?>} set re_autolink {\A<(?:(\S+@\S+)|(\S+://\S+))>} set re_comment {\A<!--.*?-->} set re_entity {\A\&\S+;} while {[set chr [string index $text $index]] ne {}} { switch $chr { "\\" { # ESCAPES set next_chr [string index $text [expr $index + 1]] if {[string first $next_chr {\`*_\{\}[]()#+-.!>|}] != -1} { set chr $next_chr incr index } } {_} - {*} { # EMPHASIS if {[regexp $re_whitespace [string index $result end]] && [regexp $re_whitespace [string index $text [expr $index + 1]]]} \ { #do nothing } \ elseif {[regexp -start $index \ "\\A(\\$chr{1,3})((?:\[^\\$chr\\\\]|\\\\\\$chr)*)\\1" \ $text m del sub]} \ { switch [string length $del] { 1 { append result "<em>[parse_inline $sub]</em>" } 2 { append result "<strong>[parse_inline $sub]</strong>" } 3 { append result "<strong><em>[parse_inline $sub]</em></strong>" } } incr index [string length $m] continue } } {`} { # CODE regexp -start $index $re_backticks $text m set start [expr $index + [string length $m]] if {[regexp -start $start -indices $m $text m]} { set stop [expr [lindex $m 0] - 1] set sub [string trim [string range $text $start $stop]] append result "<code>[html_escape $sub]</code>" set index [expr [lindex $m 1] + 1] continue } } {!} - {[} { # LINKS AND IMAGES if {$chr eq {!}} { set ref_type img } else { set ref_type link } set match_found 0 if {[regexp -start $index $re_inlinelink $text m txt url ign del title]} { # INLINE incr index [string length $m] set url [html_escape [string trim $url {<> }]] set txt [parse_inline $txt] set title [parse_inline $title] set match_found 1 } elseif {[regexp -start $index $re_reflink $text m txt lbl]} { if {$lbl eq {}} { set lbl [regsub -all {\s+} $txt { }] } set lbl [string tolower $lbl] if {[info exists ::Markdown::_references($lbl)]} { lassign $::Markdown::_references($lbl) url title set url [html_escape [string trim $url {<> }]] set txt [parse_inline $txt] set title [parse_inline $title] # REFERENCED incr index [string length $m] set match_found 1 } } # PRINT IMG, A TAG if {$match_found} { if {$ref_type eq {link}} { if {$title ne {}} { append result "<a href=\"$url\" title=\"$title\">$txt</a>" } else { append result "<a href=\"$url\">$txt</a>" } } else { if {$title ne {}} { append result "<img src=\"$url\" alt=\"$txt\" title=\"$title\"/>" } else { append result "<img src=\"$url\" alt=\"$txt\"/>" } } continue } } {<} { # HTML TAGS, COMMENTS AND AUTOLINKS if {[regexp -start $index $re_comment $text m]} { append result $m incr index [string length $m] continue } elseif {[regexp -start $index $re_autolink $text m email link]} { if {$link ne {}} { set link [html_escape $link] append result "<a href=\"$link\">$link</a>" } else { set mailto_prefix "mailto:" if {![regexp "^${mailto_prefix}(.*)" $email mailto email]} { # $email does not contain the prefix "mailto:". set mailto "mailto:$email" } append result "<a href=\"$mailto\">$email</a>" } incr index [string length $m] continue } elseif {[regexp -start $index $re_htmltag $text m]} { append result $m incr index [string length $m] continue } set chr [html_escape $chr] } {&} { # ENTITIES if {[regexp -start $index $re_entity $text m]} { append result $m incr index [string length $m] continue } set chr [html_escape $chr] } {>} - {'} - "\"" { # OTHER SPECIAL CHARACTERS set chr [html_escape $chr] } default {} } append result $chr incr index } return $result } ## \private proc is_empty_line {line} { return [regexp {^\s*$} $line] } ## \private proc html_escape {text} { return [string map {& & < < > > \" "} $text] } } package provide Markdown 1.0 |
Added modules/markdown/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded Markdown 1.0 [list source [file join $dir markdown.tcl]] |
Added modules/pkgIndex.tcl.
> > > > > > > | 1 2 3 4 5 6 7 | set PWD $dir foreach subpath [glob -nocomplain $PWD/*] { if {[file exists $subpath/pkgIndex.tcl]} { set dir $subpath source $subpath/pkgIndex.tcl } } |
Added modules/qwiki/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::qwiki 0.1 [list source [file join $dir qwiki.tcl]] |
Added modules/qwiki/qwiki.md.
Added modules/qwiki/qwiki.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | ### # Implements a barebone wiki in a community object ### package require httpd::community tao::class qwiki.layer.wiki { superclass community.layer property module user property schema version 1.0 property schema table qwiki property schema primary_key entryid property schema create_sql { create table if not exists qwiki ( qwikid uuid default (uuid_generate()), indexed integer default 0, parent uuid references qwiki (qwikid) ON UPDATE CASCADE ON DELETE SET NULL, acl_name string references acl (acl_name) ON UPDATE CASCADE ON DELETE SET NULL, class string, format string, title string, body text, ctime unixtime default now(), mtime unixtime default now(), primary key (qwikid) ); create table if not exists qwiki_property ( qwikid string references qwiki (qwikid) ON UPDATE CASCADE ON DELETE CASCADE, field string, value string, primary key (qwikid,field) ); create table if not exists qwiki_link ( linktype string, qwiki integer references qwiki (qwikid) ON UPDATE CASCADE ON DELETE CASCADE, refqwiki integer references qwiki (qwikid) ON UPDATE CASCADE ON DELETE CASCADE ); -- Generate initial content insert into qwiki(qwikid,title,class,format,page) VALUES (local.homepage,'Home','page','markdown','Welcome to Qwiki!'); -- Generate a FTS CREATE VIRTUAL TABLE qwiki_search USING fts4(title, body); } } tao::class httpd.qwiki { superclass httpd.community constructor {virtual {localopts {}} args} { my configurelist [list virtual $virtual threadargs $args {*}$localopts] ::Url_PrefixInstall $virtual [namespace code {my httpdDirect}] {*}$args my initialize } method active_layers {} { return { user {prefix uid class community.layer.user} group {prefix gid class community.layer.group} session {prefix sesid class community.layer.session} acl {prefix acl class community.layer.acl} wiki {prefix wiki class qwiki.layer.wiki} } } method /html args { my layer wiki /html local.homepage } } package provide httpd::qwiki 0.1 |
Added modules/tao-sqlite/connection.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | ### # topic: 1f4bc558d601dd0621d4f441fcf94b07 # title: High level database container # description: # A taodb::connection # <p> # This object is assumed to be a nexus of an sqlite connector # and several subject objects to manage the individual tables # accessed by this application. ### tao::class taodb::connection { superclass tao.onion property docentry {} ### # topic: 124b0e5697a3e0a179a5bc044c735a54 ### method active_layers {} { # Return a mapping of tables to their handler classes return {} } ### # topic: ad8b51dd1884240d87d7a99ee2a8b862 ### method Database_Create {} { } ### # topic: 7cb96867401c18478a3dfb74b4cd37d8 ### method Database_Functions {} { } ### # topic: 62f531b6d83adc8a10d15b27ec17b675 ### method schema::create_sql {} { set result [my property schema create_sql] foreach {layer obj} [my layers] { set table [$obj property schema table] append result "-- BEGIN $table" \n append result [$obj property schema create_sql] \n append result "-- END $table" \n } return $result } ### # topic: fb34f12af081276e36172acfbbea52cf ### method schema::tables {} { set result {} foreach {layer obj} [my layers] { set table [$obj property schema table] lappend result $table } return $result } } ### # topic: eaf5daa1dd0baa5e8501e97af3224656 # title: High level database container # description: A taodb::connection implemented for sqlite ### tao::class taodb::connection.sqlite { superclass taodb::connection tao::onion aliases moac.sqliteDb option filename { widget filename extensions {.sqlite {Sqlite Database}} } option read-only { default 0 widget boolean } option timeout { default 30000 type integer } ### # topic: f71dcb5b2e2312180e379356f3263ff9 ### method attach_sqlite_methods sqlchan { my graft db $sqlchan foreach func { authorizer backup busy cache changes close collate collation_needed commit_hook complete copy enable_load_extension errorcode eval exists function incrblob last_insert last_insert_rowid nullvalue one onecolumn profile progress restore rollback_hook status timeout total_changes trace transaction unlock_notify update_hook version } { my forward $func $sqlchan $func } } ### # topic: 93c3c991254fd21abc02add7babe5b51 # title: Evaluate an SQL expression that alters the database # description: # This method is a wrapper around "eval" that will catch # "not authorized" messages and give the user some notice that # they should rename the file before altering it. ### method change args { if {[my cget read-only]} { my message readOnlyDatabase return } uplevel 1 [list [self] eval {*}$args] } ### # topic: 8a8ecce021e1fcbf8fc25be3ce4cd1d5 ### method Database {submethod args} { return [my Database_$submethod {*}$args] } ### # topic: ba1114cdc19c7835f848f9c6ce2f21c7 ### method Database_Attach filename { set alias db if { $filename in {:memory: {}}} { set exists 0 } else { set exists [file exists $filename] } my put filename $filename set objname [my SubObject $alias] sqlite3 $objname $filename ### # Register our busy method ### $objname busy [namespace code {my Database_Busy}] ### # Wait up to 2 seconds for # a busy database ### $objname timeout [my cget timeout] my graft $alias $objname my Database_Functions my attach_sqlite_methods $objname if {!$exists} { my Database_Create } } ### # Perform a daily backup of the database ### method Database_Backup {} { set filename [my cget filename] set now [clock seconds] set today [clock format $now -format "%Y-%m-%d-%H"] set path [file join [file dirname $filename] backups] if {![file exists $path]} { file mkdir $path } set bkuplink [file join $path [file rootname $filename].latest.sqlite] file delete $bkuplink set bkupfile [file join $path [file tail [file rootname $filename]].$today.sqlite] my <db> backup $bkupfile file link $bkuplink $bkupfile ### # Keep: # * one backup per hour for the past day # * one backup per day for the past week # * one per week for the past 2 months # * one per month for the past year # * one every 6 months for years beyond ### set day [expr {3600*24}] set week [expr {$day*7}] set month [expr {$week*4}] set year [expr {$month*12}] set halfyear [expr {$month*6}] foreach file [glob -nocomplain [file join $path *.sqlite]] { set age [expr {$now - [file mtime $file]}] if { $age < $day } continue if { $age < $week } { lappend daily([expr {$age/$day}]) $age $file continue } if { $age < ($month*2) } { lappend weekly([expr {$age/$week}]) $age $file continue } if { $age < ($halfyear*2) } { lappend monthly([expr {$age/$month}]) $age $file continue } lappend halfyearly([expr {$age/$halfyear}]) $age $file } foreach {bin backups} [array get daily] { foreach {mtime file} [lrange [lsort -stride 2 -integer $backups] 2 end] { file delete $file } } foreach {bin backups} [array get weekly] { foreach {mtime file} [lrange [lsort -stride 2 -integer $backups] 2 end] { file delete $file } } foreach {bin backups} [array get monthly] { foreach {mtime file} [lrange [lsort -stride 2 -integer $backups] 2 end] { file delete $file } } foreach {bin backups} [array get halfyearly] { foreach {mtime file} [lrange [lsort -stride 2 -integer $backups] 2 end] { file delete $file } } } ### # topic: 6319133f765170f9949de3e3329bf07f # description: # Action to perform when database is busy # return "1" to cause action to fail, # 0 to allow Sqlite to wait and try again ### method Database_Busy {} { after 1 return 0 } ### # topic: 4251a1e7abd66d20c66f9dcd25bb1e54 # description: # Deep wizardry # Disable journaling and disk syncronization # If the app crashes, we really don't give a # rat's ass about the output, anyway ### method journal_mode onoff { # Store temporary tables in memory if {[string is false $onoff]} { my <db> eval { PRAGMA synchronous=0; PRAGMA journal_mode=MEMORY; PRAGMA temp_store=2; } } else { my <db> eval { PRAGMA synchronous=2; PRAGMA journal_mode=DELETE; PRAGMA temp_store=0; } } } ### # topic: 9363820d1352dc0b02d8b433be02a5b7 ### method message::readonly {} { error "Database is read-only" } ### # topic: 29d3a99d20a7f3aaa7911b2666bdf17e ### method native::table_info table { set info {} my one {select type,sql from sqlite_master where tbl_name=$table} { foreach {type field value} [::schema::createsql_to_dict $sql] { dict set info $type $field $value } } return $info } ### # topic: df7ff05563eae14512f945ac80b18ea6 ### method native::tables {} { return [my eval {SELECT name FROM sqlite_master WHERE type ='table'}] } ### # topic: 4e2dc71f459beab3d31cd49f012340fb ### method Option_set::filename filename { my Database_Attach $filename } ### # topic: d5591c09b59c6a8d50001af79d108e13 ### method SubObject::db {} { return [namespace current]::Sqlite_db } } |
Added modules/tao-sqlite/index.tcl.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package provide tao-sqlite 0.3 package require tao package require sqlite3 package require sha1 2 ::tao::module push tao-sqlite ::namespace eval ::taodb {} ::tao::load_path [::tao::script_path] { procs.tcl connection.tcl oosqlite.tcl module.tcl } ::tao::module pop |
Added modules/tao-sqlite/module.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ### # topic: d3e536874747b4e5a6b879e6f2422cd4 # description: Modules are objects that wrap around sqlite connections ### tao::class taodb::module.sqlite { superclass taodb::connection.sqlite constructor filename { package require sqlite3 if [catch { my Database_Attach $filename ### # Allow up to 2 seconds of # slack time for another process to # write to the database ### my <db> timeout 2000 }] { puts "Falling back to temporary storage" my Database_Attach {} } return 0 } ### # topic: 6292ac0c78dbb91c7aaa629f48a301a3 ### method Database_Create {} { my <db> eval [my property schema create_sql] } ### # topic: 582bb8d10136f632866e73a6b72a9c32 ### method Database_Functions {} { my <db> function uuid_generate ::tao::uuid_generate } } |
Added modules/tao-sqlite/oosqlite.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | ### # topic: 4f78c3dbc3f04099f8388b0aaf87df97 # description: # This class abstracts the normal operations undertaken # my containers and nodes that write to a single data table ### tao::class taodb::table { aliases moac.sqliteTable superclass # Properties that need to be set: # table - SQL Table # primary_key - Primary key for the sql table # default_record - Key/value list of defaults ### # topic: 6283f1ecde341c8b7dc0199226cfad86 # title: Delete a record from the database backend ### method db_record_delete nodeid { set table [my property schema table] set primary_key [my property schema primary_key] my <db> change "delete from $table where $primary_key=:nodeid" } ### # topic: d4c5e9cfea2fa029e80ac21e3173a702 ### method db_record_exists nodeid { set table [my property schema table] set primary_key [my property schema primary_key] return [my <db> exists "select $primary_key from $table where $primary_key=:nodeid"] } ### # topic: e1e4bb66d9cfc158ec9dfb8e13cfe0ce # title: Detect record key # description: The nodeid of this table from a key/value list of table contents ### method db_record_key record { set primary_key [my property schema primary_key] if {[dict exists $record $primary_key]} { return [dict get $record $primary_key] } if {[dict exists $record rowid]} { return [dict get $record rowid] } error "Could not locate the primary key" } ### # topic: 505661a4862772908e986e255ffe1f79 # description: Read a record from the database ### method db_record_load {nodeid {arrayvar {}}} { if { $arrayvar ne {} } { upvar 1 $arrayvar R } set table [my property schema table] if {$nodeid eq {}} { return {} } my <db> eval "select * from $table where rowid=:nodeid" R {} unset -nocomplain R(*) return [array get R] } ### # topic: 37e78a4cf9ab491f9894c28a128922e4 # title: Return a record number for a new entry ### method db_record_nextid {} { set primary_key [my property schema primary_key] set maxid [my <db> one "select max($primary_key) from [my property schema table]"] if { ![string is integer -strict $maxid]} { return 1 } else { return [expr {$maxid + 1}] } } ### # topic: 0960b530335749a9315d8d05af8c02c2 # description: # Write a record to the database. If nodeid is negative, # create a new record and return its ID. # This action will also perform any container specific prepwork # to stitch the node into the model, as well as re-read the node # from the database and into memory for use by the gui ### method db_record_save {nodeid record} { appmain signal dbchange set table [my property schema table] set primary_key [my property schema primary_key] set now [clock seconds] if { $nodeid < 1 || $nodeid eq {} } { set nodeid [my db_record_nextid] } if {![my <db> exists "select $primary_key from $table where rowid=:nodeid"]} { my <db> change "INSERT INTO $table ($primary_key) VALUES (:nodeid)" foreach {var val} [my property default_record] { if {![dict exists $record $var]} { dict set record $var $val } } } set oldrec [my db_record_load $nodeid] set fields {} set values {} set stmt "UPDATE $table SET " set stmtl {} set columns [dict keys $oldrec] foreach {field value} $record { if { $field in [list $primary_key mtime uuid] } continue if { $field ni $columns } continue if {[dict exists $oldrec $field]} { # Screen out values that have not changed if {[dict get $oldrec $field] eq $value } continue } lappend stmtl "$field=\$rec_${field}" set rec_${field} $value } if { $stmtl == {} } { return 0 } if { "mtime" in $columns } { lappend stmtl "mtime=now()" } append stmt [join $stmtl ,] append stmt " WHERE $primary_key=:nodeid" my <db> change $stmt return $nodeid } } ### # topic: 9032e81e051b67fa089f1326da6081f1 # description: # Managing records for tables that consist of a primary # key and a blob field that contains a key/value list # that represents the record ### tao::class taodb::table.blob { aliases moac.sqliteTable.blob superclass ### # topic: 24d95fd922c7d9d188b60b35b382b8dd ### method db_record_delete nodeid { set table [my property schema table] set primary_key [my property schema primary_key] my <db> one "delete from $table where $primary_key=:nodeid" } ### # topic: c4c57639b09ab0f1bd81700cabd6ab88 ### method db_record_load {nodeid {arrayvar {}}} { set table [my property schema table] set vfield [my property field_value] set primary_key [my property schema primary_key] if { $arrayvar ne {} } { upvar 1 $arrayvar R array set R [my <db> one "select $vfield from $table where $primary_key=:nodeid"] return [array get R] } else { return [my <db> one "select $vfield from $table where $primary_key=:nodeid"] } } ### # topic: 268efa2a6aac3451f3e5e525013ec091 ### method db_record_save {nodeid record} { set table [my property schema table] set vfield [my property field_value] set primary_key [my property schema primary_key] set result [my property default_record] foreach {var val} [my <db> one "select $vfield from $table where $primary_key=:nodeid"] { dict set result $var $val } foreach {var val} $record { dict set result $var $val } my <db> eval "update $table set $vfield=:result where $primary_key=:nodeid" } } ### # topic: df933b39a39e106c1c0b3f8651d4b5b7 # description: # Managing records for tables that consist of a primary # key a column representing a "field" and another # column representing a "value" ### tao::class taodb::table.keyvalue { aliases moac.sqliteTable.keyvalue superclass ### # topic: c32d751f91d518b47ad400ef04e4f719 ### method db_record_delete nodeid { set table [my property schema table] set primary_key [my property schema primary_key] my <db> one "delete from $table where $primary_key=:nodeid" } ### # topic: 34b5a0fefa9a9655a3f8184c3eb640a9 ### method db_record_load nodeid { set table [my property schema table] set ffield [my property field_name] set vfield [my property field_value] set primary_key [my property schema primary_key] set result [my property default_record] my <db> eval "select $ffield as field,$vfield as value from $table where $primary_key=:nodeid" { dict set result $field $value } return $result } ### # topic: 176679ea4e972f4eac12d4325979369e ### method db_record_save {nodeid record} { set table [my property schema table] set ffield [my property field_name] set vfield [my property field_value] set primary_key [my property schema primary_key] set oldrecord [my db_record_load $nodeid] foreach {var val} $record { if {[dict exists $oldrecord $var]} { if {[dict get $oldrecord $var] eq $val } continue } dict set outrecord $var $val } if {![llength $outrecord]} return my <db> transaction { foreach {var val} $outrecord { my <db> change "insert or replace into $table ($primary_key,$ffield,$vfield) VALUES (:nodeid,$var,$val)" } } } } |
Added modules/tao-sqlite/pkgIndex.tcl.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded ::tao::helpdoc 0.1 [list source [file join $dir yggdrasil.tcl]] package ifneeded tao-sqlite 0.3 [list source [file join $dir index.tcl]] |
Added modules/tao-sqlite/prefdb.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ### # topic: a499aa36ee878a743ac8a269bfd3a1e3 # description: Sqlite based storage for application settings ### tao::class taodb::prefdb { superclass taodb::module.sqlite property create_sql { create table prefs ( field string, value string, mtime integer, primary key (field) ); create table history ( field string, value string, mtime integer, primary key (field,value) on conflict replace ); create index historyMtime on history (mtime); } ### # topic: bd83ad1abbfc4516fd6adc5d6ddfd553 ### method create_temp_tables {} { create table property ( node string, field string, value string, primary key (node,field) on conflict replace ); } } |
Added modules/tao-sqlite/procs.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | ::namespace eval ::tao {} ### # topic: 0a19b0bfb98162a8a37c1d3bbfb8bc3d # description: # Because the tcllib version of uuid generate requires # network port access (which can be slow), here's a fast # and dirty rendition ### proc ::tao::uuid_generate args { if {![llength $args]} { set block [list [incr ::tao::nextuuid] {*}$::tao::UUID_Seed] } else { set block $args } return [::sha1::sha1 -hex [join $block ""]] } ### # topic: ee3ec43cc2cc2c7d6cf9a4ef1c345c19 ### proc ::tao::uuid_short args { if {![llength $args]} { set block [list [incr ::tao::nextuuid] {*}$::tao::UUID_Seed] } else { set block $args } return [string range [::sha1::sha1 -hex [join $block ""]] 0 16] } ### # topic: b14c505537274904578340ec1bc12af1 # description: # Implementation the uses a compiled in ::md5 implementation # commonly used by embedded application developers ### namespace eval ::tao { namespace export * ### # Cache the bits of the UUID seed that aren't likely to change # once the software is loaded, but which can be expensive to # generate ### variable ::tao::UUID_Seed [list [info hostname] [get env(USER)] [get env(user)] [clock format [clock seconds]]] } |
Added modules/tao-sqlite/record.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ### # topic: 49fee6ecf96ef7b3d3ecd7565a047b20 # title: Generic class to process database records ### tao::class taodb::record { superclass option layer { class organ description {Object which abstracts access to the underlying storage} } property variable nodeid {default -1} property variable unit {default {}} property array db_record {} property array db_specs {} ### # topic: b5cf9de15d1e7c7fead7b5794acb59db ### method action::delete {} { set objid [my objid] # Note: we are counting on the layer's node_edit_delete # method to call our destructor and/or destroy our window my layer db_record_delete $objid } ### # topic: 1d8ca0d3c3b915fadae5f1edb4343833 ### method action::destroy {} {} ### # topic: fa3fbe68c3a633950547bbe096dd762d ### method action::save { my variable db_record set pkey [my <layer> db_record_key [array get db_record]] set savedata [array get db_record] my <layer> db_record_ } } |
Added modules/tao-sqlite/tao-sqlite.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | Back to [tao](../tao.md) tao-sqlite is a module of related classes which act as ambassadors to **sqlte** database connections. # Sub-Modules [yggdrasil](yggdrasil.md) # Core Classes ## class taodb::connection Implements a generic wrapper around a database connection. (Note: at this point only sqlite has been developed.) Ancestors: [tao.onion](../tao/onions.md) ### Methods #### method active_layers Return a list of database layers to act as ambassodors for various collections of tables. See [onions](../tao/onions.md) #### method Database_Create Commands to invoke when the interface attempts to connect to a virgin database. This method should build the database schema and populate any starter data. #### method Database_Functions Inject functions into the database interface. For sqlite, this method invokes the interface's native *function* method to map an sqlite function to a Tcl command. #### Ensemble schema Ensemble to manage database schemas. ##### method schema create_sql Return fully formed SQL code to implement the schema The default implementation is to interrogate the object layers for a *schema create_sql* property. ##### method schema tables Return a list of tables specified by the schema. The default implementation is to interrogate the object layers for a *schema table* property. |
Added modules/tao-sqlite/yggdrasil.md.
Added modules/tao-sqlite/yggdrasil.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | ### # Structure that manages an interactive help system ### package provide ::tao::helpdoc 0.1 ### # topic: f5641520f17f23259b96facbe936c875 ### tao::class taodb::yggdrasil { aliases tao.yggdrasil superclass taodb::module.sqlite property schema create_sql { CREATE TABLE if not exists config( name TEXT PRIMARY KEY, value ANY ); create table if not exists entry ( entryid string default (uuid_generate()), indexed integer default 0, parent integer references entry (entryid), class string, name string, mtime integer, primary key (entryid) ); create table if not exists property ( entryid string references entry (entryid), field string, value string, primary key (entryid,field) ); create table if not exists link ( linktype string, entry integer references entry (entryid), refentry integer references entry (entryid) ); create table if not exists idset ( class string, id integer, name string, primary key (class,id) ); create table if not exists aliases ( class string, alias string, cname string references entry (name), primary key (class,alias) ); create table if not exists repository ( handle string, localpath string, primary key (handle) ); create table if not exists file ( fileid string default (uuid_generate()), repo string references repository (handle), path string, --path relative to repo localpath string, --cached path to local file filename string, --filename content_type string, --Content/Type of file package string, --Name of any packages provided, size integer, --File size in bytes mtime integer, --mtime in unix time hash string, --md5 hash of file primary key (fileid) ); create table if not exists filelink ( linktype string, entryid integer references entry (entryid), fileid integer references file (fileid) ); } property create_index_sql { create index if not exists nameidx on entry (entryid,name); create index if not exists parentidx on entry (parent,entryid); } ### # topic: ce057acc3716a2d568a7031702a08db6 ### method alias_list class { return [my <db> eval {select alias,cname from aliases where class=:class order by cname,alias}] } ### # topic: 181987917bb442b19b20c6a381b68e65 ### method canonical {class name} { set name [string tolower $name] if { $class in {{} * any}} { return [my <db> eval {select distinct class from aliases order by class}] } if { $name in {{} * any}} { return [my <db> eval {select alias,cname from aliases where class=:class order by cname,alias}] } set rows [my <db> eval {select entryid from entry where class=:class and name=:name}] if {[llength $rows] == 1} { return $name } if {[my <db> exists {select cname from aliases where class=:class and (alias=:name or cname=:name)}]} { return [my <db> one {select cname from aliases where class=:class and (alias=:name or cname=:name) limit 1}] } } ### # topic: e1fb31429cfba5b9c8939b3089d7dccf ### method canonical_aliases {class name} { set name [string tolower $name] return [my <db> eval {select distinct alias from aliases where class=:class and cname=:name and alias!=:name}] } ### # topic: 9892395f48e5568923ee0516ca23313a ### method canonical_id {class name} { return [my <db> eval {select id from idset where class=:class and name=:name}] } ### # topic: 0e2b411c94df5cdc082f6d909045f44c ### method canonical_set {type name cname} { set class [string tolower $type] set name [string tolower $name] set cname [string tolower $cname] variable canonical_name dict set canonical_name $class $name $cname set address $type/$name my <db> eval {replace into aliases (class,alias,cname) VALUES ($class,$name,$cname)} } ### # topic: a3ee1a620e5659107eea8b3f9ef38b0d ### method class_list class { return [lsort -dictionary [my <db> eval {select name from entry where class=:class}]] } ### # topic: 7e5caa43f37e38328ca83784db16face ### method class_nodes class { set result {} foreach {entryid name} [my <db> eval {select entryid,name from entry where class=:class order by name}] { lappend result $name [my node_properties $entryid] } return $result } ### # topic: 85fa5fdaecfbc8a8236d726b37adc8b8 ### method enum_dump class { return [my <db> eval {select id,name from idset where class=:class order by id}] } ### # topic: 54b27245e29c98708a964c0739583737 ### method enum_id {class name} { set arr ::irm::${class}_name_to_idx if {![info exists $arr]} { my <db> eval {select name as aname,id as aid from idset where class=:class} { set ${arr}($aname) $aid } } set cname [my canonical $class $name] if {![info exists ${arr}($cname)]} { error "Invalid $class $name" } return [set ${arr}($cname)] } ### # topic: 944e9861c8d04a693896c7a093bcb641 ### method enum_name {class id} { return [my <db> one {select name from idset where class=:class and id=:id}] } ### # topic: ff79f9268801cbdbf06bee1d0827a8ed ### method enum_set {class name id} { set class [string tolower $class] set name [string tolower $name] set ::irm::${class}_name_to_idx($name) $id set ::irm::${class}_idx_to_name($id) $name my <db> eval {insert or replace into idset (class,id,name) VALUES ($class,$id,$name)} } ### # topic: 848689c2e58328b9da8b97afee687e52 ### method file_hash {rawfileid {newhash {}}} { set fileid [my file_id $rawfileid] if {$fileid ne {}} { return [my <db> one {select hash from file where fileid=:fileid}] } return {} } ### # topic: 438f616e49033a8d7215330112d314ad ### method file_id {addr {create 0}} { if {[my <db> exists {select fileid from file where fileid=:addr}]} { return $addr } if {[my <db> exists {select fileid from file where hash=:addr}]} { return [my <db> one {select fileid from file where hash=:addr}] } if {[llength $addr]==2} { set repo [lindex $addr 0] set path [lindex $addr 1] if {[my <db> exists {select fileid from file where repo=:repo and path=:path}]} { return [my <db> one {select fileid from file where repo=:repo and path=:path}] } } if {[my <db> exists {select fileid from file where path=:addr}]} { return [my <db> one {select fileid from file where path=:addr}] } if {[my <db> exists {select fileid from file where localpath=:addr}]} { return [my <db> one {select fileid from file where localpath=:addr}] } if {$create} { set newuuid [my <db> one {select uuid_generate()}] if {[llength $addr]==2} { set repo [lindex $addr 0] set path [lindex $addr 1] my <db> eval {insert into file (fileid,repo,path) VALUES (:newuuid,:repo,:path);} } else { my <db> eval {insert into file (fileid,path) VALUES (:newuuid,:path);} } return $newuuid } return {} } ### # topic: c2cab41e44bb7cdcca831e05aa5ef902 ### method file_restore {nodeid info} { set stmtl {} dict with info {} set fileid [my file_id $nodeid 1] set stmt "UPDATE file SET " set stmtl {} foreach {field value} $info { switch $field { repo - path - localpath - filename - content_type - package - size - mtime - hash { if { $value ne {} } { set _$field $value lappend stmtl "$field=:_${field}" } } } } if {![llength $stmt]} return append stmt "[join $stmtl ,]" append stmt " where fileid=:fileid" my <db> eval $stmt } ### # topic: fba89244d9f7fba909fb01dc7a25535a ### method file_serialize nodeid { set result {} my <db> eval { select * from file where fileid=$nodeid } record { set fileid $record(fileid) append result "[list [self] file_restore [list $record(repo) $record(path)]] \{" \n foreach {field value} [array get record] { if { $field in {* fileid indexed export} } continue append result " [list $field $value]" \n } append result "\}" } return $result } ### # topic: f8abb1cd4c82172741704b789371c706 # title: Build a full text index ### method full_text_index {{force 0}} { my <db> eval { CREATE TABLE if not exists config( name TEXT PRIMARY KEY, value ANY ); } if {!$force && [my <db> exists {select * from config where name='fts_indexed' and value='1'}]} { return } my <db> eval { DROP TABLE IF EXISTS search; CREATE VIRTUAL TABLE search USING fts4(uuid,class,title,body); insert into search (uuid,class,title,body) SELECT entry.entryid,entry.class,entry.name,property.value FROM entry,property where entry.entryid=property.entryid and field='description'; INSERT OR REPLACE INTO config(name,value) VALUES ('fts_indexed',1); } } ### # topic: 6892a2438c56b5e207888f6683d684cc ### method link_create {entryid to {type {}}} { if { $type eq {} } { set exists [my one {select count(entry) from link where entry=$entryid and refentry=$to}] if {!$exists} { my <db> eval {insert or replace into link (entry,refentry) VALUES ($entryid,$to)} } } else { set exists [my one {select count(entry) from link where entry=$entryid and refentry=$to and linktype=$type}] if {!$exists} { my <db> eval {insert or replace into link (entry,refentry,linktype) VALUES ($entryid,$to,$type)} } } } ### # topic: bebaa55db9d00f615f4c3e589b9f5cca ### method link_detect_address args { set args [string tolower $args] if {[my node_exists $args entryid]} { return [my <db> eval {select entryid from entry where entryid=$entryid}] } ### # If the link contains a / we know it is a hard # path ### if {[my node_exists $args entryid]} { return $entryid } if {[llength $args] > 1} { set rootentries [my <db> eval {select name from entry where class='section'}] if {[lindex $args 0] in $rootentries} { set type [lindex $args 0] set name [my canonical $type [lindex $args 1]] if {[my node_exists [list $type $name] entryid]} { return $entryid } } if {[lindex $args 1] in $rootentries} { set type [lindex $args 1] set name [my canonical $type [lindex $args 0]] if {[my node_exists [list $type $name] entryid]} { return $entryid } } } set addr [lindex $args 0] set cnames [my <db> eval {select class,cname from aliases where alias=$addr}] if {[llength $cnames] == 2} { if {[my node_exists $cnames entryid]} { return $entryid } } #if {[string first / $addr] > 0 } { # return $addr #} set candidates [my <db> eval {select entryid,name from entry where name like '%$addr%'}] foreach address $candidates { if {[regexp simnode $address]} { return $address } } #puts [list CAN'T RESOLVE $args] return $args } ### # topic: 4be4c2c74388621448494e1ced97fccb # description: # Return a list of all children of node, # Filter is a key/value list that understands # the following: # type - Limit children to type # dump - Output the contents of the child node, not their id ### method node_children {nodeid class} { set dump 1 set entryid [my node_id $nodeid] if { $class eq {} } { set nodes [my <db> eval {select name,entryid from entry where parent=$entryid}] } else { set nodes [my <db> eval {select name,entryid from entry where parent=$entryid and class=$class}] } if {!$dump} { return $nodes } set result {} foreach {cname cid} $nodes { dict set result $cname [my <db> eval {select field,value from property where entryid=$cid order by field}] } return $result } ### # topic: 1ddcdaedcca9f6bf1d17564fc2b80dbe ### method node_define {class name info {nodeidvar {}}} { if {$nodeidvar ne {}} { upvar 1 $nodeidvar nodeid } set class [string tolower $class] set name [string tolower $name] if { $class eq {} || $class eq "section" } { set nodeid $name } else { set nodeid {} if {[dict exists $info topic]} { set nodeid [dict get $info topic] dict unset info topic } } if { $nodeid eq {} } { if {![my node_exists [list $class $name] nodeid]} { set nodeid [helpdoc node_id [list $class $name] 1] foreach {var val} [my node_empty $class] { my node_property_set $nodeid $var $val } } } elseif {![my node_exists $nodeid]} { my canonical_set $class $name $name my <db> eval {insert into entry (entryid,class,name) VALUES (:nodeid,:class,:name)} foreach {var val} [my node_empty $class] { my node_property_set $nodeid $var $val } } foreach {var val} $info { my node_property_set $nodeid $var $val } } ### # topic: 5cf8420243fb46472b33a18cb340f8cf ### method node_define_child {parent class name info {nodeidvar {}}} { if {$nodeidvar ne {}} { upvar 1 $nodeidvar nodeid } ### # Return an already registered node with this address ### if {[my <db> exists {select entryid from entry where parent=:parent and class=:class and name=:name}]} { set nodeid [my <db> one {select entryid from entry where parent=:parent and class=:class and name=:name}] } else { set nodeid {} if {[dict exists $info topic]} { set topicid [dict get $info topic] dict unset info topic if {![my <db> exists {select entryid from entry where entryid=:topicid}]} { # If we are recycling an unused UUID re-create the entry in the table my <db> eval {insert or replace into entry (entryid,parent,class,name) VALUES (:topicid,:parent,:class,:name)} set nodeid $topicid } } if { $nodeid eq {} } { set nodeid [::tao::uuid_generate $parent $class $name] } if {[my <db> exists {select entryid from entry where entryid=:nodeid and class=:class and name=:name}]} { ### # Correct a misfiled node ### my <db> eval {update entry set parent=:parent where entryid=:nodeid} } else { my <db> eval {insert or replace into entry (entryid,parent,class,name) VALUES (:nodeid,:parent,:class,:name)} } foreach {var val} [my node_empty $class] { if {![dict exists $info $var]} { dict set info $var $val } } } foreach {var val} $info { my node_property_set $nodeid $var $val } return $nodeid } ### # topic: 1ce63e18b2072f0218695df90c83b5e6 ### method node_empty class { set id [my <db> one {select entryid from entry where name=:class and class='section'}] return [my <db> one {select value from property where entryid=:id and field='template'}] } ### # topic: 8a70c9ed461c3728787f2e5385f8be66 ### method node_exists {node {resultvar {}}} { set parent 0 if { $resultvar != {} } { upvar 1 $resultvar row } if {[llength $node]==1} { set name [lindex $node 0] if {[my <db> exists {select entryid from entry where name=:name or entryid=:name}]} { set row [my <db> one {select entryid from entry where name=:name or entryid=:name}] return 1 } } elseif {[llength $node]==2} { set class [lindex $node 0] set name [lindex $node 1] if {[my <db> exists {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}]} { set row [my <db> one {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}] return 1 } } set class [lindex $node 0] set name [lindex $node 1] if {[my <db> exists {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}]} { set parent [my <db> one {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}] } else { return 0 } foreach {eclass ename} [lrange $node 2 end] { set row {} if {$eclass eq {}} { if {[my <db> exists {select entryid from entry where parent=:parent and (entryid=:ename or name=:ename)}]} { set row [my <db> one {select entryid from entry where parent=:parent and (entryid=:ename or name=:ename)}] } } else { if {[my <db> exists {select entryid from entry where parent=:parent and class=:eclass and (entryid=:ename or name=:ename)}]} { set row [my <db> one {select entryid from entry where parent=:parent and class=:eclass and (entryid=:ename or name=:ename)}] } } if { $row eq {} } { return 0 } set parent $row } return 1 } ### # topic: 6c3e041a03a5b2bcf5c6fdab1721d7b6 ### method node_get {nodeid {field {}}} { set result {} if {[my node_exists $nodeid entryid]} { set result [helpdoc node_properties $entryid] } else { if {[llength $nodeid] > 1} { set type [lindex $nodeid 0] set result [my node_empty $type] } } if { $field eq {} } { return $result } return [dict getnull $result $field] } ### # topic: bdeb89732bc42953dedf39bce57ab75b ### method node_id {node {create 0}} { if {[my <db> exists {select entryid from entry where entryid=:node;}]} { return [my <db> one {select entryid from entry where entryid=:node;}] } if {[llength $node]==1} { set name [lindex $node 0] if {[my <db> exists {select entryid from entry where name=:name or entryid=:name}]} { return [my <db> one {select entryid from entry where name=:name or entryid=:name}] } if { $create } { my <db> eval {insert into entry (class,name) VALUES ('section',:name)} return $name } else { error "Node $node does not exist" } } elseif {[llength $node]==2} { set class [lindex $node 0] set name [lindex $node 1] if {[my <db> exists {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}]} { set row [my <db> one {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}] return $row } } set class [lindex $node 0] set name [lindex $node 1] if {[my <db> exists {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}]} { set parent [my <db> one {select entryid from entry where (class=:class or parent=:class) and (name=:name or entryid=:name)}] } else { if {!$create} { error "Node $node does not exist" } ### # If the name contains no spaces, dots, slashes, or :: ### set row [::tao::uuid_generate $class $name] my <db> eval {insert into entry (entryid,class,name) VALUES (:row,:class,:name)} set parent $row } if { $create } { set classes [my <db> eval {select distinct class from entry}] } set eclass {} foreach token [lrange $node 2 end] { set ename $token set row {} if {$eclass eq {}} { if {[my <db> exists {select entryid from entry where parent=:parent and (entryid=:ename or name=:ename)}]} { set row [my <db> one {select entryid from entry where parent=:parent and (entryid=:ename or name=:ename)}] } } else { if {[my <db> exists {select entryid from entry where parent=:parent and class=:eclass and (entryid=:ename or name=:ename)}]} { set row [my <db> one {select entryid from entry where parent=:parent and class=:eclass and (entryid=:ename or name=:ename)}] } } if { $row eq {} } { if { $create } { if { $ename in $classes } { set eclass $token continue } else { set eclass {} my node_define_child $parent $eclass $ename {} row } } else { error "Node $node does not exist" } } set parent $row } return $row } ### # topic: 6f5dc7fcf3eb6204800a7b910d283483 ### method node_properties entryid { return [my <db> eval {select field,value from property where entryid=$entryid}] } ### # topic: 51611e18a49da769364ef583f439e8a2 ### method node_property_append {nodeid field text} { set buffer [my one {select value from property where entryid=:nodeid and field=:field}] append buffer " " [string trim $text] my <db> eval {insert or replace into property (entryid,field,value) VALUES (:nodeid,:field,:buffer)} } ### # topic: 79b939dca06915d886b2d6c0a393e803 ### method node_property_get {nodeid field} { return [my <db> one {select value from property where entryid=:nodeid and field=:field}] } ### # topic: cecb9e2416c9fec272e7beb9d4c183df # description: nodeid is any value acceptable to [lb]my node_alloc[rb] ### method node_property_lappend {entryid field args} { if {![llength $args]} return set dbvalue [my <db> eval {select value from property where entryid=$entryid and field=$field}] foreach value $args { if { $value eq {} } continue ::ladd dbvalue $value } my <db> eval {update property set value=$dbvalue where entryid=$entryid and field=$field} } ### # topic: 3f633c4bdd0fe22bb94870976e2e3aa8 ### method node_property_set {entryid args} { my variable property_info property_cname if {[llength $args]==1} { set arglist [lindex $args 0] } else { set arglist $args } foreach {field value} $arglist { if {[info exists property_cname($field)]} { set cname $property_cname($field) set rawvalue $value eval [dict getnull $property_info $cname script] } else { set cname $field } if {![my <db> exists {select value from property where entryid=:entryid and field=:cname and value=:value}]} { my <db> eval {insert or replace into property (entryid,field,value) VALUES (:entryid,:cname,:value)} } } } ### # topic: 7a941df07b5299ec365d98e284ca4442 ### method node_restore {nodeid info} { set stmtl {} dict with info {} set fields entryid set _entryid $nodeid set values "\$_entryid" foreach {field value} $info { switch $field { properties { foreach {var val} $value { my node_property_set $_entryid $var $val } } references { foreach {refid reftype} $references { my link_create $_entryid $refid $reftype } } enumid { my enum_set [lindex $value 0] [dict get $info name] [lindex $value 1] } aliases { foreach a $value { my canonical_set $_class $a $_name } } parent { if {![string is integer $value]} { set value [my node_id $value 1] } lappend fields $field lappend values "\$_$field" set _$field $value } class - address - name { if { $value ne {} } { lappend fields $field lappend values "\$_$field" set _$field $value } } } } my <db> eval "insert or replace into entry ([join $fields ,]) VALUES ([join $values ,]);" } ### # topic: 399c322eb03e90aacbc10ae171557cfd ### method node_serialize nodeid { set result {} my <db> eval { select * from entry where entryid=$nodeid } record { set entryid $record(entryid) append result "[list [self] node_restore $entryid] \{" \n foreach {field value} [array get record] { if { $field in {* entryid indexed export} } continue append result " [list $field $value]" \n } set class $record(class) set id [my canonical_id $class $record(name)] if { $id ne {} } { append result " [list enumid [list $class $id]]" \n } append result " properties \{" \n set info [my node_empty $record(class)] foreach {var val} [my node_properties $entryid] { dict set info $var $val } foreach {var} [lsort -dictionary [dict keys $info]] { if { $var in {aliases field method fields methods references id} } continue append result " [list $var [string trim [dict get $info $var]]]" \n } append result " \}" \n set references [my <db> eval {select refentry,linktype from link where entry=$entryid}] if {[llength $references]} { append result " [list references $references]" \n } set aliases [my canonical_aliases $record(class) $record(name)] if {[llength $aliases]} { append result " [list aliases $aliases]" \n } set attachments [my <db> eval {select file.hash,filelink.linktype from file,filelink where filelink.entryid=$entryid and filelink.fileid=file.fileid}] if {[llength $attachments]} { append result " [list attachments $attachments]" \n } append result "\}" } return $result } ### # topic: 841e0e684d5dd1035ed56316e3a075b2 ### method property_define {property info} { my variable property_info property_cname foreach {f v} $info { dict set property_info $property $f $v } foreach alias [dict getnull $property_info $property aliases] { set property_cname($alias) $property } set property_cname($property) $property } ### # topic: db9d2312731e0b51f1cf0ce4f597ecdb ### method reindex {} { my variable canonical_name my <db> eval {select class,alias,cname from aliases order by class,cname,alias} { dict set canonical_name $class $alias $cname } } ### # topic: 5b3aeab40382b22c6a5dda372de4faec ### method repository_restore {handle info} { set stmtl {} dict with info {} set fields handle set _handle $handle set values "\$_handle" foreach {field value} $info { switch $field { localpath { if { $value ne {} } { lappend fields $field lappend values "\$_$field" set _$field $value } } } } my <db> eval "insert or replace into repository ([join $fields ,]) VALUES ([join $values ,]);" } } interp alias {} tao.yggdrasil {} ::taodb::yggdrasil |
Added modules/tao/db.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | ### # topic: 62313463-3530-3535-3337-3237343930343 ### foreach varname { ::tao::info::class ::tao::info::object } { if {![info exists $varname]} { set $varname {} } } if {[info command ::tao::db] eq {}} { package require sqlite3 sqlite3 ::tao::db :memory: # Build the schema ::tao::db function string_match {string match} ::tao::db eval { create table class ( name string primary key, package string, superclass list default '::tao::moac', regenerate integer default 0 ); create table class_property ( class string references class, type string default const, property string, dict text, primary key (class,type,property) on conflict replace ); create table class_ensemble ( class string references class, ensemble string, method string, arglist string, body text, primary key (class,ensemble,method) on conflict replace ); create table class_typemethod ( class string references class, method string, arglist string, body text, primary key (class,method) on conflict replace ); create table class_alias ( cname string references class, alias string references class ); create table class_ancestor ( class string references class, direct integer default 0, seq integer, ancestor string references class, primary key (class,ancestor) on conflict ignore ); create table object ( name string primary key, package string, regen integer default 0 ); create table object_alias ( cname string references object, alias string references object ); create table object_bind ( object string references object, event string, script blob, primary key (object,event) on conflict replace ); create table object_schedule ( object string references object, event string, time integer, eventorder integer default 0, script string, primary key (object,event) on conflict replace ); create table object_subscribers ( sender string references object, receiver string references object, event string, primary key (sender,receiver,event) on conflict ignore ); } } ### # topic: b14c505537274904578340ec1bc12af1 ### namespace eval ::tao { variable trace 0 } |
Added modules/tao/diagram.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | ::namespace eval ::tao {} ### # topic: 9f2e173840e3307fb6bd47e72e3d2451 # title: Generate a graphviz diagram of the current object hierarchy ### proc ::tao::diagram {base filename {ignorefunct ::tao::diagram_ignore}} { set fout [open $filename w] puts $fout { /* * @command = dot * */ } puts $fout "digraph g \{" puts $fout { rankdir = LR; compound=true; } #layout = dot #compound = true # set direct 1 set classlist {} if { $base in {* all}} { ::tao::db eval {select name from class order by name} { if {[$ignorefunct $name]} continue lappend classlist $name } } else { foreach b $base { ::tao::db eval {select name from class where package=:b order by name} { if {[$ignorefunct $name]} continue lappend classlist $name ::tao::db eval {select class from class_ancestor where ancestor=:name and direct=1} { if { $class in $classlist } continue lappend classlist $class } } } } ::tao::db eval "select * from class where name in ('[join $classlist ',']')" { ladd modules($package) $name dict set classinfo $name display [diagram_name $name] dict set classinfo $name module $package dict set classinfo $name connections [::tao::db eval "select ancestor from class_ancestor where (class=:name and direct=1) order by seq desc;"] } set graphid 0 foreach {module mclasses} [lsort -dictionary -stride 2 [array get modules]] { puts $fout " subgraph \"module[incr graphid]\" \{" set includes {} foreach class $mclasses { if {[$ignorefunct $class]} continue lappend includes [diagram_name $class] set links [dict get $classinfo $class connections] foreach {link direct} $links { if { $link eq $class } continue if {[$ignorefunct $link]} continue if {[string is true -strict $direct] } { lappend indirect([diagram_name $link]) [diagram_name $class] } elseif { $link in $mclasses } { puts $fout " [diagram_name $link]->[diagram_name $class]\;" } else { lappend extlinks([diagram_name $link]) [diagram_name $class] } } } #puts $fout " rank=same; [join $includes \;]" puts $fout " [join $includes \;]" puts $fout " label = \"Module $module\"\;" puts $fout " color=lightgrey;" puts $fout "\}" } foreach {class links} [lsort -dictionary -stride 2 [array get extlinks]] { foreach link $links { puts $fout " $class->$link\;" } } foreach {class info} [get classinfo] { dict with info {} puts $fout "$display \[shape = box\; label=\"[string trimleft $class :]\"\]\;" } puts $fout "\}" close $fout } ### # topic: c4dd91d51fb5ab26ec90c39ed4dbd306 ### proc ::tao::diagram_class {base filename {show_indirect 0} {ignorefunct ::tao::diagram_ignore}} { #layout = dot #compound = true # set direct 1 set classlist {} set direct 0 set classlist $base foreach bclass $base { ::tao::db eval {select class from class_ancestor where ancestor=:bclass} { if { $class in $classlist } continue lappend classlist $class } ::tao::db eval {select ancestor from class_ancestor where class=:bclass} { if { $ancestor in $classlist } continue lappend classlist $ancestor } } ::tao::db eval "select * from class where name in ('[join $classlist ',']')" { ladd modules($package) $name dict set classinfo $name display [diagram_name $name] dict set classinfo $name module $package ::tao::db eval "select ancestor,direct from class_ancestor where (class=:name and ancestor in ('[join $classlist ',']')) order by seq desc;" { if {[$ignorefunct $ancestor]} continue if { $ancestor eq $name } continue if { !$direct } { lappend indirect([diagram_name $ancestor]) [diagram_name $name] } else { lappend extlinks([diagram_name $ancestor]) [diagram_name $name] } } } if {[info exists classinfo]} return set fout [open $filename w] puts $fout { /* * @command = dot * */ } puts $fout "digraph g \{" puts $fout { rankdir = LR; compound=true; } foreach {class links} [lsort -dictionary -stride 2 [array get extlinks]] { foreach link $links { puts $fout " $class->$link\;" } } if { $show_indirect } { puts $fout " edge \[color=red\]\;" foreach {class links} [lsort -dictionary -stride 2 [array get indirect]] { foreach link $links { puts $fout " $class->$link\; " } } } foreach {class info} $classinfo { dict with info {} puts $fout "$display \[shape = box\; label=\"[string trimleft $class :]\"\]\;" } puts $fout "\}" close $fout } ### # topic: f1b91f039c8be1c604563a6624af84fe ### proc ::tao::diagram_ignore class { if { $class in {::tao::moac ::oo::class ::oo::object} } { return 1 } return 0 } ### # topic: c7e2d0be0393921331e4476ff0a77e5a ### proc ::tao::diagram_name name { set result {} foreach i [split $name :] { if { $i ne {} } { lappend result [join [split $i .] _] } } return [join $result _] } |
Added modules/tao/event.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | ### # This file implements the Tao event manager ### ::namespace eval ::tao {} ::namespace eval ::tao::event {} ### # topic: 2097c1149d50b67b94ea09f0bcad9e5c # description: Subscribe an object to events of type <b>event</b> ### proc ::tao::event::bind {self event args} { if {![llength $args]} { return [::tao::db one {select script from object_bind where object=:self and event=:event}] } set script [lindex $args 0] if { $script eq {} } { ::tao::db eval {delete from object_bind where object=:self and event=:event} } else { ::tao::db eval { insert or ignore into object(name) VALUES (:self); insert or replace into object_bind (object,event,script) VALUES (:self,:event,:script); } } } ### # topic: f2853d380a732845610e40375bcdbe0f # description: Cancel a scheduled event ### proc ::tao::event::cancel {self {task *}} { variable timer_event foreach {id event} [array get timer_event $self:$task] { ::after cancel $event set timer_event($id) {} } } ### # topic: 8ec32f6b6ba78eaf980524f8dec55b49 # description: # Generate an event # Adds a subscription mechanism for objects # to see who has recieved this event and prevent # spamming or infinite recursion ### proc ::tao::event::generate {self event args} { set dictargs [::tao::args_to_options {*}$args] set info $dictargs set strict 0 set debug 0 set sender $self dict with dictargs {} dict set info id [::tao::event::nextid] dict set info origin $self dict set info sender $sender dict set info rcpt {} foreach who [Notification_list $self $event] { catch {::tao::event::notify $who $self $event $info} } } ### # topic: 891289a24b8cc52b6c228f6edb169959 # title: Return a unique event handle ### proc ::tao::event::nextid {} { return "event#[format %0.8x [incr ::tao::event_count]]" } ### # topic: 1e53e8405b4631aec17f98b3e8a5d6a4 # description: # Called recursively to produce a list of # who recieves notifications ### proc ::tao::event::Notification_list {self event {stackvar {}}} { if { $stackvar ne {} } { upvar 1 $stackvar stack } else { set stack {} } if {$self in $stack} { return {} } lappend stack $self ::tao::db eval {select receiver from object_subscribers where string_match(sender,:self) and string_match(event,:event)} { ::tao::db eval {select name as rcpt from object where string_match(name,:receiver)} { Notification_list $rcpt $event stack } } return $stack } ### # topic: b4b12f6aed69f74529be10966afd81da ### proc ::tao::event::notify {rcpt sender event eventinfo} { if {$::tao::trace} { puts [list event notify rcpt $rcpt sender $sender event $event info $eventinfo] } $rcpt notify $event $sender $eventinfo } ### # topic: 829c89bda736aed1c16bb0c570037088 ### proc ::tao::event::process {self handle script} { variable timer_event array unset timer_event $self:$handle set err [catch {uplevel #0 $script} result] if $err { puts "BGError: $self $handle $script ERR: $result" } } ### # topic: a6e4eebefcd2cec57ee4f0d8c10c92c0 ### proc ::tao::event::publish {self who event} { ::tao::db eval { insert or ignore into object(name) VALUES (:self); insert or replace into object_subscribers (sender,receiver,event) VALUES (:self,:who,:event); } } ### # topic: eba686cffe18cd141ac9b4accfc634bb # description: Schedule an event to occur later ### proc ::tao::event::schedule {self handle interval script} { variable timer_event if {$::tao::trace} { puts [list $self schedule $handle $interval] } if {[info exists timer_event($self:$handle)]} { ::after cancel $timer_event($self:$handle) } set timer_event($self:$handle) [::after $interval [list ::tao::event::process $self $handle $script]] } ### # topic: 63d680db51c1a3a04c2a038b8f9747d0 ### proc ::tao::event::signal {self event} { } ### # topic: e64cff024027ee93403edddd5dd9fdde ### proc ::tao::event::subscribe {self who event} { ::tao::db eval { insert or ignore into object(name) VALUES (:self); insert or replace into object_subscribers (receiver,sender,event) VALUES (:self,:who,:event); } } ### # topic: 177acc5c440c615437dd02cba0ab778c ### proc ::tao::event::unpublish {self args} { switch {[llength $args]} { 0 { ::tao::db eval {delete from object_subscribers where sender=:self} } 1 { set event [lindex $args 0] ::tao::db eval {delete from object_subscribers where sender=:self and string_match(event,:event)=1} } } } ### # topic: 5f74cfd01735fb1a90705a5f74f6cd8f ### proc ::tao::event::unsubscribe {self args} { switch {[llength $args]} { 0 { ::tao::db eval {delete from object_subscribers where receiver=:self} } 1 { set event [lindex $args 0] ::tao::db eval {delete from object_subscribers where receiver=:self and string_match(event,:event)=1} } } } ### # topic: 37e7bd0be3ca7297996da2abdf5a85c7 # description: The event manager for Tao ### namespace eval ::tao::event { variable nextevent {} variable nexteventtime 0 } |
Added modules/tao/events.md.
Added modules/tao/index.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package provide tao 9.4.4 package require sqlite3 package require TclOO package require listutil 1.7 ::namespace eval ::tao {} ### # topic: f796a2dcb22de645fb365e07d39fce07 ### proc ::tao::load_path {path {ordered_files {}}} { if {$::tcl_platform(platform) eq "windows"} { if {[string index $path 1] eq ":"} { set path [string range $path 2 end] } } lappend loaded index.tcl pkgIndex.tcl if {[file exists [file join $path baseclass.tcl]]} { lappend loaded baseclass.tcl uplevel #0 [list source [file join $path baseclass.tcl]] } foreach file $ordered_files { lappend loaded $file uplevel #0 [list source [file join $path $file]] } foreach file [glob -nocomplain [file join $path *.tcl]] { if {[file tail $file] in $loaded} continue lappend loaded [file tail $file] uplevel #0 [list source $file] } } ### # topic: b8897eebb90a62e0bac262762116b6b5 ### proc ::tao::script_path {} { set path [file dirname [file normalize [info script]]] return $path } set ::tao::root [::tao::script_path] ::tao::load_path $::tao::root { event.tcl parser.tcl ootools.tcl module.tcl db.tcl moac.tcl onion.tcl mvc.tcl } tao::module pop |
Added modules/tao/license.terms.
> > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | TAO - Tcl Architecture of Objects Copyright (c) 2012, Sean Woods All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sean Woods, Etoyoc Heavy Industries, Test and Evaluation Solutions, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY SEAN WOODS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEAN WOODS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Added modules/tao/lutils.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | ### BEGIN COPYRIGHT BLURB # # TAO - Tcl Architecture of Objects # Copyright (C) 2003 Sean Woods # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # ### END COPYRIGHT BLURB package provide listutil 1.7 proc ::tcl::mathfunc::pi {} [list return [expr 4.0*atan(1.0)]] proc ::tcl::mathfunc::pio2 {} [list return [expr 2.0*atan(1.0)]] proc ::tcl::mathfunc::sqrt2 {} [list return [expr sqrt(2)]] proc ::tcl::mathfunc::e {} [list return [expr exp(1)]] # [dict getnull] is like [dict get] but returns empty string for missing keys. proc ::tcl::dict::getnull {dictionary args} { if {[exists $dictionary {*}$args]} { get $dictionary {*}$args } } namespace ensemble configure dict -map [dict replace\ [namespace ensemble configure dict -map] getnull ::tcl::dict::getnull] if 0 { proc ::string::capitalize word { # Return $word with its first letter capitalized # Needed because sometimes [string totitle] plays games with us return [string toupper [string index $word 0]][string range $word 1 end] } } proc iscommand {name} { expr {([string length [info command $name]] > 0) || [auto_load $name]} } proc makeproc {name arglist body} { if {![iscommand $name]} { proc $name $arglist $body } } ### # Make a new md5 command that # behaves like the one in tobe ### if {[info command irmmd5] != {} } { makeproc md5Hash string { return [irmmd5 $string] } } else { package require md5 2.0 makeproc md5Hash string { return [string tolower [::md5::md5 -hex $string]] } } ### # proc: ::is_zero value # title: Returns 1 if the value is zero or null ### makeproc is_zero value { if {[string is false $value]} { return 1 } if { $value == 0.0 } { return 1 } return 0 } ### # proc: ::is_zero value # title: Returns 1 if the value is zero or null ### makeproc if_zero {value replace} { if {[string is false $value]} { return $replace } if { $value == 0.0 } { return $replace } return $value } ### # proc: ::is_zero value # title: Returns 1 if the value is zero or null ### makeproc if_null {value replace} { if {[string is false $value]} { return $replace } if { $value == 0.0 } { return $replace } return $value } ### # Print a dict to the screen ### makeproc pdict value { puts *** foreach {var val} $value { puts "$var: [list $val]" } puts *** } ############################################################## # General use procedures # proc: unique # title: Returns a unique number # makeproc unique {{val 0}} { incr val makeproc unique "{val $val}" [info body unique] return $val } makeproc setIfHigher {varname value} { upvar 1 $varname var if { $var < $value } { set var $value } } makeproc now {} { return [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] } makeproc dflt {varname i b} { upvar 1 $varname a if {![info exists a($i)] || $a($i)==""} { return $b } if {$a($i)<0.0} { return 0 } return [expr {int($a($i))}] } makeproc setVarsFromDict {dictval varlist} { foreach var $varlist { upvar 1 $var $var if ![info exists $var] { set $var {} } if [dict exists $dictval $var] { set $var [dict get $dictval $var] } } } makeproc addAutoPath path { set path [file normalize $path] if ![file exists $path] return if { $path in $::auto_path } return foreach item $::auto_path { if { [file normalize $item] == $path } return } lappend ::auto_path $path } makeproc K {x y} { return $x } makeproc combine args { foreach i $args { set c [llength $i] if { $c % 2 != 0 } { foreach {var val} $i { puts [list $var $val] } error [list Unbalanced Dict: $i $args] } lappend outstr $c } foreach {var val} [lindex $args 0] { dict set result $var $val } #set result [lindex $args 0] foreach item [lrange $args 1 end] { foreach {var val} $item { if { $val == {} } { if ![dict exists $result $var] { dict set result $var $val continue } } if { $val == "NULL" } { dict set result $var {} continue } dict set result $var $val } } return $result } makeproc dictGet {dict args} { if {[dict exists $dict {*}$args]} { return [dict get $dict {*}$args] } return {} } ### Sets or unsets a flag value makeproc flag {cmnd varname {val {}} {cd 0}} { upvar 1 $varname var if ![info exists var] { set var {} } if [regexp , $var] { set cd 1 set var [split $var ,] } switch $cmnd { add { ladd var $val } remove { ldelete var $val } fix { set cd 1 } } if $cd { set var [join $var ,] } } # # A Pure Tcl implementation of the lutil command # makeproc lutil {command varname args} { upvar 1 $varname stack if ![info exists stack] { set stack {} } set result {} switch $command { pop { set result [lindex $stack 0] set stack [lrange $stack 1 end] set setvarn [lindex $args 0] if { $setvarn != {} } { upvar 1 $setvarn setvar set setvar $result update idletasks set result [expr [llength $stack] > 0] } } queue { lappend stack [lindex $args 0] } push { set stack [linsert [K $stack [set stack {}]] 0 [lindex $args 0]] } peek { set result [lindex $stack 0] } } return $result } makeproc ldelete {varname args} { upvar 1 $varname var if ![info exists var] { return } foreach item [lsort -unique $args] { while {[set i [lsearch $var $item]]>=0} { set var [lreplace $var $i $i] } } } makeproc ladd {varname args} { upvar 1 $varname var if ![info exists var] { set var {} } foreach item $args { if {$item in $var} continue lappend var $item } return $var } makeproc ladd_sorted {varname item} { upvar 1 $varname var lappend var $item set var [lsort -dictionary -unique $var] return $var } makeproc lset {varname fieldlist datalist} { upvar 1 $varname var set idx -1 foreach field $fieldlist { set var($field) [lindex $datalist [incr idx]] } } makeproc listset {datalist varlist} { set idx -1 foreach fieldVar $varlist { upvar 1 $fieldVar $fieldVar set $fieldVar [lindex $datalist [incr idx]] } } makeproc stripList arglist { set lastitem $arglist while { [llength $arglist] == 1 } { set lastitem $arglist set arglist [lindex $arglist 0] } if { [llength $arglist] == 0 } { set arglist $lastitem } return $arglist } ### # Reverse the order of a list ### makeproc lreverse {list} { set result {} foreach item $list { set result [linsert [K $result [set result {}]] 0 $item] } return $result } makeproc lmerge {varname valuelist} { upvar 1 $varname var if ![info exists var] { set var {} } set result {} foreach a $var { if { [lsearch $result $a] < 0 } { lappend result $a } } foreach a $valuelist { if { [lsearch $result $a] < 0 } { lappend result $a } } set var $result return $result } makeproc get varname { upvar 1 $varname var if [info exists var] { return [set var] } } makeproc dictget {dict field} { if [dict exists $dict $field] { return [dict get $dict $field] } } makeproc pop {stackvar resultvar} { upvar 1 $stackvar stack upvar 1 $resultvar result if { [set len [llength $stack]] == 0 } { set result {} return 0 } set result [lindex $stack end] if { $len == 1 } { set stack {} } else { set stack [lrange $stack 0 end-1] } return 1 } makeproc peek {stackvar} { upvar 1 $stackvar stack return [lindex $stack end] } makeproc push {stackvar value} { upvar 1 $stackvar stack lappend stack $value } makeproc queue {stackvar val} { upvar 1 $stackvar stack lappend stack $val } makeproc lintersect {list value} { foreach item $value { if {[lsearch $list $item] >= 0} { return true } } return false } makeproc cat filename { set fin [open $filename r] set dat [read $fin] close $fin return $dat } |
Added modules/tao/moac.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | # Class tao::moac All classes in the Tao framework decend from tao::moac. # Concepts Back to [tao](tao.md) * [taodb](taodb.md) * [events](events.md) * [options](options.md) * [parser](parser.md) * [signals](signals.md) # Options * trace - When true, enable tracing information to stdout # Properties * options_strict - Default 0. When true, attempts to access an option through configure or cget, which was not declared by the *option* keyword, or inherited from another class, will fail. # Variables * ActiveLocks - A list of active locks * organs - A dict containing the mapping of stubs to objects # Methods ## action::busy Indicate to the user that the program is processing. (Empty method) ## action::idle Commands to run when the system releases the gui. (Empty method) ## action::morph_enter Commands to perform as an object enters this new class via the *morph* method. (Empty method) ## action::morph_leave Commands to perform as an object exits the current class via the *morph* method. (Empty method) ## action::pipeline_busy Commands to run when the system releases the locks. (Empty method) ** method cget *field* *?default?* Return the value for an option, or of the option is null return *default*. Dashes are stripped from the left of all fields. ** method code Return \[namespace code {self}\] ## method configure *keyvaluelist*|*key* *value* ?*key* *value*... Modify options. The command accepts either a single argument (a key value list), or a series of keys. Dashes are stripped from the left of all fields. Internally, *configure* normalizes the inputs, and passes them to *configurelist* and *configurelist_triggers*. ## method configurelist *keyvaluelist* Perform validation checks and modify the internal configuration of the object. This method will not trigger modification events. ## method event cancel ?*pattern*? Cancel a scheduled event. If *pattern* not specified, all scheduled tasks are cancelled. If *pattern* given, all task handles that match *pattern* are cancelled. Patterns are those used by *array get*. (Note: this method is actually a forward to ::tao::event::cancel) ## method event generate *event* *args...* Generate an event of type *event* which will be passed to the *notify* method of all objects subscribed to *event*. (Note: this method is actually a forward to ::tao::event::generate) ## method event nextid Return a unique name for an event. ## method event Notification_list *pattern* Called recursively to produce a list of who recieves notifications of pattern *pattern*. (Note: this method is actually a forward to ::tao::event::Notification\_list) ## method event publish *object_pattern* *event_pattern* Create a subscription for objects specified by *object_pattern* to events specified by *event_pattern*. Patterns should be any pattern suitiable for \[string match\] ## method event schedule *handle* *interval* *script* Arrange for *script* to be called after *interval*. Interval is any value acceptable to \[after\]. A successive call to *handle* will cancel the prior event and schedule a new one. ## method event subscribe *object_pattern* *event_pattern* Create a subscription for the current object to events emitted by objects specified by *object_pattern* to events specified by *event_pattern*. Patterns should be any pattern suitiable for \[string match\] ## method event unpublish *?event_pattern?* Remove any subscriptions to this object's events that match *event_pattern*. If *event_pattern* not given, all subscriptions are removed. ## method event unsubscribe *?event_pattern?* Remove any subscriptions this object has made to events that match *event_pattern*. If *event_pattern* not given, all subscriptions are removed. ## method forward *method* *?args...?* Forward *method* to the command specified by *args*. Internally this is just a wrapper around \[oo::objdefine forward\] ## method graft *stub* *object* ?*stub* *object*...? Calles to \<*stub*\> for this object will now forward to the *object* (or ensemble) specified. A mapping of stub->object is stored internally as a dict in the *organs* variable. ## method initialize Called during the constructor to set up all local variables and data structures. It is a seperate method to ensure inheritence chains predictably and also to keep us from having to pass along the constructor's arguments. ## method InitializePublic Provide a default value for all options and publically declared variables, and locks the pipeline mutex to prevent signal processing while the contructor is still running. A call to this method is automatically injected into the constructor by the Tao preprocessor's *constructor* keyword. Note, by default a Tao object will ignore signals until a later call to *my lock remove pipeline* ## method lock active Return a list of active locks. ## method lock create *lock* ?*lock*...? Add all arguments as locks if they are not already in the list of locks. ## method lock peek *lock* ?*lock*...? Returns true if any of the locks specified is active. ## method lock remove *lock* ?*lock*...? Remove the locks specified. If the last lock has been removed, a call to *lock remove_all* is made. ## method lock remove_all Removes all locks and makes a call to *Signal_pipeline* ## method message error *error* *errorInfo* Process a background error ## method morph *newclass* Have this object transition to *newclass* (if it isn't already that class). The following snippet describes the steps: # CALLED AS THE PRESENT CLASS my action morph_leave oo::objdefine [self] class ::${newclass} # CALLED AS THE NEW CLASS my variable config set savestate $config my InitializePublic my configurelist $savestate my action morph_enter The InitializePublic call ensures that any internal variables and options that are declared in the new class, but not present in the current class, are initialized. ## method mutex down *flag* Remove mutex *flag*. Return 1 if the mutex was active, 0 otherwise. ## method mutex peek *flag* Return 1 if mutex *flag* is active, 0 otherwise. ## method mutex up *flag* Attempt to establish a mutex *flag*. If mutex is already active, return 1. If a new mutex was successfully established, return 0. ## Ensemble notify *eventtype* *info* Process an incoming notification of *eventtime* immediately. ## Ensemble Option_set *field* *newvalue* Called by *configurelist_triggers* Process and incoming change to an option. ## method OptionsMirrored *stub* Return a list of options which should be mirrored to an object attached as \<*stub*\>. ## method organ *?stub?* Return the path to the object attached as \<*stub*\>. If stub not given, return a key/value list of all stubs and objects. ## method Prefs_Load Load persistant preferences for this object. (Empty method) ## method Prefs_Store dictargs Store persistant preferences for this object. (Empty method) ## method private *method* ?*args...*? Invoke a normally private method publically. ## method signal ?*signal* *signal...*? Generate a signal, which will ultimately schedule a call to *Signal_pipeline*. The call of one signal can trigger or suppress other signals. See [signals](signals.md) |
Added modules/tao/moac.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | if {[info command ::tao::metaclass] eq {}} { oo::class create ::tao::metaclass { superclass ::oo::class destructor { ::tao::class_destroy [self] } } } ### # topic: bb7bd8d93b61e5163b84e16341de3a35 # title: Mother of all Classes # description: # Base class used to define a global # template of expected behaviors ### tao::class tao::moac { aliases moac variable signals_pending {} variable signals_processed {} variable organs {} # Sets an active lock that will be # erased by a lock remove added to tail # of all tao constructors variable ActiveLocks constructor option trace { widget boolean default 0 } option_class variable { widget entry set-command {my Variable_set %field% %value%} get-command {my Variable_get %field%} } option_class organ { widget label set-command {my Option_graft %field% %value%} get-command {my organ %field%} } option_class property { widget label default-command {my property %field%} } property options_strict 0 constructor args { my configurelist [::tao::args_to_options {*}$args] my initialize } destructor {} ### # topic: fa52b5fa66bccb878ae6c4fe88f471a3 # description: Indicate to the user that the program is processing ### method action::busy {} ### # topic: 97d5cd58316988a2733c7ac2ad19735b # description: Commands to run when the system releases the gui ### method action::idle {} ### # topic: 03e3b8c1558a8153bc307fc098696d14 ### method action::morph_enter {} {} ### # topic: f54fc2f9dfcba2ff0e888469b3b3ba27 ### method action::morph_leave {} {} ### # topic: 7097c7ae9136bef863f89edddc384f60 ### method action::pipeline_busy {} {} ### # topic: d971de215cd4ce584813fdaa09ae6819 # description: Commands to run when the system releases the locks ### method action::pipeline_idle {} {} ### # topic: 86a1b968cea8d439df87585afdbdaadb ### method cget {field {default {}}} { my variable config set field [string trimleft $field -] set dat [my property option dict] if {[my property options_strict] && ![dict exists $dat $field]} { error "Invalid option -$field. Valid: [dict keys $dat]" } set info [dict getnull $dat $field] if {$default eq "default"} { set getcmd [dict getnull $info default-command] if {$getcmd ne {}} { return [{*}[string map [list %field% $field %self% [namespace which my]] $getcmd]] } else { return [dict getnull $info default] } } if {[dict exists $dat $field]} { set getcmd [dict getnull $info get-command] if {$getcmd ne {}} { return [{*}[string map [list %field% $field %self% [namespace which my]] $getcmd]] } if {![dict exists $config $field]} { set getcmd [dict getnull $info default-command] if {$getcmd ne {}} { dict set config $field [{*}[string map [list %field% $field %self% [namespace which my]] $getcmd]] } else { dict set config $field [dict getnull $info default] } } if {$default eq "varname"} { set varname [my varname visconfig] set ${varname}($field) [dict get $config $field] return "${varname}($field)" } return [dict get $config $field] } if {[dict exists $config $field]} { return [dict get $config $field] } return [my property $field] } ### # topic: 835853285c2acbbaaa3eb1abb5d1dbe9 ### method code {} { return [namespace code {self}] } ### # topic: 73e2566466b836cc4535f1a437c391b0 ### method configure args { # Will be removed at the end of "configurelist_triggers" set dictargs [::tao::args_to_options {*}$args] if {[llength $dictargs] == 1} { return [my cget [lindex $dictargs 0]] } my configurelist $dictargs my configurelist_triggers $dictargs } ### # topic: dc9fba12ec23a3ad000c66aea17135a5 ### method configurelist dictargs { my variable config set dat [my property option dict] if {[my property options_strict]} { foreach {field val} $dictargs { if {![dict exists $dat $field]} { error "Invalid option $field. Valid: [dict keys $dat]" } } } ### # Validate all inputs ### foreach {field val} $dictargs { set script [dict getnull $dat $field validate-command] if {$script ne {}} { {*}[string map [list %field% [list $field] %value% [list $val] %self% [namespace which my]] $script] } } ### # Apply all inputs with special rules ### foreach {field val} $dictargs { set script [dict getnull $dat $field set-command] if {$script ne {}} { {*}[string map [list %field% [list $field] %value% [list $val] %self% [namespace which my]] $script] } else { dict set config $field $val } } } ### # topic: 543c936485189593f0b9ed79b5d5f2c0 ### method configurelist_triggers dictargs { set dat [my property option dict] # Add a lock to prevent signals from # spawning signals my lock create configure ### # Apply normal inputs ### foreach {field val} $dictargs { if [catch { if {[dict exists $dat $field signal]} { my signal {*}[dict get $dat $field signal] } my Option_set $field $val } err] { puts [list [self] bg configure error: field $field val $val error $err] } } my Prefs_Store $dictargs my lock remove configure } ### # topic: 7b7c4a1ea317ff9e699c875353cf00cf ### method debugOut string {} ### # topic: 20b4a97617b2b969b96997e7b241a98a ### method event {submethod args} { ::tao::event::$submethod [self] {*}$args } ### # topic: d7787c21bbba4fbc8cc347fa6f0b1bc5 ### method forward {method args} { oo::objdefine [self] forward $method {*}$args } ### # topic: 87ba9c0905dbadcb68abe425339caddc ### method get {{field {}}} { if { $field == {} } { set result {} foreach f [::info object vars [self]] { my variable $f if {[array exists $f]} { dict set result @$f [::array get $f] } else { dict set result $f [set $f] } } return $result } my variable $field if {[array exists $field]} { return [::array get $field] } if {[info exists $field]} { return [set $field] } return {} } ### # topic: d0bf3b83fdbef6d41b5585eb034088da ### method getVarname field { return [my varname $field] } ### # topic: 9afd530cdd4fa83b793dd66f59f707af ### method graft args { my variable organs if {[llength $args] == 1} { error "Need two arguments" } set object {} foreach {stub object} $args { set stub [string trimleft $stub /] dict set organs $stub $object oo::objdefine [self] forward ${stub} $object oo::objdefine [self] forward <${stub}> $object oo::objdefine [self] export <${stub}> } return $object } ### # topic: 4369b15a85b8dc3453ee6af2902bd383 # description: # Called during the constructor to # set up all local variables and data # structures. It is a seperate method # to ensure inheritence chains predictably # and also to keep us from having to pass # along the constructor's arguments ### method initialize {} {} ### # topic: 3c4893b65a1c79b2549b9ee88f23c9e3 # description: # Provide a default value for all options and # publically declared variables, and locks the # pipeline mutex to prevent signal processing # while the contructor is still running. # Note, by default an odie object will ignore # signals until a later call to <i>my lock remove pipeline</i> ### method InitializePublic {} { my variable config if {![info exists config]} { set config {} } set dat [my property option dict] foreach {var info} $dat { if {[dict exists $info set-command]} { if {[catch {my cget $var} value]} { dict set config $var [my cget $var default] } else { if { $value eq {} } { dict set config $var [my cget $var default] } } } if {![dict exists $config $var]} { dict set config $var [my cget $var default] } } foreach {var info} [my property variable dict] { if { $var eq "config" } continue my variable $var if {![info exists $var]} { if {[dict exists $info default]} { set $var [dict get $info default] } else { set $var {} } } } foreach {var info} [my property array dict] { if { $var eq "config" } continue my variable $var if {![info exists $var]} { if {[dict exists $info default]} { array set $var [dict get $info default] } else { array set $var {} } } } my configurelist [my Prefs_Load] } ### # topic: 6c9e9e67ccd608d1983bbebcd81f2fd3 ### method lock::active {} { my variable ActiveLocks return $ActiveLocks } ### # topic: 86d39889df168ace883017cac2de3b61 ### method lock::create args { my variable ActiveLocks set result 0 foreach lock $args { if { $lock in $ActiveLocks } { set result 1 } else { lappend ActiveLocks $lock } } return $result } ### # topic: 6d8562be9185ac4990c3128a5a6aaac8 ### method lock::peek args { my variable ActiveLocks set result 0 foreach lock $args { if { $lock in $ActiveLocks } { set result 1 } } return $result } ### # topic: 8429bd3d95cbe42db11fa9d78073ed87 ### method lock::remove args { my variable ActiveLocks if {![llength $ActiveLocks]} { return 0 } set oldlist $ActiveLocks set ActiveLocks {} foreach item $oldlist { if {$item ni $args} { lappend ActiveLocks $item } } if {![llength $ActiveLocks]} { my lock remove_all return 1 } return 0 } ### # topic: 00210688cea68a175df35ff2c25ce5dd # description: Force-Removes all locks ### method lock::remove_all {} { my variable ActiveLocks set ActiveLocks {} my Signal_pipeline } ### # topic: 75af8a0e6c55a9619ee87698b08bd328 ### method message::error {error errorInfo} { puts "Error\n$error\n***\n$::errorInfo" return -code 1 $error -errorinfo $errorInfo } ### # topic: d15a85525b1f7151cd808e592bc09fed ### method morph newclass { my lock create morph set class [string trimleft [info object class [self]]] set newclass [string trimleft $newclass :] if {[info command ::$newclass] eq {}} { error "Class $newclass does not exist" } if { $class ne $newclass } { my action morph_leave oo::objdefine [self] class ::${newclass} my variable config set savestate $config my InitializePublic my configurelist $savestate my action morph_enter } my lock remove morph } ### # topic: 87c7b53c998e1f15c46b6a2fd187ef81 ### method mutex::down flag { my variable mutex if {![info exists mutex($flag)]} { set mutex($flag) 0 } set value $mutex($flag) set mutex($flag) 0 return $value } ### # topic: 958a56b4c9598f3988955d7606e8c049 ### method mutex::peek flag { my variable mutex if {![info exists mutex($flag)]} { set mutex($flag) 0 } return $mutex($flag) } ### # topic: 1adff94c1cc08f5286b11c97480b3546 ### method mutex::up flag { my variable mutex if {![info exists mutex($flag)]} { set mutex($flag) 0 } if {[set mutex($flag)] > 0} { return 1 } set mutex($flag) 1 return 0 } ### # topic: 3277490dddb5b19f42faaaaa50026f64 # description: Provide a quiet null handler for events ### method notify::default {sender dictargs} {} ### # topic: f1ce03ba2aab515d7d7c36ce04e49eda ### method Option_get::default {} { my variable $method if {[info exists $method]} { return [set $method] } return {} } ### # topic: 092e79383ef394de41de7a4143beef2b ### method Option_graft {organ pointer} { my variable config if { $pointer ne {} } { dict set config $organ $pointer my graft $organ $pointer } } ### # topic: 3749709452836a574ce3dd8165b1308c ### method Option_noop args { } ### # topic: 4fa8bc688ade4893c0083d96c9e1ddfc # description: Default handler for options ### method Option_set::default newvalue { my variable $method if {[info exists $method]} { set $method $newvalue } } ### # topic: 57e093ecd48756c19e14068cad2e6856 ### method OptionsMirrored organ { set result {} foreach {opt info} [my property option dict] { if {$organ in [dict getnull $info mirror]} { lappend result -$opt [my cget $opt] } } return $result } ### # topic: f867ee5408660c0296d731cda02b2bf8 ### method organ {{stub all}} { my variable organs if {![info exists organs]} { return {} } if { $stub eq "all" } { return $organs } return [dict getnull $organs $stub] } ### # topic: fca634e0193df7049d096dd43dd3c417 # title: Load persistant preferences ### method Prefs_Load {} {} ### # topic: e7f90dcfee554639cbf35b695827421a # title: Store persistant preferences ### method Prefs_Store dictargs {} ### # topic: 03c9ac58d726fe271c331c513f05b3a9 ### method private {method args} { return [my $method {*}$args] } ### # topic: 30668ecb1349a981d393d705f5ffe2e0 ### method proxy who { return [$who code] } ### # topic: b57ca4f29c6f69e4167176e13ced14ec ### method put args { if { [llength $args] == 1 } { set args [lindex $args 0] } foreach {key val} [::tao::args_to_dict {*}$args] { string trimleft $key - my variable $key set $key $val } } ### # topic: 1fe5a989f9e4334a1052fb4ef99eb7d1 ### method sensai object { foreach {stub obj} [$object organ all] { my graft $stub $obj } } ### # topic: b6214c62683a643102ade2ef21853873 # description: Does nothing ### method signal args { set rawlist [::tao::args_to_dict {*}$args] my variable signals_pending signals_processed set sigdat [my property signal dict] ### # Process incoming signals ### set signalmap $signals_pending foreach rawsignal $rawlist { ::tao::signal_expand $rawsignal $sigdat signalmap } set newsignals {} foreach signal $signalmap { if {$signal in $signals_processed} continue if {$signal in $signals_pending} continue set action [dict get $sigdat $signal action] if {[string length $action]} { lappend newsignals $signal lappend signals_pending $signal } set apply_action [dict get $sigdat $signal apply_action] if {[string length $apply_action]} { eval $apply_action } } if {[llength [my lock active]]} { return } if {("idle" in $rawlist && [llength $signals_pending]) || [llength $newsignals] } { set event [my event schedule signal idle [namespace code {my Signal_pipeline}]] } else { set event {} } return [list $event $signals_pending] } ### # topic: b9adb42b9e32fca79a9af340144281b6 ### method Signal_pipeline {} { if {[my mutex up pipeline]} { ### # Prevent the pipeline from being entered twice ### return } set errlist {} set trace [my cget trace] my action pipeline_busy set sigdat [my property signal dict] my variable signals_pending signals_processed set order [my property meta signal_order] set pass 0 if {$trace} { puts [list [self] [self method] $signals_pending] } if [catch { while {[llength [set signals $signals_pending]]} { ### # Copy our pending signals and clear out the list ### set signals_pending {} # Ignore mutually exclusive tasks set ignored {} foreach signal $order { if { $signal in $signals && $signal ni $ignored } { foreach item [dict get $sigdat $signal excludes] { ::ladd ignored $item } } } ### # Fire off signals in the order calculated ### foreach signal $order { if { $signal in $signals && $signal ni $ignored } { set action [dict get $sigdat $signal action] } } foreach signal $order { if { $signal in $signals && $signal ni $ignored } { lappend signals_processed $signal if {$trace} { puts [list $signal [dict get $sigdat $signal action]] } eval [dict get $sigdat $signal action] } } } } err] { lappend errlist $err $::errorInfo } my mutex down pipeline my action pipeline_idle foreach {err info} $errlist { my message error $err $info } ### # If this sequence triggered more sequences # schedule our next call ### set signals_processed {} } ### # topic: 135c91aa5f0344e5a37c31c003f7d7ca # title: Generate a path to a subordinate object ### method SubObject::default {} { return [namespace current]::SubObject_generic_$method } ### # topic: 853c3b333a67f543c032852f546556c2 ### method trace {{onoff {}}} { my variable trace if { $onoff == {} } { return $trace } set trace $onoff if { $trace } { oo::objdefine [self] method debugOut string {puts [list [my simTime] [self] $string]} } else { oo::objdefine [self] method debugOut string {} } } ### # topic: d70aa45da749a2fe7c1fb9755678322b ### method Variable_get::default {} { my variable $method return [get $method] } ### # topic: 02c62587fbec93f8adccc41d201c7c26 ### method Variable_set::default newvalue { my variable $method set $method $newvalue } } |
Added modules/tao/module.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ::namespace eval ::tao {} ### # topic: 3d9cc4f6252df40c5fd760ea4ba86f13 # title: Manage the module stack # description: # While the module stack does not impact normal operations within Tao # maintaining it allow Tao to populate the "package" field in the tao::db # [example { # ::tao::module push myPackage # ::tao::load_path $dir # ::tao::module pop # }] # darglist: [arg operation] [opt [arg module]] ### proc ::tao::module {cmd args} { ::variable moduleStack ::variable module switch $cmd { push { set module [lindex $args 0] lappend moduleStack $module return $module } pop { set priormodule [lindex $moduleStack end] set moduleStack [lrange $moduleStack 0 end-1] set module [lindex $moduleStack end] return $priormodule } peek { set module [lindex $moduleStack end] return $module } default { error "Invalid command \"$cmd\". Valid: peek, pop, push" } } } ::tao::module push core |
Added modules/tao/mvc.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | ### # Base classes for Model/View/Controller architecture ### ### # topic: 71b9a2bf1f9b9e1c8b1e06ceaa088b1d # description: # This class implements a common data store used by # a model view controller ### tao::class tao.mvcstore { } ### # topic: f9279c5be057cc75b1f1fd3bd4ee3052 ### tao::class tao.model { } ### # topic: 2927c0b0fc54227b3538f26e3bd0323b ### tao::class tao.view { } ### # topic: 2d337edf2d1b9042d4ee2510fcc4c99d ### tao::class tao.controller { variable mode_stack {} variable modes {} variable clearing 0 property default_context { class action button {} main-script {my actionstack clear} exit-script {} push-script {} appswitch-script {} popups 1 cursor arrow force_2d 1 usermode 0 icon {} auto-pop 0 edit-ok 0 interactive 0 modal 0 } signal busy { apply_action {my action busy} triggers {idle} } signal idle { apply_action {my action idle} follows * triggers {} } ### # topic: b749283c69423a3823ff4a9c5ea54a0a # description: # Code to run when the application is about to enter a # busy phase ### method action::busy {} {} ### # topic: e7b6d7ade002fab7c871236e94d09ff5 # description: Commands to run when the system ceases to be busy ### method action::idle {} {} ### # topic: 22e8612cf1155540ae8463e250978fe6 # description: # Action to perform at the top of every "peek" # onto the stack ### method action::mode_peek { } ### # topic: 1906474f86290ff6391a4eb07fa2f7e3 # description: # Action to perform when a mode is popped off # the stack/exited ### method action::mode_pop { } ### # topic: 780582fa0c41dcea48ac25c476c15604 # title: method to execute when we enter the mode from another mode # description: # Action to perform when a mode is pushed onto # the stack/entered ### method action::mode_push { } ### # topic: 849976e96911e4a595d479a45c4c2ec2 ### method action::stack_cleared { } ### # topic: 877b7f2efda12d0e9643afab6090b145 ### method actionstack::clear {} { my lock create [self method].$method set cleared 0 variable mode_stack while {[llength $mode_stack] > 0} { incr cleared if {[catch {my actionstack pop} err options]} { my action mode_peek return -options $options $err } } set mode_stack {} my action mode_peek if { $cleared } { my signal layer_update } my lock remove [self method].$method } ### # topic: 2d1fac13797eacfd48cdb8e87462565b ### method actionstack::define {name settings} { my variable modes organs if {![info exists modes]} { set modes {} } if {![dict exists $modes $name]} { set context [my property default_context] } else { set context [dict get $modes $name] } foreach {var val} $settings { dict set context $var $val } dict set modes $name $context return $name } ### # topic: 715f11d7322b94a080cc657d2fd02d7f # description: # A varient of action that clears the stack and establishes # new base-behaviors. Used to implement the different "modes" # in the visualization (i.e. runmode, playback, etc) ### method actionstack::morph newclass { ### # Tell runmode to cease ### my variable currentclass my lock create [self method].$method my actionstack clear if { [get currentclass] eq $newclass } { return } ### # After we have cleared the stack, destroy layers # we are not using and add layers that we are ### global g simconfig my action mode_pop my morph $newclass my activate_layers set currentclass $newclass my action mode_push [list prev_class $currentclass class $newclass] ### # Publish that we have changed modes ### my event generate mode_change prev_class $currentclass class $newclass my action mode_peek my lock remove [self method].$method } ### # topic: e2a03175995d1ba6e4f9e1224cbbb6cd ### method actionstack::peek {} { my lock create [self method].$method my action mode_peek my variable mode_stack organs if {[llength $mode_stack]==0} { my action mode_peek set context [my property default_context] set doPop 0 set force_interactive 1 } else { set context [lindex [get mode_stack] end] set doPop 0 set force_interactive 0 } set code [catch { dict with organs {} dict with context {} my popups_enabled ${popups} my cursor $cursor my action icon $icon if { $button != {} } { catch {$button configure -state pressed} } eval ${main-script} if { ${auto-pop} } { set doPop 1 } } result returnInfo] if { $code ni {0 2} } { set ::errorInfo [list Evaluating object [self] context $context]\n${::errorInfo} catch {my actionstack pop} return {*}${returnInfo} $result } if { $doPop } { my actionstack pop } my lock remove [self method].$method if {$force_interactive || $interactive} { my Signal_pipeline } } ### # topic: 312260fae2812d18bdb57fbbe24f7771 ### method actionstack::pop {} { my lock create [self method].$method my variable mode_stack organs set context [lindex $mode_stack end] if { $context ne {} } { if {![dict get $context usermode]} { set mode_stack [lrange $mode_stack 0 end-1] dict with organs {} dict with context {} if [catch ${exit-script} result returnInfo] { set ::errorInfo [list Evaluating object [self] context $context]\n${::errorInfo} return {*}${returnInfo} $result } } } my lock remove [self method].$method my actionstack peek } ### # topic: 6e52f9b7b20156b81348133e3c860e8f ### method actionstack::push {mode {inputcontext {}}} { my variable mode_stack modes organs my action busy my lock create [self method].$method set script {} ### # Load our organs as the local context ### set context [my property default_context] if {[dict exists $modes $mode]} { foreach {var val} [dict get $modes $mode] { dict set context $var $val } } foreach {var val} $inputcontext { dict set context $var $val } dict set context mode $mode dict set modes $mode $context set stack_clear 0 if {[dict exists $context exclusive]} { ### # If we have certain modes that are mutually exclusive on # the task stack, clear the stack ### set exclusive [dict get $context exclusive] set top [lindex $mode_stack end] if {[dict exists $top mode]} { if {[dict get $top mode] in $exclusive} { set stack_clear 1 } } } #### # Modal actions want to be the # top thing on the stack # so cancel anything else going on ### if {[dict get $context modal]} { set stack_clear 1 } if { $stack_clear } { my actionstack clear } lappend mode_stack $context dict with organs {} dict with context {} if [catch ${push-script} result returnInfo] { set ::errorInfo [list Evaluating object [self] context $context]\n${::errorInfo} return {*}${returnInfo} $result } my lock remove [self method].$method my actionstack peek } ### # topic: 3aaf2e553ea49a156469847f2a9e60f0 ### method configurelist_triggers dictargs { set dat [my property option dict] ### # Apply normal inputs ### my lock create configure foreach {field val} $dictargs { my Option_set $field $val } ### # Generate all signals ### foreach {field val} $dictargs { set signal [dict getnull $dat $field signal] if {$signal ne {}} { my signal $signal } } my Prefs_Store $dictargs my lock remove configure foreach {field val} $dictargs { set signal [dict getnull $dat $field signal] if {$signal ne {}} { my event generate {*}$signal [list value $val] } } } } |
Added modules/tao/onion.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | ### # topic: 0f30d28a31ce88dfb36ca1c12b454087 # description: # This class is a template for objects that will be managed # by an onion class ### tao::class tao::layer { aliases tao.layer option prefix {} option layer_name {} property layer_index_order 0 constructor {sharedobjects args} { foreach {organ object} $sharedobjects { my graft $organ $object } my graft layer [self] my configurelist [::tao::args_to_options {*}$args] } ### # topic: ce2844831edfd3d32b7e1044690e978a # description: Action to perform when layer is mapped visible ### method initialize {} { } ### # topic: 88c79c0e9188a477f535b66b01631961 ### method node_is_managed unit { return 0 } ### # topic: 8cc75f590cfad54a22ff0c454c90561c ### method type_is_managed unit { return [expr {$unit eq [my cget prefix]}] } } ### # topic: 2dba98b257eea6b843505bd2d4887b8a # description: # A form of megawidget which farms out major functions # to layers ### tao::class tao::onion { aliases tao.onion variable layers {} ### # Organs that are grafted into our layers ### property shared_organs { } ### # topic: 351937a37f294d3ac235e45b9c2f312e ### method action::activate_layers {} {} ### # topic: 81232b0943dce1f2586e0ac6159b1e2e ### method activate_layers {{force 0}} { set self [self] my variable layers set result {} set active [my active_layers] ### # Destroy any layers we are not using ### set lbefore [get layers] foreach {lname obj} $lbefore { if {![dict exists $active $lname] || $force} { $obj destroy dict unset layers $lname } } ### # Create or Morph the objects to represent # the layers, and then stitch them into # the application, and the application to # the layers ### foreach {lname info} $active { set class [dict get $info class] set ordercode [$class property layer_index_order] if { $ordercode ni {0 {}} } { lappend order($ordercode) $lname $info } else { lappend order(99) $lname $info } } set shared [my Shared_Organs] foreach {ordercode} [lsort -integer [array names order]] { set objlist $order($ordercode) foreach {lname info} $objlist { set created 0 set prefix [dict get $info prefix] set class [dict get $info class] set layer_obj [my SubObject layer $lname] dict set layers $lname $layer_obj if {[info command $layer_obj] == {} } { $class create $layer_obj $shared prefix $prefix layer_name $lname set created 1 foreach {organ object} $shared { $layer_obj graft $organ $object } } else { foreach {organ object} $shared { $layer_obj graft $organ $object } $layer_obj morph $class } ::ladd result $layer_obj $layer_obj event subscribe [self] * $layer_obj initialize } } my action activate_layers return $result } ### # topic: 7d8c8694fc10c9e8c5017dfaff4b1b8c # description: Returns a list of layers with properties needed to create them ### method active_layers {} { ### Example #set result { # xtype {prefix y class sde.layer.xtype} # eqpt {prefix e class sde.layer.eqpt} # portal {prefix p class sde.layer.portal} #} # return $result return {} } ### # topic: d800511c8a288ee9b935135e56c91a65 ### method layer {item args} { set scan [scan $item "%1s%d" class objid] switch $scan { 2 { # Search by class/objid if { $class eq "y"} { foreach {layer obj} [my layers] { if { [$obj type_is_managed $item] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } } } else { # Search my node if we have a prefix/number foreach {layer obj} [my layers] { if { [$obj node_is_managed $item] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } } } } default { # Search my name/prefix foreach {layer obj} [my layers] { if { [string match $item $layer] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } set data [my active_layers] if { [string match $item [dict get $data $layer prefix]] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } } # Search by string ### # Search by type ### foreach {layer obj} [my layers] { if { [$obj type_is_managed $item] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } } ### # Search fall back to search by node ### foreach {layer obj} [my layers] { if { [$obj node_is_managed $item] } { if {[llength $args]} { return [$obj {*}$args] } return $obj } } } } return ::noop } ### # topic: 75d06860b688273777a17cafb45710de # description: Return a list of layers for this application ### method layers {} { set result {} my variable layers if {![info exists layers]} { my activate_layers } return $layers } ### # topic: 96201b2abf6901f5750499e903be1351 ### method Shared_Organs {} { dict set shared master [self] foreach organ [my property shared_organs] { set obj [my organ $organ] if { $obj ne {} } { dict set shared $organ $obj } } return $shared } ### # topic: b1fe13c9c2f33fb26b71b03c7cb1d0a5 ### method SubObject::layer name { return [namespace current]::SubObject_Layer_$name } } |
Added modules/tao/onions.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | Onions have layers. Like ogres. Or parfaits. # Class tao::layer ## Options * prefix - A letter code for this layer * layer\_name - A plaintext name for this layer. * layer\_index\_order - Integer which expresses what order this layer should be index. (0 first -> infinity) ## Methods ### method node\_is\_managed *unit* Returns true if an object or record described by *unit* is managed by this object. ### method type\_is\_managed *unit* Returns true if an type, class or family of records described by *unit* is managed by this object. # Class tao::onion ## Variables * layers - A dict containing a mapping of layer names and the objects which implement them. ## Properties * shared_organs - A list of stubs which are also connected to any node or layer spawned by this object. ## Methods ### method action activate_layers Action to perform after all of the layer objects have been connected. ### method activate_layers ?1|0? Using the output of *active_layers*, build a nest of layers. If a *1* is given as the first argument, all existing layers are unmapped and destroyed before mapping new layers. Otherwise layers that were previously mapped and not present in the current incarnation of the object are destroyed. Layers which exist in the current incarnation, but which arent't mapped are created. Layers that are mapped, and present in the *active_layers*, but which have a different class implementation morph into the new class. ### method active_layers Return a dict describing the layers that should be mapped to this object. Example: method active_layers {} { set result { xtype {prefix y class sde.layer.xtype} eqpt {prefix e class sde.layer.eqpt} portal {prefix p class sde.layer.portal} } return $result } ### method layer *layerid* ?*method*? ?*args...*? With only the *layerid* argument, return the object which implements the layer described by *layerid*. If the layer does not exist, ::noop (a command which takes any argument and does nothing) is returned. If more arguments are specified, the command will exercise the *method* of the layer object using any additional *args*. Example: set obj [::db layer users] set username [$obj record_exists $userid] OR set exists [::db layer users record_exists $userid] ### method layers Return a dict describing the layers currently mapped to this object. ### method Shared_Organs Return a list of organs for this object which should also be grafted to any layers or other nodes spawned by it. The default implementation is to return the contents of the value of *property shared_organs* ### Method SubObject layer *name* Return the fully qualified name of the object which will implement this layer. The default implementation return \[namespace current\]::SubObject\_Layer\_\$name |
Added modules/tao/ootools.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | ::namespace eval ::tao {} ::namespace eval ::tao::event {} ::namespace eval ::tao::info {} ::namespace eval ::tao::parser {} ::namespace eval ::tao::signal {} ### # topic: 643efabec4303b20b66b760a1ad279bf ### proc ::tao::args_to_dict args { if {[llength $args]==1} { return [lindex $args 0] } return $args } ### # topic: b40970b0d9a2525990b9105ec8c96d3d ### proc ::tao::args_to_options args { set result {} foreach {var val} [args_to_dict {*}$args] { lappend result [string trimleft $var -] $val } return $result } ### # topic: 396899726d57640d3e90a2caa180d855 # title: Return the canonical name of a class ### proc ::tao::canonical name { set class ::[string trimleft $name :] ::tao::db eval {select cname from class_alias where alias=:class} { set class $cname } return $class } ### # topic: da87af1492df6d913beb343d9b534d1c # title: Create or modify a tao class # description: # This command is an enhancement to [emph {::oo::class create}] and [emph {oo::define}]. # In addition to the normal behavior expected from these operations, [emph tao::class] # tracks the class in the [emph tao::db] as well as rebuild the dynamic methods ### proc ::tao::class {name body} { set class [canonical $name] if { [::info command $class] == {} } { ::tao::metaclass create $class } ::tao::parser::push $class namespace eval ::tao::parser $body ::tao::parser::pop ::tao::dynamic_methods $class foreach {rname} [::tao::db eval {select name from class where regenerate!=0}] { ::tao::dynamic_methods $rname } set ::tao::coreclasses [::tao::db eval {select class from class_property where type='classinfo' and property='type' and dict='core'}] } ### # topic: 87e896b8994dba3927f227685169a939 ### proc ::tao::class_ancestors {class {stackvar {}}} { if { $stackvar ne {} } { upvar 1 $stackvar stack } else { set stack {} } if { $class in $stack } { return {} } lappend stack $class if {![catch {::info class superclasses $class} ancestors]} { foreach ancestor $ancestors { class_ancestors $ancestor stack } } if {![catch {::info class superclasses $class} ancestors]} { foreach ancestor $ancestors { class_ancestors $ancestor stack } } return $stack } ### # topic: 19f6ce3edca7d84e2f7d82e8a7e9035f # description: Return a list of tao classes ### proc ::tao::class_choices {} { return [lsort -dictionary $::tao::info:::class] } ### # topic: 8a0deafc19c1f3605a7ca961ec2ab01f ### proc ::tao::class_descendents {class {stackvar {}}} { if { $stackvar ne {} } { upvar 1 $stackvar stack } else { set stack {} } if { $class in $stack } { return {} } lappend stack $class foreach {child} [::tao::db eval {select class from class_ancestor where ancestor=:class}] { class_descendents $child stack } return $stack } ### # topic: 8c73a1ebe15b4935a4ff657399742257 ### proc ::tao::class_destroy class { if {[dict exists $::tao::info::class $class]} { dict unset ::tao::info::class $class } ::tao::db eval { delete from class_property where class=:class; delete from class_ensemble where class=:class; delete from class_typemethod where class=:class; delete from class_alias where cname=:class; delete from class_ancestor where class=:class or ancestor=:class; } } ### # topic: 4969d897a83d91a230a17f166dbcaede ### proc ::tao::dynamic_arguments {arglist args} { set idx 0 set len [llength $args] if {$len > [llength $arglist]} { ### # Catch if the user supplies too many arguments ### set dargs 0 if {[lindex $arglist end] ni {args dictargs}} { set string [dynamic_wrongargs_message $arglist] error $string } } foreach argdef $arglist { if {$argdef eq "args"} { ### # Perform args processing in the style of tcl ### uplevel 1 [list set args [lrange $args $idx end]] break } if {$argdef eq "dictargs"} { ### # Perform args processing in the style of tcl ### uplevel 1 [list set args [lrange $args $idx end]] ### # Perform args processing in the style of tao ### set dictargs [::tao::args_to_options {*}[lrange $args $idx end]] uplevel 1 [list set dictargs $dictargs] break } if {$idx > $len} { ### # Catch if the user supplies too few arguments ### if {[llength $argdef]==1} { set string [dynamic_wrongargs_message $arglist] error $string } else { uplevel 1 [list set [lindex $argdef 0] [lindex $argdef 1]] } } else { uplevel 1 [list set [lindex $argdef 0] [lindex $args $idx]] } incr idx } } ### # topic: a92cd258900010f656f4c6e7dbffae57 ### proc ::tao::dynamic_methods class { set ancestors [::tao::db eval {select ancestor from class_ancestor where class=:class order by CAST(seq as INTEGER);}] set order 0 set script {} ::tao::dynamic_methods_ensembles $class $ancestors ::tao::dynamic_methods_class $class $ancestors ::tao::dynamic_methods_property $class $ancestors ::tao::db eval {update class set regenerate=0 where name=:class;} } ### # topic: b88add196bb63abccc44639db5e5eae1 ### proc ::tao::dynamic_methods_class {thisclass ancestors} { set cmethods {} foreach anc $ancestors { ::tao::db eval {select method,arglist,body from class_typemethod where class=:anc} { if { $method in $cmethods } continue lappend cmethods $method ::oo::objdefine $thisclass method $method $arglist $body } } } ### # topic: fb8d74e9c08db81ee6f1275dad4d7d6f ### proc ::tao::dynamic_methods_ensembles {thisclass ancestors} { set ensembledict {} #set trace [string match $thisclass "::taotk::sqlconsole"] set trace 0 if {$trace} { puts "dynamic_methods_ensembles $thisclass"} foreach ancestor $ancestors { if {$trace} { puts $ancestor } ::tao::db eval {select * from class_ensemble where class=:ancestor} { if {[dict exists $ensembledict $ensemble $method]} continue if { $trace } { puts "$ensemble :: $method from $ancestor"} dict set ensembledict $ensemble $method [list $arglist $body] } } foreach {ensemble einfo} $ensembledict { set eswitch {} set default standard if {[dict exists $einfo default]} { set emethodinfo [dict get $einfo default] set arglist [lindex $emethodinfo 0] set realbody [lindex $emethodinfo 1] set body "\n ::tao::dynamic_arguments [list $arglist] {*}\$args" append body "\n " [string trim $realbody] " \n" set default $body dict unset einfo default } set eswitch \n append eswitch "\n [list <list> [list return [lsort -dictionary [dict keys $einfo]]]]" \n foreach {submethod} [lsort -dictionary [dict keys $einfo]] { set esubmethodinfo [dict get $einfo $submethod] set arglist [lindex $esubmethodinfo 0] set realbody [lindex $esubmethodinfo 1] if {[string length [string trim $realbody]] eq {}} { append eswitch " [list $submethod {}]" \n } else { set body "\n ::tao::dynamic_arguments [list $arglist] {*}\$args" append body "\n " [string trim $realbody] " \n" append eswitch " [list $submethod $body]" \n } } if {$default=="standard"} { set default "error \"unknown method $ensemble \$method. Valid: [lsort -dictionary [dict keys $eswitch]]\"" } append eswitch [list default $default] \n set body {} append body \n "set code \[catch {switch -- \$method [list $eswitch]} result opts\]" #if { $ensemble == "action" } { # append body \n { if {$code == 0} { my event generate event $method {*}$dictargs}} #} append body \n {return -options $opts $result} oo::define $thisclass method $ensemble {{method default} args} $body # Define a property for this ensemble for introspection ::tao::parser::property ensemble_methods $ensemble [lsort -dictionary [dict keys $einfo]] } if {$trace} { puts "/dynamic_methods_ensembles $thisclass"} } ### # topic: 6b7879602c202398bd25f733c0933cf9 ### proc ::tao::dynamic_methods_property {thisclass ancestors} { ### # Apply properties ### set info {} dict set info option {} set proplist {} foreach ancestor $ancestors { ::tao::db eval {select property,type,dict from class_property where class=:ancestor} { if {[dict exists $info $type $property]} continue dict set info $type $property $dict if { $type in {eval const subst variable}} { # For these values, we want to exclude equivilent calls if {[dict exists $info eval $property]} continue if {[dict exists $info const $property]} continue if {[dict exists $info subst $property]} continue lappend proplist $property set mdef [split $property _] if {[llength $mdef] > 1} { set ptype [lindex $mdef 0] lappend proptypes($ptype) $property } } } } set publicvars {} ### # Build options ### set option_classes [dict getnull $info option_class] # Build option handlers foreach {property pdict} [dict getnull $info option] { set contents { default {} } #append body \n " [list $property "return \[my cget [list $property]\]"]" set optionclass [dict getnull $pdict class] if {[dict exists $option_classes $optionclass]} { foreach {f v} [dict get $option_classes $optionclass] { dict set contents [string trimleft $f -] $v } } if {[dict exists $info option $optionclass]} { foreach {f v} [dict get $info option $optionclass] { dict set contents [string trimleft $f -] $v } } foreach {f v} $pdict { dict set contents [string trimleft $f -] $v } dict set info option $property $contents } dict set info meta class $thisclass dict set info meta ancestors $ancestors dict set info meta signal_order [::tao::signal_order [dict getnull $info signal]] dict set info meta types [lsort -dictionary -unique [array names proptypes]] dict set info meta local [get proplist] ### # Build the body of the property method ### set commonbody "switch \$field \{" append commonbody \n " [list class [list return $thisclass]]" append commonbody \n " [list ancestors [list return $ancestors]]" foreach {type typedict} $info { set typebody " switch \[lindex \$args 0\] \{" append typebody \n " [list list [list return [lsort -unique -dictionary [dict keys $typedict]]]]" append typebody \n " [list dict [list return $typedict]]" foreach {subprop value} $typedict { switch $type { variable { append typebody \n " [list $subprop [list return $value]]" } default { append typebody \n " [list $subprop [list return $value]]" } } } append typebody "\n \}" \n append commonbody \n " [list $type $typebody]" } # Build const property handlers foreach {property pdict} [dict getnull $info const] { append commonbody \n " [list $property [list return $pdict]]" } set body { my variable config if {[llength $args]==0} { if {[dict exists $config $field]} { return [dict get $config $field] } } } append body $commonbody append classbody $commonbody # Build eval property handlers foreach {property pdict} [dict getnull $info eval] { if {$property in $proplist} continue append body \n " [list $property $pdict]" } # Build subst property handlers foreach {property pdict} [dict getnull $info subst] { if {$property in $proplist} continue append body \n " [list $property [list return [subst $pdict]]]" } # Build option handlers foreach {property pdict} [dict getnull $info option] { dict set publicvars $property $pdict append body \n " [list $property "return \[my cget [list $property]\]"]" } # Build public variable handlers foreach {property pdict} [dict getnull $info variable] { dict set publicvars $property $pdict append body \n " [list $property "my variable $property \; return \$property\]"]" } # End of switch append body \n "\}" append classbody \n "\}" append body \n {return {}} oo::define $thisclass method property {field args} $body oo::objdefine $thisclass method property {field args} $classbody } ### # topic: 53ab28ac5c6ee601fe1fe07b073be88e ### proc ::tao::dynamic_wrongargs_message arglist { set result "Wrong # args: should be:" set dargs 0 foreach argdef $arglist { if {$argdef in {args dictargs}} { set dargs 1 break } if {[llength $argdef]==1} { append result " $argdef" } else { append result " ?[lindex $argdef 0]?" } } if { $dargs } { append result " ?option value?..." } return $result } ### # topic: cd54fcd0eef299655f36c9d1e1454d53 ### proc ::tao::macro {name arglist body} { proc ::tao::parser::$name $arglist $body } ### # topic: cf50771bb0664678ec3857b360c25aab # title: Go nowhere, do nothing ### proc ::tao::noop args {} ### # topic: 9e8830a711a1a888fb4c94c75bd46bad # description: Register the existence of an object ### proc ::tao::object_create object { } ### # topic: d42790a731ce9e3ff1866e71f9c42f17 # description: Unregister an object from the odie event manager ### proc ::tao::object_destroy object { variable trace if { $trace } { puts [list ::tao::object_destroy $object] } ::tao::event::generate $object destroy {} ### # Cancel any events ### ::tao::event::cancel $object * set names [list $object {*}[::tao::db eval {select alias from object_alias where cname=:object}]] foreach name $names { if {[dict exists $::tao::info::object $name]} { dict unset ::tao::info::object $name } ::tao::db eval { delete from object where name=:name; delete from object_bind where object=:name; delete from object_subscribers where sender=:name; delete from object_subscribers where receiver=:name; delete from object_alias where cname=:name or alias=:name; } } } ### # topic: d9ebb42dd1ce3ecde3905b57f96109ab ### proc ::tao::object_rename {object newname} { variable trace if { $trace } { puts [list ::tao::object_rename $object -> $newname] } rename $object ::[string trimleft $newname] ::tao::db eval { update object_alias set cname=:newname where cname=:object; update object set name=:newname where name=:object; update object_bind set object=:newname where object=:object; update object_subscribers set sender=:newname where sender=:object; update object_subscribers set receiver=:newname where receiver=:object; insert or replace into object_alias(cname,alias) VALUES (:newname,:object); } } ### # topic: 6f46e5ab32dc211c4f838aec8d187c17 ### proc ::tao::Signal_compare {i j sigdat {trace 0}} { if {$i == $j} { return 0 } set j_preceeds_i [Signal_matches $j [dict get $sigdat $i preceeds]] set i_preceeds_j [Signal_matches $i [dict get $sigdat $j preceeds]] set j_follows_i [Signal_matches $j [dict get $sigdat $i follows]] set i_follows_j [Signal_matches $i [dict get $sigdat $j follows]] if {$i_preceeds_j && !$j_preceeds_i && !$i_follows_j} { return -1 } if {$j_preceeds_i && !$i_preceeds_j && !$j_follows_i} { return 1 } if {$j_follows_i && !$i_follows_j} { return 1 } if {$i_follows_j && !$j_follows_i} { return -1 } set j_triggers_i [Signal_matches $j [dict get $sigdat $j triggers]] set i_triggers_j [Signal_matches $i [dict get $sigdat $i triggers]] return 0 } ### # topic: 1f4128fa725b7af77fc6458fe653a651 ### proc ::tao::signal_expand {rawsignal sigdat {signalvar {}}} { if {$signalvar ne {}} { upvar 1 $signalvar result } else { set result {} } if {$rawsignal in $result} { return {} } if {[dict exists $sigdat $rawsignal]} { lappend result $rawsignal # Map triggers foreach s [dict get $sigdat $rawsignal triggers] { signal_expand $s $sigdat result } } else { # Map aliases foreach {s info} $sigdat { if {$rawsignal in [dict get $info aliases]} { signal_expand $s $sigdat result } } } return $result } ### # topic: a92545861c81e86de17b19b008507776 ### proc ::tao::Signal_matches {signal fieldinfo} { foreach value $fieldinfo { if {[string match $value $signal]} { return 1 } } return 0 } ### # topic: 9cfad45cdb257837b13844261768286e ### proc ::tao::signal_order sigdat { set allsig [lsort -dictionary [dict keys $sigdat]] foreach i $allsig { set follows($i) {} set preceeds($i) {} } foreach i $allsig { foreach j $allsig { if { $i eq $j } continue set cmp [Signal_compare $i $j $sigdat] if { $cmp < 0 } { ::ladd follows($i) $j } } } # Resolve mutual dependencies foreach i $allsig { foreach j $follows($i) { foreach k $follows($j) { if {[Signal_compare $i $k $sigdat] < 0} { ::ladd follows($i) $k } } } } foreach i $allsig { foreach j $follows($i) { ::ladd preceeds($j) $i } } # Start with sorted order set order $allsig set pass 0 set changed 1 while {$changed} { set changed 0 foreach i $allsig { set iidx [lsearch $order $i] set max $iidx foreach j $preceeds($i) { set jidx [lsearch $order $j] if {$jidx > $max } { set after $j set max $jidx } } if { $max > $iidx } { set changed 1 set order [lreplace $order $iidx $iidx] set order [linsert $order [expr {$max + 1}] $i] } } if {[incr pass]>10} break } return $order } ### # topic: de8ee09c5a76e55364264b1e7a4b8003 ### proc ::tao::singleton {name body} { set class ::[string trimleft $name :].class #::ladd ::tao::class_list $class if { [::info command $class] == {} } { ::tao::metaclass create $class } ::tao::parser::push $class namespace eval ::tao::parser $body ::tao::parser::pop foreach {rname} [::tao::db eval {select name from class where regenerate!=0}] { ::tao::dynamic_methods $rname } $class create $name } |
Added modules/tao/options.md.
Added modules/tao/parser.md.
Added modules/tao/parser.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | ::namespace eval ::tao {} ::namespace eval ::tao::parser {} ### # topic: 5832132afd4f65a0dd404f834e7fce7f # title: Specify other names that this class will answer to ### proc ::tao::parser::aliases args { set class [peek] foreach name $args { set alias ::[string trimleft $name :] set cname [::tao::db one {select cname from class_alias where alias=:alias}] if { $cname ni [list {} $class] } { error "$alias is already an alias for $cname" } ::tao::db eval { insert into class_alias(cname,alias) VALUES (:class,:alias); } } } ### # topic: 7a5c7e04989704eef117ff3c9dd88823 # title: Specify the a method for the class object itself, instead of for objects of the class ### proc ::tao::parser::class_method {name arglist body} { set class [peek] method $name $arglist $body ::tao::db eval {insert or replace into class_typemethod (class,method,arglist,body) VALUES (:class,:name,:arglist,:body);} } ### # topic: 710a93168e4ba7a971d3dbb8a3e7bcbc ### proc ::tao::parser::component args { } ### # topic: 2cfc44a49f067124fda228458f77f177 # title: Specify the constructor for a class ### proc ::tao::parser::constructor {arglist rawbody} { set body { ::tao::object_create [self] my InitializePublic } append body $rawbody append body { # Remove lock constructor my lock remove constructor } ::oo::define [peek] constructor $arglist $body } ### # topic: 4cb3696bf06d1e372107795de7fe1545 # title: Specify the destructor for a class ### proc ::tao::parser::destructor rawbody { set body { ::tao::object_destroy [self] } append body $rawbody ::oo::define [peek] destructor $body } ### # topic: ec9ca249b75e2667ad5bcb2f7cd8c568 # title: Define an ensemble method for this agent ### ::proc ::tao::parser::method {rawmethod args} { set class [peek] set mlist [split $rawmethod "::"] if {[llength $mlist]==1} { set method $rawmethod set arglist [lindex $args 0] set body [lindex $args 1] ::oo::define $class method $rawmethod {*}$args return } set ensemble [lindex $mlist 0] set method [join [lrange $mlist 2 end] "::"] switch [llength $args] { 1 { set arglist dictargs set body [lindex $args 0] ::tao::db eval { insert or replace into class_ensemble(class,ensemble,method,arglist,body) VALUES (:class,:ensemble,:method,:arglist,:body)} } 2 { set arglist [lindex $args 0] set body [lindex $args 1] ::tao::db eval { insert or replace into class_ensemble(class,ensemble,method,arglist,body) VALUES (:class,:ensemble,:method,:arglist,:body)} } default { error "Usage: method NAME ARGLIST BODY" } } } ### # topic: 68aa446005235a0632a10e2a441c0777 # title: Define an option for the class ### proc ::tao::parser::option {name args} { set class [peek] set dictargs {default {}} foreach {var val} [::tao::args_to_dict {*}$args] { dict set dictargs [string trimleft $var -] $val } set name [string trimleft $name -] ### # Mirrored Option Handling ### set mirror [dict getnull $dictargs mirror] if {[llength $mirror]} { if {![dict exists $dictargs signal]} { set signal {} foreach i $mirror { set sname option_mirror_$i lappend signal $sname if {![::tao::db exists {select * from class_property where (class=:class or class in (select ancestor from class_ancestor where class=:class)) and type='signal' and property=:sname}]} { ::tao::parser::signal $sname [string map [list %signal% sname %organ% $i] { action { if {[my organ %organ%] ne {}} { my %organ% configure {*}[my OptionsMirrored %organ%] } } }] } } dict set dictargs signal $signal } } property option $name $dictargs } ### # topic: 827a3a331a2e212a6e301f59c1eead59 # title: Define a class of options # description: # Option classes are a template of properties that other # options can inherit. ### proc ::tao::parser::option_class {name args} { set class [peek] set dictargs {default {}} foreach {var val} [::tao::args_to_dict {*}$args] { dict set dictargs [string trimleft $var -] $val } set name [string trimleft $name -] property option_class $name $dictargs } ### # topic: baeb5170936f985e0e97be63018bc130 # title: Internal function # description: Returns the current class being processed ### proc ::tao::parser::peek args { if {[llength $args] == 2} { upvar 1 [lindex $args 0] class [lindex $args 1] docnode } ::variable classStack set class [lindex $classStack end] return ${class} } ### # topic: 1c598e92d29ba0311212b3fdf2334b34 # title: Internal function # description: Removes the current class being processed from the parser stack. ### proc ::tao::parser::pop {} { ::variable classStack set class [lindex $classStack end] set classStack [lrange $classStack 0 end-1] tao::db eval {update class set regenerate=1 where name=:class} # Signal for all decendents to regenerate foreach d [::tao::class_descendents $class] { tao::db eval {update class set regenerate=1 where name=:d} } return $class } ### # topic: 83160a2aba9dfa455d82b46cdd2e4127 # title: Define the properties for this class as a key/value list ### proc ::tao::parser::properties args { set class [peek] switch [llength $args] { 1 { foreach {var val} [lindex $args 0] { ::tao::db eval {insert or replace into class_property (class,type,property,dict) VALUES (:class,'const',:var,:val);} } } 2 { set type [lindex $args 0] foreach {var val} [lindex $args 1] { ::tao::db eval {insert or replace into class_property (class,type,property,dict) VALUES (:class,:type,:var,:val);} } } default { error "Usage: property ?type? infodict" } } } ### # topic: 709b71e10365e576653d00f185ca9efd # title: Define a single property for this class # description: If no type is given [emph const] is assumed. # darglist: [opt [arg type]] [arg name] [arg value] ### proc ::tao::parser::property args { set class [peek] switch [llength $args] { 2 { set type const set property [lindex $args 0] set value [lindex $args 1] } 3 { set type [lindex $args 0] set property [lindex $args 1] set value [lindex $args 2] } default { error "Usage: property ?type? field value" } default { error "Usage: property name typet valuedict OR property name value" } } if { $type eq {} } { set type eval } ::tao::db eval {insert or replace into class_property (class,type,property,dict) VALUES (:class,:type,:property,:value);} } ### # topic: bd23198ef1938428fb1532dd96de2c12 # description: Push a class onto the stack ### proc ::tao::parser::push type { ::variable classStack lappend classStack $type if {![::tao::db exists {select name from class where name=:type}]} { ::tao::db eval {insert into class(name,package,regenerate) VALUES (:type,$::tao::module,1);} } if {![dict exists $::tao::info::class $type]} { dict set ::tao::info::class $type { aliases {} ancestors {} regenerate 1 property {} ensemble {} superclass {::tao::moac} } } else { dict set ::tao::info::class $type regenerate 1 } } ### # topic: 4d12b6ca2823d960a81e6f15fd9962e6 # title: Create a signal for this class # description: # Really just a wrapper for [emph {property signal}]. However, # this keyword ensures manditory fields are given. ### proc ::tao::parser::signal {name infodict} { set result { apply_action {} action {} aliases {} comment {} excludes {} preceeds {} follows {} triggers {} } dict set result name $name foreach {f v} $infodict { dict set result $f $v } property signal $name $result } ### # topic: 2f74ddd49a0c8e8f92e73a843acca2d7 # title: Specify ancestors for this class # description: # This keyword mimics the behavior of the TclOO [emph superclass] # keyword. In addition to the TclOO connotations, this keyword # also indexes the class in the in-memory database. # [para] # For classes with no ancestors, call this keyword with no arguments. # Failure to do so will cause problems with the property method. # [para] # This function will also map classes classes refered to by alias. ### proc ::tao::parser::superclass args { set class [peek] set ancestors {} set direct {} set rawvalue {} foreach item $args { set anc ::[string trimleft $item :] set item $anc if {[::tao::db exists {select cname from class_alias where alias=:anc}]} { set item [::tao::db one {select cname from class_alias where alias=:anc}] } lappend rawvalue $item } foreach item $rawvalue { if { $item in {::tao::moac ::oo::class} } continue if { $item in $::tao::coreclasses } continue lappend direct $item if { $item ni $ancestors && $item ne $class } { lappend direct $item lappend ancestors $item } } foreach item $rawvalue { if { $item in {::tao::moac ::oo::class} } continue if { $item ni $::tao::coreclasses } continue lappend direct $item if { $item ni $ancestors && $item ne $class } { lappend direct $item lappend ancestors $item } } if { $class ne "::tao::moac" } { lappend ancestors ::tao::moac } ::tao::db eval {update class set superclass=:ancestors where name=:class} ::oo::define $class superclass {*}$ancestors set order -1 ::tao::db eval {delete from class_ancestor where class=:class} set ancestors [::tao::class_ancestors $class] foreach d $ancestors { incr order ::tao::db eval {insert into class_ancestor(class,seq,ancestor,direct) VALUES (:class,:order,:d,0);} } foreach d $direct { ::tao::db eval {update class_ancestor set direct=1 where class=:class and ancestor=:d} } property meta ancestors $ancestors } ### # topic: 615b7c43b863b0d8d1f9107a8d126b21 # title: Specify a variable which should be initialized in the constructor # description: # This keyword can also be expressed: # [example {property variable NAME {default DEFAULT}}] # [para] # Variables registered in the variable property are also initialized # (if missing) when the object changes class via the [emph morph] method. ### proc ::tao::parser::variable {name {default {}}} { property variable $name [list default $default] } ### # topic: c5f7c9ada6fe1605219273b957283d70 # description: Work space for the IRM class parser ### namespace eval ::tao::parser { foreach keyword { deletemethod export filter forward renamemethod self unexport unknown } { proc $keyword args "::oo::define \[peek\] $keyword {*}\$args" } namespace export * } |
Added modules/tao/pkgIndex.tcl.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded listutil 1.7 [list source [file join $dir lutils.tcl]] package ifneeded tao 9.4.4 [list source [file join $dir index.tcl]] |
Added modules/tao/property.md.
Added modules/tao/signals.md.
Added modules/tao/tao.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | The Tao package is a framework built on top of TclOO. Classes and objects created in Tao are 100% compadible with standard TclOO. Tao adds a host of features that is not available in vanilla TclOO They include the following: * [events](events.md) * [options](options.md) * [moac](moac.md) * [parser](parser.md) * [signals](signals.md) * [taodb](taodb.md) # Development Tao is maintained at <http://fossil.etoyoc.com/fossil/taolib>. If you are viewing this file from within tclhttpd's sources, you are viewing a snapshot that is periodically updated from the mainstream sources. Tao was built, designed, and maintained by Sean Woods <[email protected]>. # Major Concepts * All tao framework objects decend from the [Mother of all Classes](moac.md) * Tao classes are built using the *::tao::class* keyword, instead of *::oo::class create* * Tao classes can be modified using the *::tao::class* keyword, instead of *::oo::define* * A method in \<brackets\> indicates that the method is actually being forwarded to another object. * *::tao::class* is a pre-parser, which adds additional keywords and modifies the behavior of the constructor and destructor |
Added modules/tao/taodb.md.
Added modules/wysiwyg/buttons/blank-trans.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/blank.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/first-trans.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/first.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/goto.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/last-trans.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/last.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/next-trans.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/next.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/prev-trans.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/prev.gif.
cannot compute difference between binary files
Added modules/wysiwyg/buttons/search.gif.
cannot compute difference between binary files
Added modules/wysiwyg/css/styles.css.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* WYSIWYG EDITOR */ /* Toolbar */ .toolbar1 { border: 1px solid #666666; height: 26px; background-image: url(../icons/background_silver.jpg); } .toolbar2 { border: 1px solid #666666; height: 24px; background-image: url(../icons/background_silver.jpg); border-bottom: 0px; border-top: 0px; } /* Command Buttons */ .button { width: 20px; height: 20px; border: 0px solid transparent; margin: 1px; padding: 0px; background: transparent; } .buttonOver { width: 20px; height: 20px; border: 1px solid #999999; margin: 0; padding: 0px; } /* Font Type and Size Drop Down */ .dropdown { background-color: #FFFFFF; border: 1px solid #333333; height: 140px; overflow: auto; padding: 1px; } button.mouseOver { background-color: #EEEEEE; border: 1px solid #CCCCCC; padding: 3px; cursor: default; text-align: left;} button.mouseOut { background-color: #FFFFFF; border: 1px solid #FFFFFF; padding: 3px; cursor: default; text-align: left;} /* CREATE TABLE POPUP */ /* Select Border Width/Type */ .on { background-color: #EEEEEE; border: 1px solid #CCCCCC; padding: 6px; width: 140px; cursor: default; height: 5px;} .off { background-color: #FFFFFF; border: 1px solid #FFFFFF; padding: 6px; width: 140px; cursor: default; height: 5px;} /* Select Shading/Border Color */ .selectColorTable { border: 1px solid #7E7E81; background-color: #F7F7F7; padding: 1px; } .selectColorBorder { border: 1px solid #F7F7F7; } .selectColorOn { border: 1px solid #999999; background-color: #CCCCCC; } .selectColorOff { border: 1px solid #F7F7F7; background-color: #F7F7F7; } .selectColorBox { border: 1px solid #FFFFFF; font-size: 1px; height: 13px; width: 13px; } |
Added modules/wysiwyg/icons/backcolor.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/backcolor_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/background_silver.jpg.
cannot compute difference between binary files
Added modules/wysiwyg/icons/bold.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/bold_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/copy.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/copy_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/cut.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/cut_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/forecolor.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/forecolor_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/help.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/help_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/indent_left.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/indent_left_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/indent_right.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/indent_right_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_hyperlink.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_hyperlink_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_picture.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_picture_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_table.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/insert_table_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/italics.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/italics_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_center.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_center_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_left.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_left_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_right.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/justify_right_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/list_ordered.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/list_ordered_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/list_unordered.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/list_unordered_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/logo.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/paste.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/paste_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/redo.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/redo_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/select_font.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/select_font_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/select_size.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/select_size_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/seperator.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/seperator2.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/strikethrough.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/strikethrough_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/subscript.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/subscript_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/superscript.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/superscript_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/underline.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/underline_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/undo.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/undo_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/view_source.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/view_source_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/view_text.gif.
cannot compute difference between binary files
Added modules/wysiwyg/icons/view_text_on.gif.
cannot compute difference between binary files
Added modules/wysiwyg/js/ddbg3.gif.
cannot compute difference between binary files
Added modules/wysiwyg/js/example.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG Examples</title> </head> <script language="JavaScript" type="text/javascript" src="wysiwyg.js"> </script> <body> <form name="example" method="get"> <textarea id="textarea1" name="test1" style="height: 170px; width: 500px;"> <table border="0" cellpadding="0" cellspacing="0" style="margin-left: 10px;"> <tr> <td style="padding: 0 10 10 0;"><a href="http://www.openwebware.com/products/openwysiwyg/"><img src="http://www.openwebware.com/images/openwysiwyg/logo9060.gif" border="0" height="60" width="90" alt="openWYSIWYG - Cross-browser WYSIWYG editor"></a></td> <td style="font-family: verdana; font-size: 11px; line-height: 130%; color: #494949;" valign="top"> <b><a href="http://www.openwebware.com/products/openwysiwyg/" style="font-family: arial; font-size: 12px; color: #055F92;">openWYSIWYG - Cross-browser WYSIWYG editor</a></b><br /> <?php echo "Hello World"; ?> </td> </tr> </table> </textarea> <script language="javascript1.2"> generate_wysiwyg('textarea1'); </script> <br><br> <textarea id="textarea2" name="test2" style="height: 200px; width: 500px;"> <h1>GNU Lesser General Public License</h1> <tt> <p>Version 2.1, February 1999</p> <blockquote> <p>Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</p> <p>[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]</p></blockquote> <h3>Preamble</h3> <p> The licenses for most software are designed to take away your freedom to share and change it.</p> </tt> </textarea> <script language="javascript1.2"> generate_wysiwyg('textarea2'); </script> <br /><br /> <input type="submit" id="button" /> </form> </body> </html> |
Added modules/wysiwyg/js/expand.gif.
cannot compute difference between binary files
Added modules/wysiwyg/js/readme.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG - Online Documentation</title> <meta name="description" content="openWYSIWYG - An open source free cross-browser wysiwyg editor."> <meta name="keywords" content="wysiwyg editor browser dhtml javascript component content management software system open source free cross-browser"> <script language="JavaScript" type="text/javascript" src="wysiwyg.js"></script> <style> a {color: #3F8BD8;} a:hover {color: #FF9900;} h2 {font-size:15pt; font-weight:bold;color:red; font-family: "Trebuchet MS"; text-decoration: underline;} h3 {font-size:12pt; color: #494949; font-family: "Trebuchet MS";} </style> </head> <body style="background-color: #EEEEEE;"> <center> <table border="0" cellpadding="0" cellspacing="0" style=" border: 1px solid #CCCCCC; background-color: #FFFFFF; padding: 20px;"> <tr> <td><a href="http://www.openwebware.com/"><img src="http://www.openwebware.com/images/docs/logo.gif" alt="openwebware - Free Components and Applications" hspace="10" vspace="10" border="0"></a></td> <td><span style="font-family: arial, verdana, helvetica; font-size: 20px; font-weight: bold; color: #494949;">openWYSIWYG 1.01 Documentation</td> </tr> <tr> <td colspan="2" style="font-family: verdana, helvetica; font-size: 13px; color: #494949;" > <center><b>Please read this document completely before using openWYSIWYG.</b></center> <p>Please note that this documentation is not all-inclusive, a more detailed instruction manual will be available as openWYSIWYG matures. The good news, this document will walk you through the basics of getting started.</p> <p>If you have any suggestions on how to improve this document, or feel your contributions will make it more complete, please <a href="http://www.openwebware.com/about/contact/">contact us</a>. We're always looking for ways to improve, whether it's the product itself or the accompanying documentation.</p> <ol> <li><a href="#introduction">Introduction</a></li> <ol type="i"> <li><a href="#openWYSIWYG">What is openWYSIWYG?</a></li> <li><a href="#free">Is openWYSIWYG really free and open source?</a></li> <li><a href="#example">Do you have a working example I can see?</a></li> <li><a href="#info">Where can I learn more about it, download the latest version, or talk to other openWYSIWYG developers?</a></li> </ol> <li><a href="#requirements">Browser Requirements</a></li> <li><a href="#install">Installation</a></li> <ol type="i"> <li><a href="#howtoadd">How do I add openWYSIWYG to my web page or web application?</a></li> </ol> <li><a href="#faqs">Frequently Asked Questions</a></li> <ol type="i"> <li><a href="#goals">What are the project goals for openWYSIWYG?</a></li> <li><a href="#help">openWYSIWYG is great, is there anyway I can help?</a></li> <li><a href="#feature">I'd like to add a feature, can you add it?</a></li> <li><a href="#browsers">Why don't you support Safari, Opera, or <insert browser name>?</a></li> <li><a href="#question">My question isn't answered here?</a></li> </ol> <li><a href="#issues">Known Issues</a></li> <li><a href="#change">Change Log</a></li> <li><a href="#features">Feature Recommendations for the Next Version</a> <li><a href="#disclaimer">Copyright and Disclaimer</a></li> </ol> <a name="#introduction"><h2>1. Introduction</h2></a> <p>If you are just getting started with openWYSIWYG, then you've come to the right place. This document explains what openWYSIWYG is, contains information on installing and setting up openWYSIWYG, answers frequently asked questions, lists the program's requirements, and provides other useful information.</p> <br /><br /> <a name="#openWYSIWYG"><h3>1.i. What is openWYSIWYG?</h3></a> <p>openWYSIWYG is a free cross-browser WYSIWYG (what you see is what you get) editor. With just a few simple lines of JavaScript code you can easily replace a <textarea> with a powerful WYSIWYG editor that lets your users do the following:</p> <ul> <li>Format text to be bold, italicized, or underlined.</li> <li>Change the face, size, style and colour.</li> <li>Left, centre, or right-justify paragraphs.</li> <li>Make bulleted or numbered lists.</li> <li>Indent or un-indent paragraphs.</li> <li>Insert hyperlinks, images, and tables.</li> <li>View the HTML source code of what you're editing.</li> <li>And much more...</li> </ul> <p>What sets openWYSIWYG apart from other WYSIWYG editors?</p> <ul> <li>It loads extremely fast and is completely written in JavaScript and DHTML. No server side code (like PHP) required.</li> <li>Regardless of what programming language you use, openWYSIWYG will work. (ASP, ASP. Net, PHP, Perl, Java, Python, Cold Fusion, etc).</li> <li>It's open source, meaning you'll have access to the full source code to modify or customize it to your needs.</li> <li>With just one line of code it can easily be added to your content management system or custom web application.</li> <li>It's compatible with the most popular internet browsers, meaning your users will have no trouble making use of it.</li> <li>And best of all, it's free! It can be incorporated into any free or commercial program.</li> </ul> <br /><br /> <a name="#free"><h3>1.ii. Is openWYSIWYG really free and open source?</h3></a> <p>Yes! Unlike other WYSIWYG editors out there you don't have to fork out big dollars for openWYSIWYG. You can distribute it in your content management system or custom web application. It's absolutely free!</p> <p>openWYSIWYG is an open source application released under the <a href="http://www.opensource.org/licenses/lgpl-license.php" target="_blank">LGPL</a>, meaning you'll have access to the full source code to modify or customize it to your needs. Add new features, change the styles, or even optimize the code. It's entirely up to you.</p> <br /><br /> <a name="#example"><h3>1.iii. Do you have a working example I can see?</h3></a> <p>Absolutely, just check out a working example below:</p> <textarea id="textarea1" name="test1" style="height: 170px; width: 500px;"> <table border="0" cellpadding="0" cellspacing="0" style="margin-left: 10px;"> <tr> <td style="padding: 0 10 10 0;"><a href="http://www.openwebware.com/products/openwysiwyg/"><img src="http://www.openwebware.com/images/openwysiwyg/logo9060.gif" border="0" height="60" width="90" alt="openWYSIWYG - Cross-browser WYSIWYG editor"></a></td> <td style="font-family: verdana; font-size: 11px; line-height: 130%; color: #494949;" valign="top"> <b><a href="http://www.openwebware.com/products/openwysiwyg/" style="font-family: arial; font-size: 12px; color: #055F92;">openWYSIWYG - Cross-browser WYSIWYG editor</a></b><br /> Need a powerful cross-browser WYSIWYG editing component? openWYSIWYG is the ultimate &lt;textarea&gt; replacement for your content management system. </td> </tr> <tr> <td style="padding: 0 10 10 0;"><a href="http://www.openwebware.com/products/openpopups/"><img src="http://www.openwebware.com/images/openpopups/logo9060.gif" border="0" height="60" width="90" alt="openWYSIWYG - Cross-browser WYSIWYG editor"></a></td> <td style="font-family: verdana; font-size: 11px; line-height: 130%; color: #494949;" valign="top"> <b><a href="http://www.openwebware.com/products/openpopups/" style="font-family: arial; font-size: 12px; color: #055F92;">openPopUps - JavaScript and &<div&> powered popup window</a></b><br /> The perfect pop up window replacement for your advertisements and web applications. Pop up blockers will fail to prevent an openPopUp window from opening. </td> </tr> </table> </textarea> <script language="javascript1.2"> generate_wysiwyg('textarea1'); </script> <br /><br /> <a name="#info"><h3>1.iv. Where can I learn more about it, download the latest version, or talk to other openWYSIWYG developers?</h3></a> <p>You can learn more about openWYSIWYG and download the latest version at <a href="http://www.openwebware.com/products/openwysiwyg/">www.openwebware.com</a>. There's also an <a href="http://www.openwebware.com/forum/viewforum.php?f=1">excellent user community</a> where you can share ideas, learn various tricks, or even post suggestions and comments.</p> <br /><br /> <a name="#requirements"><h2>2. Browser Requirements</h2></a> <p>openWYSIWYG is cross-browser compatible and will work with the most popular internet browsers. This means your users will have no trouble making use of it. Supported browsers include: <b>IE</b> 5.5+ (Windows), <b>Firefox</b> 1.0+, <b>Mozilla</b> 1.3+ and <b>Netscape</b> 7+.</p> <br /><br /> <a name="#install"><h2>3. Installation</h2></a> <p>Once you've downloaded openWYSIWYG you'll want to unzip it (while maintaining the directory structure).</p> <p>openWYSIWYG is coded completely in JavaScript, HTML, and CSS. It also uses images (.gif and .jpg), so if you're uploading these files to your web server you'll want to make sure they're readable.</p> <p>On Unix based servers, that means every directory has chmod permissions of 755 while the files (.html, .js, .jpg., .gif, etc) are 644. Most Unix based servers use these settings for folders and files by default, so you most likely won't have to change a thing.</p> <br /><br /> <a name="#howtoadd"><h3>3.i. How do I add openWYSIWYG to my web page or web application?</h3></a> <p>You can easily add openWYSIWYG to your content management system or custom web application by just adding a few simple lines of JavaScript code.</p> <p><b>1.</b> Near the beginning of the web page to which you plan to add openWYSIWYG insert the following line of code before the closing </head> tag.</p> <div style="margin-left: 20px;">Include the following:</div> <div style="background-color: #FFFFEE; font-family: courier new; font-size: 12px; padding: 5px; width: 100%; border: 1px solid #444444; margin-left: 20px;"> <span style="color: #0000FF;"><script language=</span><!-- --><span style="color: #008080;">"JavaScript"</span> <span style="color: #0000FF;">type=</span><!-- --><span style="color: #008080;">"text/javascript"</span> <span style="color: #0000FF;">src=</span><!-- --><span style="color: #008080;">"/<span style="color: #CC0000;">your_directory_path</span>/openwysiwyg/wysiwyg.js"></span><!-- --><span style="color: #0000FF;"></script></span> </div> <p>Where <span style="font-family: courier new; font-size: 13px; color: #CC0000;">your_directory_path</span> is the path to your openwysiwyg directory. <p><b>2.</b> Next, add opening and closing <textarea> tags where you plan to include your WYSIWYG editor. You'll also want to give your <textarea> an ID value.</p> <div style="margin-left: 20px;">Example <textarea> code:</div> <div style="background-color: #FFFFEE; font-family: courier new; font-size: 12px; padding: 5px; width: 300px; border: 1px solid #444444; margin-left: 20px;"> <span style="color: #0000FF;"><textarea id="<span style="color: #CC0000;">your_textarea</span>"></textarea></span> </div> <p>Your <textarea>'s ID should be something unique.</p> <p><b>3.</b> Finally, add the following JavaScript code just below your closing </textarea> tag.</p> <div style="margin-left: 20px;">Example JavaScript code:</div> <div style="background-color: #FFFFEE; font-family: courier new; font-size: 12px; padding: 5px; width: 300px; border: 1px solid #444444; margin-left: 20px;"> <span style="color: #0000FF;"><script language=</span><span style="color: #008080;">"JavaScript"</span>><br> <span style="color: #000080;">generate_wysiwyg</span>('<span style="color: #CC0000;">your_textarea</span>');<br> <span style="color: #0000FF;"></script></span> </div> <p>The value you pass to the generate_wysiwyg function (<span style="font-family: courier new; font-size: 13px; color: #CC0000;">your_textarea</span>) must be the exact same as your <textarea>'s ID.</p> <p>And that's about it, you've just added openWYSIWYG to your content management system or custom web application with just a few small lines of code.</p> <br /><br /> <a name="#faqs"><h2>4. Frequently Asked Questions</h2></a> <a name="#goals"><h3>4.i.What are the project goals for openWYSIWYG?</h3></a> <p>The project goals for openWYSIWYG are designed to make it easy for developers who contribute to the editor to know where it's going. This also lets people know what's important to us and what we believe makes a good editor.</p> <p><b>100% JavaScript</b> <div style="margin-left: 50px;">openWYSIWYG must always be coded entirely in JavaScript and DHTML. This is so developers can use it in their applications regardless of the programming language they choose to build their web applications, be it Perl, PHP, ASP, Cold Fusion, or any other language. <br /><br /> That being said, add-ons or plug-ins (e.g. image/media uploading utility) can be coded in a server side language (Perl, PHP, ASP, etc).</div></p> <p><b>Fast Loading and Unbloated</b> <div style="margin-left: 50px;">openWYSIWYG must always be fast loading. Regardless of what feature is added, it cannot slow down the loading of the editor itself. There are far too many free WYSIWYG editors out there that take an unbelievable amount of time to load. End users (the very people who will use your web applications) don't like this!<br /><br /> Also, the editor must not become bloated, filled with features that only a small minority of users will make use of. If there's ever a doubt to which features you think should be added please refer to the list of <a href="#features">feature recommendations for the next version</a> found in this document.</div></p> <p><b>Easy to Use</b> <div style="margin-left: 50px;">openWYSIWYG must be easy to use for developers to integrate into their applications, easy for programmers to add new features, and easy for end users to use.</div></p> <br /><br /> <a name="#help"><h3>4.ii.openWYSIWYG is great, is there any way I can help?</h3></a> <p>Absolutely. Whether you're just starting with openWYSIWYG, are a developer or programmer, or have your own website, almost anyone can help.</p> <p><b>If You're a Programmer or Developer</b> <div style="margin-left: 50px;">Any code improvements you want to share are most certainly welcome. After all, openWYSIWYG is open source, so we're always open to suggestions and improvements.<br /><br /> If you notice anything that you can do better, or have an improvement you would like to make you can always share it with others in the <a href="http://www.openwebware.com/forum/viewforum.php?f=1"> openWYSIWYG forum</a>, or <a href="mailto:[email protected]">send us an email</a> with your code improvements, new features, or suggestions.<br /><br /> If you're not sure where to get started you can always check out the <a href="#features">feature recommendations</a> slated for the next version.<br /><br /> All contributions will be credited to the creator in the openWYSIWYG source code and on the openwebware.com website.</div></p> <p><b>If You're a Webmaster or Site Owner</b> <div style="margin-left: 50px;">As a webmaster, the best thing you can do to help is also the easiest thing to do; give us a link on your website. The more people who can find out about openWYSIWYG the better it will be.<br /><br /> Just copy the HTML from one of the code samples below and place it somewhere on your website.<br /><br /> <i class="siteTitles">Image Link:</i><br /> <a href="http://www.openwebware.com/products/openwysiwyg/"><img src="http://www.openwebware.com/images/openwysiwyg/32_x_88.gif" height="32" width="88" border="0" alt="openWYSIWYG - Free Open Source WYSIWYG Editor" /></a> <br /><br /> <textarea rows="4" cols="75"><a href="http://www.openwebware.com/products/openwysiwyg/"><img src="http://www.openwebware.com/images/openwysiwyg/32_x_88.gif" height="32" width="88" border="0" alt="openWYSIWYG - Free Open Source WYSIWYG Editor" /></a></textarea> <br /><br /> <i class="siteTitles">Text Link:</i><br /> <a href="http://www.openwebware.com/products/openwysiwyg/" style="font-family: arial; font-size: 12px;">openWYSIWYG - Free Open Source WYSIWYG Editor</a> <br /><br /> <textarea rows="3" cols="75"><a href="http://www.openwebware.com/products/openwysiwyg/" style="font-family: arial; font-size: 12px;">openWYSIWYG - Free Open Source WYSIWYG Editor</a></textarea> </div></p> <p><b>If You're a New User</b> <div style="margin-left: 50px;"><a href="http://www.openwebware.com/forum/viewforum.php?f=1"> Participate in our forum</a> and post a message or two to help other openWYSIWYG users (or learn something new yourself).</div></p> <br /><br /> <a name="#feature"><h3>4.iii.I'd like to add a feature, can you add it?</h3></a> <p>Probably not. If it's not listed in the <a href="#features">feature recommendations</a> for the next version we just won't have the time to work on it. That doesn't mean you can't work on it or <a href="http://www.openwebware.com/forum/viewforum.php?f=1">post a message</a> in the forum asking if someone else could help you with it.</p> <br /><br /> <a name="#browsers"><h3>4.iv.Why don't you support Safari, Opera, or <insert browser name>?</h3></a> <p>It's not that we don't want to, we just don't yet. Our first goal was to provide support for the most popular browsers, those being Internet Explorer and Mozilla (Mozilla and Firefox). Safari is definitely something we would like to support since it's gaining in popularity within the Mac community. While not fully tested, if your users are working with Macs they should be able to access openWYSIWYG using a Mozilla based browser (e.g. Mozilla or Firefox).</p> <p>As for Opera, to be realistic, we currently don't have any plans to support it. Opera just hasn't reached a level of popularity to justify the time required to develop support for it.</p> <br /><br /> <a name="#question"><h3>4.v.My question isn't answered here?</h3></a> <p>We're always happy to answer questions. <a href="http://www.openwebware.com/forum/viewforum.php?f=1"> Post your question in the forum</a> if it wasn't answered here.</p> <br /><br /> <a name="#issues"><h2>5. Known Issues</h2></a> <p><b>HTML header tags (e.g.: <body>, <head>, etc) aren't preserved</b> <div style="margin-left: 50px;">This probably has to do with the browser trying to be smart about the way it generates its HTML. The editor already has HTML header information of its own so inserting a second one confuses the browser and the content gets stripped. While this is a very minor issue, we do hope to research this further and find a solution.</div></p> <br /><br /> <a name="#change"><h2>6. Change Log</h2></a> <p><b>Version 1.01 (Released: April 9, 2006)</b><br /> Addresses the following: <ul> <li>A bizarre problem on certain version combinations of IE and Windows where; the textarea wasn't hidden, the font size and font type drop downs did not display at all, and the "Text" mode button wasn't hidden when first loading.</li> <li>Font Size and Font Select buttons weren't "unselectable" in IE 6+ (meaning users could drag and drop them into the editor). This is now fixed.</li> <li>The WYSIWYG should now always update the textarea on the user's last command.</li> <li>All document.all references have been changed to document.getElementById.</li> <li>Minor UI changes to the Insert Table popup.</li> <li>Minor design changes to the toolbar (CSS, HTML changes) so it displays better in various HTML doctypes.</li> <li>Undo/Redo now works in Internet Explorer.</li> </ul> </p> <p><b>Version 1.00 (Released: March 1, 2006)</b><br /> Initial Release</p> <br /><br /> <a name="#features"><h2>7. Feature Recommendations for the Next Version</h2></a> <p>Included below is a list of features and fixes recommended for the next update to openWYSIWYG. We could really use your help, so if you would like to lend a hand <a href="maitlo:[email protected]">let us know</a>, any additions and enhancements will be credited in the source code and on the openwebware.com website.</p> <ul> <li><b>Features and Improvements</b></li> <ul> <li>XHTML compliant code output</li> <li>Table Editing Features (modify table, insert table cell, insert row, merge table cell, etc)</li> </ul> </ul> <ul> <li><b>Add-ons and Plug-ins</b></li> <ul> <li>Image/Media uploader for PHP</li> </ul> </ul> <br /><br /> <a name="#disclaimer"><h2>8. Copyright and Disclaimer</h2></a> This application is open source software released under the <a href="http://www.opensource.org/licenses/lgpl-license.php" target="_blank">LGPL</a>. Please see source code for more details. This package and its contents are Copyright � 2006 openWebWare.com, All Rights Reserved. </td> </tr> </table> </center> </body> </html> |
Added modules/wysiwyg/js/rightarrow.gif.
cannot compute difference between binary files
Added modules/wysiwyg/js/wysiwyg.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | // // openWYSIWYG v1.01 Copyright (c) 2006 openWebWare.com // This copyright notice MUST stay intact for use. // // An open source WYSIWYG editor for use in web based applications. // For full source code and docs, visit http://www.openwebware.com/ // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation; either version 2.1 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public // License for more details. // // You should have received a copy of the GNU Lesser General Public License along // with this library; if not, write to the Free Software Foundation, Inc., 59 // Temple Place, Suite 330, Boston, MA 02111-1307 USA /* ---------------------------------------------------------------------- *\ Global Variables: Set global variables such as images directory, WYSIWYG Height, Width, and CSS Directory. \* ---------------------------------------------------------------------- */ // Images Directory imagesDir = "/wysiwyg/icons/"; // CSS Directory cssDir = "/wysiwyg/css/"; // Popups Directory popupsDir = "/wysiwyg/popups/"; // WYSIWYG Width and Height wysiwygWidth = 500; wysiwygHeight = 150; // Include Style Sheet document.write('<link rel="stylesheet" type="text/css" href="' +cssDir+ 'styles.css">\n'); /* ---------------------------------------------------------------------- *\ Toolbar Settings: Set the features and buttons available in the WYSIWYG Toolbar. \* ---------------------------------------------------------------------- */ // List of available font types var Fonts = new Array(); Fonts[0] = "Arial"; Fonts[1] = "Sans Serif"; Fonts[2] = "Tahoma"; Fonts[3] = "Verdana"; Fonts[4] = "Courier New"; Fonts[5] = "Georgia"; Fonts[6] = "Times New Roman"; Fonts[7] = "Impact"; Fonts[8] = "Comic Sans MS"; // List of available block formats (not in use) var BlockFormats = new Array(); BlockFormats[0] = "Address"; BlockFormats[1] = "Bulleted List"; BlockFormats[2] = "Definition"; BlockFormats[3] = "Definition Term"; BlockFormats[4] = "Directory List"; BlockFormats[5] = "Formatted"; BlockFormats[6] = "Heading 1"; BlockFormats[7] = "Heading 2"; BlockFormats[8] = "Heading 3"; BlockFormats[9] = "Heading 4"; BlockFormats[10] = "Heading 5"; BlockFormats[11] = "Heading 6"; BlockFormats[12] = "Menu List"; BlockFormats[13] = "Normal"; BlockFormats[14] = "Numbered List"; // List of available font sizes var FontSizes = new Array(); FontSizes[0] = "1"; FontSizes[1] = "2"; FontSizes[2] = "3"; FontSizes[3] = "4"; FontSizes[4] = "5"; FontSizes[5] = "6"; FontSizes[6] = "7"; // Order of available commands in toolbar one var buttonName = new Array(); buttonName[0] = "bold"; buttonName[1] = "italic"; buttonName[2] = "underline"; //buttonName[3] = "strikethrough"; buttonName[4] = "seperator"; buttonName[5] = "subscript"; buttonName[6] = "superscript"; buttonName[7] = "seperator"; buttonName[8] = "justifyleft"; buttonName[9] = "justifycenter"; buttonName[10] = "justifyright"; buttonName[11] = "seperator"; buttonName[12] = "unorderedlist"; buttonName[13] = "orderedlist"; buttonName[14] = "outdent"; buttonName[15] = "indent"; // Order of available commands in toolbar two var buttonName2 = new Array(); buttonName2[0] = "forecolor"; buttonName2[1] = "backcolor"; buttonName2[2] = "seperator"; buttonName2[3] = "cut"; buttonName2[4] = "copy"; buttonName2[5] = "paste"; buttonName2[6] = "seperator"; buttonName2[7] = "undo"; buttonName2[8] = "redo"; buttonName2[9] = "seperator"; buttonName2[10] = "inserttable"; buttonName2[11] = "insertimage"; buttonName2[12] = "createlink"; buttonName2[13] = "seperator"; buttonName2[14] = "viewSource"; buttonName2[15] = "seperator"; buttonName2[16] = "help"; // List of available actions and their respective ID and images var ToolbarList = { //Name buttonID buttonTitle buttonImage buttonImageRollover "bold": ['Bold', 'Bold', imagesDir + 'bold.gif', imagesDir + 'bold_on.gif'], "italic": ['Italic', 'Italic', imagesDir + 'italics.gif', imagesDir + 'italics_on.gif'], "underline": ['Underline', 'Underline', imagesDir + 'underline.gif', imagesDir + 'underline_on.gif'], "strikethrough": ['Strikethrough', 'Strikethrough', imagesDir + 'strikethrough.gif', imagesDir + 'strikethrough_on.gif'], "seperator": ['', '', imagesDir + 'seperator.gif', imagesDir + 'seperator.gif'], "subscript": ['Subscript', 'Subscript', imagesDir + 'subscript.gif', imagesDir + 'subscript_on.gif'], "superscript": ['Superscript', 'Superscript', imagesDir + 'superscript.gif', imagesDir + 'superscript_on.gif'], "justifyleft": ['Justifyleft', 'Justifyleft', imagesDir + 'justify_left.gif', imagesDir + 'justify_left_on.gif'], "justifycenter": ['Justifycenter', 'Justifycenter', imagesDir + 'justify_center.gif', imagesDir + 'justify_center_on.gif'], "justifyright": ['Justifyright', 'Justifyright', imagesDir + 'justify_right.gif', imagesDir + 'justify_right_on.gif'], "unorderedlist": ['InsertUnorderedList', 'InsertUnorderedList',imagesDir + 'list_unordered.gif', imagesDir + 'list_unordered_on.gif'], "orderedlist": ['InsertOrderedList', 'InsertOrderedList', imagesDir + 'list_ordered.gif', imagesDir + 'list_ordered_on.gif'], "outdent": ['Outdent', 'Outdent', imagesDir + 'indent_left.gif', imagesDir + 'indent_left_on.gif'], "indent": ['Indent', 'Indent', imagesDir + 'indent_right.gif', imagesDir + 'indent_right_on.gif'], "cut": ['Cut', 'Cut', imagesDir + 'cut.gif', imagesDir + 'cut_on.gif'], "copy": ['Copy', 'Copy', imagesDir + 'copy.gif', imagesDir + 'copy_on.gif'], "paste": ['Paste', 'Paste', imagesDir + 'paste.gif', imagesDir + 'paste_on.gif'], "forecolor": ['ForeColor', 'ForeColor', imagesDir + 'forecolor.gif', imagesDir + 'forecolor_on.gif'], "backcolor": ['BackColor', 'BackColor', imagesDir + 'backcolor.gif', imagesDir + 'backcolor_on.gif'], "undo": ['Undo', 'Undo', imagesDir + 'undo.gif', imagesDir + 'undo_on.gif'], "redo": ['Redo', 'Redo', imagesDir + 'redo.gif', imagesDir + 'redo_on.gif'], "inserttable": ['InsertTable', 'InsertTable', imagesDir + 'insert_table.gif', imagesDir + 'insert_table_on.gif'], "insertimage": ['InsertImage', 'InsertImage', imagesDir + 'insert_picture.gif', imagesDir + 'insert_picture_on.gif'], "createlink": ['CreateLink', 'CreateLink', imagesDir + 'insert_hyperlink.gif', imagesDir + 'insert_hyperlink_on.gif'], "viewSource": ['ViewSource', 'ViewSource', imagesDir + 'view_source.gif', imagesDir + 'view_source_on.gif'], "viewText": ['ViewText', 'ViewText', imagesDir + 'view_text.gif', imagesDir + 'view_text_on.gif'], "help": ['Help', 'Help', imagesDir + 'help.gif', imagesDir + 'help_on.gif'], "selectfont": ['SelectFont', 'SelectFont', imagesDir + 'select_font.gif', imagesDir + 'select_font_on.gif'], "selectsize": ['SelectSize', 'SelectSize', imagesDir + 'select_size.gif', imagesDir + 'select_size_on.gif'] }; /* ---------------------------------------------------------------------- *\ Function : insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement() Description : Emulates insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement() three functions so they work with Netscape 6/Mozilla Notes : by Thor Larholm [email protected] \* ---------------------------------------------------------------------- */ if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){ HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode) { switch (where){ case 'beforeBegin': this.parentNode.insertBefore(parsedNode,this) break; case 'afterBegin': this.insertBefore(parsedNode,this.firstChild); break; case 'beforeEnd': this.appendChild(parsedNode); break; case 'afterEnd': if (this.nextSibling) this.parentNode.insertBefore(parsedNode,this.nextSibling); else this.parentNode.appendChild(parsedNode); break; } } HTMLElement.prototype.insertAdjacentHTML = function (where,htmlStr) { var r = this.ownerDocument.createRange(); r.setStartBefore(this); var parsedHTML = r.createContextualFragment(htmlStr); this.insertAdjacentElement(where,parsedHTML) } HTMLElement.prototype.insertAdjacentText = function (where,txtStr) { var parsedText = document.createTextNode(txtStr) this.insertAdjacentElement(where,parsedText) } }; // Create viewTextMode global variable and set to 0 // enabling all toolbar commands while in HTML mode viewTextMode = 0; /* ---------------------------------------------------------------------- *\ Function : generate_wysiwyg() Description : replace textarea with wysiwyg editor Usage : generate_wysiwyg("textarea_id"); Arguments : textarea_id - ID of textarea to replace \* ---------------------------------------------------------------------- */ function generate_wysiwyg(textareaID) { // Hide the textarea document.getElementById(textareaID).style.display = 'none'; // Pass the textareaID to the "n" variable. var n = textareaID; // Toolbars width is 2 pixels wider than the wysiwygs toolbarWidth = parseFloat(wysiwygWidth) + 2; // Generate WYSIWYG toolbar one var toolbar; toolbar = '<table cellpadding="0" cellspacing="0" border="0" class="toolbar1" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>'; // Create IDs for inserting Font Type and Size drop downs toolbar += '<td style="width: 90px;"><span id="FontSelect' + n + '"></span></td>'; toolbar += '<td style="width: 60px;"><span id="FontSizes' + n + '"></span></td>'; // Output all command buttons that belong to toolbar one for (var i = 0; i <= buttonName.length;) { if (buttonName[i]) { var buttonObj = ToolbarList[buttonName[i]]; var buttonID = buttonObj[0]; var buttonTitle = buttonObj[1]; var buttonImage = buttonObj[2]; var buttonImageRollover = buttonObj[3]; if (buttonName[i] == "seperator") { toolbar += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>'; } else { toolbar += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' + buttonImageRollover + '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>'; } } i++; } toolbar += '<td> </td></tr></table>'; // Generate WYSIWYG toolbar two var toolbar2; toolbar2 = '<table cellpadding="0" cellspacing="0" border="0" class="toolbar2" style="width:' + toolbarWidth + 'px;"><tr><td style="width: 6px;"><img src="' +imagesDir+ 'seperator2.gif" alt="" hspace="3"></td>'; // Output all command buttons that belong to toolbar two for (var j = 0; j <= buttonName2.length;) { if (buttonName2[j]) { var buttonObj = ToolbarList[buttonName2[j]]; var buttonID = buttonObj[0]; var buttonTitle = buttonObj[1]; var buttonImage = buttonObj[2]; var buttonImageRollover = buttonObj[3]; if (buttonName2[j] == "seperator") { toolbar2 += '<td style="width: 12px;" align="center"><img src="' +buttonImage+ '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on"></td>'; } else if (buttonName2[j] == "viewSource"){ toolbar2 += '<td style="width: 22px;">'; toolbar2 += '<span id="HTMLMode' + n + '"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></span>'; toolbar2 += '<span id="textMode' + n + '"><img src="' +imagesDir+ 'view_text.gif" border=0 unselectable="on" title="viewText" id="ViewText" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +imagesDir+ 'view_text_on.gif\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' +imagesDir+ 'view_text.gif\';" unselectable="on" width="20" height="20"></span>'; toolbar2 += '</td>'; } else { toolbar2 += '<td style="width: 22px;"><img src="' +buttonImage+ '" border=0 unselectable="on" title="' +buttonTitle+ '" id="' +buttonID+ '" class="button" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'button\'){className=\'buttonOver\'}; this.src=\'' +buttonImageRollover+ '\';" onmouseout="if(className==\'buttonOver\'){className=\'button\'}; this.src=\'' + buttonImage + '\';" unselectable="on" width="20" height="20"></td>'; } } j++; } toolbar2 += '<td> </td></tr></table>'; // Create iframe which will be used for rich text editing var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + wysiwygWidth + 'px; height:' + wysiwygHeight + 'px;border: 1px inset #CCCCCC;"><tr><td valign="top">\n' + '<iframe frameborder="0" id="wysiwyg' + n + '"></iframe>\n' + '</td></tr></table>\n'; // Insert after the textArea both toolbar one and two document.getElementById(n).insertAdjacentHTML("afterEnd", toolbar + toolbar2 + iframe); // Insert the Font Type and Size drop downs into the toolbar outputFontSelect(n); outputFontSizes(n); // Hide the dynamic drop down lists for the Font Types and Sizes hideFonts(n); hideFontSizes(n); // Hide the "Text Mode" button document.getElementById("textMode" + n).style.display = 'none'; // Give the iframe the global wysiwyg height and width document.getElementById("wysiwyg" + n).style.height = wysiwygHeight + "px"; document.getElementById("wysiwyg" + n).style.width = wysiwygWidth + "px"; // Pass the textarea's existing text over to the content variable var content = document.getElementById(n).value; var doc = document.getElementById("wysiwyg" + n).contentWindow.document; // Write the textarea's content into the iframe doc.open(); doc.write(content); doc.close(); // Make the iframe editable in both Mozilla and IE doc.body.contentEditable = true; doc.designMode = "on"; // Update the textarea with content in WYSIWYG when user submits form var browserName = navigator.appName; if (browserName == "Microsoft Internet Explorer") { for (var idx=0; idx < document.forms.length; idx++) { document.forms[idx].attachEvent('onsubmit', function() { updateTextArea(n); }); } } else { for (var idx=0; idx < document.forms.length; idx++) { document.forms[idx].addEventListener('submit',function OnSumbmit() { updateTextArea(n); }, true); } } }; /* ---------------------------------------------------------------------- *\ Function : formatText() Description : replace textarea with wysiwyg editor Usage : formatText(id, n, selected); Arguments : id - The execCommand (e.g. Bold) n - The editor identifier that the command affects (the textarea's ID) selected - The selected value when applicable (e.g. Arial) \* ---------------------------------------------------------------------- */ function formatText(id, n, selected) { // When user clicks toolbar button make sure it always targets its respective WYSIWYG document.getElementById("wysiwyg" + n).contentWindow.focus(); // When in Text Mode these execCommands are disabled var formatIDs = new Array("FontSize","FontName","Bold","Italic","Underline","Subscript","Superscript","Strikethrough","Justifyleft","Justifyright","Justifycenter","InsertUnorderedList","InsertOrderedList","Indent","Outdent","ForeColor","BackColor","InsertImage","InsertTable","CreateLink"); // Check if button clicked is in disabled list for (var i = 0; i <= formatIDs.length;) { if (formatIDs[i] == id) { var disabled_id = 1; } i++; } // Check if in Text Mode and disabled button was clicked if (viewTextMode == 1 && disabled_id == 1) { alert ("You are in HTML Mode. This feature has been disabled."); } else { // FontSize if (id == "FontSize") { document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontSize", false, selected); } // FontName else if (id == "FontName") { document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontName", false, selected); } // ForeColor and BackColor else if (id == 'ForeColor' || id == 'BackColor') { var w = screen.availWidth; var h = screen.availHeight; var popW = 210, popH = 165; var leftPos = (w-popW)/2, topPos = (h-popH)/2; var currentColor = _dec_to_rgb(document.getElementById("wysiwyg" + n).contentWindow.document.queryCommandValue(id)); window.open(popupsDir + 'select_color.html?color=' + currentColor + '&command=' + id + '&wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,width=' + popW + ',height=' + popH + ',top=' + topPos + ',left=' + leftPos); } // InsertImage else if (id == "InsertImage") { window.open(popupsDir + 'insert_image.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=190'); } // InsertTable else if (id == "InsertTable") { window.open(popupsDir + 'create_table.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=360'); } // CreateLink else if (id == "CreateLink") { window.open(popupsDir + 'insert_hyperlink.html?wysiwyg=' + n,'popup','location=0,status=0,scrollbars=0,resizable=0,width=300,height=110'); } // ViewSource else if (id == "ViewSource") { viewSource(n); } // ViewText else if (id == "ViewText") { viewText(n); } // Help else if (id == "Help") { window.open(popupsDir + 'about.html','popup','location=0,status=0,scrollbars=0,resizable=0,width=400,height=330'); } // Every other command else { document.getElementById("wysiwyg" + n).contentWindow.document.execCommand(id, false, null); } } }; /* ---------------------------------------------------------------------- *\ Function : insertHTML() Description : insert HTML into WYSIWYG in rich text Usage : insertHTML(<b>hello</b>, "textareaID") Arguments : html - The HTML being inserted (e.g. <b>hello</b>) n - The editor identifier that the HTML will be inserted into (the textarea's ID) \* ---------------------------------------------------------------------- */ function insertHTML(html, n) { var browserName = navigator.appName; if (browserName == "Microsoft Internet Explorer") { document.getElementById('wysiwyg' + n).contentWindow.document.selection.createRange().pasteHTML(html); } else { var div = document.getElementById('wysiwyg' + n).contentWindow.document.createElement("div"); div.innerHTML = html; var node = insertNodeAtSelection(div, n); } } /* ---------------------------------------------------------------------- *\ Function : insertNodeAtSelection() Description : insert HTML into WYSIWYG in rich text (mozilla) Usage : insertNodeAtSelection(insertNode, n) Arguments : insertNode - The HTML being inserted (must be innerHTML inserted within a div element) n - The editor identifier that the HTML will be inserted into (the textarea's ID) \* ---------------------------------------------------------------------- */ function insertNodeAtSelection(insertNode, n) { // get current selection var sel = document.getElementById('wysiwyg' + n).contentWindow.getSelection(); // get the first range of the selection // (there's almost always only one range) var range = sel.getRangeAt(0); // deselect everything sel.removeAllRanges(); // remove content of current selection from document range.deleteContents(); // get location of current selection var container = range.startContainer; var pos = range.startOffset; // make a new range for the new selection range=document.createRange(); if (container.nodeType==3 && insertNode.nodeType==3) { // if we insert text in a textnode, do optimized insertion container.insertData(pos, insertNode.nodeValue); // put cursor after inserted text range.setEnd(container, pos+insertNode.length); range.setStart(container, pos+insertNode.length); } else { var afterNode; if (container.nodeType==3) { // when inserting into a textnode // we create 2 new textnodes // and put the insertNode in between var textNode = container; container = textNode.parentNode; var text = textNode.nodeValue; // text before the split var textBefore = text.substr(0,pos); // text after the split var textAfter = text.substr(pos); var beforeNode = document.createTextNode(textBefore); afterNode = document.createTextNode(textAfter); // insert the 3 new nodes before the old one container.insertBefore(afterNode, textNode); container.insertBefore(insertNode, afterNode); container.insertBefore(beforeNode, insertNode); // remove the old node container.removeChild(textNode); } else { // else simply insert the node afterNode = container.childNodes[pos]; container.insertBefore(insertNode, afterNode); } range.setEnd(afterNode, 0); range.setStart(afterNode, 0); } sel.addRange(range); }; /* ---------------------------------------------------------------------- *\ Function : _dec_to_rgb Description : convert a decimal color value to rgb hexadecimal Usage : var hex = _dec_to_rgb('65535'); // returns FFFF00 Arguments : value - dec value \* ---------------------------------------------------------------------- */ function _dec_to_rgb(value) { var hex_string = ""; for (var hexpair = 0; hexpair < 3; hexpair++) { var myByte = value & 0xFF; // get low byte value >>= 8; // drop low byte var nybble2 = myByte & 0x0F; // get low nybble (4 bits) var nybble1 = (myByte >> 4) & 0x0F; // get high nybble hex_string += nybble1.toString(16); // convert nybble to hex hex_string += nybble2.toString(16); // convert nybble to hex } return hex_string.toUpperCase(); }; /* ---------------------------------------------------------------------- *\ Function : outputFontSelect() Description : creates the Font Select drop down and inserts it into the toolbar Usage : outputFontSelect(n) Arguments : n - The editor identifier that the Font Select will update when making font changes (the textarea's ID) \* ---------------------------------------------------------------------- */ function outputFontSelect(n) { var FontSelectObj = ToolbarList['selectfont']; var FontSelect = FontSelectObj[2]; var FontSelectOn = FontSelectObj[3]; Fonts.sort(); var FontSelectDropDown = new Array; FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelectOn + '\';" onMouseOut="document.getElementById(\'selectFont' + n + '\').src=\'' + FontSelect + '\';"><img src="' + FontSelect + '" id="selectFont' + n + '" width="85" height="20" onClick="showFonts(\'' + n + '\');" unselectable="on"><br>'; FontSelectDropDown[n] += '<span id="Fonts' + n + '" class="dropdown" style="width: 145px;">'; for (var i = 0; i <= Fonts.length;) { if (Fonts[i]) { FontSelectDropDown[n] += '<button type="button" onClick="formatText(\'FontName\',\'' + n + '\',\'' + Fonts[i] + '\')\; hideFonts(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 120px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family:' + Fonts[i] + '; font-size: 12px;">' + Fonts[i] + '</td></tr></table></button><br>'; } i++; } FontSelectDropDown[n] += '</span></td></tr></table>'; document.getElementById('FontSelect' + n).insertAdjacentHTML("afterBegin", FontSelectDropDown[n]); }; /* ---------------------------------------------------------------------- *\ Function : outputFontSizes() Description : creates the Font Sizes drop down and inserts it into the toolbar Usage : outputFontSelect(n) Arguments : n - The editor identifier that the Font Sizes will update when making font changes (the textarea's ID) \* ---------------------------------------------------------------------- */ function outputFontSizes(n) { var FontSizeObj = ToolbarList['selectsize']; var FontSize = FontSizeObj[2]; var FontSizeOn = FontSizeObj[3]; FontSizes.sort(); var FontSizesDropDown = new Array; FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSizeOn + '\';" onMouseOut="document.getElementById(\'selectSize' + n + '\').src=\'' + FontSize + '\';"><img src="' + FontSize + '" id="selectSize' + n + '" width="49" height="20" onClick="showFontSizes(\'' + n + '\');" unselectable="on"><br>'; FontSizesDropDown[n] += '<span id="Sizes' + n + '" class="dropdown" style="width: 170px;">'; for (var i = 0; i <= FontSizes.length;) { if (FontSizes[i]) { FontSizesDropDown[n] += '<button type="button" onClick="formatText(\'FontSize\',\'' + n + '\',\'' + FontSizes[i] + '\')\;hideFontSizes(\'' + n + '\');" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 145px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family: arial, verdana, helvetica;"><font size="' + FontSizes[i] + '">size ' + FontSizes[i] + '</font></td></tr></table></button><br>'; } i++; } FontSizesDropDown[n] += '</span></td></tr></table>'; document.getElementById('FontSizes' + n).insertAdjacentHTML("afterBegin", FontSizesDropDown[n]); }; /* ---------------------------------------------------------------------- *\ Function : hideFonts() Description : Hides the list of font names in the font select drop down Usage : hideFonts(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function hideFonts(n) { document.getElementById('Fonts' + n).style.display = 'none'; }; /* ---------------------------------------------------------------------- *\ Function : hideFontSizes() Description : Hides the list of font sizes in the font sizes drop down Usage : hideFontSizes(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function hideFontSizes(n) { document.getElementById('Sizes' + n).style.display = 'none'; }; /* ---------------------------------------------------------------------- *\ Function : showFonts() Description : Shows the list of font names in the font select drop down Usage : showFonts(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function showFonts(n) { if (document.getElementById('Fonts' + n).style.display == 'block') { document.getElementById('Fonts' + n).style.display = 'none'; } else { document.getElementById('Fonts' + n).style.display = 'block'; document.getElementById('Fonts' + n).style.position = 'absolute'; } }; /* ---------------------------------------------------------------------- *\ Function : showFontSizes() Description : Shows the list of font sizes in the font sizes drop down Usage : showFonts(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function showFontSizes(n) { if (document.getElementById('Sizes' + n).style.display == 'block') { document.getElementById('Sizes' + n).style.display = 'none'; } else { document.getElementById('Sizes' + n).style.display = 'block'; document.getElementById('Sizes' + n).style.position = 'absolute'; } }; /* ---------------------------------------------------------------------- *\ Function : viewSource() Description : Shows the HTML source code generated by the WYSIWYG editor Usage : showFonts(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function viewSource(n) { var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document; var browserName = navigator.appName; // View Source for IE if (browserName == "Microsoft Internet Explorer") { var iHTML = getDocument.body.innerHTML; getDocument.body.innerText = iHTML; } // View Source for Mozilla/Netscape else { var html = document.createTextNode(getDocument.body.innerHTML); getDocument.body.innerHTML = ""; getDocument.body.appendChild(html); } // Hide the HTML Mode button and show the Text Mode button document.getElementById('HTMLMode' + n).style.display = 'none'; document.getElementById('textMode' + n).style.display = 'block'; // set the font values for displaying HTML source getDocument.body.style.fontSize = "12px"; getDocument.body.style.fontFamily = "Courier New"; viewTextMode = 1; }; /* ---------------------------------------------------------------------- *\ Function : viewSource() Description : Shows the HTML source code generated by the WYSIWYG editor Usage : showFonts(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function viewText(n) { var getDocument = document.getElementById("wysiwyg" + n).contentWindow.document; var browserName = navigator.appName; // View Text for IE if (browserName == "Microsoft Internet Explorer") { var iText = getDocument.body.innerText; getDocument.body.innerHTML = iText; } // View Text for Mozilla/Netscape else { var html = getDocument.body.ownerDocument.createRange(); html.selectNodeContents(getDocument.body); getDocument.body.innerHTML = html.toString(); } // Hide the Text Mode button and show the HTML Mode button document.getElementById('textMode' + n).style.display = 'none'; document.getElementById('HTMLMode' + n).style.display = 'block'; // reset the font values getDocument.body.style.fontSize = ""; getDocument.body.style.fontFamily = ""; viewTextMode = 0; }; /* ---------------------------------------------------------------------- *\ Function : updateTextArea() Description : Updates the text area value with the HTML source of the WYSIWYG Usage : updateTextArea(n) Arguments : n - The editor identifier (the textarea's ID) \* ---------------------------------------------------------------------- */ function updateTextArea(n) { document.getElementById(n).value = document.getElementById("wysiwyg" + n).contentWindow.document.body.innerHTML; }; |
Added modules/wysiwyg/pkgIndex.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | # Tcl package index file, version 1.1 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded httpd::wysiwyg 0.1 [list source [file join $dir wysiwyg.tcl]] |
Added modules/wysiwyg/popups/about.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <html> <head> <title>openWYSIWYG | About</title> </head> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0"> <table border="0" cellpadding="0" cellspacing="0" style="padding: 10px;"><tr><td> <table width="380" border="0" cellpadding="0" cellspacing="0"> <tr> <td style="border-bottom: 2px solid #FFFFFF;" rowspan="2"><img src="../icons/logo.gif" alt="openWebWare: openWYSIWYG" height="34" width="191"></td> <td colspan="4"> </td> </tr> <tr> <td width="60" style="background-color: #F7F7F7;"> <table width="60" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border-width: 2 2 0 2; border-style: solid; border-color: #FFFFFF; border-bottom: 2px solid #F7F7F7; padding: 2px;"> <tr> <td align="center" style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"><a href="about.html" style="color: #000000; text-decoration: none;"><div>About</div></a></td> </tr> </table> </td> <td width="5" style="border-bottom: 2px solid #FFFFFF;"> </td> <td width="60" style="background-color: #F7F7F7;"> <table width="60" border="0" cellpadding="0" cellspacing="0" style="background-color: #DDDDDD; border: 2px solid #FFFFFF; padding: 2px;"> <tr> <td align="center" style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"><a href="about_license.html" style="color: #000000; text-decoration: none;"><div>License</div></a></td> </tr> </table> </td> <td width="5" style="border-bottom: 2px solid #FFFFFF;"> </td> </tr> </table> <table width="380" border="0" cellpadding="0" cellspacing="0" style="height: 260px; background-color: #F7F7F7; border-width: 0 2 2 2; border-style: solid; border-color: #FFFFFF; padding: 5px;"> <tr> <td style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"> An open source cross-browser WYSIWYG editor.<br><br> Version 1.01<br><br> Copyright © 2006 <a href="http://www.openwebware.com/" target="_blank">openWebWare.com</a><br> All Rights Reserved<br><br> <br><b style="font-size: 12px;">Resources:</b> <ul> <li><a href="http://www.openwebware.com/" target="_blank">openWebWare.com Website</a> - open source applications and developer tools.</li> <li style="margin-top: 3px;"><a href="http://www.openwebware.com/products/openwysiwyg/" target="_blank">openWYSIWYG Homepage</a> - cross browser <textarea> replacelemt.</li> <li style="margin-top: 3px;"><a href="http://www.openwebware.com/forum/viewforum.php?f=1" target="_blank">User Forums</a> - trade openWYSIWYG tips and tricks with other developers.</li> <li style="margin-top: 3px;"><a href="http://www.openwebware.com/products/openwysiwyg/docs/" target="_blank">Online Documentation</a> - user documentation.</li> </ul> </td> </tr> </table> </td></tr></table> </body> </html> |
Added modules/wysiwyg/popups/about_license.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <html> <head> <title>openWYSIWYG | About</title> </head> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0"> <table border="0" cellpadding="0" cellspacing="0" style="padding: 10px;"><tr><td> <table width="380" border="0" cellpadding="0" cellspacing="0"> <tr> <td style="border-bottom: 2px solid #FFFFFF;" rowspan="2"><img src="../icons/logo.gif" alt="openWebWare: openWYSIWYG" height="34" width="191"></td> <td colspan="4"> </td> </tr> <tr> <td width="60" style="background-color: #F7F7F7;"> <table width="60" border="0" cellpadding="0" cellspacing="0" style="background-color: #DDDDDD; border: 2px solid #FFFFFF; padding: 2px;"> <tr> <td align="center" style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"><a href="about.html" style="color: #000000; text-decoration: none;"><div>About</div></a></td> </tr> </table> </td> <td width="5" style="border-bottom: 2px solid #FFFFFF;"> </td> <td width="60" style="background-color: #F7F7F7;"> <table width="60" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border-width: 2 2 0 2; border-style: solid; border-color: #FFFFFF; border-bottom: 2px solid #F7F7F7; padding: 2px;"> <tr> <td align="center" style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"><a href="about_license.html" style="color: #000000; text-decoration: none;"><div>License</div></a></td> </tr> </table> </td> <td width="5" style="border-bottom: 2px solid #FFFFFF;"> </td> </tr> </table> <table width="380" border="0" cellpadding="0" cellspacing="0" style="height: 260px; background-color: #F7F7F7; border-width: 0 2 2 2; border-style: solid; border-color: #FFFFFF; padding: 5px;"> <tr> <td style="font-family: arial, verdana, helvetica, sans serif; font-size: 10px;"> <iframe style="width: 360px; height: 244px;" src="license.html"></iframe> </td> </tr> </table> </td></tr></table> </body> </html> |
Added modules/wysiwyg/popups/create_table.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG | Create Table</title> </head> <link rel="stylesheet" type="text/css" href="../styles/styles.css"> <script language="JavaScript" type="text/javascript"> var qsParm = new Array(); /* ---------------------------------------------------------------------- *\ Function : init() Description : Calls the initial functions when page loads. \* ---------------------------------------------------------------------- */ function init() { retrieveWYSIWYG(); hideOnBorderStyles(); hideOnBorderWidths(); hideColorMenus(); } /* ---------------------------------------------------------------------- *\ Function : retrieveWYSIWYG() Description : Retrieves the textarea ID for which the table will be inserted into. \* ---------------------------------------------------------------------- */ function retrieveWYSIWYG() { var query = window.location.search.substring(1); var parms = query.split('&'); for (var i=0; i<parms.length; i++) { var pos = parms[i].indexOf('='); if (pos > 0) { var key = parms[i].substring(0,pos); var val = parms[i].substring(pos+1); qsParm[key] = val; } } } /* ---------------------------------------------------------------------- *\ Function : buildTable() Description : Builds a table and inserts it into the WYSIWYG. \* ---------------------------------------------------------------------- */ function buildTable() { // Checks if the table border will use the BORDER-COLLAPSE CSS attribute var collapse; if (document.getElementById('borderCollapse').checked == true) { collapse = document.getElementById('borderCollapse').value; } else { collapse = "separate"; } // Builds a table based on the data input into the form var table = '<table border="0" cellpadding="0" cellspacing="0" style="'; table += 'BORDER-COLLAPSE: ' + collapse + ';'; table += ' border: ' + document.getElementById('borderWidth').value + ' ' + document.getElementById('borderStyle').value + ' ' + document.getElementById('borderColor').value + ';'; table += ' width: ' + document.getElementById('tableWidth').value + document.getElementById('widthType').value + ';'; table += ' background-color: ' + document.getElementById('shadingColor').value + ';"'; table += ' alignment="' + document.getElementById('alignment').value + '">\n'; // Creates the number of rows and cols the table will have for (var i = 0; i < document.getElementById('rows').value; i++) { table += '<tr>\n'; for (var j = 0; j < document.getElementById('cols').value; j++) { table += '<td style="border: ' + document.getElementById('borderWidth').value + ' ' + document.getElementById('borderStyle').value + ' ' + document.getElementById('borderColor').value + '; padding: ' + document.getElementById('padding').value + ';"> </td>\n'; } table += '</tr>\n'; } table += '</table>\n'; // Inserts the table code into the WYSIWYG editor window.opener.insertHTML(table, qsParm['wysiwyg']); window.close(); } /* ---------------------------------------------------------------------- *\ Function : hideOnBorderWidths() Description : Hides any table cell with an ID of "#px on" (e.g. "3px on"). \* ---------------------------------------------------------------------- */ function hideOnBorderWidths() { var onBorderWidths = new Array(); onBorderWidths[0] = "1px on"; onBorderWidths[1] = "2px on"; onBorderWidths[2] = "3px on"; onBorderWidths[3] = "4px on"; onBorderWidths[4] = "5px on"; onBorderWidths[5] = "6px on"; for (var j = 0; j < onBorderWidths.length;) { document.getElementById(onBorderWidths[j]).style.display = 'none'; j++; } } /* ---------------------------------------------------------------------- *\ Function : showOffBorderWidths() Description : Shows all table cells with an ID of "#px" (e.g. "3px"). \* ---------------------------------------------------------------------- */ function showOffBorderWidths() { var offBorderWidths = new Array(); offBorderWidths[0] = "1px"; offBorderWidths[1] = "2px"; offBorderWidths[2] = "3px"; offBorderWidths[3] = "4px"; offBorderWidths[4] = "5px"; offBorderWidths[5] = "6px"; for (var j = 0; j < offBorderWidths.length;) { document.getElementById(offBorderWidths[j]).style.display = 'block'; j++; } } /* ---------------------------------------------------------------------- *\ Function : selectWidth() Description : Selects the width to be used in the output table. Usage : selectWidth("3px") \* ---------------------------------------------------------------------- */ function selectWidth(id) { // Hide the currently selected width hideOnBorderWidths(); // Show all of the width options as unselected showOffBorderWidths(); // Hide the "off" element and replace with an "on" element so option appears selected document.getElementById(id).style.display = 'none'; document.getElementById(id + ' on').style.display = 'block'; // Assign value to <input type="hidden" id="borderWidth"> document.getElementById('borderWidth').value = id; } /* ---------------------------------------------------------------------- *\ Function : hideOnBorderStyles() Description : Hides any table cell with an ID of "borderstyle on" (e.g. "dashed on"). \* ---------------------------------------------------------------------- */ function hideOnBorderStyles() { var onBorderStyles = new Array(); onBorderStyles[0] = "No Border on"; onBorderStyles[1] = "solid on"; onBorderStyles[2] = "dashed on"; onBorderStyles[3] = "dotted on"; onBorderStyles[4] = "double on"; onBorderStyles[5] = "inset on"; onBorderStyles[6] = "outset on"; onBorderStyles[7] = "groove on"; onBorderStyles[8] = "ridge on"; for (var j = 0; j < onBorderStyles.length;) { document.getElementById(onBorderStyles[j]).style.display = 'none'; j++; } } /* ---------------------------------------------------------------------- *\ Function : showOffBorderStyles() Description : Shows all table cells with an ID of "borderstyle" (e.g. "solid"). \* ---------------------------------------------------------------------- */ function showOffBorderStyles() { var offBorderStyles = new Array(); offBorderStyles[0] = "No Border"; offBorderStyles[1] = "solid"; offBorderStyles[2] = "dashed"; offBorderStyles[3] = "dotted"; offBorderStyles[4] = "double"; offBorderStyles[5] = "inset"; offBorderStyles[6] = "outset"; offBorderStyles[7] = "groove"; offBorderStyles[8] = "ridge"; for (var j = 0; j < offBorderStyles.length;) { document.getElementById(offBorderStyles[j]).style.display = 'block'; j++; } } /* ---------------------------------------------------------------------- *\ Function : selectBorder() Description : Selects the border style to be used in the output table. Usage : selectBorder("dashed") \* ---------------------------------------------------------------------- */ function selectBorder(id) { // Hide the currently selected border style hideOnBorderStyles(); // Show all of the border style options as unselected showOffBorderStyles(); // Hide the "off" element and replace with an "on" element so option appears selected document.getElementById(id).style.display = 'none'; document.getElementById(id + ' on').style.display = 'block'; // Assign value to <input type="hidden" id="borderStyle"> document.getElementById('borderStyle').value = id; } /* ---------------------------------------------------------------------- *\ Function : hideColorMenus() Description : Hide the menus used for selecting the border color and shading color. \* ---------------------------------------------------------------------- */ function hideColorMenus() { document.getElementById('borderColorMenu').style.display = "none"; document.getElementById('shadingColorMenu').style.display = "none"; } /* ---------------------------------------------------------------------- *\ Function : showBorderColorMenu() Description : Show the border color menu so user can select the table's border color. \* ---------------------------------------------------------------------- */ function showBorderColorMenu() { document.getElementById('borderColorMenu').style.display = "block"; } /* ---------------------------------------------------------------------- *\ Function : previewBorderColor() Description : When mousing over a border color display the color in the preview square. \* ---------------------------------------------------------------------- */ function previewBorderColor(color) { document.getElementById('borderColorPreview').style.backgroundColor = color; } /* ---------------------------------------------------------------------- *\ Function : selectBorderColor() Description : Assigns the selected border color to <input type="hidden" id="borderColor">. \* ---------------------------------------------------------------------- */ function selectBorderColor(color) { document.getElementById('borderColorPreview').style.backgroundColor = color; document.getElementById('borderColorMenu').style.display = "none"; document.getElementById('borderColor').value = color; } /* ---------------------------------------------------------------------- *\ Function : showShadingColorMenu() Description : Show the shading color menu so user can select the table's shading color. \* ---------------------------------------------------------------------- */ function showShadingColorMenu() { document.getElementById('shadingColorMenu').style.display = "block"; } /* ---------------------------------------------------------------------- *\ Function : previewShadingColor() Description : When mousing over a shading color display the color in the preview square. \* ---------------------------------------------------------------------- */ function previewShadingColor(color) { document.getElementById('shadingColorPreview').style.backgroundColor = color; } /* ---------------------------------------------------------------------- *\ Function : selectShadingColor() Description : Assigns the selected shading color to <input type="hidden" id="shadingColor">. \* ---------------------------------------------------------------------- */ function selectShadingColor(color) { document.getElementById('shadingColorPreview').style.backgroundColor = color; document.getElementById('shadingColorMenu').style.display = "none"; document.getElementById('shadingColor').value = color; } </script> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0" onLoad="init();"> <table border="0" cellpadding="0" cellspacing="0" style="padding: 10px;"><tr><td> <input type="hidden" name="borderWidth" id="borderWidth" value="0px"> <input type="hidden" name="borderStyle" id="borderStyle" value="solid"> <input type="hidden" name="borderColor" id="borderColor" value="#000000"> <input type="hidden" name="shadingColor" id="shadingColor" value="#FFFFFF"> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Table Properties:</span> <table width="380" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td style="padding-bottom: 2px; width: 50px; font-family: arial, verdana, helvetica; font-size: 11px;">Rows:</td> <td style="padding-bottom: 2px; width: 80px; "><input type="text" size="4" id="rows" name="rows" value="5" style="font-size: 10px; width: 65px;"></td> <td style="padding-bottom: 2px; width: 80px; font-family: arial, verdana, helvetica; font-size: 11px;">Table Width: <td style="padding-bottom: 2px; width: 180px; "> <input type="text" name="tableWidth" id="tableWidth" value="100" size="10" style="font-size: 10px; width: 65px;"> <select name="widthType" id="widthType" style="margin-right: 10px; font-size: 10px;"> <option value="%">Percent</option> <option value="px">Pixels</option> </select> </td> </tr> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Cols:</td> <td style="padding-bottom: 2px; padding-top: 0px;"><input type="text" size="4" id="cols" name="cols" value="5" style="font-size: 10px; width: 65px;"></td> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Alignment:</td> <td style="padding-bottom: 2px; padding-top: 0px;"> <select name="alignment" id="alignment" style="margin-right: 10px; font-size: 10px; width: 65px;"> <option value="">Not Set</option> <option value="Left">Left</option> <option value="Right">Right</option> <option value="Center">Center</option> </select> </td> </tr> <tr> <td style="padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Padding:</td> <td style="padding-top: 0px;"><input type="text" size="4" id="padding" name="padding" value="5" style="font-size: 10px; width: 65px;"></td> <td style="padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Collapse:</td> <td style="padding-top: 0px;"><input type="checkbox" name="borderCollapse" id="borderCollapse"></td> </tr> </table> <br> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Border Properties:</span> <table width="380" border="0" cellpadding="5" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td> <div style="overflow: auto; width: 135px; height: 150px; border: 1px inset #CCCCCC; background-color: #FFFFFF;"> <table border="0" cellpadding="0" cellspacing="0" width="115"> <tr id="No Border" ><td class="off" onClick="selectBorder('No Border');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'" style="font-family: arial, verdana, helvetica; font-size: 11px;"> No Border </td></tr> <tr id="No Border on" ><td class="on" style="font-family: arial, verdana, helvetica; font-size: 11px;"> No Border </td></tr> <tr id="solid" ><td class="off" onClick="selectBorder('solid');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><hr style="border: 1px solid #000000;"></td></tr> <tr id="solid on" ><td class="on"><hr style="border: 1px solid #000000;"></td></tr> <tr id="dashed" ><td class="off" onClick="selectBorder('dashed');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><hr style="border: 2px dashed #000000;"></td></tr> <tr id="dashed on" ><td class="on"><hr style="border: 2px dashed #000000;"></td></tr> <tr id="dotted" ><td class="off" onClick="selectBorder('dotted');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><hr style="border: 2px dotted #000000;"></td></tr> <tr id="dotted on" ><td class="on"><hr style="border: 2px dotted #000000;"></td></tr> <tr id="double" ><td class="off" onClick="selectBorder('double');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><div style="border-top-width: 6px; border-top-style: double; border-top-color: #000000; font-size: 1px; margin: 6 0 2 0;"> </div></td></tr> <tr id="double on" ><td class="on"><div style="border-top-width: 6px; border-top-style: double; border-top-color: #000000; font-size: 1px; margin: 6 0 2 0;"> </div></td></tr> <tr id="inset" ><td class="off" onClick="selectBorder('inset');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><div style="border: 2px inset #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="inset on" ><td class="on"><div style="border: 2px inset #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="outset" ><td class="off" onClick="selectBorder('outset');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><div style="border: 2px outset #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="outset on" ><td class="on"><div style="border: 2px outset #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="groove" ><td class="off" onClick="selectBorder('groove');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><div style="border: 2px groove #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="groove on" ><td class="on"><div style="border: 2px groove #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="ridge" ><td class="off" onClick="selectBorder('ridge');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><div style="border: 2px ridge #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> <tr id="ridge on" ><td class="on"><div style="border: 2px ridge #DDDDDD; font-size: 4px; padding: 4px;"> </div></td></tr> </table> </div> </td> <td> <div style="overflow: auto; width: 135px; height: 150px; border: 1px inset #CCCCCC; background-color: #FFFFFF;"> <table border="0" cellpadding="0" cellspacing="0" width="115"> <tr id="1px" ><td class="off" onClick="selectWidth('1px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">1px </td><td style="border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; width: 80px;"> </td></tr></table></td></tr> <tr id="1px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">1px </td><td style="border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="2px" ><td class="off" onClick="selectWidth('2px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">2px </td><td style="border-bottom-width: 2px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="2px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">2px </td><td style="border-bottom-width: 2px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="3px" ><td class="off" onClick="selectWidth('3px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">3px </td><td style="border-bottom-width: 3px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="3px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">3px </td><td style="border-bottom-width: 3px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="4px" ><td class="off" onClick="selectWidth('4px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">4px </td><td style="border-bottom-width: 4px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="4px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">4px </td><td style="border-bottom-width: 4px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="5px" ><td class="off" onClick="selectWidth('5px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">5px </td><td style="border-bottom-width: 5px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="5px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">5px </td><td style="border-bottom-width: 5px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="6px" ><td class="off" onClick="selectWidth('6px');" onMouseOver="this.className = 'on'" onMouseOut="this.className = 'off'"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">6px </td><td style="border-bottom-width: 6px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> <tr id="6px on" ><td class="on"><table cellpaddin="0" cellspacing="0" border="0"><tr><td style="font-family: arial, verdana, helvetica, sans serif; font-size: 12px;">6px </td><td style="border-bottom-width: 6px; border-bottom-style: solid; border-bottom-color: #000000; font-size: 1px; margin: 6 0 0 0; width: 80px;"> </td></tr></table></td></tr> </table> </div> </td> <td style="font-family: arial, verdana, helvetica; font-size: 11px;" valign="top"> Color: <table border="0" cellpadding="0" cellspacing="0"> <tr> <td width="25"><table border="0" cellpadding="0" cellspacing="0"><tr><td style="width: 25px; background-color: #000000; border: 1px solid #000000; font-size: 10px;" id="borderColorPreview"> </td></tr></table></td> <td><button style="font-size: 10px; font-family: arial, verdana, helvetica, sans serif; margin-left: 2px; width: 28px;" onClick="showBorderColorMenu();">Pick</button></td> </tr> </table> <div style="position: absolute; right: 30px;" id="borderColorMenu"> <table border="0" cellpadding="0" cellspacing="0" class="selectColorTable"> <tr> <td> <table border="0" cellpadding="1" cellspacing="0"> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#000000');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#000000');"><div style="background-color: #000000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#993300');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#993300');"><div style="background-color: #993300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#333300');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#333300');"><div style="background-color: #333300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#003300');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#003300');"><div style="background-color: #003300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#003366');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#003366');"><div style="background-color: #003366;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#000080');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#000080');"><div style="background-color: #000080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#333399');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#333399');"><div style="background-color: #333399;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#333333');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#333333');"><div style="background-color: #333333;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#800000');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#800000');"><div style="background-color: #800000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FF6600');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FF6600');"><div style="background-color: #FF6600;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#808000');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#808000');"><div style="background-color: #808000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#008000');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#008000');"><div style="background-color: #008000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#008080');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#008080');"><div style="background-color: #008080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#0000FF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#0000FF');"><div style="background-color: #0000FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#666699');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#666699');"><div style="background-color: #666699;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#808080');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#808080');"><div style="background-color: #808080;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FF0000');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FF0000');"><div style="background-color: #FF0000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FF9900');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FF9900');"><div style="background-color: #FF9900;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#99CC00');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#99CC00');"><div style="background-color: #99CC00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#339966');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#339966');"><div style="background-color: #339966;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#33CCCC');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#33CCCC');"><div style="background-color: #33CCCC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#3366FF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#3366FF');"><div style="background-color: #3366FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#800080');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#800080');"><div style="background-color: #800080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#999999');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#999999');"><div style="background-color: #999999;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FF00FF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FF00FF');"><div style="background-color: #FF00FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FFCC00');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FFCC00');"><div style="background-color: #FFCC00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FFFF00');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FFFF00');"><div style="background-color: #FFFF00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#00FF00');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#00FF00');"><div style="background-color: #00FF00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#00FFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#00FFFF');"><div style="background-color: #00FFFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#00CCFF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#00CCFF');"><div style="background-color: #00CCFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#993366');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#993366');"><div style="background-color: #993366;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#C0C0C0');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#C0C0C0');"><div style="background-color: #C0C0C0;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FF99CC');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FF99CC');"><div style="background-color: #FF99CC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FFCC99');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FFCC99');"><div style="background-color: #FFCC99;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FFFF99');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FFFF99');"><div style="background-color: #FFFF99;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#CCFFCC');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#CCFFCC');"><div style="background-color: #CCFFCC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#CCFFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#CCFFFF');"><div style="background-color: #CCFFFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#99CCFF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#99CCFF');"><div style="background-color: #99CCFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#CC99FF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#666699');"><div style="background-color: #666699;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewBorderColor('#FFFFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectBorderColor('#FFFFFF');"><div style="background-color: #FFFFFF;" class="selectColorBox"> </div></td> </tr> </table> </tr> </table> </div> <br> Shading: <table border="0" cellpadding="0" cellspacing="0"> <tr> <td width="25"><table border="0" cellpadding="0" cellspacing="0"><tr><td style="width: 25px; background-color: #FFFFFF; border: 1px solid #000000; font-size: 10px;" id="shadingColorPreview"> </td></tr></table></td> <td><button style="font-size: 10px; font-family: arial, verdana, helvetica, sans serif; margin-left: 2px; width: 28px;" onClick="showShadingColorMenu();">Pick</button></td> </tr> </table> <div style="position: absolute; right: 30px;" id="shadingColorMenu"> <table border="0" cellpadding="0" cellspacing="0" class="selectColorTable"> <tr> <td> <table border="0" cellpadding="1" cellspacing="0"> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#000000');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#000000');"><div style="background-color: #000000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#993300');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#993300');"><div style="background-color: #993300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#333300');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#333300');"><div style="background-color: #333300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#003300');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#003300');"><div style="background-color: #003300;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#003366');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#003366');"><div style="background-color: #003366;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#000080');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#000080');"><div style="background-color: #000080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#333399');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#333399');"><div style="background-color: #333399;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#333333');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#333333');"><div style="background-color: #333333;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#800000');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#800000');"><div style="background-color: #800000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FF6600');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FF6600');"><div style="background-color: #FF6600;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#808000');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#808000');"><div style="background-color: #808000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#008000');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#008000');"><div style="background-color: #008000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#008080');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#008080');"><div style="background-color: #008080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#0000FF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#0000FF');"><div style="background-color: #0000FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#666699');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#666699');"><div style="background-color: #666699;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#808080');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#808080');"><div style="background-color: #808080;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FF0000');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FF0000');"><div style="background-color: #FF0000;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FF9900');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FF9900');"><div style="background-color: #FF9900;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#99CC00');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#99CC00');"><div style="background-color: #99CC00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#339966');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#339966');"><div style="background-color: #339966;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#33CCCC');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#33CCCC');"><div style="background-color: #33CCCC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#3366FF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#3366FF');"><div style="background-color: #3366FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#800080');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#800080');"><div style="background-color: #800080;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#999999');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#999999');"><div style="background-color: #999999;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FF00FF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FF00FF');"><div style="background-color: #FF00FF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FFCC00');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FFCC00');"><div style="background-color: #FFCC00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FFFF00');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FFFF00');"><div style="background-color: #FFFF00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#00FF00');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#00FF00');"><div style="background-color: #00FF00;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#00FFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#00FFFF');"><div style="background-color: #00FFFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#00CCFF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#00CCFF');"><div style="background-color: #00CCFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#993366');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#993366');"><div style="background-color: #993366;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#C0C0C0');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#C0C0C0');"><div style="background-color: #C0C0C0;" class="selectColorBox"> </div></td> </tr> <tr> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FF99CC');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FF99CC');"><div style="background-color: #FF99CC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FFCC99');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FFCC99');"><div style="background-color: #FFCC99;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FFFF99');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FFFF99');"><div style="background-color: #FFFF99;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#CCFFCC');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#CCFFCC');"><div style="background-color: #CCFFCC;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#CCFFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#CCFFFF');"><div style="background-color: #CCFFFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#99CCFF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#99CCFF');"><div style="background-color: #99CCFF;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#CC99FF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#666699');"><div style="background-color: #666699;" class="selectColorBox"> </div></td> <td class="selectColorBorder" onMouseOver="className = 'selectColorOn'; previewShadingColor('#FFFFFF');" onMouseOut="className = 'selectColorOff'" onClick="selectShadingColor('#FFFFFF');"><div style="background-color: #FFFFFF;" class="selectColorBox"> </div></td> </tr> </table> </tr> </table> </div> </td> </tr> </table> </td></tr></table> <div align="right"><input type="submit" value=" Submit " onClick="buildTable();" style="font-size: 12px;"> <input type="submit" value=" Cancel " onClick="window.close();" style="font-size: 12px; margin-right: 15px;" ></div> </body> </html> |
Added modules/wysiwyg/popups/insert_hyperlink.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG | Select Color</title> </head> <script language="JavaScript" type="text/javascript"> var qsParm = new Array(); /* ---------------------------------------------------------------------- *\ Function : retrieveWYSIWYG() Description : Retrieves the textarea ID for which the link will be inserted into. \* ---------------------------------------------------------------------- */ function retrieveWYSIWYG() { var query = window.location.search.substring(1); var parms = query.split('&'); for (var i=0; i<parms.length; i++) { var pos = parms[i].indexOf('='); if (pos > 0) { var key = parms[i].substring(0,pos); var val = parms[i].substring(pos+1); qsParm[key] = val; } } } function insertHyperLink() { var hyperLink = document.getElementById('linkType').value + document.getElementById('url').value; window.opener.document.getElementById('wysiwyg' + qsParm['wysiwyg']).contentWindow.document.execCommand("CreateLink", false, hyperLink); window.close(); } </script> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0" onLoad="retrieveWYSIWYG();"> <table border="0" cellpadding="0" cellspacing="0" style="padding: 10px;"><tr><td> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Insert Hyperlink:</span> <table width="280" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td style="padding-bottom: 2px; width: 50px; font-family: arial, verdana, helvetica; font-size: 11px;">Type:</td> <td style="padding-bottom: 2px;"> <select name="linkType" id="linkType" style="margin-right: 10px; font-size: 10px;"> <option value="http://">http:</option> <option value="https://">https:</option> <option value="mailto:">mailto:</option> </select> </td> </tr> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">URL:</td> <td style="padding-bottom: 2px; padding-top: 0px;"><input type="text" name="url" id="url" value="" style="font-size: 10px; width: 100%;"></td> </tr> </table> <div align="right" style="padding-top: 5px;"><input type="submit" value=" Submit " onClick="insertHyperLink();" style="font-size: 12px;" > <input type="submit" value=" Cancel " onClick="window.close();" style="font-size: 12px;" ></div> </tr></td</table> </body> </html> |
Added modules/wysiwyg/popups/insert_image.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG | Select Color</title> </head> <script language="JavaScript" type="text/javascript"> var qsParm = new Array(); /* ---------------------------------------------------------------------- *\ Function : retrieveWYSIWYG() Description : Retrieves the textarea ID for which the image will be inserted into. \* ---------------------------------------------------------------------- */ function retrieveWYSIWYG() { var query = window.location.search.substring(1); var parms = query.split('&'); for (var i=0; i<parms.length; i++) { var pos = parms[i].indexOf('='); if (pos > 0) { var key = parms[i].substring(0,pos); var val = parms[i].substring(pos+1); qsParm[key] = val; } } } /* ---------------------------------------------------------------------- *\ Function : insertImage() Description : Inserts image into the WYSIWYG. \* ---------------------------------------------------------------------- */ function insertImage() { var image = '<img src="' + document.getElementById('imageurl').value + '" alt="' + document.getElementById('alt').value + '" alignment="' + document.getElementById('alignment').value + '" border="' + document.getElementById('borderThickness').value + '" hspace="' + document.getElementById('horizontal').value + '" vspace="' + document.getElementById('vertical').value + '">'; window.opener.insertHTML(image, qsParm['wysiwyg']); window.close(); } </script> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0" onLoad="retrieveWYSIWYG();"> <table border="0" cellpadding="0" cellspacing="0" style="padding: 10px;"><tr><td> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Insert Image:</span> <table width="380" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;" width="80">Image URL:</td> <td style="padding-bottom: 2px; padding-top: 0px;" width="300"><input type="text" name="imageurl" id="imageurl" value="" style="font-size: 10px; width: 100%;"></td> </tr> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Alternate Text:</td> <td style="padding-bottom: 2px; padding-top: 0px;"><input type="text" name="alt" id="alt" value="" style="font-size: 10px; width: 100%;"></td> </tr> </table> <table width="380" border="0" cellpadding="0" cellspacing="0" style="margin-top: 10px;"><tr><td> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Layout:</span> <table width="185" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;" width="100">Alignment:</td> <td style="padding-bottom: 2px; padding-top: 0px;" width="85"> <select name="alignment" id="alignment" style="font-family: arial, verdana, helvetica; font-size: 11px; width: 100%;"> <option value="">Not Set</option> <option value="left">Left</option> <option value="right">Right</option> <option value="texttop">Texttop</option> <option value="absmiddle">Absmiddle</option> <option value="baseline">Baseline</option> <option value="absbottom">Absbottom</option> <option value="bottom">Bottom</option> <option value="middle">Middle</option> <option value="top">Top</option> </select> </td> </tr> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Border Thickness:</td> <td style="padding-bottom: 2px; padding-top: 0px;"><input type="text" name="borderThickness" id="borderThickness" value="" style="font-size: 10px; width: 100%;"></td> </tr> </table> </td> <td width="10"> </td> <td> <span style="font-family: arial, verdana, helvetica; font-size: 11px; font-weight: bold;">Spacing:</span> <table width="185" border="0" cellpadding="0" cellspacing="0" style="background-color: #F7F7F7; border: 2px solid #FFFFFF; padding: 5px;"> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;" width="80">Horizontal:</td> <td style="padding-bottom: 2px; padding-top: 0px;" width="105"><input type="text" name="horizontal" id="horizontal" value="" style="font-size: 10px; width: 100%;"></td> </tr> <tr> <td style="padding-bottom: 2px; padding-top: 0px; font-family: arial, verdana, helvetica; font-size: 11px;">Vertical:</td> <td style="padding-bottom: 2px; padding-top: 0px;"><input type="text" name="vertical" id="vertical" value="" style="font-size: 10px; width: 100%;"></td> </tr> </table> </td></tr></table> <div align="right" style="padding-top: 5px;"><input type="submit" value=" Submit " onClick="insertImage();" style="font-size: 12px;" > <input type="submit" value=" Cancel " onClick="window.close();" style="font-size: 12px;" ></div> </tr></td</table> </body> </html> |
Added modules/wysiwyg/popups/license.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG | License</title> </head> <body style="font-family: arial, verdana, helvetia, sans serif; font-size: 12px; background-color: #FFFFFF;"> <h1>GNU Lesser General Public License</h1> <p>Version 2.1, February 1999</p> <blockquote> <p>Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</p> <p>[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]</p></blockquote> <h3>Preamble</h3> <p> The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. </p> <p>This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. </p> <p> When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.</p> <p>To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. </p> <p> For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. </p> <p>We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. </p> <p>To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. </p> <p> Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. </p> <p>Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. </p> <p>When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. </p> <p>We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. </p> <p>For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. </p> <p>In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. </p> <p> Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. </p> <p>The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. </p> <h3>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h3> <p><strong>0.</strong> This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".</p> <p> A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. </p> <p> The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) </p> <p> "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.</p> <p>Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. </p> <p><strong>1.</strong> You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. </p> <p> You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. </p> <p><strong>2.</strong> You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: </p> <blockquote> <p>a) The modified work must itself be a software library. </p> <p>b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.</p> <p>c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. </p> <p>d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. </p> <p> (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) </p> <p> These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. </p> <p>Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. </p> <p> In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. </p></blockquote> <p><strong>3.</strong> You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. </p> <p>Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. </p> <p> This option is useful when you wish to copy part of the code of the Library into a program that is not a library. </p> <p><strong>4.</strong> You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. </p> <p>If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.</p> <p><strong>5.</strong> A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. </p> <p> However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. </p> <p> When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. </p> <p> If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) </p> <p>Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. </p> <p><strong>6.</strong> As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. </p> <p> You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: </p> <blockquote><p>a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) </p> <p>b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. </p> <p> c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. </p> <p>d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. </p> <p>e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.</p> </blockquote> <p>For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. </p> <p> It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. </p> <p><strong>7.</strong> You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: </p> <blockquote> <p>a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. </p> <p>b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.</p></blockquote> <p><strong>8.</strong> You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. </p> <p> <strong>9.</strong> You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. </p> <p> <strong>10.</strong> Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. </p> <p><strong>11.</strong> If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. </p> <p> If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. </p> <p>It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. </p> <p>This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. </p> <p> <strong>12.</strong> If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. </p> <p> <strong>13.</strong> The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</p> <p>Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. </p> <p> <strong>14.</strong> If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. </p> <p> NO WARRANTY </p> <p> <strong>15. </strong>BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. </p> <p> <strong>16.</strong> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. </p> <h3><strong>END OF TERMS AND CONDITIONS</strong></h3> </body> </html> |
Added modules/wysiwyg/popups/select_color.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>openWYSIWYG | Select Color</title> </head> <script language="JavaScript" type="text/javascript"> var qsParm = new Array(); /* ---------------------------------------------------------------------- *\ Function : retrieveWYSIWYG() Description : Retrieves the textarea ID for which the color will be inserted into. \* ---------------------------------------------------------------------- */ function retreiveColor() { var query = window.location.search.substring(1); var parms = query.split('&'); for (var i=0; i<parms.length; i++) { var pos = parms[i].indexOf('='); if (pos > 0) { var key = parms[i].substring(0,pos); var val = parms[i].substring(pos+1); qsParm[key] = val; } } document.getElementById('enterColor').value = "#" + (qsParm['color']); } /* ---------------------------------------------------------------------- *\ Function : selectColor() Description : Selects the color and inserts it into the WYSIWYG \* ---------------------------------------------------------------------- */ function selectColor(color) { window.opener.document.getElementById('wysiwyg' + qsParm['wysiwyg']).contentWindow.document.execCommand(qsParm['command'], false, color); window.close(); } /* ---------------------------------------------------------------------- *\ Function : previewColor() Description : Updates the preview pane as the user mouses over different colors \* ---------------------------------------------------------------------- */ function previewColor(color) { document.getElementById('enterColor').value = color; document.getElementById('PreviewColor').style.backgroundColor = color; } </script> <body bgcolor="#EEEEEE" marginwidth="0" marginheight="0" topmargin="0" leftmargin="0" onLoad="retreiveColor();"> <center> <table border="0" cellspacing="0" cellpadding="4" width="100%"> <tr><form onSubmit="selectColor(document.getElementById('enterColor').value);"> <td valign=center><div style="background-color: #000000; padding: 1; height: 21px; width: 50px"><div id="PreviewColor" style="height: 100%; width: 100%"></div></div></td> <td valign=center><input type="text" size="15" id="enterColor" name="enterColor" id="enterColor"></td> <td width="100%"></td> </tr></form> </table> <table border=0 cellspacing=1 cellpadding=0 bgcolor="#000000" style="cursor: hand;" > <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#003300" onMouseOver="previewColor('#003300')" onClick="selectColor('#003300')" height="10" width="10"></td> <td bgcolor="#006600" onMouseOver="previewColor('#006600')" onClick="selectColor('#006600')" height="10" width="10"></td> <td bgcolor="#009900" onMouseOver="previewColor('#009900')" onClick="selectColor('#009900')" height="10" width="10"></td> <td bgcolor="#00CC00" onMouseOver="previewColor('#00CC00')" onClick="selectColor('#00CC00')" height="10" width="10"></td> <td bgcolor="#00FF00" onMouseOver="previewColor('#00FF00')" onClick="selectColor('#00FF00')" height="10" width="10"></td> <td bgcolor="#330000" onMouseOver="previewColor('#330000')" onClick="selectColor('#330000')" height="10" width="10"></td> <td bgcolor="#333300" onMouseOver="previewColor('#333300')" onClick="selectColor('#333300')" height="10" width="10"></td> <td bgcolor="#336600" onMouseOver="previewColor('#336600')" onClick="selectColor('#336600')" height="10" width="10"></td> <td bgcolor="#339900" onMouseOver="previewColor('#339900')" onClick="selectColor('#339900')" height="10" width="10"></td> <td bgcolor="#33CC00" onMouseOver="previewColor('#33CC00')" onClick="selectColor('#33CC00')" height="10" width="10"></td> <td bgcolor="#33FF00" onMouseOver="previewColor('#33FF00')" onClick="selectColor('#33FF00')" height="10" width="10"></td> <td bgcolor="#660000" onMouseOver="previewColor('#660000')" onClick="selectColor('#660000')" height="10" width="10"></td> <td bgcolor="#663300" onMouseOver="previewColor('#663300')" onClick="selectColor('#663300')" height="10" width="10"></td> <td bgcolor="#666600" onMouseOver="previewColor('#666600')" onClick="selectColor('#666600')" height="10" width="10"></td> <td bgcolor="#669900" onMouseOver="previewColor('#669900')" onClick="selectColor('#669900')" height="10" width="10"></td> <td bgcolor="#66CC00" onMouseOver="previewColor('#66CC00')" onClick="selectColor('#66CC00')" height="10" width="10"></td> <td bgcolor="#66FF00" onMouseOver="previewColor('#66FF00')" onClick="selectColor('#66FF00')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#333333" onMouseOver="previewColor('#333333')" onClick="selectColor('#333333')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000033" onMouseOver="previewColor('#000033')" onClick="selectColor('#000033')" height="10" width="10"></td> <td bgcolor="#003333" onMouseOver="previewColor('#003333')" onClick="selectColor('#003333')" height="10" width="10"></td> <td bgcolor="#006633" onMouseOver="previewColor('#006633')" onClick="selectColor('#006633')" height="10" width="10"></td> <td bgcolor="#009933" onMouseOver="previewColor('#009933')" onClick="selectColor('#009933')" height="10" width="10"></td> <td bgcolor="#00CC33" onMouseOver="previewColor('#00CC33')" onClick="selectColor('#00CC33')" height="10" width="10"></td> <td bgcolor="#00FF33" onMouseOver="previewColor('#00FF33')" onClick="selectColor('#00FF33')" height="10" width="10"></td> <td bgcolor="#330033" onMouseOver="previewColor('#330033')" onClick="selectColor('#330033')" height="10" width="10"></td> <td bgcolor="#333333" onMouseOver="previewColor('#333333')" onClick="selectColor('#333333')" height="10" width="10"></td> <td bgcolor="#336633" onMouseOver="previewColor('#336633')" onClick="selectColor('#336633')" height="10" width="10"></td> <td bgcolor="#339933" onMouseOver="previewColor('#339933')" onClick="selectColor('#339933')" height="10" width="10"></td> <td bgcolor="#33CC33" onMouseOver="previewColor('#33CC33')" onClick="selectColor('#33CC33')" height="10" width="10"></td> <td bgcolor="#33FF33" onMouseOver="previewColor('#33FF33')" onClick="selectColor('#33FF33')" height="10" width="10"></td> <td bgcolor="#660033" onMouseOver="previewColor('#660033')" onClick="selectColor('#660033')" height="10" width="10"></td> <td bgcolor="#663333" onMouseOver="previewColor('#663333')" onClick="selectColor('#663333')" height="10" width="10"></td> <td bgcolor="#666633" onMouseOver="previewColor('#666633')" onClick="selectColor('#666633')" height="10" width="10"></td> <td bgcolor="#669933" onMouseOver="previewColor('#669933')" onClick="selectColor('#669933')" height="10" width="10"></td> <td bgcolor="#66CC33" onMouseOver="previewColor('#66CC33')" onClick="selectColor('#66CC33')" height="10" width="10"></td> <td bgcolor="#66FF33" onMouseOver="previewColor('#66FF33')" onClick="selectColor('#66FF33')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#666666" onMouseOver="previewColor('#666666')" onClick="selectColor('#666666')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000066" onMouseOver="previewColor('#000066')" onClick="selectColor('#000066')" height="10" width="10"></td> <td bgcolor="#003366" onMouseOver="previewColor('#003366')" onClick="selectColor('#003366')" height="10" width="10"></td> <td bgcolor="#006666" onMouseOver="previewColor('#006666')" onClick="selectColor('#006666')" height="10" width="10"></td> <td bgcolor="#009966" onMouseOver="previewColor('#009966')" onClick="selectColor('#009966')" height="10" width="10"></td> <td bgcolor="#00CC66" onMouseOver="previewColor('#00CC66')" onClick="selectColor('#00CC66')" height="10" width="10"></td> <td bgcolor="#00FF66" onMouseOver="previewColor('#00FF66')" onClick="selectColor('#00FF66')" height="10" width="10"></td> <td bgcolor="#330066" onMouseOver="previewColor('#330066')" onClick="selectColor('#330066')" height="10" width="10"></td> <td bgcolor="#333366" onMouseOver="previewColor('#333366')" onClick="selectColor('#333366')" height="10" width="10"></td> <td bgcolor="#336666" onMouseOver="previewColor('#336666')" onClick="selectColor('#336666')" height="10" width="10"></td> <td bgcolor="#339966" onMouseOver="previewColor('#339966')" onClick="selectColor('#339966')" height="10" width="10"></td> <td bgcolor="#33CC66" onMouseOver="previewColor('#33CC66')" onClick="selectColor('#33CC66')" height="10" width="10"></td> <td bgcolor="#33FF66" onMouseOver="previewColor('#33FF66')" onClick="selectColor('#33FF66')" height="10" width="10"></td> <td bgcolor="#660066" onMouseOver="previewColor('#660066')" onClick="selectColor('#660066')" height="10" width="10"></td> <td bgcolor="#663366" onMouseOver="previewColor('#663366')" onClick="selectColor('#663366')" height="10" width="10"></td> <td bgcolor="#666666" onMouseOver="previewColor('#666666')" onClick="selectColor('#666666')" height="10" width="10"></td> <td bgcolor="#669966" onMouseOver="previewColor('#669966')" onClick="selectColor('#669966')" height="10" width="10"></td> <td bgcolor="#66CC66" onMouseOver="previewColor('#66CC66')" onClick="selectColor('#66CC66')" height="10" width="10"></td> <td bgcolor="#66FF66" onMouseOver="previewColor('#66FF66')" onClick="selectColor('#66FF66')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#999999" onMouseOver="previewColor('#999999')" onClick="selectColor('#999999')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#000099" onMouseOver="previewColor('#000099')" onClick="selectColor('#000099')" height="10" width="10"></td> <td bgcolor="#003399" onMouseOver="previewColor('#003399')" onClick="selectColor('#003399')" height="10" width="10"></td> <td bgcolor="#006699" onMouseOver="previewColor('#006699')" onClick="selectColor('#006699')" height="10" width="10"></td> <td bgcolor="#009999" onMouseOver="previewColor('#009999')" onClick="selectColor('#009999')" height="10" width="10"></td> <td bgcolor="#00CC99" onMouseOver="previewColor('#00CC99')" onClick="selectColor('#00CC99')" height="10" width="10"></td> <td bgcolor="#00FF99" onMouseOver="previewColor('#00FF99')" onClick="selectColor('#00FF99')" height="10" width="10"></td> <td bgcolor="#330099" onMouseOver="previewColor('#330099')" onClick="selectColor('#330099')" height="10" width="10"></td> <td bgcolor="#333399" onMouseOver="previewColor('#333399')" onClick="selectColor('#333399')" height="10" width="10"></td> <td bgcolor="#336699" onMouseOver="previewColor('#336699')" onClick="selectColor('#336699')" height="10" width="10"></td> <td bgcolor="#339999" onMouseOver="previewColor('#339999')" onClick="selectColor('#339999')" height="10" width="10"></td> <td bgcolor="#33CC99" onMouseOver="previewColor('#33CC99')" onClick="selectColor('#33CC99')" height="10" width="10"></td> <td bgcolor="#33FF99" onMouseOver="previewColor('#33FF99')" onClick="selectColor('#33FF99')" height="10" width="10"></td> <td bgcolor="#660099" onMouseOver="previewColor('#660099')" onClick="selectColor('#660099')" height="10" width="10"></td> <td bgcolor="#663399" onMouseOver="previewColor('#663399')" onClick="selectColor('#663399')" height="10" width="10"></td> <td bgcolor="#666699" onMouseOver="previewColor('#666699')" onClick="selectColor('#666699')" height="10" width="10"></td> <td bgcolor="#669999" onMouseOver="previewColor('#669999')" onClick="selectColor('#669999')" height="10" width="10"></td> <td bgcolor="#66CC99" onMouseOver="previewColor('#66CC99')" onClick="selectColor('#66CC99')" height="10" width="10"></td> <td bgcolor="#66FF99" onMouseOver="previewColor('#66FF99')" onClick="selectColor('#66FF99')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#CCCCCC" onMouseOver="previewColor('#CCCCCC')" onClick="selectColor('#CCCCCC')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#0000CC" onMouseOver="previewColor('#0000CC')" onClick="selectColor('#0000CC')" height="10" width="10"></td> <td bgcolor="#0033CC" onMouseOver="previewColor('#0033CC')" onClick="selectColor('#0033CC')" height="10" width="10"></td> <td bgcolor="#0066CC" onMouseOver="previewColor('#0066CC')" onClick="selectColor('#0066CC')" height="10" width="10"></td> <td bgcolor="#0099CC" onMouseOver="previewColor('#0099CC')" onClick="selectColor('#0099CC')" height="10" width="10"></td> <td bgcolor="#00CCCC" onMouseOver="previewColor('#00CCCC')" onClick="selectColor('#00CCCC')" height="10" width="10"></td> <td bgcolor="#00FFCC" onMouseOver="previewColor('#00FFCC')" onClick="selectColor('#00FFCC')" height="10" width="10"></td> <td bgcolor="#3300CC" onMouseOver="previewColor('#3300CC')" onClick="selectColor('#3300CC')" height="10" width="10"></td> <td bgcolor="#3333CC" onMouseOver="previewColor('#3333CC')" onClick="selectColor('#3333CC')" height="10" width="10"></td> <td bgcolor="#3366CC" onMouseOver="previewColor('#3366CC')" onClick="selectColor('#3366CC')" height="10" width="10"></td> <td bgcolor="#3399CC" onMouseOver="previewColor('#3399CC')" onClick="selectColor('#3399CC')" height="10" width="10"></td> <td bgcolor="#33CCCC" onMouseOver="previewColor('#33CCCC')" onClick="selectColor('#33CCCC')" height="10" width="10"></td> <td bgcolor="#33FFCC" onMouseOver="previewColor('#33FFCC')" onClick="selectColor('#33FFCC')" height="10" width="10"></td> <td bgcolor="#6600CC" onMouseOver="previewColor('#6600CC')" onClick="selectColor('#6600CC')" height="10" width="10"></td> <td bgcolor="#6633CC" onMouseOver="previewColor('#6633CC')" onClick="selectColor('#6633CC')" height="10" width="10"></td> <td bgcolor="#6666CC" onMouseOver="previewColor('#6666CC')" onClick="selectColor('#6666CC')" height="10" width="10"></td> <td bgcolor="#6699CC" onMouseOver="previewColor('#6699CC')" onClick="selectColor('#6699CC')" height="10" width="10"></td> <td bgcolor="#66CCCC" onMouseOver="previewColor('#66CCCC')" onClick="selectColor('#66CCCC')" height="10" width="10"></td> <td bgcolor="#66FFCC" onMouseOver="previewColor('#66FFCC')" onClick="selectColor('#66FFCC')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#FFFFFF" onMouseOver="previewColor('#FFFFFF')" onClick="selectColor('#FFFFFF')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#0000FF" onMouseOver="previewColor('#0000FF')" onClick="selectColor('#0000FF')" height="10" width="10"></td> <td bgcolor="#0033FF" onMouseOver="previewColor('#0033FF')" onClick="selectColor('#0033FF')" height="10" width="10"></td> <td bgcolor="#0066FF" onMouseOver="previewColor('#0066FF')" onClick="selectColor('#0066FF')" height="10" width="10"></td> <td bgcolor="#0099FF" onMouseOver="previewColor('#0099FF')" onClick="selectColor('#0099FF')" height="10" width="10"></td> <td bgcolor="#00CCFF" onMouseOver="previewColor('#00CCFF')" onClick="selectColor('#00CCFF')" height="10" width="10"></td> <td bgcolor="#00FFFF" onMouseOver="previewColor('#00FFFF')" onClick="selectColor('#00FFFF')" height="10" width="10"></td> <td bgcolor="#3300FF" onMouseOver="previewColor('#3300FF')" onClick="selectColor('#3300FF')" height="10" width="10"></td> <td bgcolor="#3333FF" onMouseOver="previewColor('#3333FF')" onClick="selectColor('#3333FF')" height="10" width="10"></td> <td bgcolor="#3366FF" onMouseOver="previewColor('#3366FF')" onClick="selectColor('#3366FF')" height="10" width="10"></td> <td bgcolor="#3399FF" onMouseOver="previewColor('#3399FF')" onClick="selectColor('#3399FF')" height="10" width="10"></td> <td bgcolor="#33CCFF" onMouseOver="previewColor('#33CCFF')" onClick="selectColor('#33CCFF')" height="10" width="10"></td> <td bgcolor="#33FFFF" onMouseOver="previewColor('#33FFFF')" onClick="selectColor('#33FFFF')" height="10" width="10"></td> <td bgcolor="#6600FF" onMouseOver="previewColor('#6600FF')" onClick="selectColor('#6600FF')" height="10" width="10"></td> <td bgcolor="#6633FF" onMouseOver="previewColor('#6633FF')" onClick="selectColor('#6633FF')" height="10" width="10"></td> <td bgcolor="#6666FF" onMouseOver="previewColor('#6666FF')" onClick="selectColor('#6666FF')" height="10" width="10"></td> <td bgcolor="#6699FF" onMouseOver="previewColor('#6699FF')" onClick="selectColor('#6699FF')" height="10" width="10"></td> <td bgcolor="#66CCFF" onMouseOver="previewColor('#66CCFF')" onClick="selectColor('#66CCFF')" height="10" width="10"></td> <td bgcolor="#66FFFF" onMouseOver="previewColor('#66FFFF')" onClick="selectColor('#66FFFF')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#FF0000" onMouseOver="previewColor('#FF0000')" onClick="selectColor('#FF0000')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#990000" onMouseOver="previewColor('#990000')" onClick="selectColor('#990000')" height="10" width="10"></td> <td bgcolor="#993300" onMouseOver="previewColor('#993300')" onClick="selectColor('#993300')" height="10" width="10"></td> <td bgcolor="#996600" onMouseOver="previewColor('#996600')" onClick="selectColor('#996600')" height="10" width="10"></td> <td bgcolor="#999900" onMouseOver="previewColor('#999900')" onClick="selectColor('#999900')" height="10" width="10"></td> <td bgcolor="#99CC00" onMouseOver="previewColor('#99CC00')" onClick="selectColor('#99CC00')" height="10" width="10"></td> <td bgcolor="#99FF00" onMouseOver="previewColor('#99FF00')" onClick="selectColor('#99FF00')" height="10" width="10"></td> <td bgcolor="#CC0000" onMouseOver="previewColor('#CC0000')" onClick="selectColor('#CC0000')" height="10" width="10"></td> <td bgcolor="#CC3300" onMouseOver="previewColor('#CC3300')" onClick="selectColor('#CC3300')" height="10" width="10"></td> <td bgcolor="#CC6600" onMouseOver="previewColor('#CC6600')" onClick="selectColor('#CC6600')" height="10" width="10"></td> <td bgcolor="#CC9900" onMouseOver="previewColor('#CC9900')" onClick="selectColor('#CC9900')" height="10" width="10"></td> <td bgcolor="#CCCC00" onMouseOver="previewColor('#CCCC00')" onClick="selectColor('#CCCC00')" height="10" width="10"></td> <td bgcolor="#CCFF00" onMouseOver="previewColor('#CCFF00')" onClick="selectColor('#CCFF00')" height="10" width="10"></td> <td bgcolor="#FF0000" onMouseOver="previewColor('#FF0000')" onClick="selectColor('#FF0000')" height="10" width="10"></td> <td bgcolor="#FF3300" onMouseOver="previewColor('#FF3300')" onClick="selectColor('#FF3300')" height="10" width="10"></td> <td bgcolor="#FF6600" onMouseOver="previewColor('#FF6600')" onClick="selectColor('#FF6600')" height="10" width="10"></td> <td bgcolor="#FF9900" onMouseOver="previewColor('#FF9900')" onClick="selectColor('#FF9900')" height="10" width="10"></td> <td bgcolor="#FFCC00" onMouseOver="previewColor('#FFCC00')" onClick="selectColor('#FFCC00')" height="10" width="10"></td> <td bgcolor="#FFFF00" onMouseOver="previewColor('#FFFF00')" onClick="selectColor('#FFFF00')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#00FF00" onMouseOver="previewColor('#00FF00')" onClick="selectColor('#00FF00')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#990033" onMouseOver="previewColor('#990033')" onClick="selectColor('#990033')" height="10" width="10"></td> <td bgcolor="#993333" onMouseOver="previewColor('#993333')" onClick="selectColor('#993333')" height="10" width="10"></td> <td bgcolor="#996633" onMouseOver="previewColor('#996633')" onClick="selectColor('#996633')" height="10" width="10"></td> <td bgcolor="#999933" onMouseOver="previewColor('#999933')" onClick="selectColor('#999933')" height="10" width="10"></td> <td bgcolor="#99CC33" onMouseOver="previewColor('#99CC33')" onClick="selectColor('#99CC33')" height="10" width="10"></td> <td bgcolor="#99FF33" onMouseOver="previewColor('#99FF33')" onClick="selectColor('#99FF33')" height="10" width="10"></td> <td bgcolor="#CC0033" onMouseOver="previewColor('#CC0033')" onClick="selectColor('#CC0033')" height="10" width="10"></td> <td bgcolor="#CC3333" onMouseOver="previewColor('#CC3333')" onClick="selectColor('#CC3333')" height="10" width="10"></td> <td bgcolor="#CC6633" onMouseOver="previewColor('#CC6633')" onClick="selectColor('#CC6633')" height="10" width="10"></td> <td bgcolor="#CC9933" onMouseOver="previewColor('#CC9933')" onClick="selectColor('#CC9933')" height="10" width="10"></td> <td bgcolor="#CCCC33" onMouseOver="previewColor('#CCCC33')" onClick="selectColor('#CCCC33')" height="10" width="10"></td> <td bgcolor="#CCFF33" onMouseOver="previewColor('#CCFF33')" onClick="selectColor('#CCFF33')" height="10" width="10"></td> <td bgcolor="#FF0033" onMouseOver="previewColor('#FF0033')" onClick="selectColor('#FF0033')" height="10" width="10"></td> <td bgcolor="#FF3333" onMouseOver="previewColor('#FF3333')" onClick="selectColor('#FF3333')" height="10" width="10"></td> <td bgcolor="#FF6633" onMouseOver="previewColor('#FF6633')" onClick="selectColor('#FF6633')" height="10" width="10"></td> <td bgcolor="#FF9933" onMouseOver="previewColor('#FF9933')" onClick="selectColor('#FF9933')" height="10" width="10"></td> <td bgcolor="#FFCC33" onMouseOver="previewColor('#FFCC33')" onClick="selectColor('#FFCC33')" height="10" width="10"></td> <td bgcolor="#FFFF33" onMouseOver="previewColor('#FFFF33')" onClick="selectColor('#FFFF33')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#0000FF" onMouseOver="previewColor('#0000FF')" onClick="selectColor('#0000FF')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#990066" onMouseOver="previewColor('#990066')" onClick="selectColor('#990066')" height="10" width="10"></td> <td bgcolor="#993366" onMouseOver="previewColor('#993366')" onClick="selectColor('#993366')" height="10" width="10"></td> <td bgcolor="#996666" onMouseOver="previewColor('#996666')" onClick="selectColor('#996666')" height="10" width="10"></td> <td bgcolor="#999966" onMouseOver="previewColor('#999966')" onClick="selectColor('#999966')" height="10" width="10"></td> <td bgcolor="#99CC66" onMouseOver="previewColor('#99CC66')" onClick="selectColor('#99CC66')" height="10" width="10"></td> <td bgcolor="#99FF66" onMouseOver="previewColor('#99FF66')" onClick="selectColor('#99FF66')" height="10" width="10"></td> <td bgcolor="#CC0066" onMouseOver="previewColor('#CC0066')" onClick="selectColor('#CC0066')" height="10" width="10"></td> <td bgcolor="#CC3366" onMouseOver="previewColor('#CC3366')" onClick="selectColor('#CC3366')" height="10" width="10"></td> <td bgcolor="#CC6666" onMouseOver="previewColor('#CC6666')" onClick="selectColor('#CC6666')" height="10" width="10"></td> <td bgcolor="#CC9966" onMouseOver="previewColor('#CC9966')" onClick="selectColor('#CC9966')" height="10" width="10"></td> <td bgcolor="#CCCC66" onMouseOver="previewColor('#CCCC66')" onClick="selectColor('#CCCC66')" height="10" width="10"></td> <td bgcolor="#CCFF66" onMouseOver="previewColor('#CCFF66')" onClick="selectColor('#CCFF66')" height="10" width="10"></td> <td bgcolor="#FF0066" onMouseOver="previewColor('#FF0066')" onClick="selectColor('#FF0066')" height="10" width="10"></td> <td bgcolor="#FF3366" onMouseOver="previewColor('#FF3366')" onClick="selectColor('#FF3366')" height="10" width="10"></td> <td bgcolor="#FF6666" onMouseOver="previewColor('#FF6666')" onClick="selectColor('#FF6666')" height="10" width="10"></td> <td bgcolor="#FF9966" onMouseOver="previewColor('#FF9966')" onClick="selectColor('#FF9966')" height="10" width="10"></td> <td bgcolor="#FFCC66" onMouseOver="previewColor('#FFCC66')" onClick="selectColor('#FFCC66')" height="10" width="10"></td> <td bgcolor="#FFFF66" onMouseOver="previewColor('#FFFF66')" onClick="selectColor('#FFFF66')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#FFFF00" onMouseOver="previewColor('#FFFF00')" onClick="selectColor('#FFFF00')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#990099" onMouseOver="previewColor('#990099')" onClick="selectColor('#990099')" height="10" width="10"></td> <td bgcolor="#993399" onMouseOver="previewColor('#993399')" onClick="selectColor('#993399')" height="10" width="10"></td> <td bgcolor="#996699" onMouseOver="previewColor('#996699')" onClick="selectColor('#996699')" height="10" width="10"></td> <td bgcolor="#999999" onMouseOver="previewColor('#999999')" onClick="selectColor('#999999')" height="10" width="10"></td> <td bgcolor="#99CC99" onMouseOver="previewColor('#99CC99')" onClick="selectColor('#99CC99')" height="10" width="10"></td> <td bgcolor="#99FF99" onMouseOver="previewColor('#99FF99')" onClick="selectColor('#99FF99')" height="10" width="10"></td> <td bgcolor="#CC0099" onMouseOver="previewColor('#CC0099')" onClick="selectColor('#CC0099')" height="10" width="10"></td> <td bgcolor="#CC3399" onMouseOver="previewColor('#CC3399')" onClick="selectColor('#CC3399')" height="10" width="10"></td> <td bgcolor="#CC6699" onMouseOver="previewColor('#CC6699')" onClick="selectColor('#CC6699')" height="10" width="10"></td> <td bgcolor="#CC9999" onMouseOver="previewColor('#CC9999')" onClick="selectColor('#CC9999')" height="10" width="10"></td> <td bgcolor="#CCCC99" onMouseOver="previewColor('#CCCC99')" onClick="selectColor('#CCCC99')" height="10" width="10"></td> <td bgcolor="#CCFF99" onMouseOver="previewColor('#CCFF99')" onClick="selectColor('#CCFF99')" height="10" width="10"></td> <td bgcolor="#FF0099" onMouseOver="previewColor('#FF0099')" onClick="selectColor('#FF0099')" height="10" width="10"></td> <td bgcolor="#FF3399" onMouseOver="previewColor('#FF3399')" onClick="selectColor('#FF3399')" height="10" width="10"></td> <td bgcolor="#FF6699" onMouseOver="previewColor('#FF6699')" onClick="selectColor('#FF6699')" height="10" width="10"></td> <td bgcolor="#FF9999" onMouseOver="previewColor('#FF9999')" onClick="selectColor('#FF9999')" height="10" width="10"></td> <td bgcolor="#FFCC99" onMouseOver="previewColor('#FFCC99')" onClick="selectColor('#FFCC99')" height="10" width="10"></td> <td bgcolor="#FFFF99" onMouseOver="previewColor('#FFFF99')" onClick="selectColor('#FFFF99')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#00FFFF" onMouseOver="previewColor('#00FFFF')" onClick="selectColor('#00FFFF')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#9900CC" onMouseOver="previewColor('#9900CC')" onClick="selectColor('#9900CC')" height="10" width="10"></td> <td bgcolor="#9933CC" onMouseOver="previewColor('#9933CC')" onClick="selectColor('#9933CC')" height="10" width="10"></td> <td bgcolor="#9966CC" onMouseOver="previewColor('#9966CC')" onClick="selectColor('#9966CC')" height="10" width="10"></td> <td bgcolor="#9999CC" onMouseOver="previewColor('#9999CC')" onClick="selectColor('#9999CC')" height="10" width="10"></td> <td bgcolor="#99CCCC" onMouseOver="previewColor('#99CCCC')" onClick="selectColor('#99CCCC')" height="10" width="10"></td> <td bgcolor="#99FFCC" onMouseOver="previewColor('#99FFCC')" onClick="selectColor('#99FFCC')" height="10" width="10"></td> <td bgcolor="#CC00CC" onMouseOver="previewColor('#CC00CC')" onClick="selectColor('#CC00CC')" height="10" width="10"></td> <td bgcolor="#CC33CC" onMouseOver="previewColor('#CC33CC')" onClick="selectColor('#CC33CC')" height="10" width="10"></td> <td bgcolor="#CC66CC" onMouseOver="previewColor('#CC66CC')" onClick="selectColor('#CC66CC')" height="10" width="10"></td> <td bgcolor="#CC99CC" onMouseOver="previewColor('#CC99CC')" onClick="selectColor('#CC99CC')" height="10" width="10"></td> <td bgcolor="#CCCCCC" onMouseOver="previewColor('#CCCCCC')" onClick="selectColor('#CCCCCC')" height="10" width="10"></td> <td bgcolor="#CCFFCC" onMouseOver="previewColor('#CCFFCC')" onClick="selectColor('#CCFFCC')" height="10" width="10"></td> <td bgcolor="#FF00CC" onMouseOver="previewColor('#FF00CC')" onClick="selectColor('#FF00CC')" height="10" width="10"></td> <td bgcolor="#FF33CC" onMouseOver="previewColor('#FF33CC')" onClick="selectColor('#FF33CC')" height="10" width="10"></td> <td bgcolor="#FF66CC" onMouseOver="previewColor('#FF66CC')" onClick="selectColor('#FF66CC')" height="10" width="10"></td> <td bgcolor="#FF99CC" onMouseOver="previewColor('#FF99CC')" onClick="selectColor('#FF99CC')" height="10" width="10"></td> <td bgcolor="#FFCCCC" onMouseOver="previewColor('#FFCCCC')" onClick="selectColor('#FFCCCC')" height="10" width="10"></td> <td bgcolor="#FFFFCC" onMouseOver="previewColor('#FFFFCC')" onClick="selectColor('#FFFFCC')" height="10" width="10"></td> </tr> <tr> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#FF00FF" onMouseOver="previewColor('#FF00FF')" onClick="selectColor('#FF00FF')" height="10" width="10"></td> <td bgcolor="#000000" onMouseOver="previewColor('#000000')" onClick="selectColor('#000000')" height="10" width="10"></td> <td bgcolor="#9900FF" onMouseOver="previewColor('#9900FF')" onClick="selectColor('#9900FF')" height="10" width="10"></td> <td bgcolor="#9933FF" onMouseOver="previewColor('#9933FF')" onClick="selectColor('#9933FF')" height="10" width="10"></td> <td bgcolor="#9966FF" onMouseOver="previewColor('#9966FF')" onClick="selectColor('#9966FF')" height="10" width="10"></td> <td bgcolor="#9999FF" onMouseOver="previewColor('#9999FF')" onClick="selectColor('#9999FF')" height="10" width="10"></td> <td bgcolor="#99CCFF" onMouseOver="previewColor('#99CCFF')" onClick="selectColor('#99CCFF')" height="10" width="10"></td> <td bgcolor="#99FFFF" onMouseOver="previewColor('#99FFFF')" onClick="selectColor('#99FFFF')" height="10" width="10"></td> <td bgcolor="#CC00FF" onMouseOver="previewColor('#CC00FF')" onClick="selectColor('#CC00FF')" height="10" width="10"></td> <td bgcolor="#CC33FF" onMouseOver="previewColor('#CC33FF')" onClick="selectColor('#CC33FF')" height="10" width="10"></td> <td bgcolor="#CC66FF" onMouseOver="previewColor('#CC66FF')" onClick="selectColor('#CC66FF')" height="10" width="10"></td> <td bgcolor="#CC99FF" onMouseOver="previewColor('#CC99FF')" onClick="selectColor('#CC99FF')" height="10" width="10"></td> <td bgcolor="#CCCCFF" onMouseOver="previewColor('#CCCCFF')" onClick="selectColor('#CCCCFF')" height="10" width="10"></td> <td bgcolor="#CCFFFF" onMouseOver="previewColor('#CCFFFF')" onClick="selectColor('#CCFFFF')" height="10" width="10"></td> <td bgcolor="#FF00FF" onMouseOver="previewColor('#FF00FF')" onClick="selectColor('#FF00FF')" height="10" width="10"></td> <td bgcolor="#FF33FF" onMouseOver="previewColor('#FF33FF')" onClick="selectColor('#FF33FF')" height="10" width="10"></td> <td bgcolor="#FF66FF" onMouseOver="previewColor('#FF66FF')" onClick="selectColor('#FF66FF')" height="10" width="10"></td> <td bgcolor="#FF99FF" onMouseOver="previewColor('#FF99FF')" onClick="selectColor('#FF99FF')" height="10" width="10"></td> <td bgcolor="#FFCCFF" onMouseOver="previewColor('#FFCCFF')" onClick="selectColor('#FFCCFF')" height="10" width="10"></td> <td bgcolor="#FFFFFF" onMouseOver="previewColor('#FFFFFF')" onClick="selectColor('#FFFFFF')" height="10" width="10"></td> </tr> </table> </center> </body> </html> |
Added modules/wysiwyg/wysiwyg.tcl.
> > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ### # Add hooks for openWYSIWYG ### package require httpd::doc ;# Httpd_Redirect Httpd_ReturnData set PWD [file dirname [file normalize [info script]]] Doc_AddRoot /wysiwyg/buttons $PWD/buttons Doc_AddRoot /wysiwyg/css $PWD/css Doc_AddRoot /wysiwyg/icons $PWD/icons Doc_AddRoot /wysiwyg/js $PWD/js Doc_AddRoot /wysiwyg/popups $PWD/popups package provide httpd::wysiwyg 0.1 |
Changes to sampleapp/snmp/snmp.tcl.
︙ | ︙ | |||
425 426 427 428 429 430 431 | append result "<tr><td colspan=5><input type=submit value=\"$submit\">" append result "</tr>\n" append result </form>\n } append result </table>\n } | < < | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | append result "<tr><td colspan=5><input type=submit value=\"$submit\">" append result "</tr>\n" append result </form>\n } append result </table>\n } proc Snmp_setMib {session mib} { upvar #0 Session:$session state foreach {num type value} [lindex [$state(snmp) get $mib] 0] {} set names [lindex [mib tc $mib] 3] if {[llength $names] >1} { append result "<select name=\"[mib name $mib]\">\n" foreach name $names { lassign $name choice index set s [expr {("$value" == "$choice") ? "SELECTED" : ""}] append result " <option value=$index$s>$choice\n" } append result "</select>" } else { append result "<input name=\"[mib name $mib]\" value=\"$value\">" } |
︙ | ︙ |
Changes to sampleapp/sunscript/htmlutils.tcl.
︙ | ︙ | |||
46 47 48 49 50 51 52 | proc Body {args} { global page set html "" if {[info exists page(head)]} { append html "[CloseTag]\n" ;# Should be HEAD } | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | proc Body {args} { global page set html "" if {[info exists page(head)]} { append html "[CloseTag]\n" ;# Should be HEAD } append html [OpenTag body {*}$args]\n return $html } # End # Close out all the open tags. Especially useful for # Tables that do not display at all if they are unclosed. |
︙ | ︙ |
Deleted tclhttpd.spec.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added tclhttpd.spec.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | %define contentdir /usr/tclhttpd Summary: Extensible Web+Application server written in Tcl. Name: tclhttpd Version: @PKG_MAJOR_VERSION@.@PKG_MINOR_VERSION@@PKG_PATCHLEVEL@ Release: @PKG_FEDORA_RELEASE@ Epoch: 0 License: BSD Group: System Environment/Daemons URL: http://core.tcl.tk/tclhttpd Source0: http://fossil.etoyoc.com/fossil/tclhttpd/tarball/tclhttpd-4.0.0.tar.gz?uuid=4_0 Patch0: tclhttpd_fedora.1.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: tcl tcllib expect BuildRequires: tcl-devel Prereq: /sbin/chkconfig, /usr/sbin/useradd %description TclHttpd is a Web server implemented in pure Tcl. It works out of the box as a Web server, but is really designed to be a Tcl application server. It supports HTML+Tcl templates, and is extensible in a variety of ways. %prep %setup -q -n %{name}%{version} %patch -p1 %build %configure --with-serverroot=%{contentdir} make %{?_smp_mflags} %install make install DESTDIR=$RPM_BUILD_ROOT install -p -D bin/redhat.init.tclhttpd $RPM_BUILD_ROOT/%{_sysconfdir}/init.d/tclhttpd mkdir -p $RPM_BUILD_ROOT/var/run/tclhttpd # Replace the numeric id in this configuration file with a name. We don't # know what numeric id it will end up with when it's created during # the rpm installation. sed -e 's/Config uid.*/Config uid tclhttpd/' -e 's/Config gid.*/Config gid tclhttpd/' < bin/tclhttpd.rc > $RPM_BUILD_ROOT/%{_prefix}/bin/tclhttpd.rc # This cgi is precompiled and has some old libc dependencies. I'm removing # it until I find out what it's used for. rm $RPM_BUILD_ROOT/%{contentdir}/htdocs/cgi-bin/env ln -s ./httpd.tcl $RPM_BUILD_ROOT/%{_prefix}/bin/tclhttpd %pre # Add the "tclhttpd" user %_sbindir/useradd -c "Tclhttpd" -s /sbin/nologin -r -d %{contentdir} tclhttpd 2> /dev/null || : %post if [ $1 -eq 1 ]; then /sbin/chkconfig --add tclhttpd # No need to run ldconfig because the shared objects are only # loaded by Tcl's package system, which doesn't require # anything in the ld cache. # /sbin/ldconfig fi %preun if [ $1 = 0 ]; then /sbin/service tclhttpd stop > /dev/null 2>&1 /sbin/chkconfig --del tclhttpd rm -f /var/run/tclhttpd/tclhttpd.pid fi %postun # No need to run ldconfig because the shared objects are only # loaded by Tcl's package system, which doesn't require # anything in the ld cache. # /sbin/ldconfig # Clean up a turd that is often left behind if [ $1 = 0 ]; then # uninstalling %_sbindir/userdel tclhttpd fi rm -f /tmp/tclhttpd.default %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,tclhttpd,tclhttpd) %{_libdir}/*.so %{_libdir}/crypt1.0 %{_libdir}/limit1.0 %{_libdir}/%{name}%{version} %{_bindir}/* %{_mandir}/man1/* %{contentdir} /var/run/tclhttpd %{_sysconfdir}/init.d/tclhttpd %changelog * Sat May 28 2015 <yoda at etoyoc.com> - 0:4.0.0.fdr.1 - Utilizes Tcl8.6. * Sun Oct 24 2004 <wart at kobold.org> - 0:3.5.1-0.fdr.4 - Change package group in the specfile. Add tcllib to dependency list. Remove tclhttpd user during uninstall. * Wed Oct 6 2004 <wart at kobold.org> - 0:3.5.1-0.fdr.3 - Fix bug in the /etc/init.d/tclhttpd startup script that was causing it to kill a random tclsh process during shutdown, and misreporting the status of tclhttpd. * Tue Sep 21 2004 <wart at kobold.org> - 0:3.5.1-0.fdr.2 - remove hardcoded path in the %build section of the rpm spec file. * Sun Sep 12 2004 <wart at kobold.org> - 0:3.5.1-0.fdr.1 - Initial rpm with a Fedora-compatible spec file. Included patch for better /etc/init.d script behaviour. |