debian/0000775000000000000000000000000012631464525007200 5ustar debian/logcheck.paranoid0000664000000000000000000000217712631352100012466 0ustar ntop[^:]*: Extending TCP hash ntop[^:]*: Extending hash: ntop[^:]*: Shrinking hash: ntop[^:]*: Shrinking TCP hash ntop[^:]*: readLsofInfo completed ntop[^:]*: Index error idx= ntop[^:]*: Cleaning up... ntop[^:]*: Waiting until threads terminate... ntop[^:]*: Terminating Web connections... ntop[^:]*: Freeing hash host instances... ntop[^:]*: .* instances freed ntop[^:]*: Unloading plugins \(if any\)... ntop[^:]*: Done. ntop[^:]*: Thanks for using ntop[^:]*: .* packets received by filter on ntop[^:]*: Freeing device ntop[^:]*: .* packets dropped by ntop[^:]*: Bye bye: I'm becoming a daemon... ntop[^:]*: ntop v.* MT ntop[^:]*: Listening on ntop[^:]*: Copyright .* by Luca Deri ntop[^:]*: Get the freshest ntop from http://www.ntop.org/ ntop[^:]*: Parsing ntop rules... ntop[^:]*: Loading plugins \(if any\)... ntop[^:]*: Searching plugins in /usr/lib/ntop/ntop/plugins ntop[^:]*: Welcome to ntop[^:]*: Resetting traffic statistics... ntop[^:]*: Started thread ntop[^:]*: Initializing ntop[^:]*: Waiting for HTTP connections on port ntop[^:]*: Sniffying... ntop[^:]*: Started thread ntop[^:]*: [[:space:]]*\*\*WARNING\*\* packet truncated debian/prng.h0000664000000000000000000000260112631352100010277 0ustar // Probabilistic Random Number Generators // Collected from various sources by Graham Cormode, 2000-2003 // #include #ifndef _PRNG #define MOD 2147483647 #define HL 31 extern long hash31(long long, long long, long long); extern long fourwise(long long, long long, long long, long long, long long); #define KK 17 #define NTAB 32 typedef struct prng_type{ int usenric; // which prng to use float scale; /* 2^(- integer size) */ long floatidum; long intidum; // needed to keep track of where we are in the // nric random number generators long iy; long iv[NTAB]; /* global variables */ unsigned long randbuffer[KK]; /* history buffer */ int r_p1, r_p2; /* indexes into history buffer */ int iset; double gset; } prng_type; #define _PRNG 1 #endif extern long prng_int(prng_type *); extern float prng_float(prng_type *); extern prng_type * prng_Init(long, int); extern void prng_Destroy(prng_type * prng); void prng_Reseed(prng_type *, long); //extern long double zipf(double, long) ; extern double fastzipf(double, long, double, prng_type *); extern double zeta(long, double); extern double prng_normal(prng_type * prng); extern double prng_stable(prng_type * prng, double); //extern double stable(double); // stable distributions //extern double stabledevd(float) ; //extern long double stabledevl(float) ; //extern double altstab(double); debian/compat0000664000000000000000000000000212631352100010357 0ustar 8 debian/rules0000775000000000000000000000510712631352100010244 0ustar #!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CPPFLAGS_MAINT_APPEND = -DMAKE_WITH_IGNORE_SIGPIPE override_dh_auto_configure: ./autogen.sh \ --prefix=/usr --bindir=/usr/sbin --libdir=/usr/lib/ntop \ --sysconfdir=/usr/share --localstatedir=/var/lib \ --without-ssl \ $(shell dpkg-buildflags --export=configure) override_dh_auto_install: dh_auto_install chmod -x $(CURDIR)/debian/tmp/usr/share/ntop/python/templates/rrdAlarmStart.tmpl find $(CURDIR)/debian/tmp/usr/share/ntop/html -type f -exec chmod -x '{}' \; mkdir -p $(CURDIR)/debian/tmp/etc/ntop cp debian/protocol.list $(CURDIR)/debian/tmp/etc/ntop gunzip $(CURDIR)/debian/tmp/usr/share/ntop/*.gz #logcheck mkdir -p $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.server mkdir -p $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.workstation mkdir -p $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.paranoid cp debian/logcheck $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.server/ntop cp debian/logcheck $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.workstation/ntop cp debian/logcheck.paranoid $(CURDIR)/debian/tmp/etc/logcheck/ignore.d.paranoid/ntop #logrotate mkdir -p $(CURDIR)/debian/tmp/etc/logrotate.d cp debian/logrotate $(CURDIR)/debian/tmp/etc/logrotate.d/ntop # remove development files find $(CURDIR)/debian/tmp/usr/lib -name "*.a" -exec rm '{}' \; find $(CURDIR)/debian/tmp/usr/lib -name "*.la" -exec rm '{}' \; find $(CURDIR)/debian/tmp/usr/lib -name "lib*Plugin*.so" -exec rm '{}' \; # link to GeoIP databases ln -s /usr/share/GeoIP/GeoLiteCity.dat $(CURDIR)/debian/tmp/usr/share/ntop/GeoLiteCity.dat ln -s /usr/share/GeoIP/GeoIPASNum.dat $(CURDIR)/debian/tmp/usr/share/ntop/GeoIPASNum.dat # avoid useless call to ldconfig for private libraries (see bug #205142) override_dh_makeshlibs: dh_makeshlibs -Xusr/lib/ntop override_dh_strip: dh_strip --dbg-package=ntop-dbg override_dh_auto_clean: dh_auto_clean ./autogen.sh -p || true rm -f etter.finger.os.gz \ oui.txt.gz \ specialMAC.txt.gz \ version.c \ faq.html \ html/faq.html rm -fr m4 debconf-updatepo %: dh $@ --with autotools_dev DEB_UPSTREAM_VERSION=$(shell dpkg-parsechangelog | sed -rne 's,^Version: ([0-9]+:)?([^+]+).*,\2,p') DEB_DFSG_VERSION=$(shell dpkg-parsechangelog | sed -rne 's,^Version: ([0-9]+:)?(.*\+dfsg[0-9]+).*,\2,p') NDPI_REV=$(shell dpkg-parsechangelog | sed -rne 's,^Version: ([0-9]+:)?[^+]+(\+ndpi([0-9]+))?\+dfsg.*,\2,p') get-orig-source: sh debian/get-orig-source.sh $(DEB_UPSTREAM_VERSION) $(DEB_DFSG_VERSION) $(NDPI_REV) debian/changelog0000664000000000000000000012217212631464520011052 0ustar ntop (3:5.0.1+dfsg1-2.2ubuntu1) xenial; urgency=medium * Merge from Debian unstable. Remaining changes: - debian/rules: Use dh_autotools-dev to update config.* for new ports. - debian/patches/kfreebsd-ftbfs.patch: Fix broken preprocessor ifdefs. -- Logan Rosen Tue, 08 Dec 2015 00:22:12 -0500 ntop (3:5.0.1+dfsg1-2.2) unstable; urgency=medium * Non-maintainer upload. * debian/control: fixed the build-dependency to librrd-dev (Closes: #801608). -- Giovani Augusto Ferreira Wed, 02 Dec 2015 01:59:31 -0200 ntop (3:5.0.1+dfsg1-2.1ubuntu2) wily; urgency=medium * Build-depend on librrd-dev instead of removed librrd2-dev. -- Logan Rosen Wed, 21 Oct 2015 01:05:11 -0400 ntop (3:5.0.1+dfsg1-2.1ubuntu1) vivid; urgency=low * Merge from Debian unstable. Remaining changes: - debian/rules: (Closes: #743134) + Use dh_autotools-dev to update config.* for new ports. - debian/patches/kfreebsd-ftbfs.patch: + Fix broken preprocessor ifdefs. -- Artur Rona Thu, 19 Feb 2015 19:48:56 +0100 ntop (3:5.0.1+dfsg1-2.1) unstable; urgency=medium * Non-maintainer upload. * Check for libtoolize rather than libtool. Closes: #761781 -- Johannes Schauer Tue, 07 Oct 2014 21:47:07 +0200 ntop (3:5.0.1+dfsg1-2ubuntu1) trusty; urgency=medium * debian/rules: use dh_autotools-dev to update config.* for new ports. * debian/patches/kfreebsd-ftbfs.patch: fix broken preprocessor ifdefs. -- Adam Conrad Sun, 30 Mar 2014 01:12:55 -0600 ntop (3:5.0.1+dfsg1-2) unstable; urgency=medium * Use system jquery js and css (Closes: #737444). * Include non-minimized source for jquery.jqplot.js (Closes: #737444). * Add versioncheck.patch to fix handling and documentation of --skip-version-check command line option (Closes: #737917). * Update Standards-Version to 3.9.5. -- Ludovico Cavedon Sat, 01 Mar 2014 01:05:28 -0800 ntop (3:5.0.1+dfsg1-1) unstable; urgency=low * Imported Upstream version 5.0.1+dfsg1 * Update copyright. * Update NEWS about this being the last release. * Make ndpi svn revsion optional in the package version string. * Remove patches merged upstream: - tcp-option-parsing.patch - l7_major_proto-fix.patch - install-jqplot.patch - remove-fragment-handling.patch * Refresh other pacthes. * Update debian/copyright, listing html/JSCookMenu.js correctly as MIT license (Closes: #696749). * Add dependency on python. * Update Japanese debconf translation (Closes: #715284). * Update Vcs fileds to canonical form. * Update Standards-Versions to 3.9.4. -- Ludovico Cavedon Thu, 12 Sep 2013 10:56:36 +0200 ntop (3:4.99.3+ndpi5517+dfsg3-1) unstable; urgency=high * Repackage source removing stale license notice from protocls.c (Closes: #695424). * Remove IP fragment handling code (Closes: #700442). * Disable OpenSSL (thanks to Giovanni Rapagnani, Closes: #695422). -- Ludovico Cavedon Thu, 28 Feb 2013 23:23:02 -0800 ntop (3:4.99.3+ndpi5517+dfsg2-1) unstable; urgency=medium * Repackage upstream source replacing non-DFSG countmin code with the GPL one (Closes: #692732). * Update Maintainer and Uploaders. -- Ludovico Cavedon Fri, 30 Nov 2012 00:07:10 -0800 ntop (3:4.99.3+ndpi5517+dfsg1-1) unstable; urgency=low * Imported Upstream version 4.99.3 and nDPI r5517. * get-orig-source.sh: incude nDPI in the orig tarball. * No longer suggest ntop-graphs and update NEWS about that. * Update copyright for the new jqPlot library. * Refresh patches. * Enable hardening flags. * Add install-jqplot.patch to install jqPlot. -- Ludovico Cavedon Wed, 27 Jun 2012 00:24:42 -0700 ntop (3:4.99.0-rc+ndpi5237+dfsg1-1) unstable; urgency=low * Imported Upstream version 4.99+rc and nDPI r5237. * Update Dutch debconf template transation by Jeroen Schot (Closes: #650750). * Update Galician debconf translation by Anxo Outeiral (Closes: #626699). * Add Polish debconf translation by Michał Kułach (Closes: #660884). * Remove non-free Highcharts JS API from upstream tarball, document it in debian/NEWS, and suggest ntop-graphs package. * Remove commands to stop ntop in prerm script, as they are already added by debhelper. * Use "none" as default interface if no previous configuration exist. * Remove check for existing interaces during config. * Fix init script failure in some cases (Closes: #649639). * Add build dependency on groff for documentation generation (Closes: #633956). * Update watch file for upstream "-rc" suffix. * Refresh patches. * Add do-not-require-svn.patch to remove unneeded dependecy on svn. * Update reduce-autogen-purged-files.patch so nDPI is not be removed on cleanup. * Removed no longer needed dependency on mochikit. * Update Standards-Version to 3.9.3. * Add separate package for debug symbols. * Update copyright for new upstream version. * Add l7_major_proto-fix.patch and tcp-option-parsing.patch to fix crashes. * Build-Depends on libpng-dev to allow linpng transitions (Closes: #662447). * Prevent the init script to exit with an error if one of the configured interaces is not available (Closes: #662212, LP: #402215). * Add /sbin path to invocation of start-stop-daemon (Closes: #350693). * Add status command to init script (Closes: #513779, LP: #323717). * Refresh & fix patches. * Add LSB description to init script. * Re-enable DNS resolution. * Suggest ntop-graphs. -- Ludovico Cavedon Mon, 19 Mar 2012 23:56:18 -0700 ntop (3:4.1.0+dfsg1-1) unstable; urgency=low * New upstream version (Closes: #520266, LP: #365145, LP: #777801). * Add kfreebsd-ftbfs.patch by Christoph Egger to fix FTBS under kFreeBSD (Closes: #636389). * Update Brazilian debconf messages translation by Eder L. Marques (Closes: #629113). * Update po files. -- Ludovico Cavedon Sat, 20 Aug 2011 20:14:58 -0700 ntop (3:4.0.3+dfsg1-4) unstable; urgency=low * Avoid adduser warnings during postinst (Closes: #338648). * Update Finnish debconf template transation by Esko Arajärvi (Closes: #614652). * Update Slovak debconf template translation by Slavko (Closes: #622109). * /etc/default/init: do dot reference debconf settings and add description for user editable variables (Closes: #498308). * Redirect output messages to syslog (Closes: #391366). * Create empty access.log in postinst (Closes: #602890). * Use lsb helper functions for output in init script. Let start-stop-daemon handle detection of running daemon. * Depend on libjpeg-dev instead of libjpeg62-dev (Closes: #635485). * Update Standards-Version to 3.9.2. -- Ludovico Cavedon Sun, 31 Jul 2011 21:39:04 -0700 ntop (3:4.0.3+dfsg1-3) unstable; urgency=low [ Ludovico Cavedon ] * Fix typo in debconf template. * Update po files. * Add/update debconf template transation: - Basque by Iñaki Larrañaga Murgoitio (Closes: #611164) - Danish by Joe Hansen (Closes: #611204) - Portuguese by Ricardo Silva (Closes: #611225) - Norwegian Nynorsk by Yngve Spjeld Landro - Swedish by Martin Bagge (Closes: #611186) - Slovak debconf template translation by Slavko (Closes: #611310) - Czech translation Miroslav Kure (Closes: #612635). - Italian. * Update hostaname-in-man-description.patch, being less vague about URL of ntop web interface (Closes: #466507). * Add netflow-plugin-links.patch: fix links in NetFlow plugin description (Closes: #530334). * Add ability to disable ntop from /etc/default/ntop (Closes: #531380). * Make sure the ntop group exists in the postinst (Closes: #613033). * Move adduser from Pre-depend to depend. [ Daniel Baumann ] * Adding French debconf translations from Steve Petruzzello (Closes: #611715). * Running debconf-update on po files. * Removing useless whitespaces from EOL and EOF. * Updating to debhelper version 8. * Adding updated German debconf translations from Helge Kreutzmann (Closes: #611986). * Adding updated Russian debconf translations from Yuri Kozlov (Closes: #611973). * Adding updated Spanish debconf translations from Ricardo Fraile (Closes: #611881). -- Ludovico Cavedon Mon, 14 Feb 2011 13:10:19 -0800 ntop (3:4.0.3+dfsg1-2) unstable; urgency=low [ Ludovico Cavedon ] * Rename maintainer scripts including the package name. * Remove misplaced ru.po file. * Add Vcs-* headers. * Do not call netstat, but read interface list from /proc (Closes: #607637). * Use "set -e" in maintainer scripts (see lintian warning maintainer-script-without-set-e). * Fix bug in check_interfaces() config function. * ntop.default: avoid prerm failure if package has never been fully configured. * Prevent config script failure if password is not asked (Closes: #607580). * Cleanup postrm script, thanks to J.M.Roth (Closes: #568626): - do not delete user (might be shared) - no need to remove /etc/ntop - wrap db_purge in a debconf availability check - re-indent * Add hostname-in-man-description.patch by A. Costa in order to add hostname:port in the description section of the man page (Closes: #466506). * Remove init.cfg from source package, as it is generated by postinst. * Handle interface "none", merged patch from Jason Healy (Closes: #520319). * Add dependency on net-tools, needed by the init script. * Make sure /var/log/ntop is not world readable and set group to adm. Thanks to J.M.Roth (Closes: #568641). * Set random password admin password if no password have ever been set and it is not possible to ask the user (LP: #355127). * Suggest geoip-database-contrib and add symlinks to its files. Explained in README.Debian. * Fix permissions in /var/lib/ntop (LP: #138682). Set sticky bit on /var/lib/ntop, so ntop user cannot change init.cfg, but can create subdirectories. * Disable DNS resolution as it makes ntop unstable. * Fix detection of not-active interfaces in ntop.init (LP: #231024). * Update po files. [ Jordan Metzmeier ] * Set password in postinst instead of config (Closes: #609070) * Add prompt to reset password if it is already set. * Update debconf template thanks to reviews by Christian Perrier and Justin B Rye. [ Daniel Baumann ] * Correct chown calls in ntop.postinst to not fail upon initial installation when the respective files are not yet present on the system. -- Ludovico Cavedon Tue, 25 Jan 2011 23:39:56 -0800 ntop (3:4.0.3+dfsg1-1) unstable; urgency=low [ Jordan Metzmeier ] * New upstream release (Closes: #522042) * Move data files to /usr/share/ntop (Closes: #595450). * Package architecture independent data in a separate ntop-data package. * Use debhelper 7. * Update Standards-Version to 3.9.1. * Depend on python-mako. * Do not include ntop.txt in binary packages as it is a copy of the man page. * Do not include NEWS, as it is outdated. * Switch to package source version 3.0 (quilt). * Add password creation to debconf * Changed init script to fix localization problems (thanks to Alejandro Varas , LP: #257466) * Remove manual update-rc.d calls from postrm and postinst. debhelper adds this for us. * Add pre-depends on adduser for postinst script. * Fix errors in the manpages: fix-manpage-errors.patch. * Added fixes for matching active interfaces. * Added a watch file. [ Ludovico Cavedon ] * Remove direct changes to upstream tree, and move them into specific patch files: - fix-manpage-errors.patch: fix typos in ntop.8. - dot-path.patch: fix path of /usr/bin/dot executable * Add patches: - reduce-autogen-purged-files.patch: prevent agutogen.sh from removing too many files during cleanup. - Add build-without-ntop-darwin.patch, to fix compilation without ntop_darwin.c. * No longer add faq.html, as it is not distributed in the upstream tarball. * Use ${source:Version} in control file. Have ntop-data recommend ntop. * Rename dirs to ntop.dirs and keep only empty directories that need to be created. * Remove var/lib from ntop.install file, as it is empty (keeping it in ntop.dirs). * Update po files. * Breaks and Replaces instead of Conflitcs for ntop-data. * Use a longer package description. * Remove useless configure options from debian/rules. * Move private shared libraries libraries in /usr/lib/ntop. * Add change-plugin-dir.patch for adjusting plugin directory. * Remove development files. * Use system library for MochiKit.js. * Rewrite DEP5 copyright file. * Repackage upstream tarball in order to remove non-DFSG-compliant code. Add get-orig-source.sh script and get-orig-source target in debian/rules. * Add explanation to README.Debian why geolocation is no longer working. * Add avoid-copy-maxmind-db.patch to prevent copying of Geo*.dat files. * Remove old unused patches. -- Ludovico Cavedon Wed, 15 Dec 2010 20:06:19 +0100 ntop (3:3.3-15) unstable; urgency=low * New maintainers (Closes: #586410). * Compile without SSL support, due to license issues (thanks to Alexander Reichle-Schmehl for the patch, Closes: #595446). -- Ludovico Cavedon Mon, 25 Oct 2010 16:45:31 -0700 ntop (3:3.3-14) unstable; urgency=low * Logcheck will now ignore packet truncated warnings. Closes: #585525. -- Ola Lundqvist Sat, 12 Jun 2010 12:55:26 +0200 ntop (3:3.3-13) unstable; urgency=high * Rebuilt to make sure that ntop libraries are referenced correctly. Closes: #549102. Ntop can not be installed when building. -- Ola Lundqvist Mon, 05 Oct 2009 21:18:50 +0200 ntop (3:3.3-12) unstable; urgency=low * Correction for CVE-2009-2732. Closes: #543312. * Brazilian translation added. Closes: #501754. * Russian translation added. Closes: #534779. * Added autogen.sh -p to the clean target to make sure that the build works fine. Closes: #527757. -- Ola Lundqvist Sun, 27 Sep 2009 09:20:27 +0200 ntop (3:3.3-11) unstable; urgency=low * Correction of Polish translation encoding, closes: #479490. Thanks to Christian Perrier for the help. -- Ola Lundqvist Sun, 15 Jun 2008 14:38:28 +0200 ntop (3:3.3-10) unstable; urgency=low * Added --disable-snmp to the autogen line in order to make sure that it builds properly even with libsnmp-dev installed. This is a workaround. The goal is to enable snmp support when this build problem has been fixed. Closes: #482764. Thanks to Sebastian Harl for the suggested fix. -- Ola Lundqvist Mon, 26 May 2008 20:40:46 +0200 ntop (3:3.3-9) unstable; urgency=low * Added Russian debconf translation, closes: #479780. Thanks to Yuri Kozlov . * Correction of pt.po file, closes: #479490. Thanks to Christian Perrier . * Added Czech debconf translation, closes: #480304. Thanks to Miroslav Kure . -- Ola Lundqvist Sun, 11 May 2008 14:24:57 +0200 ntop (3:3.3-8) unstable; urgency=low * Correction of language translation encodings, closes: #479225. Thanks to Christian Perrier for the fix. -- Ola Lundqvist Sat, 3 May 2008 21:36:37 +0200 ntop (3:3.3-7) unstable; urgency=low * Added [INTL:eu] ntop debconf templates Basque translation, closes: #478660. Thanks to Piarres Beobide for the translation. -- Ola Lundqvist Wed, 30 Apr 2008 18:10:57 +0200 ntop (3:3.3-6) unstable; urgency=low [Ola Lundqvist ] * Updated description of the package, closes: #466508. * Dot path corrected, closes: #449503. [Christian Perrier ] * Upload to fix pending l10n issues. * Fix typos and errors in the man page. Thanks to A. Costa for the patch. Closes: #466505 * Debconf translations: - Portuguese. Closes: #414836 - Finnish. Closes: #476981 - Galician. Closes: #476982 * [Lintian] Set debhelper compatibility level in debian/compat * [Lintian] No longer ignore errors by make in the clean target * [Lintian] Add copyright information to debian/copyright -- Ola Lundqvist Wed, 30 Apr 2008 07:55:38 +0200 ntop (3:3.3-5) unstable; urgency=low * Changed init script to use valid options. * Added export LANG=C as a workaround for #471862. Closes: #471862. -- Ola Lundqvist Tue, 25 Mar 2008 21:56:48 +0100 ntop (3:3.3-4) unstable; urgency=medium * Incorporated changes for #417013, similar to version 3:3.2-10.1 by Mario Iseli NMU. Closes: #417013. -- Ola Lundqvist Tue, 18 Mar 2008 21:06:55 +0100 ntop (3:3.3-3) unstable; urgency=low * Upload to unstable. Closes: #463984, #428276, #420633, #420633, #368680, #462406, #399581, #369554, #374703, #460225, #415035, #449505. -- Ola Lundqvist Tue, 18 Mar 2008 20:53:50 +0100 ntop (3:3.3-2) experimental; urgency=low * Added librrd2-dev to depends list, closes: #463984. -- Ola Lundqvist Mon, 4 Feb 2008 18:26:38 +0100 ntop (3:3.3-1) experimental; urgency=low * New upstream release, closes: #428276, #420633. Requires libpcap0.8-dev or later to build. This version have improved load and crash handling, closes: #420633, #368680, #462406. Updated rpath handling, closes: #399581. * Removed --skip-version-check from init script as that do not work in version 3.3. * Make sure that empty /usr/lib/plugins is not installed, closes: #369554. * Now ldconfig is run in postinst and postrm. * reload option now return error 3 to be LSB compliant, closes: #374703. * Added LSB dependency in init script, closes: #460225. Thanks to Petter Reinholdtsen for the fix. * Correction of bin/dot path, closes: #415035. * Suggests gsfonts package, closes: #449505. -- Ola Lundqvist Fri, 7 Dec 2007 07:30:02 +0100 ntop (3:3.2-11) experimental; urgency=low * Correction of bin/dot path, closes: #415035. -- Ola Lundqvist Tue, 27 Mar 2007 16:15:55 +0200 ntop (3:3.2-10.1) unstable; urgency=medium * Non-maintainer upload during BSP. * Only "source" /usr/share/debconf/confmodule in postrm if it's available to fix the purge procedure (Closes: #417013). -- Mario Iseli Fri, 18 May 2007 19:31:49 +0200 ntop (3:3.2-10) unstable; urgency=high * Added Japanese debconf templates translation from Kobayashi Noritada , closes: #413004. -- Ola Lundqvist Sun, 4 Mar 2007 09:41:19 +0100 ntop (3:3.2-9) unstable; urgency=medium * Correction of SIGSEGV problem with netflows on vlan interfaces, closes: #412568. -- Ola Lundqvist Mon, 26 Feb 2007 20:15:24 +0100 ntop (3:3.2-8) unstable; urgency=low * Added Spanish debconf translation from Rudy Godoy , closes: #404245. -- Ola Lundqvist Sat, 23 Dec 2006 21:09:16 +0100 ntop (3:3.2-7) unstable; urgency=low * Added a german translation, closes: #396105. Thanks to Helge Kreutzmann for the translation. -- Ola Lundqvist Mon, 30 Oct 2006 07:55:38 +0100 ntop (3:3.2-6) unstable; urgency=low * Added binary-indep target to debian/rules file, closes: #395721. * Updated to standards version 3.7.2. * Added build dependency on po-debconf. -- Ola Lundqvist Sat, 28 Oct 2006 10:07:10 +0200 ntop (3:3.2-5) unstable; urgency=low * Corrected so that sslv3 is enabled, thanks to Martin Hamrle , closes: #383246. * Now invoke-rc.d is used for all init.d calls, closes: #367764. * Added nl debconf translation, thanks to Esther Hanko , closes: #375083. * Added it debconf translation, thanks to Luca Monducci , closes: #366442. -- Ola Lundqvist Wed, 16 Aug 2006 07:35:58 +0200 ntop (3:3.2-4) unstable; urgency=low * Corrected logrotate line to use group adm instead of ntop, closes: #357559. * Suggests graphviz, closes: #360094. -- Ola Lundqvist Sat, 1 Apr 2006 12:34:09 +0200 ntop (3:3.2-3) unstable; urgency=low * Patch for log rotation, closes: #357559. Thanks to 'F.A.G. Luteijn' . -- Ola Lundqvist Sat, 18 Mar 2006 19:07:49 +0100 ntop (3:3.2-2) unstable; urgency=low * Applied patches from "Javier Fernandez-Sanguino Pena" with init script and config improvements, closes: #355756, #355760. -- Ola Lundqvist Sat, 11 Mar 2006 17:40:32 +0100 ntop (3:3.2-1) unstable; urgency=low * New upstream release. Closes: #307722. Lot of work has been made on memory management. The rest is probably nothing you can do something about, closes: #288006, #311129, #319516. * Added some language translations: - French by Sylvain Archenault , closes: #331455. - Swedish by Daniel Nylander , closes: #332965. - Czech by Miroslav Kure , closes: #333983. * Updated standards version to 3.6.2. * Now all config files are updateable (not in gz format), closes: #238500. -- Ola Lundqvist Sun, 23 Oct 2005 00:16:58 +0200 ntop (2:3.2rc1-3) unstable; urgency=low * Applied patch from Kurt Roeckx to make ntop build properly on some more architectures, closes: #332775. * Added /etc/ntop/protocol.list to the init script, closes: #332581. -- Ola Lundqvist Sat, 8 Oct 2005 19:05:18 +0200 ntop (2:3.2rc1-2) unstable; urgency=low * Changed build dependency from librrd0-dev to librrd2-dev, closes: #330517. * Updated init script for better log dir handling, closes: #312069. * Changed to new postal address for FSF in debian/copyright. * Added dependency on adduser as it use it in postinst script. * Fixed bashism in debian/config file. -- Ola Lundqvist Sun, 2 Oct 2005 21:51:44 +0200 ntop (2:3.2rc1-1) unstable; urgency=low * New upstream release, closes: #301698, #317237. * Added an alternative dependency on debconf-2.0. * Applied patch from Lucas Wall to make it use po debconf, closes: #295846. -- Ola Lundqvist Mon, 26 Sep 2005 22:21:54 +0200 ntop (2:3.0-5) unstable; urgency=low * Updated README.Debian file so users will understand what to do at install, closes: #291794, #287802. * Updated ntop init script to give better output. * Also changed log directory from /var/lib/ntop to /var/log/ntop, closes: #252352. * Quoted the interface list to allow whitespace, closes: #267248. * Added a couple of logcheck ignores, closes: #269321, #269319. -- Ola Lundqvist Sun, 30 Jan 2005 21:59:13 +0100 ntop (2:3.0-4) unstable; urgency=low * Fixed dependency problem with libgd2-xpm by build depending on libgd2-noxpm-dev instead, closes: #273870, #291701. -- Ola Lundqvist Mon, 4 Oct 2004 20:42:15 +0200 ntop (2:3.0-3) unstable; urgency=low * Fixed (now) broken build dependencies, closes: #264468. -- Ola Lundqvist Mon, 9 Aug 2004 13:05:57 +0200 ntop (2:3.0-2) unstable; urgency=low * Added --skip-version-check to default init script, closes: #252353. * Removed emacs variables from bottom of this changelog. * Updated standards version to 3.6.1. * Added not about how to set the admin password at installation to the README.Debian file, closes: #259727. * Removed read access from the /var/lib/ntop directory at upgrade. Closes: #261907. * Converted changelog to UTF-8. * Changed to DH_COMPAT=4 in rules file. * Fixed so that doc files is not executable. -- Ola Lundqvist Fri, 6 Aug 2004 21:37:54 +0200 ntop (2:3.0-1) unstable; urgency=low * New upstream version, closes: #221100. * This question has been removed in last upload, closes: #226920. -- Ola Lundqvist Mon, 17 May 2004 11:15:44 +0200 ntop (1:3.0rc1-1) unstable; urgency=low * New upstream release. * It is a lot more stable, closes: #136627, #160766, #163291, #168944, #123003, #230673. * New version of libtool in upstream assumed, closes: #201926. * Reguilding, closes: #216022. * Removed gdchart from the source. * Added --enable-i18n and --enable-sslv3 to configure line. * Changed so it ignores sigpipes, closes: #223034. * Removed most debconf questions, closes: #193306. * Moved debconf file to /var/lib/ntop * Updated README.Debian file. * Changed so that /var/lib/ntop and /var/log/ntop will be owned by the ntop user (in order to let it run as it should). * Removed automatic include of protocols.lst file. Defaults will be used instead. * No longer install files in /etc/ntop as executable, closes: #238500. * Now AS numbers is included in the package so it can be used for monitoring. -- Ola Lundqvist Fri, 19 Mar 2004 21:26:01 +0100 ntop (1:2.2c-1) unstable; urgency=low * New upstream version, closes: #214910. -- Ola Lundqvist Sat, 11 Oct 2003 12:27:56 +0200 ntop (2.2.0-6) unstable; urgency=low * Fixed getopt issue inspired by a patch from Javier Fernández-Sanguino Peña , closes: #212380. -- Ola Lundqvist Mon, 29 Sep 2003 19:07:46 +0200 ntop (2.2.0-5) unstable; urgency=low * Fixed SSL option, closes: #196747. * Rebuilt using other gdbm lib, closes: #196104. -- Ola Lundqvist Tue, 10 Jun 2003 20:18:58 +0200 ntop (2.2.0-4) unstable; urgency=low * Fixed build depends, closes: #194337, #194500. -- Ola Lundqvist Mon, 2 Jun 2003 15:26:09 +0200 ntop (2.2.0-3) unstable; urgency=low * New maintainer. * Fixed prerm script, closes: #190820, #161303. * Now fixes so that it do not require $SSLPORT, closes: #193266. -- Ola Lundqvist Thu, 22 May 2003 09:58:03 +0200 ntop (2.2.0-2) unstable; urgency=low * fixed logrotate script so we don't use reload -- Dennis Schoen Tue, 13 May 2003 09:36:21 +0200 ntop (2.2.0-1) unstable; urgency=low * new upstream version * supports rrdtool * build without intop - it's no longer supported * for a complete log of changes see /usr/share/doc/ntop/changelog.gz -- Dennis Schoen Tue, 15 Apr 2003 11:46:18 +0000 ntop (2.1.2-5) unstable; urgency=low * build without optimise CFLAGS :-( (Closes: #162160) -- Dennis Schoen Tue, 24 Sep 2002 13:53:52 +0200 ntop (2.1.2-4) unstable; urgency=low * build against libpng3 -- Dennis Schoen Fri, 20 Sep 2002 15:34:34 +0200 ntop (2.1.2-3) unstable; urgency=low * fix bug with config, where list of interfaces was not actually written to config file. (Closes: #160851) * updated Standards-Version * fixed bug with admins's reset and shutdown confirmation * build against correct libpng (Closes: #161630) -- Dennis Schoen Thu, 19 Sep 2002 12:11:56 +0200 ntop (2.1.2-2) unstable; urgency=low * build i386 without optimised CFLAGS (Closes: #159270) * updated Standards-Version * enlarged buffer of hostname variable (fixes HTML Rendering) * added fix that allows ntop to purge hosts without IP Address (MAC addresses only) -- Dennis Schoen Mon, 2 Sep 2002 13:47:09 +0200 ntop (2.1.2-1) unstable; urgency=low * build against new libpcap0.7 (Closes: #156177) * fixed build error with newer libtool versions * added checks for incomplete DNS results * fix case where a double HTTP header was send -- Dennis Schoen Mon, 26 Aug 2002 13:33:04 +0200 ntop (2.1.2-0) unstable; urgency=low * new upstream version -- Dennis Schoen Fri, 2 Aug 2002 08:59:51 +0200 ntop (2.1.0-3) unstable; urgency=low * fixed calls to autogen.sh -- Dennis Schoen Sat, 13 Jul 2002 14:50:58 +0200 ntop (2.1.0-2) unstable; urgency=low * aargh! fixed build depends on automake -- Dennis Schoen Fri, 12 Jul 2002 11:25:20 +0200 ntop (2.1.0-1) unstable; urgency=low * new upstream version * fixed build depends (depend on automake < 1.6) * this version should fix some of the memory usage problems. * initial admin password can now be specified (Closes: #146553) * removed ntop rules stuff which is no longer supported upstream * fixed typo in manpage. (Closes: #146445) * ntop now listens on 127.0.0.1:3000 per default (Closes: #146572) * trigger 404 error if we can't generate a page (Closes: #142970) * fixed URL encoding bug (Closes: #149102) * fixed "IP Subnet Traffic Matrix" (Closes: #140337) * compiled with mysql support -- Dennis Schoen Thu, 11 Jun 2002 14:01:21 +0200 ntop (2.0.0-15) unstable; urgency=low * removed some options from the protocols.list file because they're provide by ntop itself. * ntop will not start as a daemon when debconf is set to 'critical'. Changed the default to false. (Closes: #145516) -- Dennis Schoen Tue, 7 May 2002 16:54:03 +0200 ntop (2.0.0-14) unstable; urgency=low * split reload and restart in init.d script in different function blocks, reload won't restart ntop, if not already running. (Closes: #142372) -- Dennis Schoen Fri, 12 Apr 2002 11:38:47 +0200 ntop (2.0.0-13) unstable; urgency=low * mark /etc/logrotate.d/ntop as conffile * fixes ownership of /var/{lib/log}/ntop * removed config.status file from source * remove user only if we created him (Closes: #142342) -- Dennis Schoen Thu, 11 Apr 2002 15:04:29 +0200 ntop (2.0.0-12) unstable; urgency=low * Added -O option for log directory. * Added ignore files for logcheck so logcheck do not generate so much data in the sent mail. Ignoring uninteresting events. * Moved the default location for the access log to /var/log/ntop. * Added logrotate files for the logging. This means that statistics will be restarted every week. * all changes above made by Ola Lundqvist (Closes: #139386) * added ability to choose traceLevel (-t option) (Closes: #140920) -- Dennis Schoen Tue, 2 Apr 2002 17:02:57 +0200 ntop (2.0.0-11) unstable; urgency=low * fixed chown bug (Closes: #139326) -- Dennis Schoen Mon, 26 Mar 2002 15:26:25 +0100 ntop (2.0.0-10) unstable; urgency=low * fixed call to dh_installmanpages (Closes: #139283, #139295) -- Dennis Schoen Mon, 21 Mar 2002 10:30:07 +0100 ntop (2.0.0-9) unstable; urgency=low * fixed user delete stuff in postrm (Closes: #139128) * fixed permissions on /var/lib/ntop (Closes: #139136) -- Dennis Schoen Mon, 20 Mar 2002 10:02:22 +0100 ntop (2.0.0-8) unstable; urgency=low * fixed postrm stuff huge thanks to "Mark Robinson" for his help debugging this one. (Closes: #132532, #129688) -- Dennis Schoen Mon, 11 Mar 2002 13:31:12 +0100 ntop (2.0.0-7) unstable; urgency=low * init script can now be used to start ntop even if we decided not to start ntop on boot (Closes: #135960) -- Dennis Schoen Thu, 7 Mar 2002 10:26:28 +0100 ntop (2.0.0-6) unstable; urgency=low * fixed "tr" call in debconf config file thanks to Jean Charles Delepine (Closes: #137184) -- Dennis Schoen Thu, 7 Mar 2002 09:58:10 +0100 ntop (2.0.0-5) unstable; urgency=high * preserve local changes on /etc/ntop/init.cfg (Closes: #137068) -- Dennis Schoen Wed, 6 Mar 2002 13:23:48 +0100 ntop (2.0.0-4) unstable; urgency=high * fixes Remotely exploitable format string vulnerability in util.c -- Dennis Schoen Tue, 5 Mar 2002 10:06:24 +0100 ntop (2.0.0-3) unstable; urgency=low * added ntop-rules manpage (Closes: #133206) * implemented /etc/ntop/rules file (Closes: #133207) -- Dennis Schoen Fri, 22 Feb 2002 09:34:26 +0100 ntop (2.0.0-2.1) unstable; urgency=high * Non-maintainer upload * Fix RC bug to try to get ntop back into woody * Run 'make distclean' from debian/rules to clean up after the build (Closes: #133183) -- Matt Zimmerman Thu, 21 Feb 2002 23:34:40 -0500 ntop (2.0.0-2) unstable; urgency=low * updated config.{guess/sub} (Closes: #131059) -- Dennis Schoen Mon, 28 Jan 2002 14:19:49 +0100 ntop (2.0.0-1) unstable; urgency=low * modified init script to prevent zombie processes on restart * upgraded config.{guess/sub} (Closes: #103343) * added support for /etc/ntop/protocols.list Closes: #120819 * added ability to save state of hosts (Closes: #120821) * link gdchart library against debian libgd2-dev package * compiled gdchart library with "-fPIC" -> hopefully fixes build errors on hppa * fixed spelling error (Closes: #125192) * remove ntop user on purge (Closes: #120710) * declared datatype for "GDCPIE_other_threshold" in gdchart library as "signed char" to fix errors on systems where char is *not* signed per default (powerpc/s390/arm) * new upstream release -- Dennis Schoen Fri, 23 Nov 2001 10:37:56 +0100 ntop (2.0beta3-4) unstable; urgency=low * updated config.{guess/sub} in gdchart sub-directory Closes: #116158 -- Dennis Schoen Mon, 19 Nov 2001 14:38:40 +0100 ntop (2.0beta3-3) unstable; urgency=low * added Build-Depends on libwrap0-dev (Closes: #117604) -- Dennis Schoen Tue, 30 Oct 2001 10:04:32 +0100 ntop (2.0beta3-2) unstable; urgency=low * patched to use new config.guess & config.sub (Closes: #116158) * added Build-Depends on libtool (Closes: #116165) -- Dennis Schoen Fri, 19 Oct 2001 10:35:16 +0200 ntop (2.0beta3-1) unstable; urgency=low * CVS snapshot * Changed IP Protocols label to TCP/UDP Protocols where appropriated (Closes: #115348) * provides new command line interface intop. (Closes: #53744) * provides init script (Closes: #81085) * no longer uses javascript (Closes: #43382) * compiled with no optimization (Closes: #45831) -- Dennis Schoen Fri, 19 Oct 2001 10:35:06 +0200 ntop (1.3.1.cvs20001025-2) unstable; urgency=low * new maintainer upload * please see README.Debian for the future of ntop -- Dennis Schoen Wed, 26 Sep 2001 19:59:21 +0200 ntop (1.3.1.cvs20001025-1.1) unstable; urgency=low * Non-maintainer upload. * Run libtoolize to get support for new architectures. Closes: #103343 -- LaMont Jones Mon, 9 Jul 2001 21:39:34 -0600 ntop (1.3.1.cvs20001025-1) unstable; urgency=low * New upstream CVS snapshot * fixes local root compromise, previous versions (>=1.2a7-11) of the package are NOT affected by the bug * no declaration of inet_aton(), should build on archs regardless of pre- or post-2.1.94-1 glibc (glibc changed inet_aton inet -> in_addr_t) fixed upstream (Closes: #75461) -- Oliver M. Bolzer Sun, 29 Oct 2000 11:42:11 +0100 ntop (1.3.1.cvs20000929-1) unstable; urgency=low * new maintainer * new upstream from CVS * basically repackaged the whole thing due to upstream architecture changes * it is now possible to drop root privileges using -u and restrict access using /etc/hosts.{allow,deny}, ALWAYS DO THIS * clean target now removes config.cache and friends (Closes: #70543) * ntop databases are now put in /var/lib/ntop (Closes: #66767, #54508) -- Oliver M. Bolzer Mon, 4 Sep 2000 11:01:35 +0000 ntop (1.2a7-11) stable unstable; urgency=high * GRAVE security hole, install immediatly! * Ntop, when run in web mode, as root (this is typical use), can be remotely exploited to gain root access. Disabled web mode. Preinst now kills all ntop processes running in web mode. * This is also exploitable if ntop is made suid/sgid -- allows local users to obtain root. Ntop is not shipped this way, but suigregister could be used by the admin to make it suid. The preinst now removes all such bits, and suidregister can no longer control the program's permissions. Also added a README.Debian about this. * Reference: http://lwn.net/2000/0824/a/fb-ntop.php3 * Recommendation: Ntop currently has no maintainer in debian, and seems to be full of security holes. After a reasonable period to allow current installations to be updated to this version, it is my opinion it should be removed from unstable. * Closes: #69842. -- Joey Hess Mon, 4 Sep 2000 11:01:26 +0000 ntop (1.2a7-10) frozen unstable; urgency=HIGH * GRAVE security hole, install immediatly! * Ntop in web mode could be used to read any file on the system. Fixed by backporting fix from 1.2a10. Closes: #68418 * Also, the postinst detects upgrades from a version earlier than this, checks to see if ntop is running with -w as a parameter, and kills all such processes. -- Joey Hess Wed, 2 Aug 2000 11:33:16 -0700 ntop (1.2a7-9) unstable; urgency=low * Orphaned the package. -- Joey Hess Mon, 31 Jul 2000 17:35:28 -0700 ntop (1.2a7-8) unstable; urgency=low * Applied patch from Ricardo Kustner to fix image display problems. (Makes output 8-bit clean.) Closes: #60251, #58241 -- Joey Hess Mon, 3 Apr 2000 14:32:12 -0700 ntop (1.2a7-7) unstable; urgency=low * Updated config.* for the ARM port. Closes: #59052 * Added autoconf to build deps, and corrected ncurses-dev build dep. Closes: #58228 -- Joey Hess Thu, 2 Mar 2000 13:41:09 -0800 ntop (1.2a7-6) frozen unstable; urgency=HIGH * Fixed remote exploits. -- Joey Hess Sat, 12 Feb 2000 15:31:00 -0800 ntop (1.2a7-5) unstable; urgency=low * Modified to build using libwrap, Closes: #53518 -- Joey Hess Tue, 4 Jan 2000 15:41:07 -0800 ntop (1.2a7-4) unstable; urgency=low * Build-depends on queso and lsof so it will configure to use them. Closes: #53127 -- Joey Hess Mon, 20 Dec 1999 12:18:52 -0800 ntop (1.2a7-3) unstable; urgency=low * Fixed plugins. -- Joey Hess Fri, 17 Dec 1999 10:21:20 -0800 ntop (1.2a7-2) unstable; urgency=low * Build deps. -- Joey Hess Sat, 4 Dec 1999 14:21:12 -0800 ntop (1.2a7-1) unstable; urgency=low * New upstream version. * Closes: #48202, which has been fixed already. -- Joey Hess Mon, 22 Nov 1999 13:01:44 -0800 ntop (1.2a5-5) unstable; urgency=low * Check local directory last for static html, so it doesn't load up the wrong thing by accident. -- Joey Hess Tue, 16 Nov 1999 13:50:35 -0800 ntop (1.2a5-4) unstable; urgency=low * Fixed half of #48202 by fixing the broken gif problem again. -- Joey Hess Sat, 13 Nov 1999 20:18:57 -0800 ntop (1.2a5-3) unstable; urgency=low * Corrected mkdir build problem. Closes: #46664 -- Joey Hess Tue, 5 Oct 1999 12:38:37 -0700 ntop (1.2a5-2) unstable; urgency=low * Removed install-stamp, which can cause problems. -- Joey Hess Thu, 30 Sep 1999 13:15:06 -0700 ntop (1.2a5-1) unstable; urgency=low * New upstream release. -- Joey Hess Fri, 10 Sep 1999 20:45:36 -0700 ntop (1.2a4-4) unstable; urgency=low * FHS -- Joey Hess Mon, 6 Sep 1999 14:53:55 -0700 ntop (1.2a4-3) unstable; urgency=low * Hm, it looks like a rm -f ... #* ... was commenting out the part of the Makefile that was supposed to delete config.cache. Fixed that. -- Joey Hess Sat, 28 Aug 1999 00:09:30 -0700 ntop (1.2a4-2) unstable; urgency=low * A config.cache in the sources was causing problems to porters. Since it's in the upstream source, I cannot remove it from the package. But I _can_ force make distclean to be called by the build target, and now I do. Closes: #43434 * Also hard-wired in the location of lsof and queso in debian/rules. -- Joey Hess Fri, 27 Aug 1999 21:52:09 -0700 ntop (1.2a4-1) unstable; urgency=low * New upstream release that fixes Domain Stats segfault, Closes: #43101. * Depends on queso, Closes: #43099. * Fixed broken gif problem by editing http.c to look in /usr/doc/ntop/html for html stuff. -- Joey Hess Tue, 17 Aug 1999 10:49:04 -0700 ntop (1.2a2-2) unstable; urgency=low * Use Apps/Net, not Network. (Closes: #42246, #42257) -- Joey Hess Mon, 2 Aug 1999 10:42:05 -0700 ntop (1.2a2-1) unstable; urgency=low * First release now that the license is cleared up. -- Joey Hess Fri, 16 Jul 1999 09:33:12 -0700 debian/ntop-data.install0000664000000000000000000000001712631352100012436 0ustar usr/share/ntop debian/ntop.install0000664000000000000000000000007412631352100011532 0ustar usr/sbin/ntop usr/lib etc/ntop etc/logcheck etc/logrotate.d debian/extra-source/0000775000000000000000000000000012631352110011603 5ustar debian/extra-source/jquery.jqplot.js0000664000000000000000000154477212631352100015013 0ustar /** * Title: jqPlot Charts * * Pure JavaScript plotting plugin for jQuery. * * About: Version * * 1.0.0b2_r1012 * * About: Copyright & License * * Copyright (c) 2009-2011 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT and GPL version 2.0 licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * See and contained within this distribution for further information. * * The author would appreciate an email letting him know of any substantial * use of jqPlot. You can reach the author at: chris at jqplot dot com * or see http://www.jqplot.com/info.php. This is, of course, not required. * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php. * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * * * About: Introduction * * jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.2 is included in the distribution. * To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and optionally * the excanvas script for IE support in your web page: * * > * > * > * > * * jqPlot can be customized by overriding the defaults of any of the objects which make * up the plot. The general usage of jqplot is: * * > chart = $.jqplot('targetElemId', [dataArray,...], {optionsObject}); * * The options available to jqplot are detailed in in the jqPlotOptions.txt file. * * An actual call to $.jqplot() may look like the * examples below: * * > chart = $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]); * * or * * > dataArray = [34,12,43,55,77]; * > chart = $.jqplot('targetElemId', [dataArray, ...], {title:'My Plot', axes:{yaxis:{min:20, max:100}}}); * * For more inforrmation, see . * * About: Usage * * See * * About: Available Options * * See for a list of options available thorugh the options object (not complete yet!) * * About: Options Usage * * See * * About: Changes * * See * */ (function($) { // make sure undefined is undefined var undefined; $.fn.emptyForce = function() { for ( var i = 0, elem; (elem = $(this)[i]) != null; i++ ) { // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( elem.getElementsByTagName("*") ); } // Remove any remaining nodes if ($.jqplot_use_excanvas) { elem.outerHTML = ""; } else { while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } } elem = null; } return $(this); }; $.fn.removeChildForce = function(parent) { while ( parent.firstChild ) { this.removeChildForce( parent.firstChild ); parent.removeChild( parent.firstChild ); } }; /** * Namespace: $.jqplot * jQuery function called by the user to create a plot. * * Parameters: * target - ID of target element to render the plot into. * data - an array of data series. * options - user defined options object. See the individual classes for available options. * * Properties: * config - object to hold configuration information for jqPlot plot object. * * attributes: * enablePlugins - False to disable plugins by default. Plugins must then be explicitly * enabled in the individual plot options. Default: false. * This property sets the "show" property of certain plugins to true or false. * Only plugins that can be immediately active upon loading are affected. This includes * non-renderer plugins like cursor, dragable, highlighter, and trendline. * defaultHeight - Default height for plots where no css height specification exists. This * is a jqplot wide default. * defaultWidth - Default height for plots where no css height specification exists. This * is a jqplot wide default. */ $.jqplot = function(target, data, options) { var _data, _options; if (options == null) { if (jQuery.isArray(data)) { _data = data; _options = null; } else if (typeof(data) === 'object') { _data = null; _options = data; } } else { _data = data; _options = options; } var plot = new jqPlot(); // remove any error class that may be stuck on target. $('#'+target).removeClass('jqplot-error'); if ($.jqplot.config.catchErrors) { try { plot.init(target, _data, _options); plot.draw(); plot.themeEngine.init.call(plot); return plot; } catch(e) { var msg = $.jqplot.config.errorMessage || e.message; $('#'+target).append('
'+msg+'
'); $('#'+target).addClass('jqplot-error'); document.getElementById(target).style.background = $.jqplot.config.errorBackground; document.getElementById(target).style.border = $.jqplot.config.errorBorder; document.getElementById(target).style.fontFamily = $.jqplot.config.errorFontFamily; document.getElementById(target).style.fontSize = $.jqplot.config.errorFontSize; document.getElementById(target).style.fontStyle = $.jqplot.config.errorFontStyle; document.getElementById(target).style.fontWeight = $.jqplot.config.errorFontWeight; } } else { plot.init(target, _data, _options); plot.draw(); plot.themeEngine.init.call(plot); return plot; } }; $.jqplot.version = "1.0.0b2_r1012"; // canvas manager to reuse canvases on the plot. // Should help solve problem of canvases not being freed and // problem of waiting forever for firefox to decide to free memory. $.jqplot.CanvasManager = function() { // canvases are managed globally so that they can be reused // across plots after they have been freed if (typeof $.jqplot.CanvasManager.canvases == 'undefined') { $.jqplot.CanvasManager.canvases = []; $.jqplot.CanvasManager.free = []; } var myCanvases = []; this.getCanvas = function() { var canvas; var makeNew = true; if (!$.jqplot.use_excanvas) { for (var i = 0, l = $.jqplot.CanvasManager.canvases.length; i < l; i++) { if ($.jqplot.CanvasManager.free[i] === true) { makeNew = false; canvas = $.jqplot.CanvasManager.canvases[i]; // $(canvas).removeClass('jqplot-canvasManager-free').addClass('jqplot-canvasManager-inuse'); $.jqplot.CanvasManager.free[i] = false; myCanvases.push(i); break; } } } if (makeNew) { canvas = document.createElement('canvas'); myCanvases.push($.jqplot.CanvasManager.canvases.length); $.jqplot.CanvasManager.canvases.push(canvas); $.jqplot.CanvasManager.free.push(false); } return canvas; }; // this method has to be used after settings the dimesions // on the element returned by getCanvas() this.initCanvas = function(canvas) { if ($.jqplot.use_excanvas) { return window.G_vmlCanvasManager.initElement(canvas); } return canvas; }; this.freeAllCanvases = function() { for (var i = 0, l=myCanvases.length; i < l; i++) { this.freeCanvas(myCanvases[i]); } myCanvases = []; }; this.freeCanvas = function(idx) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { // excanvas can't be reused, but properly unset window.G_vmlCanvasManager.uninitElement($.jqplot.CanvasManager.canvases[idx]); $.jqplot.CanvasManager.canvases[idx] = null; } else { var canvas = $.jqplot.CanvasManager.canvases[idx]; canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); $(canvas).unbind().removeAttr('class').removeAttr('style'); // Style attributes seemed to be still hanging around. wierd. Some ticks // still retained a left: 0px attribute after reusing a canvas. $(canvas).css({left: '', top: '', position: ''}); // setting size to 0 may save memory of unused canvases? canvas.width = 0; canvas.height = 0; $.jqplot.CanvasManager.free[idx] = true; } }; }; // Convienence function that won't hang IE or FF without FireBug. $.jqplot.log = function() { if (window.console) { window.console.log.apply(window.console, arguments); } }; $.jqplot.config = { addDomReference: false, enablePlugins:false, defaultHeight:300, defaultWidth:400, UTCAdjust:false, timezoneOffset: new Date(new Date().getTimezoneOffset() * 60000), errorMessage: '', errorBackground: '', errorBorder: '', errorFontFamily: '', errorFontSize: '', errorFontStyle: '', errorFontWeight: '', catchErrors: false, defaultTickFormatString: "%.1f", defaultColors: [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], defaultNegativeColors: [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"], dashLength: 4, gapLength: 4, dotGapLength: 2.5, srcLocation: 'jqplot/src/', pluginLocation: 'jqplot/src/plugins/' }; $.jqplot.arrayMax = function( array ){ return Math.max.apply( Math, array ); }; $.jqplot.arrayMin = function( array ){ return Math.min.apply( Math, array ); }; $.jqplot.enablePlugins = $.jqplot.config.enablePlugins; // canvas related tests taken from modernizer: // Copyright (c) 2009 - 2010 Faruk Ates. // http://www.modernizr.com $.jqplot.support_canvas = function() { if (typeof $.jqplot.support_canvas.result == 'undefined') { $.jqplot.support_canvas.result = !!document.createElement('canvas').getContext; } return $.jqplot.support_canvas.result; }; $.jqplot.support_canvas_text = function() { if (typeof $.jqplot.support_canvas_text.result == 'undefined') { if (window.G_vmlCanvasManager !== undefined && window.G_vmlCanvasManager._version > 887) { $.jqplot.support_canvas_text.result = true; } else { $.jqplot.support_canvas_text.result = !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); } } return $.jqplot.support_canvas_text.result; }; $.jqplot.use_excanvas = ($.browser.msie && !$.jqplot.support_canvas()) ? true : false; /** * * Hooks: jqPlot Pugin Hooks * * $.jqplot.preInitHooks - called before initialization. * $.jqplot.postInitHooks - called after initialization. * $.jqplot.preParseOptionsHooks - called before user options are parsed. * $.jqplot.postParseOptionsHooks - called after user options are parsed. * $.jqplot.preDrawHooks - called before plot draw. * $.jqplot.postDrawHooks - called after plot draw. * $.jqplot.preDrawSeriesHooks - called before each series is drawn. * $.jqplot.postDrawSeriesHooks - called after each series is drawn. * $.jqplot.preDrawLegendHooks - called before the legend is drawn. * $.jqplot.addLegendRowHooks - called at the end of legend draw, so plugins * can add rows to the legend table. * $.jqplot.preSeriesInitHooks - called before series is initialized. * $.jqplot.postSeriesInitHooks - called after series is initialized. * $.jqplot.preParseSeriesOptionsHooks - called before series related options * are parsed. * $.jqplot.postParseSeriesOptionsHooks - called after series related options * are parsed. * $.jqplot.eventListenerHooks - called at the end of plot drawing, binds * listeners to the event canvas which lays on top of the grid area. * $.jqplot.preDrawSeriesShadowHooks - called before series shadows are drawn. * $.jqplot.postDrawSeriesShadowHooks - called after series shadows are drawn. * */ $.jqplot.preInitHooks = []; $.jqplot.postInitHooks = []; $.jqplot.preParseOptionsHooks = []; $.jqplot.postParseOptionsHooks = []; $.jqplot.preDrawHooks = []; $.jqplot.postDrawHooks = []; $.jqplot.preDrawSeriesHooks = []; $.jqplot.postDrawSeriesHooks = []; $.jqplot.preDrawLegendHooks = []; $.jqplot.addLegendRowHooks = []; $.jqplot.preSeriesInitHooks = []; $.jqplot.postSeriesInitHooks = []; $.jqplot.preParseSeriesOptionsHooks = []; $.jqplot.postParseSeriesOptionsHooks = []; $.jqplot.eventListenerHooks = []; $.jqplot.preDrawSeriesShadowHooks = []; $.jqplot.postDrawSeriesShadowHooks = []; // A superclass holding some common properties and methods. $.jqplot.ElemContainer = function() { this._elem; this._plotWidth; this._plotHeight; this._plotDimensions = {height:null, width:null}; }; $.jqplot.ElemContainer.prototype.createElement = function(el, offsets, clss, cssopts, attrib) { this._offsets = offsets; var klass = clss || 'jqplot'; var elem = document.createElement(el); this._elem = $(elem); this._elem.addClass(klass); this._elem.css(cssopts); this._elem.attr(attrib); // avoid memory leak; elem = null; return this._elem; }; $.jqplot.ElemContainer.prototype.getWidth = function() { if (this._elem) { return this._elem.outerWidth(true); } else { return null; } }; $.jqplot.ElemContainer.prototype.getHeight = function() { if (this._elem) { return this._elem.outerHeight(true); } else { return null; } }; $.jqplot.ElemContainer.prototype.getPosition = function() { if (this._elem) { return this._elem.position(); } else { return {top:null, left:null, bottom:null, right:null}; } }; $.jqplot.ElemContainer.prototype.getTop = function() { return this.getPosition().top; }; $.jqplot.ElemContainer.prototype.getLeft = function() { return this.getPosition().left; }; $.jqplot.ElemContainer.prototype.getBottom = function() { return this._elem.css('bottom'); }; $.jqplot.ElemContainer.prototype.getRight = function() { return this._elem.css('right'); }; /** * Class: Axis * An individual axis object. Cannot be instantiated directly, but created * by the Plot oject. Axis properties can be set or overriden by the * options passed in from the user. * */ function Axis(name) { $.jqplot.ElemContainer.call(this); // Group: Properties // // Axes options are specified within an axes object at the top level of the // plot options like so: // > { // > axes: { // > xaxis: {min: 5}, // > yaxis: {min: 2, max: 8, numberTicks:4}, // > x2axis: {pad: 1.5}, // > y2axis: {ticks:[22, 44, 66, 88]} // > } // > } // There are 2 x axes, 'xaxis' and 'x2axis', and // 9 yaxes, 'yaxis', 'y2axis'. 'y3axis', ... Any or all of which may be specified. this.name = name; this._series = []; // prop: show // Wether to display the axis on the graph. this.show = false; // prop: tickRenderer // A class of a rendering engine for creating the ticks labels displayed on the plot, // See <$.jqplot.AxisTickRenderer>. this.tickRenderer = $.jqplot.AxisTickRenderer; // prop: tickOptions // Options that will be passed to the tickRenderer, see <$.jqplot.AxisTickRenderer> options. this.tickOptions = {}; // prop: labelRenderer // A class of a rendering engine for creating an axis label. this.labelRenderer = $.jqplot.AxisLabelRenderer; // prop: labelOptions // Options passed to the label renderer. this.labelOptions = {}; // prop: label // Label for the axis this.label = null; // prop: showLabel // true to show the axis label. this.showLabel = true; // prop: min // minimum value of the axis (in data units, not pixels). this.min = null; // prop: max // maximum value of the axis (in data units, not pixels). this.max = null; // prop: autoscale // DEPRECATED // the default scaling algorithm produces superior results. this.autoscale = false; // prop: pad // Padding to extend the range above and below the data bounds. // The data range is multiplied by this factor to determine minimum and maximum axis bounds. // A value of 0 will be interpreted to mean no padding, and pad will be set to 1.0. this.pad = 1.2; // prop: padMax // Padding to extend the range above data bounds. // The top of the data range is multiplied by this factor to determine maximum axis bounds. // A value of 0 will be interpreted to mean no padding, and padMax will be set to 1.0. this.padMax = null; // prop: padMin // Padding to extend the range below data bounds. // The bottom of the data range is multiplied by this factor to determine minimum axis bounds. // A value of 0 will be interpreted to mean no padding, and padMin will be set to 1.0. this.padMin = null; // prop: ticks // 1D [val, val, ...] or 2D [[val, label], [val, label], ...] array of ticks for the axis. // If no label is specified, the value is formatted into an appropriate label. this.ticks = []; // prop: numberTicks // Desired number of ticks. Default is to compute automatically. this.numberTicks; // prop: tickInterval // number of units between ticks. Mutually exclusive with numberTicks. this.tickInterval; // prop: renderer // A class of a rendering engine that handles tick generation, // scaling input data to pixel grid units and drawing the axis element. this.renderer = $.jqplot.LinearAxisRenderer; // prop: rendererOptions // renderer specific options. See <$.jqplot.LinearAxisRenderer> for options. this.rendererOptions = {}; // prop: showTicks // Wether to show the ticks (both marks and labels) or not. // Will not override showMark and showLabel options if specified on the ticks themselves. this.showTicks = true; // prop: showTickMarks // Wether to show the tick marks (line crossing grid) or not. // Overridden by showTicks and showMark option of tick itself. this.showTickMarks = true; // prop: showMinorTicks // Wether or not to show minor ticks. This is renderer dependent. this.showMinorTicks = true; // prop: drawMajorGridlines // True to draw gridlines for major axis ticks. this.drawMajorGridlines = true; // prop: drawMinorGridlines // True to draw gridlines for minor ticks. this.drawMinorGridlines = false; // prop: drawMajorTickMarks // True to draw tick marks for major axis ticks. this.drawMajorTickMarks = true; // prop: drawMinorTickMarks // True to draw tick marks for minor ticks. This is renderer dependent. this.drawMinorTickMarks = true; // prop: useSeriesColor // Use the color of the first series associated with this axis for the // tick marks and line bordering this axis. this.useSeriesColor = false; // prop: borderWidth // width of line stroked at the border of the axis. Defaults // to the width of the grid boarder. this.borderWidth = null; // prop: borderColor // color of the border adjacent to the axis. Defaults to grid border color. this.borderColor = null; // minimum and maximum values on the axis. this._dataBounds = {min:null, max:null}; // statistics (min, max, mean) as well as actual data intervals for each series attached to axis. // holds collection of {intervals:[], min:, max:, mean: } objects for each series on axis. this._intervalStats = []; // pixel position from the top left of the min value and max value on the axis. this._offsets = {min:null, max:null}; this._ticks=[]; this._label = null; // prop: syncTicks // true to try and synchronize tick spacing across multiple axes so that ticks and // grid lines line up. This has an impact on autoscaling algorithm, however. // In general, autoscaling an individual axis will work better if it does not // have to sync ticks. this.syncTicks = null; // prop: tickSpacing // Approximate pixel spacing between ticks on graph. Used during autoscaling. // This number will be an upper bound, actual spacing will be less. this.tickSpacing = 75; // Properties to hold the original values for min, max, ticks, tickInterval and numberTicks // so they can be restored if altered by plugins. this._min = null; this._max = null; this._tickInterval = null; this._numberTicks = null; this.__ticks = null; // hold original user options. this._options = {}; } Axis.prototype = new $.jqplot.ElemContainer(); Axis.prototype.constructor = Axis; Axis.prototype.init = function() { this.renderer = new this.renderer(); // set the axis name this.tickOptions.axis = this.name; // if showMark or showLabel tick options not specified, use value of axis option. // showTicks overrides showTickMarks. if (this.tickOptions.showMark == null) { this.tickOptions.showMark = this.showTicks; } if (this.tickOptions.showMark == null) { this.tickOptions.showMark = this.showTickMarks; } if (this.tickOptions.showLabel == null) { this.tickOptions.showLabel = this.showTicks; } if (this.label == null || this.label == '') { this.showLabel = false; } else { this.labelOptions.label = this.label; } if (this.showLabel == false) { this.labelOptions.show = false; } // set the default padMax, padMin if not specified // special check, if no padding desired, padding // should be set to 1.0 if (this.pad == 0) { this.pad = 1.0; } if (this.padMax == 0) { this.padMax = 1.0; } if (this.padMin == 0) { this.padMin = 1.0; } if (this.padMax == null) { this.padMax = (this.pad-1)/2 + 1; } if (this.padMin == null) { this.padMin = (this.pad-1)/2 + 1; } // now that padMin and padMax are correctly set, reset pad in case user has supplied // padMin and/or padMax this.pad = this.padMax + this.padMin - 1; if (this.min != null || this.max != null) { this.autoscale = false; } // if not set, sync ticks for y axes but not x by default. if (this.syncTicks == null && this.name.indexOf('y') > -1) { this.syncTicks = true; } else if (this.syncTicks == null){ this.syncTicks = false; } this.renderer.init.call(this, this.rendererOptions); }; Axis.prototype.draw = function(ctx, plot) { // Memory Leaks patch if (this.__ticks) { this.__ticks = null; } return this.renderer.draw.call(this, ctx, plot); }; Axis.prototype.set = function() { this.renderer.set.call(this); }; Axis.prototype.pack = function(pos, offsets) { if (this.show) { this.renderer.pack.call(this, pos, offsets); } // these properties should all be available now. if (this._min == null) { this._min = this.min; this._max = this.max; this._tickInterval = this.tickInterval; this._numberTicks = this.numberTicks; this.__ticks = this._ticks; } }; // reset the axis back to original values if it has been scaled, zoomed, etc. Axis.prototype.reset = function() { this.renderer.reset.call(this); }; Axis.prototype.resetScale = function(opts) { $.extend(true, this, {min: null, max: null, numberTicks: null, tickInterval: null, _ticks: [], ticks: []}, opts); this.resetDataBounds(); }; Axis.prototype.resetDataBounds = function() { // Go through all the series attached to this axis and find // the min/max bounds for this axis. var db = this._dataBounds; db.min = null; db.max = null; var l, s, d; // check for when to force min 0 on bar series plots. var doforce = (this.show) ? true : false; for (var i=0; i db.max) || db.max == null) { db.max = d[j][0]; } } else { if ((d[j][minyidx] != null && d[j][minyidx] < db.min) || db.min == null) { db.min = d[j][minyidx]; } if ((d[j][maxyidx] != null && d[j][maxyidx] > db.max) || db.max == null) { db.max = d[j][maxyidx]; } } } // Hack to not pad out bottom of bar plots unless user has specified a padding. // every series will have a chance to set doforce to false. once it is set to // false, it cannot be reset to true. // If any series attached to axis is not a bar, wont force 0. if (doforce && s.renderer.constructor !== $.jqplot.BarRenderer) { doforce = false; } else if (doforce && this._options.hasOwnProperty('forceTickAt0') && this._options.forceTickAt0 == false) { doforce = false; } else if (doforce && s.renderer.constructor === $.jqplot.BarRenderer) { if (s.barDirection == 'vertical' && this.name != 'xaxis' && this.name != 'x2axis') { if (this._options.pad != null || this._options.padMin != null) { doforce = false; } } else if (s.barDirection == 'horizontal' && (this.name == 'xaxis' || this.name == 'x2axis')) { if (this._options.pad != null || this._options.padMin != null) { doforce = false; } } } } } if (doforce && this.renderer.constructor === $.jqplot.LinearAxisRenderer && db.min >= 0) { this.padMin = 1.0; this.forceTickAt0 = true; } }; /** * Class: Legend * Legend object. Cannot be instantiated directly, but created * by the Plot oject. Legend properties can be set or overriden by the * options passed in from the user. */ function Legend(options) { $.jqplot.ElemContainer.call(this); // Group: Properties // prop: show // Wether to display the legend on the graph. this.show = false; // prop: location // Placement of the legend. one of the compass directions: nw, n, ne, e, se, s, sw, w this.location = 'ne'; // prop: labels // Array of labels to use. By default the renderer will look for labels on the series. // Labels specified in this array will override labels specified on the series. this.labels = []; // prop: showLabels // true to show the label text on the legend. this.showLabels = true; // prop: showSwatch // true to show the color swatches on the legend. this.showSwatches = true; // prop: placement // "insideGrid" places legend inside the grid area of the plot. // "outsideGrid" places the legend outside the grid but inside the plot container, // shrinking the grid to accomodate the legend. // "inside" synonym for "insideGrid", // "outside" places the legend ouside the grid area, but does not shrink the grid which // can cause the legend to overflow the plot container. this.placement = "insideGrid"; // prop: xoffset // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. // properties or via CSS margin styling of the .jqplot-table-legend class. this.xoffset = 0; // prop: yoffset // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. // properties or via CSS margin styling of the .jqplot-table-legend class. this.yoffset = 0; // prop: border // css spec for the border around the legend box. this.border; // prop: background // css spec for the background of the legend box. this.background; // prop: textColor // css color spec for the legend text. this.textColor; // prop: fontFamily // css font-family spec for the legend text. this.fontFamily; // prop: fontSize // css font-size spec for the legend text. this.fontSize ; // prop: rowSpacing // css padding-top spec for the rows in the legend. this.rowSpacing = '0.5em'; // renderer // A class that will create a DOM object for the legend, // see <$.jqplot.TableLegendRenderer>. this.renderer = $.jqplot.TableLegendRenderer; // prop: rendererOptions // renderer specific options passed to the renderer. this.rendererOptions = {}; // prop: predraw // Wether to draw the legend before the series or not. // Used with series specific legend renderers for pie, donut, mekko charts, etc. this.preDraw = false; // prop: marginTop // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginTop = null; // prop: marginRight // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginRight = null; // prop: marginBottom // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginBottom = null; // prop: marginLeft // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginLeft = null; // prop: escapeHtml // True to escape special characters with their html entity equivalents // in legend text. "<" becomes < and so on, so html tags are not rendered. this.escapeHtml = false; this._series = []; $.extend(true, this, options); } Legend.prototype = new $.jqplot.ElemContainer(); Legend.prototype.constructor = Legend; Legend.prototype.setOptions = function(options) { $.extend(true, this, options); // Try to emulate deprecated behaviour // if user has specified xoffset or yoffset, copy these to // the margin properties. if (this.placement == 'inside') { this.placement = 'insideGrid'; } if (this.xoffset >0) { if (this.placement == 'insideGrid') { switch (this.location) { case 'nw': case 'w': case 'sw': if (this.marginLeft == null) { this.marginLeft = this.xoffset + 'px'; } this.marginRight = '0px'; break; case 'ne': case 'e': case 'se': default: if (this.marginRight == null) { this.marginRight = this.xoffset + 'px'; } this.marginLeft = '0px'; break; } } else if (this.placement == 'outside') { switch (this.location) { case 'nw': case 'w': case 'sw': if (this.marginRight == null) { this.marginRight = this.xoffset + 'px'; } this.marginLeft = '0px'; break; case 'ne': case 'e': case 'se': default: if (this.marginLeft == null) { this.marginLeft = this.xoffset + 'px'; } this.marginRight = '0px'; break; } } this.xoffset = 0; } if (this.yoffset >0) { if (this.placement == 'outside') { switch (this.location) { case 'sw': case 's': case 'se': if (this.marginTop == null) { this.marginTop = this.yoffset + 'px'; } this.marginBottom = '0px'; break; case 'ne': case 'n': case 'nw': default: if (this.marginBottom == null) { this.marginBottom = this.yoffset + 'px'; } this.marginTop = '0px'; break; } } else if (this.placement == 'insideGrid') { switch (this.location) { case 'sw': case 's': case 'se': if (this.marginBottom == null) { this.marginBottom = this.yoffset + 'px'; } this.marginTop = '0px'; break; case 'ne': case 'n': case 'nw': default: if (this.marginTop == null) { this.marginTop = this.yoffset + 'px'; } this.marginBottom = '0px'; break; } } this.yoffset = 0; } // TO-DO: // Handle case where offsets are < 0. // }; Legend.prototype.init = function() { this.renderer = new this.renderer(); this.renderer.init.call(this, this.rendererOptions); }; Legend.prototype.draw = function(offsets) { for (var i=0; i<$.jqplot.preDrawLegendHooks.length; i++){ $.jqplot.preDrawLegendHooks[i].call(this, offsets); } return this.renderer.draw.call(this, offsets); }; Legend.prototype.pack = function(offsets) { this.renderer.pack.call(this, offsets); }; /** * Class: Title * Plot Title object. Cannot be instantiated directly, but created * by the Plot oject. Title properties can be set or overriden by the * options passed in from the user. * * Parameters: * text - text of the title. */ function Title(text) { $.jqplot.ElemContainer.call(this); // Group: Properties // prop: text // text of the title; this.text = text; // prop: show // wether or not to show the title this.show = true; // prop: fontFamily // css font-family spec for the text. this.fontFamily; // prop: fontSize // css font-size spec for the text. this.fontSize ; // prop: textAlign // css text-align spec for the text. this.textAlign; // prop: textColor // css color spec for the text. this.textColor; // prop: renderer // A class for creating a DOM element for the title, // see <$.jqplot.DivTitleRenderer>. this.renderer = $.jqplot.DivTitleRenderer; // prop: rendererOptions // renderer specific options passed to the renderer. this.rendererOptions = {}; // prop: escapeHtml // True to escape special characters with their html entity equivalents // in title text. "<" becomes < and so on, so html tags are not rendered. this.escapeHtml = false; } Title.prototype = new $.jqplot.ElemContainer(); Title.prototype.constructor = Title; Title.prototype.init = function() { this.renderer = new this.renderer(); this.renderer.init.call(this, this.rendererOptions); }; Title.prototype.draw = function(width) { return this.renderer.draw.call(this, width); }; Title.prototype.pack = function() { this.renderer.pack.call(this); }; /** * Class: Series * An individual data series object. Cannot be instantiated directly, but created * by the Plot oject. Series properties can be set or overriden by the * options passed in from the user. */ function Series() { $.jqplot.ElemContainer.call(this); // Group: Properties // Properties will be assigned from a series array at the top level of the // options. If you had two series and wanted to change the color and line // width of the first and set the second to use the secondary y axis with // no shadow and supply custom labels for each: // > { // > series:[ // > {color: '#ff4466', lineWidth: 5, label:'good line'}, // > {yaxis: 'y2axis', shadow: false, label:'bad line'} // > ] // > } // prop: show // wether or not to draw the series. this.show = true; // prop: xaxis // which x axis to use with this series, either 'xaxis' or 'x2axis'. this.xaxis = 'xaxis'; this._xaxis; // prop: yaxis // which y axis to use with this series, either 'yaxis' or 'y2axis'. this.yaxis = 'yaxis'; this._yaxis; this.gridBorderWidth = 2.0; // prop: renderer // A class of a renderer which will draw the series, // see <$.jqplot.LineRenderer>. this.renderer = $.jqplot.LineRenderer; // prop: rendererOptions // Options to pass on to the renderer. this.rendererOptions = {}; this.data = []; this.gridData = []; // prop: label // Line label to use in the legend. this.label = ''; // prop: showLabel // true to show label for this series in the legend. this.showLabel = true; // prop: color // css color spec for the series this.color; // prop: negativeColor // css color spec used for filled (area) plots that are filled to zero and // the "useNegativeColors" option is true. this.negativeColor; // prop: lineWidth // width of the line in pixels. May have different meanings depending on renderer. this.lineWidth = 2.5; // prop: lineJoin // Canvas lineJoin style between segments of series. this.lineJoin = 'round'; // prop: lineCap // Canvas lineCap style at ends of line. this.lineCap = 'round'; // prop: linePattern // line pattern 'dashed', 'dotted', 'solid', some combination // of '-' and '.' characters such as '.-.' or a numerical array like // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, // [1, 10, 20, 10] to draw a dot-dash line, and so on. this.linePattern = 'solid'; this.shadow = true; // prop: shadowAngle // Shadow angle in degrees this.shadowAngle = 45; // prop: shadowOffset // Shadow offset from line in pixels this.shadowOffset = 1.25; // prop: shadowDepth // Number of times shadow is stroked, each stroke offset shadowOffset from the last. this.shadowDepth = 3; // prop: shadowAlpha // Alpha channel transparency of shadow. 0 = transparent. this.shadowAlpha = '0.1'; // prop: breakOnNull // Wether line segments should be be broken at null value. // False will join point on either side of line. this.breakOnNull = false; // prop: markerRenderer // A class of a renderer which will draw marker (e.g. circle, square, ...) at the data points, // see <$.jqplot.MarkerRenderer>. this.markerRenderer = $.jqplot.MarkerRenderer; // prop: markerOptions // renderer specific options to pass to the markerRenderer, // see <$.jqplot.MarkerRenderer>. this.markerOptions = {}; // prop: showLine // wether to actually draw the line or not. Series will still be renderered, even if no line is drawn. this.showLine = true; // prop: showMarker // wether or not to show the markers at the data points. this.showMarker = true; // prop: index // 0 based index of this series in the plot series array. this.index; // prop: fill // true or false, wether to fill under lines or in bars. // May not be implemented in all renderers. this.fill = false; // prop: fillColor // CSS color spec to use for fill under line. Defaults to line color. this.fillColor; // prop: fillAlpha // Alpha transparency to apply to the fill under the line. // Use this to adjust alpha separate from fill color. this.fillAlpha; // prop: fillAndStroke // If true will stroke the line (with color this.color) as well as fill under it. // Applies only when fill is true. this.fillAndStroke = false; // prop: disableStack // true to not stack this series with other series in the plot. // To render properly, non-stacked series must come after any stacked series // in the plot's data series array. So, the plot's data series array would look like: // > [stackedSeries1, stackedSeries2, ..., nonStackedSeries1, nonStackedSeries2, ...] // disableStack will put a gap in the stacking order of series, and subsequent // stacked series will not fill down through the non-stacked series and will // most likely not stack properly on top of the non-stacked series. this.disableStack = false; // _stack is set by the Plot if the plot is a stacked chart. // will stack lines or bars on top of one another to build a "mountain" style chart. // May not be implemented in all renderers. this._stack = false; // prop: neighborThreshold // how close or far (in pixels) the cursor must be from a point marker to detect the point. this.neighborThreshold = 4; // prop: fillToZero // true will force bar and filled series to fill toward zero on the fill Axis. this.fillToZero = false; // prop: fillToValue // fill a filled series to this value on the fill axis. // Works in conjunction with fillToZero, so that must be true. this.fillToValue = 0; // prop: fillAxis // Either 'x' or 'y'. Which axis to fill the line toward if fillToZero is true. // 'y' means fill up/down to 0 on the y axis for this series. this.fillAxis = 'y'; // prop: useNegativeColors // true to color negative values differently in filled and bar charts. this.useNegativeColors = true; this._stackData = []; // _plotData accounts for stacking. If plots not stacked, _plotData and data are same. If // stacked, _plotData is accumulation of stacking data. this._plotData = []; // _plotValues hold the individual x and y values that will be plotted for this series. this._plotValues = {x:[], y:[]}; // statistics about the intervals between data points. Used for auto scaling. this._intervals = {x:{}, y:{}}; // data from the previous series, for stacked charts. this._prevPlotData = []; this._prevGridData = []; this._stackAxis = 'y'; this._primaryAxis = '_xaxis'; // give each series a canvas to draw on. This should allow for redrawing speedups. this.canvas = new $.jqplot.GenericCanvas(); this.shadowCanvas = new $.jqplot.GenericCanvas(); this.plugins = {}; // sum of y values in this series. this._sumy = 0; this._sumx = 0; this._type = ''; } Series.prototype = new $.jqplot.ElemContainer(); Series.prototype.constructor = Series; Series.prototype.init = function(index, gridbw, plot) { // weed out any null values in the data. this.index = index; this.gridBorderWidth = gridbw; var d = this.data; var temp = [], i; for (i=0; i. this.renderer = $.jqplot.CanvasGridRenderer; // prop: rendererOptions // Options to pass on to the renderer, // see <$.jqplot.CanvasGridRenderer>. this.rendererOptions = {}; this._offsets = {top:null, bottom:null, left:null, right:null}; } Grid.prototype = new $.jqplot.ElemContainer(); Grid.prototype.constructor = Grid; Grid.prototype.init = function() { this.renderer = new this.renderer(); this.renderer.init.call(this, this.rendererOptions); }; Grid.prototype.createElement = function(offsets,plot) { this._offsets = offsets; return this.renderer.createElement.call(this, plot); }; Grid.prototype.draw = function() { this.renderer.draw.call(this); }; $.jqplot.GenericCanvas = function() { $.jqplot.ElemContainer.call(this); this._ctx; }; $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer(); $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas; $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions, plot) { this._offsets = offsets; var klass = 'jqplot'; if (clss != undefined) { klass = clss; } var elem; elem = plot.canvasManager.getCanvas(); // if new plotDimensions supplied, use them. if (plotDimensions != null) { this._plotDimensions = plotDimensions; } elem.width = this._plotDimensions.width - this._offsets.left - this._offsets.right; elem.height = this._plotDimensions.height - this._offsets.top - this._offsets.bottom; this._elem = $(elem); this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top }); this._elem.addClass(klass); elem = plot.canvasManager.initCanvas(elem); elem = null; return this._elem; }; $.jqplot.GenericCanvas.prototype.setContext = function() { this._ctx = this._elem.get(0).getContext("2d"); return this._ctx; }; // Memory Leaks patch $.jqplot.GenericCanvas.prototype.resetCanvas = function() { if (this._elem) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); } //this._elem.remove(); this._elem.emptyForce(); } this._ctx = null; }; $.jqplot.HooksManager = function () { this.hooks =[]; this.args = []; }; $.jqplot.HooksManager.prototype.addOnce = function(fn, args) { args = args || []; var havehook = false; for (var i=0, l=this.hooks.length; i { // > axesDefaults:{min:0}, // > series:[{color:'#6633dd'}], // > title: 'A Plot' // > } // // prop: animate // True to animate the series on initial plot draw (renderer dependent). // Actual animation functionality must be supported in the renderer. this.animate = false; // prop: animateReplot // True to animate series after a call to the replot() method. // Use with caution! Replots can happen very frequently under // certain circumstances (e.g. resizing, dragging points) and // animation in these situations can cause problems. this.animateReplot = false; // prop: axes // up to 4 axes are supported, each with it's own options, // See for axis specific options. this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis'), yMidAxis: new Axis('yMidAxis')}; this.baseCanvas = new $.jqplot.GenericCanvas(); // true to intercept right click events and fire a 'jqplotRightClick' event. // this will also block the context menu. this.captureRightClick = false; // prop: data // user's data. Data should *NOT* be specified in the options object, // but be passed in as the second argument to the $.jqplot() function. // The data property is described here soley for reference. // The data should be in the form of an array of 2D or 1D arrays like // > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ]. this.data = []; // prop: dataRenderer // A callable which can be used to preprocess data passed into the plot. // Will be called with 2 arguments, the plot data and a reference to the plot. this.dataRenderer; // prop: dataRendererOptions // Options that will be passed to the dataRenderer. // Can be of any type. this.dataRendererOptions; this.defaults = { // prop: axesDefaults // default options that will be applied to all axes. // see for axes options. axesDefaults: {}, axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}, yMidAxis:{}}, // prop: seriesDefaults // default options that will be applied to all series. // see for series options. seriesDefaults: {}, series:[] }; // prop: defaultAxisStart // 1-D data series are internally converted into 2-D [x,y] data point arrays // by jqPlot. This is the default starting value for the missing x or y value. // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...]) // starting at this value. this.defaultAxisStart = 1; // this.doCustomEventBinding = true; // prop: drawIfHidden // True to execute the draw method even if the plot target is hidden. // Generally, this should be false. Most plot elements will not be sized/ // positioned correclty if renderered into a hidden container. To render into // a hidden container, call the replot method when the container is shown. this.drawIfHidden = false; this.eventCanvas = new $.jqplot.GenericCanvas(); // prop: fillBetween // Fill between 2 line series in a plot. // Options object: // { // series1: first index (0 based) of series in fill // series2: second index (0 based) of series in fill // color: color of fill [default fillColor of series1] // baseSeries: fill will be drawn below this series (0 based index) // fill: false to turn off fill [default true]. // } this.fillBetween = { series1: null, series2: null, color: null, baseSeries: 0, fill: true }; // prop; fontFamily // css spec for the font-family attribute. Default for the entire plot. this.fontFamily; // prop: fontSize // css spec for the font-size attribute. Default for the entire plot. this.fontSize; // prop: grid // See for grid specific options. this.grid = new Grid(); // prop: legend // see <$.jqplot.TableLegendRenderer> this.legend = new Legend(); // prop: noDataIndicator // Options to set up a mock plot with a data loading indicator if no data is specified. this.negativeSeriesColors = $.jqplot.config.defaultNegativeColors; this.noDataIndicator = { show: false, indicator: 'Loading Data...', axes: { xaxis: { min: 0, max: 10, tickInterval: 2, show: true }, yaxis: { min: 0, max: 12, tickInterval: 3, show: true } } }; // container to hold all of the merged options. Convienence for plugins. this.options = {}; this.previousSeriesStack = []; // Namespece to hold plugins. Generally non-renderer plugins add themselves to here. this.plugins = {}; // prop: series // Array of series object options. // see for series specific options. this.series = []; // array of series indicies. Keep track of order // which series canvases are displayed, lowest // to highest, back to front. this.seriesStack = []; // prop: seriesColors // Ann array of CSS color specifications that will be applied, in order, // to the series in the plot. Colors will wrap around so, if their // are more series than colors, colors will be reused starting at the // beginning. For pie charts, this specifies the colors of the slices. this.seriesColors = $.jqplot.config.defaultColors; // prop: sortData // false to not sort the data passed in by the user. // Many bar, stakced and other graphs as well as many plugins depend on // having sorted data. this.sortData = true; // prop: stackSeries // true or false, creates a stack or "mountain" plot. // Not all series renderers may implement this option. this.stackSeries = false; // a shortcut for axis syncTicks options. Not implemented yet. this.syncXTicks = true; // a shortcut for axis syncTicks options. Not implemented yet. this.syncYTicks = true; // the jquery object for the dom target. this.target = null; // The id of the dom element to render the plot into this.targetId = null; // prop textColor // css spec for the css color attribute. Default for the entire plot. this.textColor; // prop: title // Title object. See for specific options. As a shortcut, you // can specify the title option as just a string like: title: 'My Plot' // and this will create a new title object with the specified text. this.title = new Title(); // Count how many times the draw method has been called while the plot is visible. // Mostly used to test if plot has never been dran (=0), has been successfully drawn // into a visible container once (=1) or draw more than once into a visible container. // Can use this in tests to see if plot has been visibly drawn at least one time. // After plot has been visibly drawn once, it generally doesn't need redrawn if its // container is hidden and shown. this._drawCount = 0; // sum of y values for all series in plot. // used in mekko chart. this._sumy = 0; this._sumx = 0; // array to hold the cumulative stacked series data. // used to ajust the individual series data, which won't have access to other // series data. this._stackData = []; // array that holds the data to be plotted. This will be the series data // merged with the the appropriate data from _stackData according to the stackAxis. this._plotData = []; this._width = null; this._height = null; this._plotDimensions = {height:null, width:null}; this._gridPadding = {top:null, right:null, bottom:null, left:null}; this._defaultGridPadding = {top:10, right:10, bottom:23, left:10}; this._addDomReference = $.jqplot.config.addDomReference; this.preInitHooks = new $.jqplot.HooksManager(); this.postInitHooks = new $.jqplot.HooksManager(); this.preParseOptionsHooks = new $.jqplot.HooksManager(); this.postParseOptionsHooks = new $.jqplot.HooksManager(); this.preDrawHooks = new $.jqplot.HooksManager(); this.postDrawHooks = new $.jqplot.HooksManager(); this.preDrawSeriesHooks = new $.jqplot.HooksManager(); this.postDrawSeriesHooks = new $.jqplot.HooksManager(); this.preDrawLegendHooks = new $.jqplot.HooksManager(); this.addLegendRowHooks = new $.jqplot.HooksManager(); this.preSeriesInitHooks = new $.jqplot.HooksManager(); this.postSeriesInitHooks = new $.jqplot.HooksManager(); this.preParseSeriesOptionsHooks = new $.jqplot.HooksManager(); this.postParseSeriesOptionsHooks = new $.jqplot.HooksManager(); this.eventListenerHooks = new $.jqplot.EventListenerManager(); this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager(); this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager(); this.colorGenerator = new $.jqplot.ColorGenerator(); this.negativeColorGenerator = new $.jqplot.ColorGenerator(); this.canvasManager = new $.jqplot.CanvasManager(); this.themeEngine = new $.jqplot.ThemeEngine(); var seriesColorsIndex = 0; // Group: methods // // method: init // sets the plot target, checks data and applies user // options to plot. this.init = function(target, data, options) { options = options || {}; for (var i=0; i<$.jqplot.preInitHooks.length; i++) { $.jqplot.preInitHooks[i].call(this, target, data, options); } for (var i=0; i<this.preInitHooks.hooks.length; i++) { this.preInitHooks.hooks[i].call(this, target, data, options); } this.targetId = '#'+target; this.target = $('#'+target); ////// // Add a reference to plot ////// if (this._addDomReference) { this.target.data('jqplot_plot', this); } // remove any error class that may be stuck on target. this.target.removeClass('jqplot-error'); if (!this.target.get(0)) { throw "No plot target specified"; } // make sure the target is positioned by some means and set css if (this.target.css('position') == 'static') { this.target.css('position', 'relative'); } if (!this.target.hasClass('jqplot-target')) { this.target.addClass('jqplot-target'); } // if no height or width specified, use a default. if (!this.target.height()) { var h; if (options && options.height) { h = parseInt(options.height, 10); } else if (this.target.attr('data-height')) { h = parseInt(this.target.attr('data-height'), 10); } else { h = parseInt($.jqplot.config.defaultHeight, 10); } this._height = h; this.target.css('height', h+'px'); } else { this._height = h = this.target.height(); } if (!this.target.width()) { var w; if (options && options.width) { w = parseInt(options.width, 10); } else if (this.target.attr('data-width')) { w = parseInt(this.target.attr('data-width'), 10); } else { w = parseInt($.jqplot.config.defaultWidth, 10); } this._width = w; this.target.css('width', w+'px'); } else { this._width = w = this.target.width(); } this._plotDimensions.height = this._height; this._plotDimensions.width = this._width; this.grid._plotDimensions = this._plotDimensions; this.title._plotDimensions = this._plotDimensions; this.baseCanvas._plotDimensions = this._plotDimensions; this.eventCanvas._plotDimensions = this._plotDimensions; this.legend._plotDimensions = this._plotDimensions; if (this._height <=0 || this._width <=0 || !this._height || !this._width) { throw "Canvas dimension not set"; } if (options.dataRenderer && jQuery.isFunction(options.dataRenderer)) { if (options.dataRendererOptions) { this.dataRendererOptions = options.dataRendererOptions; } this.dataRenderer = options.dataRenderer; data = this.dataRenderer(data, this, this.dataRendererOptions); } if (options.noDataIndicator && jQuery.isPlainObject(options.noDataIndicator)) { $.extend(true, this.noDataIndicator, options.noDataIndicator); } if (data == null || jQuery.isArray(data) == false || data.length == 0 || jQuery.isArray(data[0]) == false || data[0].length == 0) { if (this.noDataIndicator.show == false) { throw{ name: "DataError", message: "No data to plot." }; } else { // have to be descructive here in order for plot to not try and render series. // This means that $.jqplot() will have to be called again when there is data. //delete options.series; for (var ax in this.noDataIndicator.axes) { for (var prop in this.noDataIndicator.axes[ax]) { this.axes[ax][prop] = this.noDataIndicator.axes[ax][prop]; } } this.postDrawHooks.add(function() { var eh = this.eventCanvas.getHeight(); var ew = this.eventCanvas.getWidth(); var temp = $('<div class="jqplot-noData-container" style="position:absolute;"></div>'); this.target.append(temp); temp.height(eh); temp.width(ew); temp.css('top', this.eventCanvas._offsets.top); temp.css('left', this.eventCanvas._offsets.left); var temp2 = $('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>'); temp.append(temp2); temp2.html(this.noDataIndicator.indicator); var th = temp2.height(); var tw = temp2.width(); temp2.height(th); temp2.width(tw); temp2.css('top', (eh - th)/2 + 'px'); }); } } this.data = data; this.parseOptions(options); if (this.textColor) { this.target.css('color', this.textColor); } if (this.fontFamily) { this.target.css('font-family', this.fontFamily); } if (this.fontSize) { this.target.css('font-size', this.fontSize); } this.title.init(); this.legend.init(); this._sumy = 0; this._sumx = 0; for (var i=0; i<this.series.length; i++) { // set default stacking order for series canvases this.seriesStack.push(i); this.previousSeriesStack.push(i); this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; this.series[i].canvas._plotDimensions = this._plotDimensions; for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { this.preSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); } this.populatePlotData(this.series[i], i); this.series[i]._plotDimensions = this._plotDimensions; this.series[i].init(i, this.grid.borderWidth, this); for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { this.postSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); } this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } var name; for (var i=0; i<12; i++) { name = _axisNames[i]; this.axes[name]._plotDimensions = this._plotDimensions; this.axes[name].init(); if (this.axes[name].borderColor == null) { if (name.charAt(0) !== 'x' && this.axes[name].useSeriesColor === true && this.axes[name].show) { this.axes[name].borderColor = this.axes[name]._series[0].color; } else { this.axes[name].borderColor = this.grid.borderColor; } } } if (this.sortData) { sortData(this.series); } this.grid.init(); this.grid._axes = this.axes; this.legend._series = this.series; for (var i=0; i<$.jqplot.postInitHooks.length; i++) { $.jqplot.postInitHooks[i].call(this, target, data, options); } for (var i=0; i<this.postInitHooks.hooks.length; i++) { this.postInitHooks.hooks[i].call(this, target, data, options); } }; // method: resetAxesScale // Reset the specified axes min, max, numberTicks and tickInterval properties to null // or reset these properties on all axes if no list of axes is provided. // // Parameters: // axes - Boolean to reset or not reset all axes or an array or object of axis names to reset. this.resetAxesScale = function(axes, options) { var opts = options || {}; var ax = axes || this.axes; if (ax === true) { ax = this.axes; } if (jQuery.isArray(ax)) { for (var i = 0; i < ax.length; i++) { this.axes[ax[i]].resetScale(opts[ax[i]]); } } else if (typeof(ax) === 'object') { for (var name in ax) { this.axes[name].resetScale(opts[name]); } } }; // method: reInitialize // reinitialize plot for replotting. // not called directly. this.reInitialize = function () { // Plot should be visible and have a height and width. // If plot doesn't have height and width for some // reason, set it by other means. Plot must not have // a display:none attribute, however. this._height = this.target.height(); this._width = this.target.width(); if (this._height <=0 || this._width <=0 || !this._height || !this._width) { throw "Target dimension not set"; } this._plotDimensions.height = this._height; this._plotDimensions.width = this._width; this.grid._plotDimensions = this._plotDimensions; this.title._plotDimensions = this._plotDimensions; this.baseCanvas._plotDimensions = this._plotDimensions; this.eventCanvas._plotDimensions = this._plotDimensions; this.legend._plotDimensions = this._plotDimensions; for (var n in this.axes) { this.axes[n]._plotWidth = this._width; this.axes[n]._plotHeight = this._height; } this.title._plotWidth = this._width; if (this.textColor) { this.target.css('color', this.textColor); } if (this.fontFamily) { this.target.css('font-family', this.fontFamily); } if (this.fontSize) { this.target.css('font-size', this.fontSize); } this._sumy = 0; this._sumx = 0; for (var i=0; i<this.series.length; i++) { this.populatePlotData(this.series[i], i); if (this.series[i]._type === 'line' && this.series[i].renderer.bands.show) { this.series[i].renderer.initBands.call(this.series[i], this.series[i].renderer.options, this); } this.series[i]._plotDimensions = this._plotDimensions; this.series[i].canvas._plotDimensions = this._plotDimensions; //this.series[i].init(i, this.grid.borderWidth); this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } var name; for (var j=0; j<12; j++) { name = _axisNames[j]; // Memory Leaks patch : clear ticks elements var t = this.axes[name]._ticks; for (var i = 0; i < t.length; i++) { var el = t[i]._elem; if (el) { // if canvas renderer if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(el.get(0)); } el.emptyForce(); el = null; t._elem = null; } } t = null; this.axes[name]._plotDimensions = this._plotDimensions; this.axes[name]._ticks = []; // this.axes[name].renderer.init.call(this.axes[name], {}); } if (this.sortData) { sortData(this.series); } this.grid._axes = this.axes; this.legend._series = this.series; }; // sort the series data in increasing order. function sortData(series) { var d, sd, pd, ppd, ret; for (var i=0; i<series.length; i++) { var check; var bat = [series[i].data, series[i]._stackData, series[i]._plotData, series[i]._prevPlotData]; for (var n=0; n<4; n++) { check = true; d = bat[n]; if (series[i]._stackAxis == 'x') { for (var j = 0; j < d.length; j++) { if (typeof(d[j][1]) != "number") { check = false; break; } } if (check) { d.sort(function(a,b) { return a[1] - b[1]; }); } } else { for (var j = 0; j < d.length; j++) { if (typeof(d[j][0]) != "number") { check = false; break; } } if (check) { d.sort(function(a,b) { return a[0] - b[0]; }); } } } } } // populate the _stackData and _plotData arrays for the plot and the series. this.populatePlotData = function(series, index) { // if a stacked chart, compute the stacked data this._plotData = []; this._stackData = []; series._stackData = []; series._plotData = []; var plotValues = {x:[], y:[]}; if (this.stackSeries && !series.disableStack) { series._stack = true; var sidx = series._stackAxis == 'x' ? 0 : 1; var idx = sidx ? 0 : 1; // push the current data into stackData //this._stackData.push(this.series[i].data); var temp = $.extend(true, [], series.data); // create the data that will be plotted for this series var plotdata = $.extend(true, [], series.data); // for first series, nothing to add to stackData. for (var j=0; j<index; j++) { var cd = this.series[j].data; for (var k=0; k<cd.length; k++) { temp[k][0] += cd[k][0]; temp[k][1] += cd[k][1]; // only need to sum up the stack axis column of data plotdata[k][sidx] += cd[k][sidx]; } } for (var i=0; i<plotdata.length; i++) { plotValues.x.push(plotdata[i][0]); plotValues.y.push(plotdata[i][1]); } this._plotData.push(plotdata); this._stackData.push(temp); series._stackData = temp; series._plotData = plotdata; series._plotValues = plotValues; } else { for (var i=0; i<series.data.length; i++) { plotValues.x.push(series.data[i][0]); plotValues.y.push(series.data[i][1]); } this._stackData.push(series.data); this.series[index]._stackData = series.data; this._plotData.push(series.data); series._plotData = series.data; series._plotValues = plotValues; } if (index>0) { series._prevPlotData = this.series[index-1]._plotData; } series._sumy = 0; series._sumx = 0; for (i=series.data.length-1; i>-1; i--) { series._sumy += series.data[i][1]; series._sumx += series.data[i][0]; } }; // function to safely return colors from the color array and wrap around at the end. this.getNextSeriesColor = (function(t) { var idx = 0; var sc = t.seriesColors; return function () { if (idx < sc.length) { return sc[idx++]; } else { idx = 0; return sc[idx++]; } }; })(this); this.parseOptions = function(options){ for (var i=0; i<this.preParseOptionsHooks.hooks.length; i++) { this.preParseOptionsHooks.hooks[i].call(this, options); } for (var i=0; i<$.jqplot.preParseOptionsHooks.length; i++) { $.jqplot.preParseOptionsHooks[i].call(this, options); } this.options = $.extend(true, {}, this.defaults, options); var opts = this.options; this.animate = opts.animate; this.animateReplot = opts.animateReplot; this.stackSeries = opts.stackSeries; if ($.isPlainObject(opts.fillBetween)) { var temp = ['series1', 'series2', 'color', 'baseSeries', 'fill'], tempi; for (var i=0, l=temp.length; i<l; i++) { tempi = temp[i]; if (opts.fillBetween[tempi] != null) { this.fillBetween[tempi] = opts.fillBetween[tempi]; } } } if (opts.seriesColors) { this.seriesColors = opts.seriesColors; } if (opts.negativeSeriesColors) { this.negativeSeriesColors = opts.negativeSeriesColors; } if (opts.captureRightClick) { this.captureRightClick = opts.captureRightClick; } this.defaultAxisStart = (options && options.defaultAxisStart != null) ? options.defaultAxisStart : this.defaultAxisStart; this.colorGenerator.setColors(this.seriesColors); this.negativeColorGenerator.setColors(this.negativeSeriesColors); // var cg = new this.colorGenerator(this.seriesColors); // var ncg = new this.colorGenerator(this.negativeSeriesColors); // this._gridPadding = this.options.gridPadding; $.extend(true, this._gridPadding, opts.gridPadding); this.sortData = (opts.sortData != null) ? opts.sortData : this.sortData; for (var i=0; i<12; i++) { var n = _axisNames[i]; var axis = this.axes[n]; axis._options = $.extend(true, {}, opts.axesDefaults, opts.axes[n]); $.extend(true, axis, opts.axesDefaults, opts.axes[n]); axis._plotWidth = this._width; axis._plotHeight = this._height; } // if (this.data.length == 0) { // this.data = []; // for (var i=0; i<this.options.series.length; i++) { // this.data.push(this.options.series.data); // } // } var normalizeData = function(data, dir, start) { // return data as an array of point arrays, // in form [[x1,y1...], [x2,y2...], ...] var temp = []; var i; dir = dir || 'vertical'; if (!jQuery.isArray(data[0])) { // we have a series of scalars. One line with just y values. // turn the scalar list of data into a data array of form: // [[1, data[0]], [2, data[1]], ...] for (i=0; i<data.length; i++) { if (dir == 'vertical') { temp.push([start + i, data[i]]); } else { temp.push([data[i], start+i]); } } } else { // we have a properly formatted data series, copy it. $.extend(true, temp, data); } return temp; }; var colorIndex = 0; for (var i=0; i<this.data.length; i++) { var temp = new Series(); for (var j=0; j<$.jqplot.preParseSeriesOptionsHooks.length; j++) { $.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); } for (var j=0; j<this.preParseSeriesOptionsHooks.hooks.length; j++) { this.preParseSeriesOptionsHooks.hooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); } $.extend(true, temp, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i], {rendererOptions:{animation:{show: this.animate}}}); var dir = 'vertical'; if (temp.renderer === $.jqplot.BarRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal' && temp.transposeData === true) { dir = 'horizontal'; } temp.data = normalizeData(this.data[i], dir, this.defaultAxisStart); switch (temp.xaxis) { case 'xaxis': temp._xaxis = this.axes.xaxis; break; case 'x2axis': temp._xaxis = this.axes.x2axis; break; default: break; } temp._yaxis = this.axes[temp.yaxis]; temp._xaxis._series.push(temp); temp._yaxis._series.push(temp); if (temp.show) { temp._xaxis.show = true; temp._yaxis.show = true; } // // parse the renderer options and apply default colors if not provided // if (!temp.color && temp.show != false) { // temp.color = cg.next(); // colorIndex = cg.getIndex() - 1;; // } // if (!temp.negativeColor && temp.show != false) { // temp.negativeColor = ncg.get(colorIndex); // ncg.setIndex(colorIndex); // } if (!temp.label) { temp.label = 'Series '+ (i+1).toString(); } // temp.rendererOptions.show = temp.show; // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions); this.series.push(temp); for (var j=0; j<$.jqplot.postParseSeriesOptionsHooks.length; j++) { $.jqplot.postParseSeriesOptionsHooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); } for (var j=0; j<this.postParseSeriesOptionsHooks.hooks.length; j++) { this.postParseSeriesOptionsHooks.hooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); } } // copy the grid and title options into this object. $.extend(true, this.grid, this.options.grid); // if axis border properties aren't set, set default. for (var i=0; i<12; i++) { var n = _axisNames[i]; var axis = this.axes[n]; if (axis.borderWidth == null) { axis.borderWidth =this.grid.borderWidth; } } if (typeof this.options.title == 'string') { this.title.text = this.options.title; } else if (typeof this.options.title == 'object') { $.extend(true, this.title, this.options.title); } this.title._plotWidth = this._width; this.legend.setOptions(this.options.legend); for (var i=0; i<$.jqplot.postParseOptionsHooks.length; i++) { $.jqplot.postParseOptionsHooks[i].call(this, options); } for (var i=0; i<this.postParseOptionsHooks.hooks.length; i++) { this.postParseOptionsHooks.hooks[i].call(this, options); } }; // method: destroy // Releases all resources occupied by the plot this.destroy = function() { this.canvasManager.freeAllCanvases(); if (this.eventCanvas && this.eventCanvas._elem) { this.eventCanvas._elem.unbind(); } // Couple of posts on Stack Overflow indicate that empty() doesn't // always cear up the dom and release memory. Sometimes setting // innerHTML property to null is needed. Particularly on IE, may // have to directly set it to null, bypassing jQuery. this.target.empty(); this.target[0].innerHTML = ''; }; // method: replot // Does a reinitialization of the plot followed by // a redraw. Method could be used to interactively // change plot characteristics and then replot. // // Parameters: // options - Options used for replotting. // // Properties: // clear - false to not clear (empty) the plot container before replotting (default: true). // resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves. // optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false). this.replot = function(options) { var opts = options || {}; var clear = (opts.clear === false) ? false : true; var resetAxes = opts.resetAxes || false; this.target.trigger('jqplotPreReplot'); if (clear) { this.destroy(); } this.reInitialize(); if (resetAxes) { this.resetAxesScale(resetAxes, opts.axes); } this.draw(); this.target.trigger('jqplotPostReplot'); }; // method: redraw // Empties the plot target div and redraws the plot. // This enables plot data and properties to be changed // and then to comletely clear the plot and redraw. // redraw *will not* reinitialize any plot elements. // That is, axes will not be autoscaled and defaults // will not be reapplied to any plot elements. redraw // is used primarily with zooming. // // Parameters: // clear - false to not clear (empty) the plot container before redrawing (default: true). this.redraw = function(clear) { clear = (clear != null) ? clear : true; this.target.trigger('jqplotPreRedraw'); if (clear) { this.canvasManager.freeAllCanvases(); this.eventCanvas._elem.unbind(); // Dont think I bind any events to the target, this shouldn't be necessary. // It will remove user's events. // this.target.unbind(); this.target.empty(); } for (var ax in this.axes) { this.axes[ax]._ticks = []; } for (var i=0; i<this.series.length; i++) { this.populatePlotData(this.series[i], i); } this._sumy = 0; this._sumx = 0; for (i=0; i<this.series.length; i++) { this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } this.draw(); this.target.trigger('jqplotPostRedraw'); }; // method: draw // Draws all elements of the plot into the container. // Does not clear the container before drawing. this.draw = function(){ if (this.drawIfHidden || this.target.is(':visible')) { this.target.trigger('jqplotPreDraw'); var i, j, l, tempseries; for (i=0, l=$.jqplot.preDrawHooks.length; i<l; i++) { $.jqplot.preDrawHooks[i].call(this); } for (i=0, l=this.preDrawHooks.length; i<l; i++) { this.preDrawHooks.hooks[i].apply(this, this.preDrawSeriesHooks.args[i]); } // create an underlying canvas to be used for special features. this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas', null, this)); this.baseCanvas.setContext(); this.target.append(this.title.draw()); this.title.pack({top:0, left:0}); // make room for the legend between the grid and the edge. var legendElem = this.legend.draw(); var gridPadding = {top:0, left:0, bottom:0, right:0}; if (this.legend.placement == "outsideGrid") { // temporarily append the legend to get dimensions this.target.append(legendElem); switch (this.legend.location) { case 'n': gridPadding.top += this.legend.getHeight(); break; case 's': gridPadding.bottom += this.legend.getHeight(); break; case 'ne': case 'e': case 'se': gridPadding.right += this.legend.getWidth(); break; case 'nw': case 'w': case 'sw': gridPadding.left += this.legend.getWidth(); break; default: // same as 'ne' gridPadding.right += this.legend.getWidth(); break; } legendElem = legendElem.detach(); } var ax = this.axes; var name; // draw the yMidAxis first, so xaxis of pyramid chart can adjust itself if needed. for (i=0; i<12; i++) { name = _axisNames[i]; this.target.append(ax[name].draw(this.baseCanvas._ctx, this)); ax[name].set(); } if (ax.yaxis.show) { gridPadding.left += ax.yaxis.getWidth(); } var ra = ['y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; var rapad = [0, 0, 0, 0, 0, 0, 0, 0]; var gpr = 0; var n; for (n=0; n<8; n++) { if (ax[ra[n]].show) { gpr += ax[ra[n]].getWidth(); rapad[n] = gpr; } } gridPadding.right += gpr; if (ax.x2axis.show) { gridPadding.top += ax.x2axis.getHeight(); } if (this.title.show) { gridPadding.top += this.title.getHeight(); } if (ax.xaxis.show) { gridPadding.bottom += ax.xaxis.getHeight(); } // end of gridPadding adjustments. // if user passed in gridDimensions option, check against calculated gridPadding if (this.options.gridDimensions && $.isPlainObject(this.options.gridDimensions)) { var gdw = parseInt(this.options.gridDimensions.width, 10) || 0; var gdh = parseInt(this.options.gridDimensions.height, 10) || 0; var widthAdj = (this._width - gridPadding.left - gridPadding.right - gdw)/2; var heightAdj = (this._height - gridPadding.top - gridPadding.bottom - gdh)/2; if (heightAdj >= 0 && widthAdj >= 0) { gridPadding.top += heightAdj; gridPadding.bottom += heightAdj; gridPadding.left += widthAdj; gridPadding.right += widthAdj; } } var arr = ['top', 'bottom', 'left', 'right']; for (var n in arr) { if (this._gridPadding[arr[n]] == null && gridPadding[arr[n]] > 0) { this._gridPadding[arr[n]] = gridPadding[arr[n]]; } else if (this._gridPadding[arr[n]] == null) { this._gridPadding[arr[n]] = this._defaultGridPadding[arr[n]]; } } var legendPadding = (this.legend.placement == 'outsideGrid') ? {top:this.title.getHeight(), left: 0, right: 0, bottom: 0} : this._gridPadding; ax.xaxis.pack({position:'absolute', bottom:this._gridPadding.bottom - ax.xaxis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); ax.yaxis.pack({position:'absolute', top:0, left:this._gridPadding.left - ax.yaxis.getWidth(), height:this._height}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); ax.x2axis.pack({position:'absolute', top:this._gridPadding.top - ax.x2axis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); for (i=8; i>0; i--) { ax[ra[i-1]].pack({position:'absolute', top:0, right:this._gridPadding.right - rapad[i-1]}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); } var ltemp = (this._width - this._gridPadding.left - this._gridPadding.right)/2.0 + this._gridPadding.left - ax.yMidAxis.getWidth()/2.0; ax.yMidAxis.pack({position:'absolute', top:0, left:ltemp, zIndex:9, textAlign: 'center'}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); this.target.append(this.grid.createElement(this._gridPadding, this)); this.grid.draw(); var series = this.series; var seriesLength = series.length; // put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars. for (i=0, l=seriesLength; i<l; i++) { // draw series in order of stacking. This affects only // order in which canvases are added to dom. j = this.seriesStack[i]; this.target.append(series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas', null, this)); series[j].shadowCanvas.setContext(); series[j].shadowCanvas._elem.data('seriesIndex', j); } for (i=0, l=seriesLength; i<l; i++) { // draw series in order of stacking. This affects only // order in which canvases are added to dom. j = this.seriesStack[i]; this.target.append(series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas', null, this)); series[j].canvas.setContext(); series[j].canvas._elem.data('seriesIndex', j); } // Need to use filled canvas to capture events in IE. // Also, canvas seems to block selection of other elements in document on FF. this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this)); this.eventCanvas.setContext(); this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)'; this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height); // bind custom event handlers to regular events. this.bindCustomEvents(); // draw legend before series if the series needs to know the legend dimensions. if (this.legend.preDraw) { this.eventCanvas._elem.before(legendElem); this.legend.pack(legendPadding); if (this.legend._elem) { this.drawSeries({legendInfo:{location:this.legend.location, placement:this.legend.placement, width:this.legend.getWidth(), height:this.legend.getHeight(), xoffset:this.legend.xoffset, yoffset:this.legend.yoffset}}); } else { this.drawSeries(); } } else { // draw series before legend this.drawSeries(); if (seriesLength) { $(series[seriesLength-1].canvas._elem).after(legendElem); } this.legend.pack(legendPadding); } // register event listeners on the overlay canvas for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) { // in the handler, this will refer to the eventCanvas dom element. // make sure there are references back into plot objects. this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); } // register event listeners on the overlay canvas for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) { // in the handler, this will refer to the eventCanvas dom element. // make sure there are references back into plot objects. this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]); } var fb = this.fillBetween; if (fb.fill && fb.series1 !== fb.series2 && fb.series1 < seriesLength && fb.series2 < seriesLength && series[fb.series1]._type === 'line' && series[fb.series2]._type === 'line') { this.doFillBetweenLines(); } for (var i=0, l=$.jqplot.postDrawHooks.length; i<l; i++) { $.jqplot.postDrawHooks[i].call(this); } for (var i=0, l=this.postDrawHooks.hooks.length; i<l; i++) { this.postDrawHooks.hooks[i].apply(this, this.postDrawHooks.args[i]); } if (this.target.is(':visible')) { this._drawCount += 1; } var temps, tempr, sel, _els; // ughh. ideally would hide all series then show them. for (i=0, l=seriesLength; i<l; i++) { temps = series[i]; tempr = temps.renderer; sel = '.jqplot-point-label.jqplot-series-'+i; if (tempr.animation && tempr.animation._supported && tempr.animation.show && (this._drawCount < 2 || this.animateReplot)) { _els = this.target.find(sel); _els.stop(true, true).hide(); temps.canvas._elem.stop(true, true).hide(); temps.shadowCanvas._elem.stop(true, true).hide(); temps.canvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); temps.shadowCanvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); _els.fadeIn(tempr.animation.speed*0.8); } } _els = null; this.target.trigger('jqplotPostDraw', [this]); } }; jqPlot.prototype.doFillBetweenLines = function () { var fb = this.fillBetween; var sid1 = fb.series1; var sid2 = fb.series2; // first series should always be lowest index var id1 = (sid1 < sid2) ? sid1 : sid2; var id2 = (sid2 > sid1) ? sid2 : sid1; var series1 = this.series[id1]; var series2 = this.series[id2]; if (series2.renderer.smooth) { var tempgd = series2.renderer._smoothedData.slice(0).reverse(); } else { var tempgd = series2.gridData.slice(0).reverse(); } if (series1.renderer.smooth) { var gd = series1.renderer._smoothedData.concat(tempgd); } else { var gd = series1.gridData.concat(tempgd); } var color = (fb.color !== null) ? fb.color : this.series[sid1].fillColor; var baseSeries = (fb.baseSeries !== null) ? fb.baseSeries : id1; // now apply a fill to the shape on the lower series shadow canvas, // so it is behind both series. var sr = this.series[baseSeries].renderer.shapeRenderer; var opts = {fillStyle: color, fill: true, closePath: true}; sr.draw(series1.shadowCanvas._ctx, gd, opts); }; this.bindCustomEvents = function() { this.eventCanvas._elem.bind('click', {plot:this}, this.onClick); this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); this.eventCanvas._elem.bind('mousedown', {plot:this}, this.onMouseDown); this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove); this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); if (this.captureRightClick) { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick); this.eventCanvas._elem.get(0).oncontextmenu = function() { return false; }; } else { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp); } }; function getEventPosition(ev) { var plot = ev.data.plot; var go = plot.eventCanvas._elem.offset(); var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null}; var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; var ax = plot.axes; var n, axis; for (n=11; n>0; n--) { axis = an[n-1]; if (ax[axis].show) { dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); } } return {offsets:go, gridPos:gridPos, dataPos:dataPos}; } // function to check if event location is over a area area function checkIntersection(gridpos, plot) { var series = plot.series; var i, j, k, s, r, x, y, theta, sm, sa, minang, maxang; var d0, d, p, pp, points, bw; var threshold, t; for (k=plot.seriesStack.length-1; k>=0; k--) { i = plot.seriesStack[k]; s = series[i]; switch (s.renderer.constructor) { case $.jqplot.BarRenderer: case $.jqplot.PyramidRenderer: x = gridpos.x; y = gridpos.y; for (j=0; j<s._barPoints.length; j++) { points = s._barPoints[j]; p = s.gridData[j]; if (x>points[0][0] && x<points[2][0] && y>points[2][1] && y<points[0][1]) { return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; } } break; case $.jqplot.DonutRenderer: sa = s.startAngle/180*Math.PI; x = gridpos.x - s._center[0]; y = gridpos.y - s._center[1]; r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); if (x > 0 && -y >= 0) { theta = 2*Math.PI - Math.atan(-y/x); } else if (x > 0 && -y < 0) { theta = -Math.atan(-y/x); } else if (x < 0) { theta = Math.PI - Math.atan(-y/x); } else if (x == 0 && -y > 0) { theta = 3*Math.PI/2; } else if (x == 0 && -y < 0) { theta = Math.PI/2; } else if (x == 0 && y == 0) { theta = 0; } if (sa) { theta -= sa; if (theta < 0) { theta += 2*Math.PI; } else if (theta > 2*Math.PI) { theta -= 2*Math.PI; } } sm = s.sliceMargin/180*Math.PI; if (r < s._radius && r > s._innerRadius) { for (j=0; j<s.gridData.length; j++) { minang = (j>0) ? s.gridData[j-1][1]+sm : sm; maxang = s.gridData[j][1]; if (theta > minang && theta < maxang) { return {seriesIndex:s.index, pointIndex:j, gridData:s.gridData[j], data:s.data[j]}; } } } break; case $.jqplot.PieRenderer: sa = s.startAngle/180*Math.PI; x = gridpos.x - s._center[0]; y = gridpos.y - s._center[1]; r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); if (x > 0 && -y >= 0) { theta = 2*Math.PI - Math.atan(-y/x); } else if (x > 0 && -y < 0) { theta = -Math.atan(-y/x); } else if (x < 0) { theta = Math.PI - Math.atan(-y/x); } else if (x == 0 && -y > 0) { theta = 3*Math.PI/2; } else if (x == 0 && -y < 0) { theta = Math.PI/2; } else if (x == 0 && y == 0) { theta = 0; } if (sa) { theta -= sa; if (theta < 0) { theta += 2*Math.PI; } else if (theta > 2*Math.PI) { theta -= 2*Math.PI; } } sm = s.sliceMargin/180*Math.PI; if (r < s._radius) { for (j=0; j<s.gridData.length; j++) { minang = (j>0) ? s.gridData[j-1][1]+sm : sm; maxang = s.gridData[j][1]; if (theta > minang && theta < maxang) { return {seriesIndex:s.index, pointIndex:j, gridData:s.gridData[j], data:s.data[j]}; } } } break; case $.jqplot.BubbleRenderer: x = gridpos.x; y = gridpos.y; var ret = null; if (s.show) { for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= p[2] && (d <= d0 || d0 == null)) { d0 = d; ret = {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } if (ret != null) { return ret; } } break; case $.jqplot.FunnelRenderer: x = gridpos.x; y = gridpos.y; var v = s._vertices, vfirst = v[0], vlast = v[v.length-1], lex, rex, cv; // equations of right and left sides, returns x, y values given height of section (y value and 2 points) function findedge (l, p1 , p2) { var m = (p1[1] - p2[1])/(p1[0] - p2[0]); var b = p1[1] - m*p1[0]; var y = l + p1[1]; return [(y - b)/m, y]; } // check each section lex = findedge(y, vfirst[0], vlast[3]); rex = findedge(y, vfirst[1], vlast[2]); for (j=0; j<v.length; j++) { cv = v[j]; if (y >= cv[0][1] && y <= cv[3][1] && x >= lex[0] && x <= rex[0]) { return {seriesIndex:s.index, pointIndex:j, gridData:null, data:s.data[j]}; } } break; case $.jqplot.LineRenderer: x = gridpos.x; y = gridpos.y; r = s.renderer; if (s.show) { if ((s.fill || (s.renderer.bands.show && s.renderer.bands.fill)) && (!plot.plugins.highlighter || !plot.plugins.highlighter.show)) { // first check if it is in bounding box var inside = false; if (x>s._boundingBox[0][0] && x<s._boundingBox[1][0] && y>s._boundingBox[1][1] && y<s._boundingBox[0][1]) { // now check the crossing number var numPoints = s._areaPoints.length; var ii; var j = numPoints-1; for(var ii=0; ii < numPoints; ii++) { var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]]; var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]]; if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) { if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) { inside = !inside; } } j = ii; } } if (inside) { return {seriesIndex:i, pointIndex:null, gridData:s.gridData, data:s.data, points:s._areaPoints}; } break; } else { t = s.markerRenderer.size/2+s.neighborThreshold; threshold = (t > 0) ? t : 0; for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; // neighbor looks different to OHLC chart. if (r.constructor == $.jqplot.OHLCRenderer) { if (r.candleStick) { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // if an open hi low close chart else if (!r.hlc){ var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // a hi low close chart else { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } else if (p[0] != null && p[1] != null){ d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= threshold && (d <= d0 || d0 == null)) { d0 = d; return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } } } break; default: x = gridpos.x; y = gridpos.y; r = s.renderer; if (s.show) { t = s.markerRenderer.size/2+s.neighborThreshold; threshold = (t > 0) ? t : 0; for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; // neighbor looks different to OHLC chart. if (r.constructor == $.jqplot.OHLCRenderer) { if (r.candleStick) { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // if an open hi low close chart else if (!r.hlc){ var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // a hi low close chart else { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } else { d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= threshold && (d <= d0 || d0 == null)) { d0 = d; return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } } break; } } return null; } this.onClick = function(ev) { // Event passed in is normalized and will have data attribute. // Event passed out is unnormalized. var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = jQuery.Event('jqplotClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onDblClick = function(ev) { // Event passed in is normalized and will have data attribute. // Event passed out is unnormalized. var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = jQuery.Event('jqplotDblClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseDown = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = jQuery.Event('jqplotMouseDown'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseUp = function(ev) { var positions = getEventPosition(ev); var evt = jQuery.Event('jqplotMouseUp'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, ev.data.plot]); }; this.onRightClick = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); if (p.captureRightClick) { if (ev.which == 3) { var evt = jQuery.Event('jqplotRightClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); } else { var evt = jQuery.Event('jqplotMouseUp'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); } } }; this.onMouseMove = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = jQuery.Event('jqplotMouseMove'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseEnter = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var evt = jQuery.Event('jqplotMouseEnter'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; evt.relatedTarget = ev.relatedTarget; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); }; this.onMouseLeave = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var evt = jQuery.Event('jqplotMouseLeave'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; evt.relatedTarget = ev.relatedTarget; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); }; // method: drawSeries // Redraws all or just one series on the plot. No axis scaling // is performed and no other elements on the plot are redrawn. // options is an options object to pass on to the series renderers. // It can be an empty object {}. idx is the series index // to redraw if only one series is to be redrawn. this.drawSeries = function(options, idx){ var i, series, ctx; // if only one argument passed in and it is a number, use it ad idx. idx = (typeof(options) === "number" && idx == null) ? options : idx; options = (typeof(options) === "object") ? options : {}; // draw specified series if (idx != undefined) { series = this.series[idx]; ctx = series.shadowCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.drawShadow(ctx, options, this); ctx = series.canvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.draw(ctx, options, this); if (series.renderer.constructor == $.jqplot.BezierCurveRenderer) { if (idx < this.series.length - 1) { this.drawSeries(idx+1); } } } else { // if call series drawShadow method first, in case all series shadows // should be drawn before any series. This will ensure, like for // stacked bar plots, that shadows don't overlap series. for (i=0; i<this.series.length; i++) { // first clear the canvas series = this.series[i]; ctx = series.shadowCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.drawShadow(ctx, options, this); ctx = series.canvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.draw(ctx, options, this); } } options = idx = i = series = ctx = null; }; // method: moveSeriesToFront // This method requires jQuery 1.4+ // Moves the specified series canvas in front of all other series canvases. // This effectively "draws" the specified series on top of all other series, // although it is performed through DOM manipulation, no redrawing is performed. // // Parameters: // idx - 0 based index of the series to move. This will be the index of the series // as it was first passed into the jqplot function. this.moveSeriesToFront = function (idx) { idx = parseInt(idx, 10); var stackIndex = $.inArray(idx, this.seriesStack); // if already in front, return if (stackIndex == -1) { return; } if (stackIndex == this.seriesStack.length -1) { this.previousSeriesStack = this.seriesStack.slice(0); return; } var opidx = this.seriesStack[this.seriesStack.length -1]; var serelem = this.series[idx].canvas._elem.detach(); var shadelem = this.series[idx].shadowCanvas._elem.detach(); this.series[opidx].shadowCanvas._elem.after(shadelem); this.series[opidx].canvas._elem.after(serelem); this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack.splice(stackIndex, 1); this.seriesStack.push(idx); }; // method: moveSeriesToBack // This method requires jQuery 1.4+ // Moves the specified series canvas behind all other series canvases. // // Parameters: // idx - 0 based index of the series to move. This will be the index of the series // as it was first passed into the jqplot function. this.moveSeriesToBack = function (idx) { idx = parseInt(idx, 10); var stackIndex = $.inArray(idx, this.seriesStack); // if already in back, return if (stackIndex == 0 || stackIndex == -1) { return; } var opidx = this.seriesStack[0]; var serelem = this.series[idx].canvas._elem.detach(); var shadelem = this.series[idx].shadowCanvas._elem.detach(); this.series[opidx].shadowCanvas._elem.before(shadelem); this.series[opidx].canvas._elem.before(serelem); this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack.splice(stackIndex, 1); this.seriesStack.unshift(idx); }; // method: restorePreviousSeriesOrder // This method requires jQuery 1.4+ // Restore the series canvas order to its previous state. // Useful to put a series back where it belongs after moving // it to the front. this.restorePreviousSeriesOrder = function () { var i, j, serelem, shadelem, temp, move, keep; // if no change, return. if (this.seriesStack == this.previousSeriesStack) { return; } for (i=1; i<this.previousSeriesStack.length; i++) { move = this.previousSeriesStack[i]; keep = this.previousSeriesStack[i-1]; serelem = this.series[move].canvas._elem.detach(); shadelem = this.series[move].shadowCanvas._elem.detach(); this.series[keep].shadowCanvas._elem.after(shadelem); this.series[keep].canvas._elem.after(serelem); } temp = this.seriesStack.slice(0); this.seriesStack = this.previousSeriesStack.slice(0); this.previousSeriesStack = temp; }; // method: restoreOriginalSeriesOrder // This method requires jQuery 1.4+ // Restore the series canvas order to its original order // when the plot was created. this.restoreOriginalSeriesOrder = function () { var i, j, arr=[], serelem, shadelem; for (i=0; i<this.series.length; i++) { arr.push(i); } if (this.seriesStack == arr) { return; } this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack = arr; for (i=1; i<this.seriesStack.length; i++) { serelem = this.series[i].canvas._elem.detach(); shadelem = this.series[i].shadowCanvas._elem.detach(); this.series[i-1].shadowCanvas._elem.after(shadelem); this.series[i-1].canvas._elem.after(serelem); } }; this.activateTheme = function (name) { this.themeEngine.activate(this, name); }; } // conpute a highlight color or array of highlight colors from given colors. $.jqplot.computeHighlightColors = function(colors) { var ret; if (jQuery.isArray(colors)) { ret = []; for (var i=0; i<colors.length; i++){ var rgba = $.jqplot.getColorComponents(colors[i]); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; newrgb[j] = parseInt(newrgb[j], 10); (newrgb[j] > 255) ? 255 : newrgb[j]; } // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; newrgb[3] = 0.3 + 0.35 * rgba[3]; ret.push('rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'); } } else { var rgba = $.jqplot.getColorComponents(colors); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. // newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); // newrgb[j] = parseInt(newrgb[j], 10); newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; newrgb[j] = parseInt(newrgb[j], 10); (newrgb[j] > 255) ? 255 : newrgb[j]; } // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; newrgb[3] = 0.3 + 0.35 * rgba[3]; ret = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'; } return ret; }; $.jqplot.ColorGenerator = function(colors) { colors = colors || $.jqplot.config.defaultColors; var idx = 0; this.next = function () { if (idx < colors.length) { return colors[idx++]; } else { idx = 0; return colors[idx++]; } }; this.previous = function () { if (idx > 0) { return colors[idx--]; } else { idx = colors.length-1; return colors[idx]; } }; // get a color by index without advancing pointer. this.get = function(i) { var idx = i - colors.length * Math.floor(i/colors.length); return colors[idx]; }; this.setColors = function(c) { colors = c; }; this.reset = function() { idx = 0; }; this.getIndex = function() { return idx; }; this.setIndex = function(index) { idx = index; }; }; // convert a hex color string to rgb string. // h - 3 or 6 character hex string, with or without leading # // a - optional alpha $.jqplot.hex2rgb = function(h, a) { h = h.replace('#', ''); if (h.length == 3) { h = h.charAt(0)+h.charAt(0)+h.charAt(1)+h.charAt(1)+h.charAt(2)+h.charAt(2); } var rgb; rgb = 'rgba('+parseInt(h.slice(0,2), 16)+', '+parseInt(h.slice(2,4), 16)+', '+parseInt(h.slice(4,6), 16); if (a) { rgb += ', '+a; } rgb += ')'; return rgb; }; // convert an rgb color spec to a hex spec. ignore any alpha specification. $.jqplot.rgb2hex = function(s) { var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/; var m = s.match(pat); var h = '#'; for (var i=1; i<4; i++) { var temp; if (m[i].search(/%/) != -1) { temp = parseInt(255*m[i]/100, 10).toString(16); if (temp.length == 1) { temp = '0'+temp; } } else { temp = parseInt(m[i], 10).toString(16); if (temp.length == 1) { temp = '0'+temp; } } h += temp; } return h; }; // given a css color spec, return an rgb css color spec $.jqplot.normalize2rgb = function(s, a) { if (s.search(/^ *rgba?\(/) != -1) { return s; } else if (s.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/) != -1) { return $.jqplot.hex2rgb(s, a); } else { throw 'invalid color spec'; } }; // extract the r, g, b, a color components out of a css color spec. $.jqplot.getColorComponents = function(s) { // check to see if a color keyword. s = $.jqplot.colorKeywordMap[s] || s; var rgb = $.jqplot.normalize2rgb(s); var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/; var m = rgb.match(pat); var ret = []; for (var i=1; i<4; i++) { if (m[i].search(/%/) != -1) { ret[i-1] = parseInt(255*m[i]/100, 10); } else { ret[i-1] = parseInt(m[i], 10); } } ret[3] = parseFloat(m[4]) ? parseFloat(m[4]) : 1.0; return ret; }; $.jqplot.colorKeywordMap = { aliceblue: 'rgb(240, 248, 255)', antiquewhite: 'rgb(250, 235, 215)', aqua: 'rgb( 0, 255, 255)', aquamarine: 'rgb(127, 255, 212)', azure: 'rgb(240, 255, 255)', beige: 'rgb(245, 245, 220)', bisque: 'rgb(255, 228, 196)', black: 'rgb( 0, 0, 0)', blanchedalmond: 'rgb(255, 235, 205)', blue: 'rgb( 0, 0, 255)', blueviolet: 'rgb(138, 43, 226)', brown: 'rgb(165, 42, 42)', burlywood: 'rgb(222, 184, 135)', cadetblue: 'rgb( 95, 158, 160)', chartreuse: 'rgb(127, 255, 0)', chocolate: 'rgb(210, 105, 30)', coral: 'rgb(255, 127, 80)', cornflowerblue: 'rgb(100, 149, 237)', cornsilk: 'rgb(255, 248, 220)', crimson: 'rgb(220, 20, 60)', cyan: 'rgb( 0, 255, 255)', darkblue: 'rgb( 0, 0, 139)', darkcyan: 'rgb( 0, 139, 139)', darkgoldenrod: 'rgb(184, 134, 11)', darkgray: 'rgb(169, 169, 169)', darkgreen: 'rgb( 0, 100, 0)', darkgrey: 'rgb(169, 169, 169)', darkkhaki: 'rgb(189, 183, 107)', darkmagenta: 'rgb(139, 0, 139)', darkolivegreen: 'rgb( 85, 107, 47)', darkorange: 'rgb(255, 140, 0)', darkorchid: 'rgb(153, 50, 204)', darkred: 'rgb(139, 0, 0)', darksalmon: 'rgb(233, 150, 122)', darkseagreen: 'rgb(143, 188, 143)', darkslateblue: 'rgb( 72, 61, 139)', darkslategray: 'rgb( 47, 79, 79)', darkslategrey: 'rgb( 47, 79, 79)', darkturquoise: 'rgb( 0, 206, 209)', darkviolet: 'rgb(148, 0, 211)', deeppink: 'rgb(255, 20, 147)', deepskyblue: 'rgb( 0, 191, 255)', dimgray: 'rgb(105, 105, 105)', dimgrey: 'rgb(105, 105, 105)', dodgerblue: 'rgb( 30, 144, 255)', firebrick: 'rgb(178, 34, 34)', floralwhite: 'rgb(255, 250, 240)', forestgreen: 'rgb( 34, 139, 34)', fuchsia: 'rgb(255, 0, 255)', gainsboro: 'rgb(220, 220, 220)', ghostwhite: 'rgb(248, 248, 255)', gold: 'rgb(255, 215, 0)', goldenrod: 'rgb(218, 165, 32)', gray: 'rgb(128, 128, 128)', grey: 'rgb(128, 128, 128)', green: 'rgb( 0, 128, 0)', greenyellow: 'rgb(173, 255, 47)', honeydew: 'rgb(240, 255, 240)', hotpink: 'rgb(255, 105, 180)', indianred: 'rgb(205, 92, 92)', indigo: 'rgb( 75, 0, 130)', ivory: 'rgb(255, 255, 240)', khaki: 'rgb(240, 230, 140)', lavender: 'rgb(230, 230, 250)', lavenderblush: 'rgb(255, 240, 245)', lawngreen: 'rgb(124, 252, 0)', lemonchiffon: 'rgb(255, 250, 205)', lightblue: 'rgb(173, 216, 230)', lightcoral: 'rgb(240, 128, 128)', lightcyan: 'rgb(224, 255, 255)', lightgoldenrodyellow: 'rgb(250, 250, 210)', lightgray: 'rgb(211, 211, 211)', lightgreen: 'rgb(144, 238, 144)', lightgrey: 'rgb(211, 211, 211)', lightpink: 'rgb(255, 182, 193)', lightsalmon: 'rgb(255, 160, 122)', lightseagreen: 'rgb( 32, 178, 170)', lightskyblue: 'rgb(135, 206, 250)', lightslategray: 'rgb(119, 136, 153)', lightslategrey: 'rgb(119, 136, 153)', lightsteelblue: 'rgb(176, 196, 222)', lightyellow: 'rgb(255, 255, 224)', lime: 'rgb( 0, 255, 0)', limegreen: 'rgb( 50, 205, 50)', linen: 'rgb(250, 240, 230)', magenta: 'rgb(255, 0, 255)', maroon: 'rgb(128, 0, 0)', mediumaquamarine: 'rgb(102, 205, 170)', mediumblue: 'rgb( 0, 0, 205)', mediumorchid: 'rgb(186, 85, 211)', mediumpurple: 'rgb(147, 112, 219)', mediumseagreen: 'rgb( 60, 179, 113)', mediumslateblue: 'rgb(123, 104, 238)', mediumspringgreen: 'rgb( 0, 250, 154)', mediumturquoise: 'rgb( 72, 209, 204)', mediumvioletred: 'rgb(199, 21, 133)', midnightblue: 'rgb( 25, 25, 112)', mintcream: 'rgb(245, 255, 250)', mistyrose: 'rgb(255, 228, 225)', moccasin: 'rgb(255, 228, 181)', navajowhite: 'rgb(255, 222, 173)', navy: 'rgb( 0, 0, 128)', oldlace: 'rgb(253, 245, 230)', olive: 'rgb(128, 128, 0)', olivedrab: 'rgb(107, 142, 35)', orange: 'rgb(255, 165, 0)', orangered: 'rgb(255, 69, 0)', orchid: 'rgb(218, 112, 214)', palegoldenrod: 'rgb(238, 232, 170)', palegreen: 'rgb(152, 251, 152)', paleturquoise: 'rgb(175, 238, 238)', palevioletred: 'rgb(219, 112, 147)', papayawhip: 'rgb(255, 239, 213)', peachpuff: 'rgb(255, 218, 185)', peru: 'rgb(205, 133, 63)', pink: 'rgb(255, 192, 203)', plum: 'rgb(221, 160, 221)', powderblue: 'rgb(176, 224, 230)', purple: 'rgb(128, 0, 128)', red: 'rgb(255, 0, 0)', rosybrown: 'rgb(188, 143, 143)', royalblue: 'rgb( 65, 105, 225)', saddlebrown: 'rgb(139, 69, 19)', salmon: 'rgb(250, 128, 114)', sandybrown: 'rgb(244, 164, 96)', seagreen: 'rgb( 46, 139, 87)', seashell: 'rgb(255, 245, 238)', sienna: 'rgb(160, 82, 45)', silver: 'rgb(192, 192, 192)', skyblue: 'rgb(135, 206, 235)', slateblue: 'rgb(106, 90, 205)', slategray: 'rgb(112, 128, 144)', slategrey: 'rgb(112, 128, 144)', snow: 'rgb(255, 250, 250)', springgreen: 'rgb( 0, 255, 127)', steelblue: 'rgb( 70, 130, 180)', tan: 'rgb(210, 180, 140)', teal: 'rgb( 0, 128, 128)', thistle: 'rgb(216, 191, 216)', tomato: 'rgb(255, 99, 71)', turquoise: 'rgb( 64, 224, 208)', violet: 'rgb(238, 130, 238)', wheat: 'rgb(245, 222, 179)', white: 'rgb(255, 255, 255)', whitesmoke: 'rgb(245, 245, 245)', yellow: 'rgb(255, 255, 0)', yellowgreen: 'rgb(154, 205, 50)' }; // class: $.jqplot.AxisLabelRenderer // Renderer to place labels on the axes. $.jqplot.AxisLabelRenderer = function(options) { // Group: Properties $.jqplot.ElemContainer.call(this); // name of the axis associated with this tick this.axis; // prop: show // wether or not to show the tick (mark and label). this.show = true; // prop: label // The text or html for the label. this.label = ''; this.fontFamily = null; this.fontSize = null; this.textColor = null; this._elem; // prop: escapeHTML // true to escape HTML entities in the label. this.escapeHTML = false; $.extend(true, this, options); }; $.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer(); $.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer; $.jqplot.AxisLabelRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.AxisLabelRenderer.prototype.draw = function(ctx, plot) { // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } this._elem = $('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>'); if (Number(this.label)) { this._elem.css('white-space', 'nowrap'); } if (!this.escapeHTML) { this._elem.html(this.label); } else { this._elem.text(this.label); } if (this.fontFamily) { this._elem.css('font-family', this.fontFamily); } if (this.fontSize) { this._elem.css('font-size', this.fontSize); } if (this.textColor) { this._elem.css('color', this.textColor); } return this._elem; }; $.jqplot.AxisLabelRenderer.prototype.pack = function() { }; // class: $.jqplot.AxisTickRenderer // A "tick" object showing the value of a tick/gridline on the plot. $.jqplot.AxisTickRenderer = function(options) { // Group: Properties $.jqplot.ElemContainer.call(this); // prop: mark // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. this.mark = 'outside'; // name of the axis associated with this tick this.axis; // prop: showMark // wether or not to show the mark on the axis. this.showMark = true; // prop: showGridline // wether or not to draw the gridline on the grid at this tick. this.showGridline = true; // prop: isMinorTick // if this is a minor tick. this.isMinorTick = false; // prop: size // Length of the tick beyond the grid in pixels. // DEPRECATED: This has been superceeded by markSize this.size = 4; // prop: markSize // Length of the tick marks in pixels. For 'cross' style, length // will be stoked above and below axis, so total length will be twice this. this.markSize = 6; // prop: show // wether or not to show the tick (mark and label). // Setting this to false requires more testing. It is recommended // to set showLabel and showMark to false instead. this.show = true; // prop: showLabel // wether or not to show the label. this.showLabel = true; this.label = null; this.value = null; this._styles = {}; // prop: formatter // A class of a formatter for the tick text. sprintf by default. this.formatter = $.jqplot.DefaultTickFormatter; // prop: prefix // String to prepend to the tick label. // Prefix is prepended to the formatted tick label. this.prefix = ''; // prop: formatString // string passed to the formatter. this.formatString = ''; // prop: fontFamily // css spec for the font-family css attribute. this.fontFamily; // prop: fontSize // css spec for the font-size css attribute. this.fontSize; // prop: textColor // css spec for the color attribute. this.textColor; // prop: escapeHTML // true to escape HTML entities in the label. this.escapeHTML = false; this._elem; this._breakTick = false; $.extend(true, this, options); }; $.jqplot.AxisTickRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer(); $.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer; $.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { this.value = value; this.axis = axisName; if (isMinor) { this.isMinorTick = true; } return this; }; $.jqplot.AxisTickRenderer.prototype.draw = function() { if (this.label === null) { this.label = this.prefix + this.formatter(this.formatString, this.value); } var style = {position: 'absolute'}; if (Number(this.label)) { style['whitSpace'] = 'nowrap'; } // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } this._elem = $(document.createElement('div')); this._elem.addClass("jqplot-"+this.axis+"-tick"); if (!this.escapeHTML) { this._elem.html(this.label); } else { this._elem.text(this.label); } this._elem.css(style); for (var s in this._styles) { this._elem.css(s, this._styles[s]); } if (this.fontFamily) { this._elem.css('font-family', this.fontFamily); } if (this.fontSize) { this._elem.css('font-size', this.fontSize); } if (this.textColor) { this._elem.css('color', this.textColor); } if (this._breakTick) { this._elem.addClass('jqplot-breakTick'); } return this._elem; }; $.jqplot.DefaultTickFormatter = function (format, val) { if (typeof val == 'number') { if (!format) { format = $.jqplot.config.defaultTickFormatString; } return $.jqplot.sprintf(format, val); } else { return String(val); } }; $.jqplot.AxisTickRenderer.prototype.pack = function() { }; // Class: $.jqplot.CanvasGridRenderer // The default jqPlot grid renderer, creating a grid on a canvas element. // The renderer has no additional options beyond the <Grid> class. $.jqplot.CanvasGridRenderer = function(){ this.shadowRenderer = new $.jqplot.ShadowRenderer(); }; // called with context of Grid object $.jqplot.CanvasGridRenderer.prototype.init = function(options) { this._ctx; $.extend(true, this, options); // set the shadow renderer options var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; this.renderer.shadowRenderer.init(sopts); }; // called with context of Grid. $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) { var elem; // Memory Leaks patch if (this._elem) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { elem = this._elem.get(0); window.G_vmlCanvasManager.uninitElement(elem); elem = null; } this._elem.emptyForce(); this._elem = null; } elem = plot.canvasManager.getCanvas(); var w = this._plotDimensions.width; var h = this._plotDimensions.height; elem.width = w; elem.height = h; this._elem = $(elem); this._elem.addClass('jqplot-grid-canvas'); this._elem.css({ position: 'absolute', left: 0, top: 0 }); elem = plot.canvasManager.initCanvas(elem); this._top = this._offsets.top; this._bottom = h - this._offsets.bottom; this._left = this._offsets.left; this._right = w - this._offsets.right; this._width = this._right - this._left; this._height = this._bottom - this._top; // avoid memory leak elem = null; return this._elem; }; $.jqplot.CanvasGridRenderer.prototype.draw = function() { this._ctx = this._elem.get(0).getContext("2d"); var ctx = this._ctx; var axes = this._axes; // Add the grid onto the grid canvas. This is the bottom most layer. ctx.save(); ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); ctx.fillStyle = this.backgroundColor || this.background; ctx.fillRect(this._left, this._top, this._width, this._height); ctx.save(); ctx.lineJoin = 'miter'; ctx.lineCap = 'butt'; ctx.lineWidth = this.gridLineWidth; ctx.strokeStyle = this.gridLineColor; var b, e, s, m; var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis']; for (var i=4; i>0; i--) { var name = ax[i-1]; var axis = axes[name]; var ticks = axis._ticks; var numticks = ticks.length; if (axis.show) { if (axis.drawBaseline) { var bopts = {}; if (axis.baselineWidth !== null) { bopts.lineWidth = axis.baselineWidth; } if (axis.baselineColor !== null) { bopts.strokeStyle = axis.baselineColor; } switch (name) { case 'xaxis': drawLine (this._left, this._bottom, this._right, this._bottom, bopts); break; case 'yaxis': drawLine (this._left, this._bottom, this._left, this._top, bopts); break; case 'x2axis': drawLine (this._left, this._bottom, this._right, this._bottom, bopts); break; case 'y2axis': drawLine (this._right, this._bottom, this._right, this._top, bopts); break; } } for (var j=numticks; j>0; j--) { var t = ticks[j-1]; if (t.show) { var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (name) { case 'xaxis': // draw the grid line if we should if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(pos, this._top, pos, this._bottom); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._bottom; e = this._bottom+s; break; case 'inside': b = this._bottom-s; e = this._bottom; break; case 'cross': b = this._bottom-s; e = this._bottom+s; break; default: b = this._bottom; e = this._bottom+s; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); } // draw the line drawLine(pos, b, pos, e); } break; case 'yaxis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(this._right, pos, this._left, pos); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._left-s; e = this._left; break; case 'inside': b = this._left; e = this._left+s; break; case 'cross': b = this._left-s; e = this._left+s; break; default: b = this._left-s; e = this._left; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } break; case 'x2axis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(pos, this._bottom, pos, this._top); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._top-s; e = this._top; break; case 'inside': b = this._top; e = this._top+s; break; case 'cross': b = this._top-s; e = this._top+s; break; default: b = this._top-s; e = this._top; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); } drawLine(pos, b, pos, e); } break; case 'y2axis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(this._left, pos, this._right, pos); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._right; e = this._right+s; break; case 'inside': b = this._right-s; e = this._right; break; case 'cross': b = this._right-s; e = this._right+s; break; default: b = this._right; e = this._right+s; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } break; default: break; } } } t = null; } axis = null; ticks = null; } // Now draw grid lines for additional y axes ////// // TO DO: handle yMidAxis ////// ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; for (var i=7; i>0; i--) { var axis = axes[ax[i-1]]; var ticks = axis._ticks; if (axis.show) { var tn = ticks[axis.numberTicks-1]; var t0 = ticks[0]; var left = axis.getLeft(); var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]]; // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false}); } // draw the line drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth}); // draw the tick marks for (var j=ticks.length; j>0; j--) { var t = ticks[j-1]; s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; if (t.showMark && t.mark) { switch (m) { case 'outside': b = left; e = left+s; break; case 'inside': b = left-s; e = left; break; case 'cross': b = left-s; e = left+s; break; default: b = left; e = left+s; break; } points = [[b,pos], [e,pos]]; // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } // draw the line drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } t = null; } t0 = null; } axis = null; ticks = null; } ctx.restore(); function drawLine(bx, by, ex, ey, opts) { ctx.save(); opts = opts || {}; if (opts.lineWidth == null || opts.lineWidth != 0){ $.extend(true, ctx, opts); ctx.beginPath(); ctx.moveTo(bx, by); ctx.lineTo(ex, ey); ctx.stroke(); ctx.restore(); } } if (this.shadow) { var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; this.renderer.shadowRenderer.draw(ctx, points); } // Now draw border around grid. Use axis border definitions. start at // upper left and go clockwise. if (this.borderWidth != 0 && this.drawBorder) { drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); } // ctx.lineWidth = this.borderWidth; // ctx.strokeStyle = this.borderColor; // ctx.strokeRect(this._left, this._top, this._width, this._height); ctx.restore(); ctx = null; axes = null; }; // Class: $.jqplot.DivTitleRenderer // The default title renderer for jqPlot. This class has no options beyond the <Title> class. $.jqplot.DivTitleRenderer = function() { }; $.jqplot.DivTitleRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.DivTitleRenderer.prototype.draw = function() { // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } var r = this.renderer; var elem = document.createElement('div'); this._elem = $(elem); this._elem.addClass('jqplot-title'); if (!this.text) { this.show = false; this._elem.height(0); this._elem.width(0); } else if (this.text) { var color; if (this.color) { color = this.color; } else if (this.textColor) { color = this.textColor; } // don't trust that a stylesheet is present, set the position. var styles = {position:'absolute', top:'0px', left:'0px'}; if (this._plotWidth) { styles['width'] = this._plotWidth+'px'; } if (this.fontSize) { styles['fontSize'] = this.fontSize; } if (typeof this.textAlign === 'string') { styles['textAlign'] = this.textAlign; } else { styles['textAlign'] = 'center'; } if (color) { styles['color'] = color; } if (this.paddingBottom) { styles['paddingBottom'] = this.paddingBottom; } if (this.fontFamily) { styles['fontFamily'] = this.fontFamily; } this._elem.css(styles); if (this.escapeHtml) { this._elem.text(this.text); } else { this._elem.html(this.text); } // styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : ''; // styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; // styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;'; // styletext += (color) ? 'color:'+color+';' : ''; // styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : ''; // this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>'); // if (this.fontFamily) { // this._elem.css('font-family', this.fontFamily); // } } elem = null; return this._elem; }; $.jqplot.DivTitleRenderer.prototype.pack = function() { // nothing to do here }; var dotlen = 0.1; $.jqplot.LinePattern = function (ctx, pattern) { var defaultLinePatterns = { dotted: [ dotlen, $.jqplot.config.dotGapLength ], dashed: [ $.jqplot.config.dashLength, $.jqplot.config.gapLength ], solid: null }; if (typeof pattern === 'string') { if (pattern[0] === '.' || pattern[0] === '-') { var s = pattern; pattern = []; for (var i=0, imax=s.length; i<imax; i++) { if (s[i] === '.') { pattern.push( dotlen ); } else if (s[i] === '-') { pattern.push( $.jqplot.config.dashLength ); } else { continue; } pattern.push( $.jqplot.config.gapLength ); } } else { pattern = defaultLinePatterns[pattern]; } } if (!(pattern && pattern.length)) { return ctx; } var patternIndex = 0; var patternDistance = pattern[0]; var px = 0; var py = 0; var pathx0 = 0; var pathy0 = 0; var moveTo = function (x, y) { ctx.moveTo( x, y ); px = x; py = y; pathx0 = x; pathy0 = y; }; var lineTo = function (x, y) { var scale = ctx.lineWidth; var dx = x - px; var dy = y - py; var dist = Math.sqrt(dx*dx+dy*dy); if ((dist > 0) && (scale > 0)) { dx /= dist; dy /= dist; while (true) { var dp = scale * patternDistance; if (dp < dist) { px += dp * dx; py += dp * dy; if ((patternIndex & 1) == 0) { ctx.lineTo( px, py ); } else { ctx.moveTo( px, py ); } dist -= dp; patternIndex++; if (patternIndex >= pattern.length) { patternIndex = 0; } patternDistance = pattern[patternIndex]; } else { px = x; py = y; if ((patternIndex & 1) == 0) { ctx.lineTo( px, py ); } else { ctx.moveTo( px, py ); } patternDistance -= dist / scale; break; } } } }; var beginPath = function () { ctx.beginPath(); }; var closePath = function () { lineTo( pathx0, pathy0 ); }; return { moveTo: moveTo, lineTo: lineTo, beginPath: beginPath, closePath: closePath }; }; // Class: $.jqplot.LineRenderer // The default line renderer for jqPlot, this class has no options beyond the <Series> class. // Draws series as a line. $.jqplot.LineRenderer = function(){ this.shapeRenderer = new $.jqplot.ShapeRenderer(); this.shadowRenderer = new $.jqplot.ShadowRenderer(); }; // called with scope of series. $.jqplot.LineRenderer.prototype.init = function(options, plot) { // Group: Properties // options = options || {}; this._type='line'; this.renderer.animation = { show: false, direction: 'left', speed: 2500, _supported: true }; // prop: smooth // True to draw a smoothed (interpolated) line through the data points // with automatically computed number of smoothing points. // Set to an integer number > 2 to specify number of smoothing points // to use between each data point. this.renderer.smooth = false; // true or a number > 2 for smoothing. this.renderer.tension = null; // null to auto compute or a number typically > 6. Fewer points requires higher tension. // prop: constrainSmoothing // True to use a more accurate smoothing algorithm that will // not overshoot any data points. False to allow overshoot but // produce a smoother looking line. this.renderer.constrainSmoothing = true; // this is smoothed data in grid coordinates, like gridData this.renderer._smoothedData = []; // this is smoothed data in plot units (plot coordinates), like plotData. this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; // prop: bandData // Data used to draw error bands or confidence intervals above/below a line. // // bandData can be input in 3 forms. jqPlot will figure out which is the // low band line and which is the high band line for all forms: // // A 2 dimensional array like [[yl1, yl2, ...], [yu1, yu2, ...]] where // [yl1, yl2, ...] are y values of the lower line and // [yu1, yu2, ...] are y values of the upper line. // In this case there must be the same number of y data points as data points // in the series and the bands will inherit the x values of the series. // // A 2 dimensional array like [[[xl1, yl1], [xl2, yl2], ...], [[xh1, yh1], [xh2, yh2], ...]] // where [xl1, yl1] are x,y data points for the lower line and // [xh1, yh1] are x,y data points for the high line. // x values do not have to correspond to the x values of the series and can // be of any arbitrary length. // // Can be of form [[yl1, yu1], [yl2, yu2], [yl3, yu3], ...] where // there must be 3 or more arrays and there must be the same number of arrays // as there are data points in the series. In this case, // [yl1, yu1] specifies the lower and upper y values for the 1st // data point and so on. The bands will inherit the x // values from the series. this.renderer.bandData = []; // Group: bands // Banding around line, e.g error bands or confidence intervals. this.renderer.bands = { // prop: show // true to show the bands. If bandData or interval is // supplied, show will be set to true by default. show: false, hiData: [], lowData: [], // prop: color // color of lines at top and bottom of bands [default: series color]. color: this.color, // prop: showLines // True to show lines at top and bottom of bands [default: false]. showLines: false, // prop: fill // True to fill area between bands [default: true]. fill: true, // prop: fillColor // css color spec for filled area. [default: series color]. fillColor: null, _min: null, _max: null, // prop: interval // User specified interval above and below line for bands [default: '3%'']. // Can be a value like 3 or a string like '3%' // or an upper/lower array like [1, -2] or ['2%', '-1.5%'] interval: '3%' }; var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor}; delete (options.highlightMouseOver); delete (options.highlightMouseDown); delete (options.highlightColor); $.extend(true, this.renderer, options); this.renderer.options = options; // if we are given some band data, and bands aren't explicity set to false in options, turn them on. if (this.renderer.bandData.length > 1 && (!options.bands || options.bands.show == null)) { this.renderer.bands.show = true; } // if we are given an interval, and bands aren't explicity set to false in options, turn them on. else if (options.bands && options.bands.show == null && options.bands.interval != null) { this.renderer.bands.show = true; } // if plot is filled, turn off bands. if (this.fill) { this.renderer.bands.show = false; } if (this.renderer.bands.show) { this.renderer.initBands.call(this, this.renderer.options, plot); } // smoothing is not compatible with stacked lines, disable if (this._stack) { this.renderer.smooth = false; } // set the shape renderer options var opts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; this.renderer.shapeRenderer.init(opts); var shadow_offset = options.shadowOffset; // set the shadow renderer options if (shadow_offset == null) { // scale the shadowOffset to the width of the line. if (this.lineWidth > 2.5) { shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); // var shadow_offset = this.shadowOffset; } // for skinny lines, don't make such a big shadow. else { shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163; } } var sopts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; this.renderer.shadowRenderer.init(sopts); this._areaPoints = []; this._boundingBox = [[],[]]; if (!this.isTrendline && this.fill || this.renderer.bands.show) { // Group: Properties // // prop: highlightMouseOver // True to highlight area on a filled plot when moused over. // This must be false to enable highlightMouseDown to highlight when clicking on an area on a filled plot. this.highlightMouseOver = true; // prop: highlightMouseDown // True to highlight when a mouse button is pressed over an area on a filled plot. // This will be disabled if highlightMouseOver is true. this.highlightMouseDown = false; // prop: highlightColor // color to use when highlighting an area on a filled plot. this.highlightColor = null; // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver if (lopts.highlightMouseDown && lopts.highlightMouseOver == null) { lopts.highlightMouseOver = false; } $.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor}); if (!this.highlightColor) { var fc = (this.renderer.bands.show) ? this.renderer.bands.fillColor : this.fillColor; this.highlightColor = $.jqplot.computeHighlightColors(fc); } // turn off (disable) the highlighter plugin if (this.highlighter) { this.highlighter.show = false; } } if (!this.isTrendline && plot) { plot.plugins.lineRenderer = {}; plot.postInitHooks.addOnce(postInit); plot.postDrawHooks.addOnce(postPlotDraw); plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); plot.eventListenerHooks.addOnce('jqplotClick', handleClick); plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); } }; $.jqplot.LineRenderer.prototype.initBands = function(options, plot) { // use bandData if no data specified in bands option //var bd = this.renderer.bandData; var bd = options.bandData || []; var bands = this.renderer.bands; bands.hiData = []; bands.lowData = []; var data = this.data; bands._max = null; bands._min = null; // If 2 arrays, and each array greater than 2 elements, assume it is hi and low data bands of y values. if (bd.length == 2) { // Do we have an array of x,y values? // like [[[1,1], [2,4], [3,3]], [[1,3], [2,6], [3,5]]] if ($.isArray(bd[0][0])) { // since an arbitrary array of points, spin through all of them to determine max and min lines. var p; var bdminidx = 0, bdmaxidx = 0; for (var i = 0, l = bd[0].length; i<l; i++) { p = bd[0][i]; if ((p[1] != null && p[1] > bands._max) || bands._max == null) { bands._max = p[1]; } if ((p[1] != null && p[1] < bands._min) || bands._min == null) { bands._min = p[1]; } } for (var i = 0, l = bd[1].length; i<l; i++) { p = bd[1][i]; if ((p[1] != null && p[1] > bands._max) || bands._max == null) { bands._max = p[1]; bdmaxidx = 1; } if ((p[1] != null && p[1] < bands._min) || bands._min == null) { bands._min = p[1]; bdminidx = 1; } } if (bdmaxidx === bdminidx) { bands.show = false; } bands.hiData = bd[bdmaxidx]; bands.lowData = bd[bdminidx]; } // else data is arrays of y values // like [[1,4,3], [3,6,5]] // must have same number of band data points as points in series else if (bd[0].length === data.length && bd[1].length === data.length) { var hi = (bd[0][0] > bd[1][0]) ? 0 : 1; var low = (hi) ? 0 : 1; for (var i=0, l=data.length; i < l; i++) { bands.hiData.push([data[i][0], bd[hi][i]]); bands.lowData.push([data[i][0], bd[low][i]]); } } // we don't have proper data array, don't show bands. else { bands.show = false; } } // if more than 2 arrays, have arrays of [ylow, yhi] values. // note, can't distinguish case of [[ylow, yhi], [ylow, yhi]] from [[ylow, ylow], [yhi, yhi]] // this is assumed to be of the latter form. else if (bd.length > 2 && !$.isArray(bd[0][0])) { var hi = (bd[0][0] > bd[0][1]) ? 0 : 1; var low = (hi) ? 0 : 1; for (var i=0, l=bd.length; i<l; i++) { bands.hiData.push([data[i][0], bd[i][hi]]); bands.lowData.push([data[i][0], bd[i][low]]); } } // don't have proper data, auto calculate else { var intrv = bands.interval; var a = null; var b = null; var afunc = null; var bfunc = null; if ($.isArray(intrv)) { a = intrv[0]; b = intrv[1]; } else { a = intrv; } if (isNaN(a)) { // we have a string if (a.charAt(a.length - 1) === '%') { afunc = 'multiply'; a = parseFloat(a)/100 + 1; } } else { a = parseFloat(a); afunc = 'add'; } if (b !== null && isNaN(b)) { // we have a string if (b.charAt(b.length - 1) === '%') { bfunc = 'multiply'; b = parseFloat(b)/100 + 1; } } else if (b !== null) { b = parseFloat(b); bfunc = 'add'; } if (a !== null) { if (b === null) { b = -a; bfunc = afunc; if (bfunc === 'multiply') { b += 2; } } // make sure a always applies to hi band. if (a < b) { var temp = a; a = b; b = temp; temp = afunc; afunc = bfunc; bfunc = temp; } for (var i=0, l = data.length; i < l; i++) { switch (afunc) { case 'add': bands.hiData.push([data[i][0], data[i][1] + a]); break; case 'multiply': bands.hiData.push([data[i][0], data[i][1] * a]); break; } switch (bfunc) { case 'add': bands.lowData.push([data[i][0], data[i][1] + b]); break; case 'multiply': bands.lowData.push([data[i][0], data[i][1] * b]); break; } } } else { bands.show = false; } } var hd = bands.hiData; var ld = bands.lowData; for (var i = 0, l = hd.length; i<l; i++) { if ((hd[i][1] != null && hd[i][1] > bands._max) || bands._max == null) { bands._max = hd[i][1]; } } for (var i = 0, l = ld.length; i<l; i++) { if ((ld[i][1] != null && ld[i][1] < bands._min) || bands._min == null) { bands._min = ld[i][1]; } } // one last check for proper data // these don't apply any more since allowing arbitrary x,y values // if (bands.hiData.length != bands.lowData.length) { // bands.show = false; // } // if (bands.hiData.length != this.data.length) { // bands.show = false; // } if (bands.fillColor === null) { var c = $.jqplot.getColorComponents(bands.color); // now adjust alpha to differentiate fill c[3] = c[3] * 0.5; bands.fillColor = 'rgba(' + c[0] +', '+ c[1] +', '+ c[2] +', '+ c[3] + ')'; } }; function getSteps (d, f) { return (3.4182054+f) * Math.pow(d, -0.3534992); } function computeSteps (d1, d2) { var s = Math.sqrt(Math.pow((d2[0]- d1[0]), 2) + Math.pow ((d2[1] - d1[1]), 2)); return 5.7648 * Math.log(s) + 7.4456; } function tanh (x) { var a = (Math.exp(2*x) - 1) / (Math.exp(2*x) + 1); return a; } ////////// // computeConstrainedSmoothedData // An implementation of the constrained cubic spline interpolation // method as presented in: // // Kruger, CJC, Constrained Cubic Spine Interpolation for Chemical Engineering Applications // http://www.korf.co.uk/spline.pdf // // The implementation below borrows heavily from the sample Visual Basic // implementation by CJC Kruger found in http://www.korf.co.uk/spline.xls // ///////// // called with scope of series function computeConstrainedSmoothedData (gd) { var smooth = this.renderer.smooth; var dim = this.canvas.getWidth(); var xp = this._xaxis.series_p2u; var yp = this._yaxis.series_p2u; var steps =null; var _steps = null; var dist = gd.length/dim; var _smoothedData = []; var _smoothedPlotData = []; if (!isNaN(parseFloat(smooth))) { steps = parseFloat(smooth); } else { steps = getSteps(dist, 0.5); } var yy = []; var xx = []; for (var i=0, l = gd.length; i<l; i++) { yy.push(gd[i][1]); xx.push(gd[i][0]); } function dxx(x1, x0) { if (x1 - x0 == 0) { return Math.pow(10,10); } else { return x1 - x0; } } var A, B, C, D; // loop through each line segment. Have # points - 1 line segments. Nmber segments starting at 1. var nmax = gd.length - 1; for (var num = 1, gdl = gd.length; num<gdl; num++) { var gxx = []; var ggxx = []; // point at each end of segment. for (var j = 0; j < 2; j++) { var i = num - 1 + j; // point number, 0 to # points. if (i == 0 || i == nmax) { gxx[j] = Math.pow(10, 10); } else if (yy[i+1] - yy[i] == 0 || yy[i] - yy[i-1] == 0) { gxx[j] = 0; } else if (((xx[i+1] - xx[i]) / (yy[i+1] - yy[i]) + (xx[i] - xx[i-1]) / (yy[i] - yy[i-1])) == 0 ) { gxx[j] = 0; } else if ( (yy[i+1] - yy[i]) * (yy[i] - yy[i-1]) < 0 ) { gxx[j] = 0; } else { gxx[j] = 2 / (dxx(xx[i + 1], xx[i]) / (yy[i + 1] - yy[i]) + dxx(xx[i], xx[i - 1]) / (yy[i] - yy[i - 1])); } } // Reset first derivative (slope) at first and last point if (num == 1) { // First point has 0 2nd derivative gxx[0] = 3 / 2 * (yy[1] - yy[0]) / dxx(xx[1], xx[0]) - gxx[1] / 2; } else if (num == nmax) { // Last point has 0 2nd derivative gxx[1] = 3 / 2 * (yy[nmax] - yy[nmax - 1]) / dxx(xx[nmax], xx[nmax - 1]) - gxx[0] / 2; } // Calc second derivative at points ggxx[0] = -2 * (gxx[1] + 2 * gxx[0]) / dxx(xx[num], xx[num - 1]) + 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); ggxx[1] = 2 * (2 * gxx[1] + gxx[0]) / dxx(xx[num], xx[num - 1]) - 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); // Calc constants for cubic interpolation D = 1 / 6 * (ggxx[1] - ggxx[0]) / dxx(xx[num], xx[num - 1]); C = 1 / 2 * (xx[num] * ggxx[0] - xx[num - 1] * ggxx[1]) / dxx(xx[num], xx[num - 1]); B = (yy[num] - yy[num - 1] - C * (Math.pow(xx[num], 2) - Math.pow(xx[num - 1], 2)) - D * (Math.pow(xx[num], 3) - Math.pow(xx[num - 1], 3))) / dxx(xx[num], xx[num - 1]); A = yy[num - 1] - B * xx[num - 1] - C * Math.pow(xx[num - 1], 2) - D * Math.pow(xx[num - 1], 3); var increment = (xx[num] - xx[num - 1]) / steps; var temp, tempx; for (var j = 0, l = steps; j < l; j++) { temp = []; tempx = xx[num - 1] + j * increment; temp.push(tempx); temp.push(A + B * tempx + C * Math.pow(tempx, 2) + D * Math.pow(tempx, 3)); _smoothedData.push(temp); _smoothedPlotData.push([xp(temp[0]), yp(temp[1])]); } } _smoothedData.push(gd[i]); _smoothedPlotData.push([xp(gd[i][0]), yp(gd[i][1])]); return [_smoothedData, _smoothedPlotData]; } /////// // computeHermiteSmoothedData // A hermite spline smoothing of the plot data. // This implementation is derived from the one posted // by krypin on the jqplot-users mailing list: // // http://groups.google.com/group/jqplot-users/browse_thread/thread/748be6a445723cea?pli=1 // // with a blog post: // // http://blog.statscollector.com/a-plugin-renderer-for-jqplot-to-draw-a-hermite-spline/ // // and download of the original plugin: // // http://blog.statscollector.com/wp-content/uploads/2010/02/jqplot.hermiteSplineRenderer.js ////////// // called with scope of series function computeHermiteSmoothedData (gd) { var smooth = this.renderer.smooth; var tension = this.renderer.tension; var dim = this.canvas.getWidth(); var xp = this._xaxis.series_p2u; var yp = this._yaxis.series_p2u; var steps =null; var _steps = null; var a = null; var a1 = null; var a2 = null; var slope = null; var slope2 = null; var temp = null; var t, s, h1, h2, h3, h4; var TiX, TiY, Ti1X, Ti1Y; var pX, pY, p; var sd = []; var spd = []; var dist = gd.length/dim; var min, max, stretch, scale, shift; var _smoothedData = []; var _smoothedPlotData = []; if (!isNaN(parseFloat(smooth))) { steps = parseFloat(smooth); } else { steps = getSteps(dist, 0.5); } if (!isNaN(parseFloat(tension))) { tension = parseFloat(tension); } for (var i=0, l = gd.length-1; i < l; i++) { if (tension === null) { slope = Math.abs((gd[i+1][1] - gd[i][1]) / (gd[i+1][0] - gd[i][0])); min = 0.3; max = 0.6; stretch = (max - min)/2.0; scale = 2.5; shift = -1.4; temp = slope/scale + shift; a1 = stretch * tanh(temp) - stretch * tanh(shift) + min; // if have both left and right line segments, will use minimum tension. if (i > 0) { slope2 = Math.abs((gd[i][1] - gd[i-1][1]) / (gd[i][0] - gd[i-1][0])); } temp = slope2/scale + shift; a2 = stretch * tanh(temp) - stretch * tanh(shift) + min; a = (a1 + a2)/2.0; } else { a = tension; } for (t=0; t < steps; t++) { s = t / steps; h1 = (1 + 2*s)*Math.pow((1-s),2); h2 = s*Math.pow((1-s),2); h3 = Math.pow(s,2)*(3-2*s); h4 = Math.pow(s,2)*(s-1); if (gd[i-1]) { TiX = a * (gd[i+1][0] - gd[i-1][0]); TiY = a * (gd[i+1][1] - gd[i-1][1]); } else { TiX = a * (gd[i+1][0] - gd[i][0]); TiY = a * (gd[i+1][1] - gd[i][1]); } if (gd[i+2]) { Ti1X = a * (gd[i+2][0] - gd[i][0]); Ti1Y = a * (gd[i+2][1] - gd[i][1]); } else { Ti1X = a * (gd[i+1][0] - gd[i][0]); Ti1Y = a * (gd[i+1][1] - gd[i][1]); } pX = h1*gd[i][0] + h3*gd[i+1][0] + h2*TiX + h4*Ti1X; pY = h1*gd[i][1] + h3*gd[i+1][1] + h2*TiY + h4*Ti1Y; p = [pX, pY]; _smoothedData.push(p); _smoothedPlotData.push([xp(pX), yp(pY)]); } } _smoothedData.push(gd[l]); _smoothedPlotData.push([xp(gd[l][0]), yp(gd[l][1])]); return [_smoothedData, _smoothedPlotData]; } // setGridData // converts the user data values to grid coordinates and stores them // in the gridData array. // Called with scope of a series. $.jqplot.LineRenderer.prototype.setGridData = function(plot) { // recalculate the grid data var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var data = this._plotData; var pdata = this._prevPlotData; this.gridData = []; this._prevGridData = []; this.renderer._smoothedData = []; this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; var bands = this.renderer.bands; var hasNull = false; for (var i=0, l=this.data.length; i < l; i++) { // if not a line series or if no nulls in data, push the converted point onto the array. if (data[i][0] != null && data[i][1] != null) { this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); } // else if there is a null, preserve it. else if (data[i][0] == null) { hasNull = true; this.gridData.push([null, yp.call(this._yaxis, data[i][1])]); } else if (data[i][1] == null) { hasNull = true; this.gridData.push([xp.call(this._xaxis, data[i][0]), null]); } // if not a line series or if no nulls in data, push the converted point onto the array. if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] != null) { this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]); } // else if there is a null, preserve it. else if (pdata[i] != null && pdata[i][0] == null) { this._prevGridData.push([null, yp.call(this._yaxis, pdata[i][1])]); } else if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] == null) { this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]); } } // don't do smoothing or bands on broken lines. if (hasNull) { this.renderer.smooth = false; if (this._type === 'line') { bands.show = false; } } if (this._type === 'line' && bands.show) { for (var i=0, l=bands.hiData.length; i<l; i++) { this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); } for (var i=0, l=bands.lowData.length; i<l; i++) { this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); } } // calculate smoothed data if enough points and no nulls if (this._type === 'line' && this.renderer.smooth && this.gridData.length > 2) { var ret; if (this.renderer.constrainSmoothing) { ret = computeConstrainedSmoothedData.call(this, this.gridData); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } else { ret = computeHermiteSmoothedData.call(this, this.gridData); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } } }; // makeGridData // converts any arbitrary data values to grid coordinates and // returns them. This method exists so that plugins can use a series' // linerenderer to generate grid data points without overwriting the // grid data associated with that series. // Called with scope of a series. $.jqplot.LineRenderer.prototype.makeGridData = function(data, plot) { // recalculate the grid data var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var gd = []; var pgd = []; this.renderer._smoothedData = []; this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; var bands = this.renderer.bands; var hasNull = false; for (var i=0; i<data.length; i++) { // if not a line series or if no nulls in data, push the converted point onto the array. if (data[i][0] != null && data[i][1] != null) { gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); } // else if there is a null, preserve it. else if (data[i][0] == null) { hasNull = true; gd.push([null, yp.call(this._yaxis, data[i][1])]); } else if (data[i][1] == null) { hasNull = true; gd.push([xp.call(this._xaxis, data[i][0]), null]); } } // don't do smoothing or bands on broken lines. if (hasNull) { this.renderer.smooth = false; if (this._type === 'line') { bands.show = false; } } if (this._type === 'line' && bands.show) { for (var i=0, l=bands.hiData.length; i<l; i++) { this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); } for (var i=0, l=bands.lowData.length; i<l; i++) { this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); } } if (this._type === 'line' && this.renderer.smooth && gd.length > 2) { var ret; if (this.renderer.constrainSmoothing) { ret = computeConstrainedSmoothedData.call(this, gd); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } else { ret = computeHermiteSmoothedData.call(this, gd); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } } return gd; }; // called within scope of series. $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options, plot) { var i; // get a copy of the options, so we don't modify the original object. var opts = $.extend(true, {}, options); var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; var fill = (opts.fill != undefined) ? opts.fill : this.fill; var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; var xmin, ymin, xmax, ymax; ctx.save(); if (gd.length) { if (showLine) { // if we fill, we'll have to add points to close the curve. if (fill) { if (this.fillToZero) { // have to break line up into shapes at axis crossings var negativeColor = this.negativeColor; if (! this.useNegativeColors) { negativeColor = opts.fillStyle; } var isnegative = false; var posfs = opts.fillStyle; // if stoking line as well as filling, get a copy of line data. if (fillAndStroke) { var fasgd = gd.slice(0); } // if not stacked, fill down to axis if (this.index == 0 || !this._stack) { var tempgd = []; var pd = (this.renderer.smooth) ? this.renderer._smoothedPlotData : this._plotData; this._areaPoints = []; var pyzero = this._yaxis.series_u2p(this.fillToValue); var pxzero = this._xaxis.series_u2p(this.fillToValue); opts.closePath = true; if (this.fillAxis == 'y') { tempgd.push([gd[0][0], pyzero]); this._areaPoints.push([gd[0][0], pyzero]); for (var i=0; i<gd.length-1; i++) { tempgd.push(gd[i]); this._areaPoints.push(gd[i]); // do we have an axis crossing? if (pd[i][1] * pd[i+1][1] < 0) { if (pd[i][1] < 0) { isnegative = true; opts.fillStyle = negativeColor; } else { isnegative = false; opts.fillStyle = posfs; } var xintercept = gd[i][0] + (gd[i+1][0] - gd[i][0]) * (pyzero-gd[i][1])/(gd[i+1][1] - gd[i][1]); tempgd.push([xintercept, pyzero]); this._areaPoints.push([xintercept, pyzero]); // now draw this shape and shadow. if (shadow) { this.renderer.shadowRenderer.draw(ctx, tempgd, opts); } this.renderer.shapeRenderer.draw(ctx, tempgd, opts); // now empty temp array and continue tempgd = [[xintercept, pyzero]]; // this._areaPoints = [[xintercept, pyzero]]; } } if (pd[gd.length-1][1] < 0) { isnegative = true; opts.fillStyle = negativeColor; } else { isnegative = false; opts.fillStyle = posfs; } tempgd.push(gd[gd.length-1]); this._areaPoints.push(gd[gd.length-1]); tempgd.push([gd[gd.length-1][0], pyzero]); this._areaPoints.push([gd[gd.length-1][0], pyzero]); } // now draw the last area. if (shadow) { this.renderer.shadowRenderer.draw(ctx, tempgd, opts); } this.renderer.shapeRenderer.draw(ctx, tempgd, opts); // var gridymin = this._yaxis.series_u2p(0); // // IE doesn't return new length on unshift // gd.unshift([gd[0][0], gridymin]); // len = gd.length; // gd.push([gd[len - 1][0], gridymin]); } // if stacked, fill to line below else { var prev = this._prevGridData; for (var i=prev.length; i>0; i--) { gd.push(prev[i-1]); // this._areaPoints.push(prev[i-1]); } if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this._areaPoints = gd; this.renderer.shapeRenderer.draw(ctx, gd, opts); } } ///////////////////////// // Not filled to zero //////////////////////// else { // if stoking line as well as filling, get a copy of line data. if (fillAndStroke) { var fasgd = gd.slice(0); } // if not stacked, fill down to axis if (this.index == 0 || !this._stack) { // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2; var gridymin = ctx.canvas.height; // IE doesn't return new length on unshift gd.unshift([gd[0][0], gridymin]); var len = gd.length; gd.push([gd[len - 1][0], gridymin]); } // if stacked, fill to line below else { var prev = this._prevGridData; for (var i=prev.length; i>0; i--) { gd.push(prev[i-1]); } } this._areaPoints = gd; if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this.renderer.shapeRenderer.draw(ctx, gd, opts); } if (fillAndStroke) { var fasopts = $.extend(true, {}, opts, {fill:false, closePath:false}); this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts); ////////// // TODO: figure out some way to do shadows nicely // if (shadow) { // this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts); // } // now draw the markers if (this.markerRenderer.show) { if (this.renderer.smooth) { fasgd = this.gridData; } for (i=0; i<fasgd.length; i++) { this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions); } } } } else { if (this.renderer.bands.show) { var bdat; var bopts = $.extend(true, {}, opts); if (this.renderer.bands.showLines) { bdat = (this.renderer.smooth) ? this.renderer._hiBandSmoothedData : this.renderer._hiBandGridData; this.renderer.shapeRenderer.draw(ctx, bdat, opts); bdat = (this.renderer.smooth) ? this.renderer._lowBandSmoothedData : this.renderer._lowBandGridData; this.renderer.shapeRenderer.draw(ctx, bdat, bopts); } if (this.renderer.bands.fill) { if (this.renderer.smooth) { bdat = this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse()); } else { bdat = this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse()); } this._areaPoints = bdat; bopts.closePath = true; bopts.fill = true; bopts.fillStyle = this.renderer.bands.fillColor; this.renderer.shapeRenderer.draw(ctx, bdat, bopts); } } if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this.renderer.shapeRenderer.draw(ctx, gd, opts); } } // calculate the bounding box var xmin = xmax = ymin = ymax = null; for (i=0; i<this._areaPoints.length; i++) { var p = this._areaPoints[i]; if (xmin > p[0] || xmin == null) { xmin = p[0]; } if (ymax < p[1] || ymax == null) { ymax = p[1]; } if (xmax < p[0] || xmax == null) { xmax = p[0]; } if (ymin > p[1] || ymin == null) { ymin = p[1]; } } if (this.type === 'line' && this.renderer.bands.show) { ymax = this._yaxis.series_u2p(this.renderer.bands._min); ymin = this._yaxis.series_u2p(this.renderer.bands._max); } this._boundingBox = [[xmin, ymax], [xmax, ymin]]; // now draw the markers if (this.markerRenderer.show && !fill) { if (this.renderer.smooth) { gd = this.gridData; } for (i=0; i<gd.length; i++) { if (gd[i][0] != null && gd[i][1] != null) { this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions); } } } } ctx.restore(); }; $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) { // This is a no-op, shadows drawn with lines. }; // called with scope of plot. // make sure to not leave anything highlighted. function postInit(target, data, options) { for (var i=0; i<this.series.length; i++) { if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) { // don't allow mouseover and mousedown at same time. if (this.series[i].highlightMouseOver) { this.series[i].highlightMouseDown = false; } } } } // called within context of plot // create a canvas which we can draw on. // insert it before the eventCanvas, so eventCanvas will still capture events. function postPlotDraw() { // Memory Leaks patch if (this.plugins.lineRenderer && this.plugins.lineRenderer.highlightCanvas) { this.plugins.lineRenderer.highlightCanvas.resetCanvas(); this.plugins.lineRenderer.highlightCanvas = null; } this.plugins.lineRenderer.highlightedSeriesIndex = null; this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions, this)); this.plugins.lineRenderer.highlightCanvas.setContext(); this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); } function highlight (plot, sidx, pidx, points) { var s = plot.series[sidx]; var canvas = plot.plugins.lineRenderer.highlightCanvas; canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); s._highlightedPoint = pidx; plot.plugins.lineRenderer.highlightedSeriesIndex = sidx; var opts = {fillStyle: s.highlightColor}; if (s.type === 'line' && s.renderer.bands.show) { opts.fill = true; opts.closePath = true; } s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); canvas = null; } function unhighlight (plot) { var canvas = plot.plugins.lineRenderer.highlightCanvas; canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); for (var i=0; i<plot.series.length; i++) { plot.series[i]._highlightedPoint = null; } plot.plugins.lineRenderer.highlightedSeriesIndex = null; plot.target.trigger('jqplotDataUnhighlight'); canvas = null; } function handleMove(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt1 = jQuery.Event('jqplotDataMouseOver'); evt1.pageX = ev.pageX; evt1.pageY = ev.pageY; plot.target.trigger(evt1, ins); if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } } function handleClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt = jQuery.Event('jqplotDataClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } function handleRightClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } var evt = jQuery.Event('jqplotDataRightClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } // class: $.jqplot.LinearAxisRenderer // The default jqPlot axis renderer, creating a numeric axis. $.jqplot.LinearAxisRenderer = function() { }; // called with scope of axis object. $.jqplot.LinearAxisRenderer.prototype.init = function(options){ // prop: breakPoints // EXPERIMENTAL!! Use at your own risk! // Works only with linear axes and the default tick renderer. // Array of [start, stop] points to create a broken axis. // Broken axes have a "jump" in them, which is an immediate // transition from a smaller value to a larger value. // Currently, axis ticks MUST be manually assigned if using breakPoints // by using the axis ticks array option. this.breakPoints = null; // prop: breakTickLabel // Label to use at the axis break if breakPoints are specified. this.breakTickLabel = "≈"; // prop: drawBaseline // True to draw the axis baseline. this.drawBaseline = true; // prop: baselineWidth // width of the baseline in pixels. this.baselineWidth = null; // prop: baselineColor // CSS color spec for the baseline. this.baselineColor = null; // prop: forceTickAt0 // This will ensure that there is always a tick mark at 0. // If data range is strictly positive or negative, // this will force 0 to be inside the axis bounds unless // the appropriate axis pad (pad, padMin or padMax) is set // to 0, then this will force an axis min or max value at 0. // This has know effect when any of the following options // are set: autoscale, min, max, numberTicks or tickInterval. this.forceTickAt0 = false; // prop: forceTickAt100 // This will ensure that there is always a tick mark at 100. // If data range is strictly above or below 100, // this will force 100 to be inside the axis bounds unless // the appropriate axis pad (pad, padMin or padMax) is set // to 0, then this will force an axis min or max value at 100. // This has know effect when any of the following options // are set: autoscale, min, max, numberTicks or tickInterval. this.forceTickAt100 = false; // prop: tickInset // Controls the amount to inset the first and last ticks from // the edges of the grid, in multiples of the tick interval. // 0 is no inset, 0.5 is one half a tick interval, 1 is a full // tick interval, etc. this.tickInset = 0; // prop: minorTicks // Number of ticks to add between "major" ticks. // Major ticks are ticks supplied by user or auto computed. // Minor ticks cannot be created by user. this.minorTicks = 0; // prop: alignTicks // true to align tick marks across opposed axes // such as from the y2axis to yaxis. this.alignTicks = false; this._autoFormatString = ''; this._overrideFormatString = false; this._scalefact = 1.0; $.extend(true, this, options); if (this.breakPoints) { if (!$.isArray(this.breakPoints)) { this.breakPoints = null; } else if (this.breakPoints.length < 2 || this.breakPoints[1] <= this.breakPoints[0]) { this.breakPoints = null; } } if (this.numberTicks != null && this.numberTicks < 2) { this.numberTicks = 2; } this.resetDataBounds(); }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx, plot) { if (this.show) { // populate the axis label and value properties. // createTicks is a method on the renderer, but // call it within the scope of the axis. this.renderer.createTicks.call(this, plot); // fill a div with axes labels in the right direction. // Need to pregenerate each axis to get it's bounds and // position it and the labels correctly on the plot. var dim=0; var temp; // Added for theming. if (this._elem) { // Memory Leaks patch //this._elem.empty(); this._elem.emptyForce(); this._elem = null; } this._elem = $(document.createElement('div')); this._elem.addClass('jqplot-axis jqplot-'+this.name); this._elem.css('position', 'absolute'); if (this.name == 'xaxis' || this.name == 'x2axis') { this._elem.width(this._plotDimensions.width); } else { this._elem.height(this._plotDimensions.height); } // create a _label object. this.labelOptions.axis = this.name; this._label = new this.labelRenderer(this.labelOptions); if (this._label.show) { var elem = this._label.draw(ctx, plot); elem.appendTo(this._elem); elem = null; } var t = this._ticks; var tick; for (var i=0; i<t.length; i++) { tick = t[i]; if (tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { this._elem.append(tick.draw(ctx, plot)); } } tick = null; t = null; } return this._elem; }; // called with scope of an axis $.jqplot.LinearAxisRenderer.prototype.reset = function() { this.min = this._options.min; this.max = this._options.max; this.tickInterval = this._options.tickInterval; this.numberTicks = this._options.numberTicks; this._autoFormatString = ''; if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) { this.tickOptions.formatString = ''; } // this._ticks = this.__ticks; }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.set = function() { var dim = 0; var temp; var w = 0; var h = 0; var lshow = (this._label == null) ? false : this._label.show; if (this.show) { var t = this._ticks; var tick; for (var i=0; i<t.length; i++) { tick = t[i]; if (!tick._breakTick && tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { if (this.name == 'xaxis' || this.name == 'x2axis') { temp = tick._elem.outerHeight(true); } else { temp = tick._elem.outerWidth(true); } if (temp > dim) { dim = temp; } } } tick = null; t = null; if (lshow) { w = this._label._elem.outerWidth(true); h = this._label._elem.outerHeight(true); } if (this.name == 'xaxis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); } else if (this.name == 'x2axis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); } else if (this.name == 'yaxis') { dim = dim + w; this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } else { dim = dim + w; this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } } }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.createTicks = function(plot) { // we're are operating on an axis here var ticks = this._ticks; var userTicks = this.ticks; var name = this.name; // databounds were set on axis initialization. var db = this._dataBounds; var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; var interval; var min, max; var pos1, pos2; var tt, i; // get a copy of user's settings for min/max. var userMin = this.min; var userMax = this.max; var userNT = this.numberTicks; var userTI = this.tickInterval; var threshold = 30; this._scalefact = (Math.max(dim, threshold+1) - threshold)/300.0; // if we already have ticks, use them. // ticks must be in order of increasing value. if (userTicks.length) { // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed for (i=0; i<userTicks.length; i++){ var ut = userTicks[i]; var t = new this.tickRenderer(this.tickOptions); if ($.isArray(ut)) { t.value = ut[0]; if (this.breakPoints) { if (ut[0] == this.breakPoints[0]) { t.label = this.breakTickLabel; t._breakTick = true; t.showGridline = false; t.showMark = false; } else if (ut[0] > this.breakPoints[0] && ut[0] <= this.breakPoints[1]) { t.show = false; t.showGridline = false; t.label = ut[1]; } else { t.label = ut[1]; } } else { t.label = ut[1]; } t.setTick(ut[0], this.name); this._ticks.push(t); } else if ($.isPlainObject(ut)) { $.extend(true, t, ut); t.axis = this.name; this._ticks.push(t); } else { t.value = ut; if (this.breakPoints) { if (ut == this.breakPoints[0]) { t.label = this.breakTickLabel; t._breakTick = true; t.showGridline = false; t.showMark = false; } else if (ut > this.breakPoints[0] && ut <= this.breakPoints[1]) { t.show = false; t.showGridline = false; } } t.setTick(ut, this.name); this._ticks.push(t); } } this.numberTicks = userTicks.length; this.min = this._ticks[0].value; this.max = this._ticks[this.numberTicks-1].value; this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); } // we don't have any ticks yet, let's make some! else { if (name == 'xaxis' || name == 'x2axis') { dim = this._plotDimensions.width; } else { dim = this._plotDimensions.height; } var _numberTicks = this.numberTicks; // if aligning this axis, use number of ticks from previous axis. // Do I need to reset somehow if alignTicks is changed and then graph is replotted?? if (this.alignTicks) { if (this.name === 'x2axis' && plot.axes.xaxis.show) { _numberTicks = plot.axes.xaxis.numberTicks; } else if (this.name.charAt(0) === 'y' && this.name !== 'yaxis' && this.name !== 'yMidAxis' && plot.axes.yaxis.show) { _numberTicks = plot.axes.yaxis.numberTicks; } } min = ((this.min != null) ? this.min : db.min); max = ((this.max != null) ? this.max : db.max); var range = max - min; var rmin, rmax; var temp; if (this.tickOptions == null || !this.tickOptions.formatString) { this._overrideFormatString = true; } // Doing complete autoscaling if (this.min == null && this.max == null && this.tickInterval == null && !this.autoscale) { // Check if user must have tick at 0 or 100 and ensure they are in range. // The autoscaling algorithm will always place ticks at 0 and 100 if they are in range. if (this.forceTickAt0) { if (min > 0) { min = 0; } if (max < 0) { max = 0; } } if (this.forceTickAt100) { if (min > 100) { min = 100; } if (max < 100) { max = 100; } } // var threshold = 30; // var tdim = Math.max(dim, threshold+1); // this._scalefact = (tdim-threshold)/300.0; var ret = $.jqplot.LinearTickGenerator(min, max, this._scalefact, _numberTicks); // calculate a padded max and min, points should be less than these // so that they aren't too close to the edges of the plot. // User can adjust how much padding is allowed with pad, padMin and PadMax options. var tumin = min + range*(this.padMin - 1); var tumax = max - range*(this.padMax - 1); // if they're equal, we shouldn't have to do anything, right? // if (min <=tumin || max >= tumax) { if (min <tumin || max > tumax) { tumin = min - range*(this.padMin - 1); tumax = max + range*(this.padMax - 1); ret = $.jqplot.LinearTickGenerator(tumin, tumax, this._scalefact, _numberTicks); } this.min = ret[0]; this.max = ret[1]; // if numberTicks specified, it should return the same. this.numberTicks = ret[2]; this._autoFormatString = ret[3]; this.tickInterval = ret[4]; } // User has specified some axis scale related option, can use auto algorithm else { // if min and max are same, space them out a bit if (min == max) { var adj = 0.05; if (min > 0) { adj = Math.max(Math.log(min)/Math.LN10, 0.05); } min -= adj; max += adj; } // autoscale. Can't autoscale if min or max is supplied. // Will use numberTicks and tickInterval if supplied. Ticks // across multiple axes may not line up depending on how // bars are to be plotted. if (this.autoscale && this.min == null && this.max == null) { var rrange, ti, margin; var forceMinZero = false; var forceZeroLine = false; var intervals = {min:null, max:null, average:null, stddev:null}; // if any series are bars, or if any are fill to zero, and if this // is the axis to fill toward, check to see if we can start axis at zero. for (var i=0; i<this._series.length; i++) { var s = this._series[i]; var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name; // check to see if this is the fill axis if (this.name == faname) { var vals = s._plotValues[s.fillAxis]; var vmin = vals[0]; var vmax = vals[0]; for (var j=1; j<vals.length; j++) { if (vals[j] < vmin) { vmin = vals[j]; } else if (vals[j] > vmax) { vmax = vals[j]; } } var dp = (vmax - vmin) / vmax; // is this sries a bar? if (s.renderer.constructor == $.jqplot.BarRenderer) { // if no negative values and could also check range. if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { forceMinZero = true; } else { forceMinZero = false; if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) { forceZeroLine = true; } else { forceZeroLine = false; } } } // if not a bar and filling, use appropriate method. else if (s.fill) { if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { forceMinZero = true; } else if (vmin < 0 && vmax > 0 && s.fillToZero) { forceMinZero = false; forceZeroLine = true; } else { forceMinZero = false; forceZeroLine = false; } } // if not a bar and not filling, only change existing state // if it doesn't make sense else if (vmin < 0) { forceMinZero = false; } } } // check if we need make axis min at 0. if (forceMinZero) { // compute number of ticks this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); this.min = 0; userMin = 0; // what order is this range? // what tick interval does that give us? ti = max/(this.numberTicks-1); temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); if (ti/temp == parseInt(ti/temp, 10)) { ti += temp; } this.tickInterval = Math.ceil(ti/temp) * temp; this.max = this.tickInterval * (this.numberTicks - 1); } // check if we need to make sure there is a tick at 0. else if (forceZeroLine) { // compute number of ticks this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1)); var ntmax = this.numberTicks - 1 - ntmin; ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax)); temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); this.tickInterval = Math.ceil(ti/temp) * temp; this.max = this.tickInterval * ntmax; this.min = -this.tickInterval * ntmin; } // if nothing else, do autoscaling which will try to line up ticks across axes. else { if (this.numberTicks == null){ if (this.tickInterval) { this.numberTicks = 3 + Math.ceil(range / this.tickInterval); } else { this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); } } if (this.tickInterval == null) { // get a tick interval ti = range/(this.numberTicks - 1); if (ti < 1) { temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); } else { temp = 1; } this.tickInterval = Math.ceil(ti*temp*this.pad)/temp; } else { temp = 1 / this.tickInterval; } // try to compute a nicer, more even tick interval // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10)); // this.tickInterval = Math.ceil(ti/temp) * temp; rrange = this.tickInterval * (this.numberTicks - 1); margin = (rrange - range)/2; if (this.min == null) { this.min = Math.floor(temp*(min-margin))/temp; } if (this.max == null) { this.max = this.min + rrange; } } // Compute a somewhat decent format string if it is needed. // get precision of interval and determine a format string. var sf = $.jqplot.getSignificantFigures(this.tickInterval); var fstr; // if we have only a whole number, use integer formatting if (sf.digitsLeft >= sf.significantDigits) { fstr = '%d'; } else { var temp = Math.max(0, 5 - sf.digitsLeft); temp = Math.min(temp, sf.digitsRight); fstr = '%.'+ temp + 'f'; } this._autoFormatString = fstr; } // Use the default algorithm which pads each axis to make the chart // centered nicely on the grid. else { rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1); rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1); range = rmax - rmin; if (this.numberTicks == null){ // if tickInterval is specified by user, we will ignore computed maximum. // max will be equal or greater to fit even # of ticks. if (this.tickInterval != null) { this.numberTicks = Math.ceil((rmax - rmin)/this.tickInterval)+1; } else if (dim > 100) { this.numberTicks = parseInt(3+(dim-100)/75, 10); } else { this.numberTicks = 2; } } if (this.tickInterval == null) { this.tickInterval = range / (this.numberTicks-1); } if (this.max == null) { rmax = rmin + this.tickInterval*(this.numberTicks - 1); } if (this.min == null) { rmin = rmax - this.tickInterval*(this.numberTicks - 1); } // get precision of interval and determine a format string. var sf = $.jqplot.getSignificantFigures(this.tickInterval); var fstr; // if we have only a whole number, use integer formatting if (sf.digitsLeft >= sf.significantDigits) { fstr = '%d'; } else { var temp = Math.max(0, 5 - sf.digitsLeft); temp = Math.min(temp, sf.digitsRight); fstr = '%.'+ temp + 'f'; } this._autoFormatString = fstr; this.min = rmin; this.max = rmax; } if (this.renderer.constructor == $.jqplot.LinearAxisRenderer && this._autoFormatString == '') { // fix for misleading tick display with small range and low precision. range = this.max - this.min; // figure out precision var temptick = new this.tickRenderer(this.tickOptions); // use the tick formatString or, the default. var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString; var fs = fs.match($.jqplot.sprintf.regex)[0]; var precision = 0; if (fs) { if (fs.search(/[fFeEgGpP]/) > -1) { var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/); if (m) { precision = parseInt(m[1], 10); } else { precision = 6; } } else if (fs.search(/[di]/) > -1) { precision = 0; } // fact will be <= 1; var fact = Math.pow(10, -precision); if (this.tickInterval < fact) { // need to correct underrange if (userNT == null && userTI == null) { this.tickInterval = fact; if (userMax == null && userMin == null) { // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact; this.min = Math.floor(this._dataBounds.min/fact) * fact; if (this.min == this._dataBounds.min) { this.min = this._dataBounds.min - this.tickInterval; } // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact; this.max = Math.ceil(this._dataBounds.max/fact) * fact; if (this.max == this._dataBounds.max) { this.max = this._dataBounds.max + this.tickInterval; } var n = (this.max - this.min)/this.tickInterval; n = n.toFixed(11); n = Math.ceil(n); this.numberTicks = n + 1; } else if (userMax == null) { // add one tick for top of range. var n = (this._dataBounds.max - this.min) / this.tickInterval; n = n.toFixed(11); this.numberTicks = Math.ceil(n) + 2; this.max = this.min + this.tickInterval * (this.numberTicks-1); } else if (userMin == null) { // add one tick for bottom of range. var n = (this.max - this._dataBounds.min) / this.tickInterval; n = n.toFixed(11); this.numberTicks = Math.ceil(n) + 2; this.min = this.max - this.tickInterval * (this.numberTicks-1); } else { // calculate a number of ticks so max is within axis scale this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1; // if user's min and max don't fit evenly in ticks, adjust. // This takes care of cases such as user min set to 0, max set to 3.5 but tick // format string set to %d (integer ticks) this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision); this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision); // this.max = this.min + this.tickInterval*(this.numberTicks-1); this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1; } } } } } } if (this._overrideFormatString && this._autoFormatString != '') { this.tickOptions = this.tickOptions || {}; this.tickOptions.formatString = this._autoFormatString; } var t, to; for (var i=0; i<this.numberTicks; i++){ tt = this.min + i * this.tickInterval; t = new this.tickRenderer(this.tickOptions); // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); t.setTick(tt, this.name); this._ticks.push(t); if (i < this.numberTicks - 1) { for (var j=0; j<this.minorTicks; j++) { tt += this.tickInterval/(this.minorTicks+1); to = $.extend(true, {}, this.tickOptions, {name:this.name, value:tt, label:'', isMinorTick:true}); t = new this.tickRenderer(to); this._ticks.push(t); } } t = null; } } if (this.tickInset) { this.min = this.min - this.tickInset * this.tickInterval; this.max = this.max + this.tickInset * this.tickInterval; } ticks = null; }; // Used to reset just the values of the ticks and then repack, which will // recalculate the positioning functions. It is assuemd that the // number of ticks is the same and the values of the new array are at the // proper interval. // This method needs to be called with the scope of an axis object, like: // // > plot.axes.yaxis.renderer.resetTickValues.call(plot.axes.yaxis, yarr); // $.jqplot.LinearAxisRenderer.prototype.resetTickValues = function(opts) { if ($.isArray(opts) && opts.length == this._ticks.length) { var t; for (var i=0; i<opts.length; i++) { t = this._ticks[i]; t.value = opts[i]; t.label = t.formatter(t.formatString, opts[i]); t.label = t.prefix + t.label; t._elem.html(t.label); } t = null; this.min = $.jqplot.arrayMin(opts); this.max = $.jqplot.arrayMax(opts); this.pack(); } // Not implemented yet. // else if ($.isPlainObject(opts)) { // // } }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) { // Add defaults for repacking from resetTickValues function. pos = pos || {}; offsets = offsets || this._offsets; var ticks = this._ticks; var max = this.max; var min = this.min; var offmax = offsets.max; var offmin = offsets.min; var lshow = (this._label == null) ? false : this._label.show; for (var p in pos) { this._elem.css(p, pos[p]); } this._offsets = offsets; // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. var pixellength = offmax - offmin; var unitlength = max - min; // point to unit and unit to point conversions references to Plot DOM element top left corner. if (this.breakPoints) { unitlength = unitlength - this.breakPoints[1] + this.breakPoints[0]; this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u <= this.breakPoints[0]) { return (u - min) * pixellength / unitlength + offmin; } else { return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength + offmin; } }; if (this.name.charAt(0) == 'x'){ this.series_u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u <= this.breakPoints[0]) { return (u - min) * pixellength / unitlength; } else { return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength; } }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u >= this.breakPoints[1]) { return (u - max) * pixellength / unitlength; } else { return (u + this.breakPoints[1] - this.breakPoints[0] - max) * pixellength / unitlength; } }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } else { this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ return (u - min) * pixellength / unitlength + offmin; }; if (this.name == 'xaxis' || this.name == 'x2axis'){ this.series_u2p = function(u){ return (u - min) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ return (u - max) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } if (this.show) { if (this.name == 'xaxis' || this.name == 'x2axis') { for (var i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'xaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end if (temp * t.angle < 0) { shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; } // position at start else { shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; } break; case 'end': shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; case 'start': shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; break; case 'middle': shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; default: shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; } } else { shim = -t.getWidth()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('left', val); t.pack(); } } if (lshow) { var w = this._label._elem.outerWidth(true); this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); if (this.name == 'xaxis') { this._label._elem.css('bottom', '0px'); } else { this._label._elem.css('top', '0px'); } this._label.pack(); } } else { for (var i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'yaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end case 'end': if (temp * t.angle < 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'start': if (t.angle > 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'middle': // if (t.angle > 0) { // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; // } // else { // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; // } shim = -t.getHeight()/2; break; default: shim = -t.getHeight()/2; break; } } else { shim = -t.getHeight()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('top', val); t.pack(); } } if (lshow) { var h = this._label._elem.outerHeight(true); this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); if (this.name == 'yaxis') { this._label._elem.css('left', '0px'); } else { this._label._elem.css('right', '0px'); } this._label.pack(); } } } ticks = null; }; /** * The following code was generaously given to me a while back by Scott Prahl. * He did a good job at computing axes min, max and number of ticks for the * case where the user has not set any scale related parameters (tickInterval, * numberTicks, min or max). I had ignored this use case for a long time, * focusing on the more difficult case where user has set some option controlling * tick generation. Anyway, about time I got this into jqPlot. * Thanks Scott!! */ /** * Copyright (c) 2010 Scott Prahl * The next three routines are currently available for use in all personal * or commercial projects under both the MIT and GPL version 2.0 licenses. * This means that you can choose the license that best suits your project * and use it accordingly. */ // A good format string depends on the interval. If the interval is greater // than 1 then there is no need to show any decimal digits. If it is < 1.0, then // use the magnitude of the interval to determine the number of digits to show. function bestFormatString (interval) { var fstr; interval = Math.abs(interval); if (interval >= 10) { fstr = '%d'; } else if (interval > 1) { if (interval === parseInt(interval, 10)) { fstr = '%d'; } else { fstr = '%.1f'; } } else { var expv = -Math.floor(Math.log(interval)/Math.LN10); fstr = '%.' + expv + 'f'; } return fstr; } var _factors = [0.1, 0.2, 0.3, 0.4, 0.5, 0.8, 1, 2, 3, 4, 5]; var _getLowerFactor = function(f) { var i = _factors.indexOf(f); if (i > 0) { return _factors[i-1]; } else { return _factors[_factors.length - 1] / 100; } }; var _getHigherFactor = function(f) { var i = _factors.indexOf(f); if (i < _factors.length-1) { return _factors[i+1]; } else { return _factors[0] * 100; } }; // Given a fixed minimum and maximum and a target number ot ticks // figure out the best interval and // return min, max, number ticks, format string and tick interval function bestConstrainedInterval(min, max, nttarget) { // run through possible number to ticks and see which interval is best var low = Math.floor(nttarget/2); var hi = Math.ceil(nttarget*1.5); var badness = Number.MAX_VALUE; var r = (max - min); var temp; var sd; var bestNT; var fsd; var fs; var gsf = $.jqplot.getSignificantFigures; var currentNT; var bestPrec; for (var i=0, l=hi-low+1; i<l; i++) { currentNT = low + i; temp = r/(currentNT-1); sd = gsf(temp); temp = Math.abs(nttarget - currentNT) + sd.digitsRight; if (temp < badness) { badness = temp; bestNT = currentNT; bestPrec = sd.digitsRight; } else if (temp === badness) { // let nicer ticks trump number ot ticks if (sd.digitsRight < bestPrec) { bestNT = currentNT; bestPrec = sd.digitsRight; } } } fsd = Math.max(bestPrec, Math.max(gsf(min).digitsRight, gsf(max).digitsRight)); if (fsd === 0) { fs = '%d'; } else { fs = '%.' + fsd + 'f'; } temp = r / (bestNT - 1); // min, max, number ticks, format string, tick interval return [min, max, bestNT, fs, temp]; } // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n // it is based soley on the range and number of ticks. So if user specifies // number of ticks, use this. function bestInterval(range, numberTicks) { numberTicks = numberTicks || 7; var minimum = range / (numberTicks - 1); var magnitude = Math.pow(10, Math.floor(Math.log(minimum) / Math.LN10)); var residual = minimum / magnitude; var interval; // "nicest" ranges are 1, 2, 5 or powers of these. // for magnitudes below 1, only allow these. if (magnitude < 1) { if (residual > 5) { interval = 10 * magnitude; } else if (residual > 2) { interval = 5 * magnitude; } else if (residual > 1) { interval = 2 * magnitude; } else { interval = magnitude; } } // for large ranges (whole integers), allow intervals like 3, 4 or powers of these. // this helps a lot with poor choices for number of ticks. else { if (residual > 5) { interval = 10 * magnitude; } else if (residual > 4) { interval = 5 * magnitude; } else if (residual > 3) { interval = 4 * magnitude; } else if (residual > 2) { interval = 3 * magnitude; } else if (residual > 1) { interval = 2 * magnitude; } else { interval = magnitude; } } return interval; } // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n // it is based soley on the range of data, number of ticks must be computed later. function bestLinearInterval(range, scalefact) { scalefact = scalefact || 1; var expv = Math.floor(Math.log(range)/Math.LN10); var magnitude = Math.pow(10, expv); // 0 < f < 10 var f = range / magnitude; var fact; // for large plots, scalefact will decrease f and increase number of ticks. // for small plots, scalefact will increase f and decrease number of ticks. f = f/scalefact; // for large plots, smaller interval, more ticks. if (f<=0.38) { fact = 0.1; } else if (f<=1.6) { fact = 0.2; } else if (f<=4.0) { fact = 0.5; } else if (f<=8.0) { fact = 1.0; } // for very small plots, larger interval, less ticks in number ticks else if (f<=16.0) { fact = 2; } else { fact = 5; } return fact*magnitude; } function bestLinearComponents(range, scalefact) { var expv = Math.floor(Math.log(range)/Math.LN10); var magnitude = Math.pow(10, expv); // 0 < f < 10 var f = range / magnitude; var interval; var fact; // for large plots, scalefact will decrease f and increase number of ticks. // for small plots, scalefact will increase f and decrease number of ticks. f = f/scalefact; // for large plots, smaller interval, more ticks. if (f<=0.38) { fact = 0.1; } else if (f<=1.6) { fact = 0.2; } else if (f<=4.0) { fact = 0.5; } else if (f<=8.0) { fact = 1.0; } // for very small plots, larger interval, less ticks in number ticks else if (f<=16.0) { fact = 2; } // else if (f<=20.0) { // fact = 3; // } // else if (f<=24.0) { // fact = 4; // } else { fact = 5; } interval = fact * magnitude; return [interval, fact, magnitude]; } // Given the min and max for a dataset, return suitable endpoints // for the graphing, a good number for the number of ticks, and a // format string so that extraneous digits are not displayed. // returned is an array containing [min, max, nTicks, format] $.jqplot.LinearTickGenerator = function(axis_min, axis_max, scalefact, numberTicks) { // if endpoints are equal try to include zero otherwise include one if (axis_min === axis_max) { axis_max = (axis_max) ? 0 : 1; } scalefact = scalefact || 1.0; // make sure range is positive if (axis_max < axis_min) { var a = axis_max; axis_max = axis_min; axis_min = a; } var r = []; var ss = bestLinearInterval(axis_max - axis_min, scalefact); if (numberTicks == null) { // Figure out the axis min, max and number of ticks // the min and max will be some multiple of the tick interval, // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the // axis min is negative, 0 will be a tick. r[0] = Math.floor(axis_min / ss) * ss; // min r[1] = Math.ceil(axis_max / ss) * ss; // max r[2] = Math.round((r[1]-r[0])/ss+1.0); // number of ticks r[3] = bestFormatString(ss); // format string r[4] = ss; // tick Interval } else { var tempr = []; // Figure out the axis min, max and number of ticks // the min and max will be some multiple of the tick interval, // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the // axis min is negative, 0 will be a tick. tempr[0] = Math.floor(axis_min / ss) * ss; // min tempr[1] = Math.ceil(axis_max / ss) * ss; // max tempr[2] = Math.round((tempr[1]-tempr[0])/ss+1.0); // number of ticks tempr[3] = bestFormatString(ss); // format string tempr[4] = ss; // tick Interval // first, see if we happen to get the right number of ticks if (tempr[2] === numberTicks) { r = tempr; } else { var newti = bestInterval(tempr[1] - tempr[0], numberTicks); r[0] = tempr[0]; r[2] = numberTicks; r[4] = newti; r[3] = bestFormatString(newti); r[1] = r[0] + (r[2] - 1) * r[4]; // max } } return r; }; $.jqplot.LinearTickGenerator.bestLinearInterval = bestLinearInterval; $.jqplot.LinearTickGenerator.bestInterval = bestInterval; $.jqplot.LinearTickGenerator.bestLinearComponents = bestLinearComponents; $.jqplot.LinearTickGenerator.bestConstrainedInterval = bestConstrainedInterval; // class: $.jqplot.MarkerRenderer // The default jqPlot marker renderer, rendering the points on the line. $.jqplot.MarkerRenderer = function(options){ // Group: Properties // prop: show // wether or not to show the marker. this.show = true; // prop: style // One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare this.style = 'filledCircle'; // prop: lineWidth // size of the line for non-filled markers. this.lineWidth = 2; // prop: size // Size of the marker (diameter or circle, length of edge of square, etc.) this.size = 9.0; // prop: color // color of marker. Will be set to color of series by default on init. this.color = '#666666'; // prop: shadow // wether or not to draw a shadow on the line this.shadow = true; // prop: shadowAngle // Shadow angle in degrees this.shadowAngle = 45; // prop: shadowOffset // Shadow offset from line in pixels this.shadowOffset = 1; // prop: shadowDepth // Number of times shadow is stroked, each stroke offset shadowOffset from the last. this.shadowDepth = 3; // prop: shadowAlpha // Alpha channel transparency of shadow. 0 = transparent. this.shadowAlpha = '0.07'; // prop: shadowRenderer // Renderer that will draws the shadows on the marker. this.shadowRenderer = new $.jqplot.ShadowRenderer(); // prop: shapeRenderer // Renderer that will draw the marker. this.shapeRenderer = new $.jqplot.ShapeRenderer(); $.extend(true, this, options); }; $.jqplot.MarkerRenderer.prototype.init = function(options) { $.extend(true, this, options); var sdopt = {angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, lineWidth:this.lineWidth, depth:this.shadowDepth, closePath:true}; if (this.style.indexOf('filled') != -1) { sdopt.fill = true; } if (this.style.indexOf('ircle') != -1) { sdopt.isarc = true; sdopt.closePath = false; } this.shadowRenderer.init(sdopt); var shopt = {fill:false, isarc:false, strokeStyle:this.color, fillStyle:this.color, lineWidth:this.lineWidth, closePath:true}; if (this.style.indexOf('filled') != -1) { shopt.fill = true; } if (this.style.indexOf('ircle') != -1) { shopt.isarc = true; shopt.closePath = false; } this.shapeRenderer.init(shopt); }; $.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) { var stretch = 1.2; var dx = this.size/2/stretch; var dy = this.size/2*stretch; var points = [[x-dx, y], [x, y+dy], [x+dx, y], [x, y-dy]]; if (this.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, options); }; $.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) { var stretch = 1.0; var dx = this.size/2*stretch; var dy = this.size/2*stretch; var points1 = [[x, y-dy], [x, y+dy]]; var points2 = [[x+dx, y], [x-dx, y]]; var opts = $.extend(true, {}, this.options, {closePath:false}); if (this.shadow) { this.shadowRenderer.draw(ctx, points1, {closePath:false}); this.shadowRenderer.draw(ctx, points2, {closePath:false}); } this.shapeRenderer.draw(ctx, points1, opts); this.shapeRenderer.draw(ctx, points2, opts); }; $.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) { var stretch = 1.0; var dx = this.size/2*stretch; var dy = this.size/2*stretch; var opts = $.extend(true, {}, this.options, {closePath:false}); var points1 = [[x-dx, y-dy], [x+dx, y+dy]]; var points2 = [[x-dx, y+dy], [x+dx, y-dy]]; if (this.shadow) { this.shadowRenderer.draw(ctx, points1, {closePath:false}); this.shadowRenderer.draw(ctx, points2, {closePath:false}); } this.shapeRenderer.draw(ctx, points1, opts); this.shapeRenderer.draw(ctx, points2, opts); }; $.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) { var stretch = 1.0; var dx = this.size/2*stretch; var dy = this.size/2*stretch; var points = [[x-dx, y], [x+dx, y]]; if (this.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, options); }; $.jqplot.MarkerRenderer.prototype.drawLine = function(p1, p2, ctx, fill, options) { var points = [p1, p2]; if (this.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, options); }; $.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) { var stretch = 1.0; var dx = this.size/2/stretch; var dy = this.size/2*stretch; var points = [[x-dx, y-dy], [x-dx, y+dy], [x+dx, y+dy], [x+dx, y-dy]]; if (this.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, options); }; $.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) { var radius = this.size/2; var end = 2*Math.PI; var points = [x, y, radius, 0, end, true]; if (this.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, options); }; $.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) { options = options || {}; // hack here b/c shape renderer uses canvas based color style options // and marker uses css style names. if (options.show == null || options.show != false) { if (options.color && !options.fillStyle) { options.fillStyle = options.color; } if (options.color && !options.strokeStyle) { options.strokeStyle = options.color; } switch (this.style) { case 'diamond': this.drawDiamond(x,y,ctx, false, options); break; case 'filledDiamond': this.drawDiamond(x,y,ctx, true, options); break; case 'circle': this.drawCircle(x,y,ctx, false, options); break; case 'filledCircle': this.drawCircle(x,y,ctx, true, options); break; case 'square': this.drawSquare(x,y,ctx, false, options); break; case 'filledSquare': this.drawSquare(x,y,ctx, true, options); break; case 'x': this.drawX(x,y,ctx, true, options); break; case 'plus': this.drawPlus(x,y,ctx, true, options); break; case 'dash': this.drawDash(x,y,ctx, true, options); break; case 'line': this.drawLine(x, y, ctx, false, options); break; default: this.drawDiamond(x,y,ctx, false, options); break; } } }; // class: $.jqplot.shadowRenderer // The default jqPlot shadow renderer, rendering shadows behind shapes. $.jqplot.ShadowRenderer = function(options){ // Group: Properties // prop: angle // Angle of the shadow in degrees. Measured counter-clockwise from the x axis. this.angle = 45; // prop: offset // Pixel offset at the given shadow angle of each shadow stroke from the last stroke. this.offset = 1; // prop: alpha // alpha transparency of shadow stroke. this.alpha = 0.07; // prop: lineWidth // width of the shadow line stroke. this.lineWidth = 1.5; // prop: lineJoin // How line segments of the shadow are joined. this.lineJoin = 'miter'; // prop: lineCap // how ends of the shadow line are rendered. this.lineCap = 'round'; // prop; closePath // whether line path segment is closed upon itself. this.closePath = false; // prop: fill // whether to fill the shape. this.fill = false; // prop: depth // how many times the shadow is stroked. Each stroke will be offset by offset at angle degrees. this.depth = 3; this.strokeStyle = 'rgba(0,0,0,0.1)'; // prop: isarc // wether the shadow is an arc or not. this.isarc = false; $.extend(true, this, options); }; $.jqplot.ShadowRenderer.prototype.init = function(options) { $.extend(true, this, options); }; // function: draw // draws an transparent black (i.e. gray) shadow. // // ctx - canvas drawing context // points - array of points or [x, y, radius, start angle (rad), end angle (rad)] $.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) { ctx.save(); var opts = (options != null) ? options : {}; var fill = (opts.fill != null) ? opts.fill : this.fill; var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; var offset = (opts.offset != null) ? opts.offset : this.offset; var alpha = (opts.alpha != null) ? opts.alpha : this.alpha; var depth = (opts.depth != null) ? opts.depth : this.depth; var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth; ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin; ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap; ctx.strokeStyle = opts.strokeStyle || this.strokeStyle || 'rgba(0,0,0,'+alpha+')'; ctx.fillStyle = opts.fillStyle || this.fillStyle || 'rgba(0,0,0,'+alpha+')'; for (var j=0; j<depth; j++) { var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); ctx.translate(Math.cos(this.angle*Math.PI/180)*offset, Math.sin(this.angle*Math.PI/180)*offset); ctxPattern.beginPath(); if (isarc) { ctx.arc(points[0], points[1], points[2], points[3], points[4], true); } else if (fillRect) { if (fillRect) { ctx.fillRect(points[0], points[1], points[2], points[3]); } } else if (points && points.length){ var move = true; for (var i=0; i<points.length; i++) { // skip to the first non-null point and move to it. if (points[i][0] != null && points[i][1] != null) { if (move) { ctxPattern.moveTo(points[i][0], points[i][1]); move = false; } else { ctxPattern.lineTo(points[i][0], points[i][1]); } } else { move = true; } } } if (closePath) { ctxPattern.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } } ctx.restore(); }; // class: $.jqplot.shapeRenderer // The default jqPlot shape renderer. Given a set of points will // plot them and either stroke a line (fill = false) or fill them (fill = true). // If a filled shape is desired, closePath = true must also be set to close // the shape. $.jqplot.ShapeRenderer = function(options){ this.lineWidth = 1.5; // prop: linePattern // line pattern 'dashed', 'dotted', 'solid', some combination // of '-' and '.' characters such as '.-.' or a numerical array like // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, // [1, 10, 20, 10] to draw a dot-dash line, and so on. this.linePattern = 'solid'; // prop: lineJoin // How line segments of the shadow are joined. this.lineJoin = 'miter'; // prop: lineCap // how ends of the shadow line are rendered. this.lineCap = 'round'; // prop; closePath // whether line path segment is closed upon itself. this.closePath = false; // prop: fill // whether to fill the shape. this.fill = false; // prop: isarc // wether the shadow is an arc or not. this.isarc = false; // prop: fillRect // true to draw shape as a filled rectangle. this.fillRect = false; // prop: strokeRect // true to draw shape as a stroked rectangle. this.strokeRect = false; // prop: clearRect // true to cear a rectangle. this.clearRect = false; // prop: strokeStyle // css color spec for the stoke style this.strokeStyle = '#999999'; // prop: fillStyle // css color spec for the fill style. this.fillStyle = '#999999'; $.extend(true, this, options); }; $.jqplot.ShapeRenderer.prototype.init = function(options) { $.extend(true, this, options); }; // function: draw // draws the shape. // // ctx - canvas drawing context // points - array of points for shapes or // [x, y, width, height] for rectangles or // [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs. $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) { ctx.save(); var opts = (options != null) ? options : {}; var fill = (opts.fill != null) ? opts.fill : this.fill; var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect; var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect; var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); ctx.lineWidth = opts.lineWidth || this.lineWidth; ctx.lineJoin = opts.lineJoin || this.lineJoin; ctx.lineCap = opts.lineCap || this.lineCap; ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle; ctx.fillStyle = opts.fillStyle || this.fillStyle; ctx.beginPath(); if (isarc) { ctx.arc(points[0], points[1], points[2], points[3], points[4], true); if (closePath) { ctx.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } ctx.restore(); return; } else if (clearRect) { ctx.clearRect(points[0], points[1], points[2], points[3]); ctx.restore(); return; } else if (fillRect || strokeRect) { if (fillRect) { ctx.fillRect(points[0], points[1], points[2], points[3]); } if (strokeRect) { ctx.strokeRect(points[0], points[1], points[2], points[3]); ctx.restore(); return; } } else if (points && points.length){ var move = true; for (var i=0; i<points.length; i++) { // skip to the first non-null point and move to it. if (points[i][0] != null && points[i][1] != null) { if (move) { ctxPattern.moveTo(points[i][0], points[i][1]); move = false; } else { ctxPattern.lineTo(points[i][0], points[i][1]); } } else { move = true; } } if (closePath) { ctxPattern.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } } ctx.restore(); }; // class $.jqplot.TableLegendRenderer // The default legend renderer for jqPlot. $.jqplot.TableLegendRenderer = function(){ // }; $.jqplot.TableLegendRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) { var rs = (pad) ? this.rowSpacing+'px' : '0px'; var tr; var td; var elem; var div0; var div1; elem = document.createElement('tr'); tr = $(elem); tr.addClass('jqplot-table-legend'); elem = null; if (reverse){ tr.prependTo(this._elem); } else{ tr.appendTo(this._elem); } if (this.showSwatches) { td = $(document.createElement('td')); td.addClass('jqplot-table-legend jqplot-table-legend-swatch'); td.css({textAlign: 'center', paddingTop: rs}); div0 = $(document.createElement('div')); div0.addClass('jqplot-table-legend-swatch-outline'); div1 = $(document.createElement('div')); div1.addClass('jqplot-table-legend-swatch'); div1.css({backgroundColor: color, borderColor: color}); tr.append(td.append(div0.append(div1))); // $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+ // '</div></td>').appendTo(tr); } if (this.showLabels) { td = $(document.createElement('td')); td.addClass('jqplot-table-legend jqplot-table-legend-label'); td.css('paddingTop', rs); tr.append(td); // elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); // elem.appendTo(tr); if (this.escapeHtml) { td.text(label); } else { td.html(label); } } td = null; div0 = null; div1 = null; tr = null; elem = null; }; // called with scope of legend $.jqplot.TableLegendRenderer.prototype.draw = function() { if (this._elem) { this._elem.emptyForce(); this._elem = null; } if (this.show) { var series = this._series; // make a table. one line label per row. var elem = document.createElement('table'); this._elem = $(elem); this._elem.addClass('jqplot-table-legend'); var ss = {position:'absolute'}; if (this.background) { ss['background'] = this.background; } if (this.border) { ss['border'] = this.border; } if (this.fontSize) { ss['fontSize'] = this.fontSize; } if (this.fontFamily) { ss['fontFamily'] = this.fontFamily; } if (this.textColor) { ss['textColor'] = this.textColor; } if (this.marginTop != null) { ss['marginTop'] = this.marginTop; } if (this.marginBottom != null) { ss['marginBottom'] = this.marginBottom; } if (this.marginLeft != null) { ss['marginLeft'] = this.marginLeft; } if (this.marginRight != null) { ss['marginRight'] = this.marginRight; } var pad = false, reverse = false, s; for (var i = 0; i< series.length; i++) { s = series[i]; if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){ reverse = true; } if (s.show && s.showLabel) { var lt = this.labels[i] || s.label.toString(); if (lt) { var color = s.color; if (reverse && i < series.length - 1){ pad = true; } else if (reverse && i == series.length - 1){ pad = false; } this.renderer.addrow.call(this, lt, color, pad, reverse); pad = true; } // let plugins add more rows to legend. Used by trend line plugin. for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { var item = $.jqplot.addLegendRowHooks[j].call(this, s); if (item) { this.renderer.addrow.call(this, item.label, item.color, pad); pad = true; } } lt = null; } } } return this._elem; }; $.jqplot.TableLegendRenderer.prototype.pack = function(offsets) { if (this.show) { if (this.placement == 'insideGrid') { switch (this.location) { case 'nw': var a = offsets.left; var b = offsets.top; this._elem.css('left', a); this._elem.css('top', b); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = offsets.top; this._elem.css('left', a); this._elem.css('top', b); break; case 'ne': var a = offsets.right; var b = offsets.top; this._elem.css({right:a, top:b}); break; case 'e': var a = offsets.right; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:a, top:b}); break; case 'se': var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 'sw': var a = offsets.left; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 'w': var a = offsets.left; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:a, top:b}); break; default: // same as 'se' var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; } } else if (this.placement == 'outside'){ switch (this.location) { case 'nw': var a = this._plotDimensions.width - offsets.left; var b = offsets.top; this._elem.css('right', a); this._elem.css('top', b); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = this._plotDimensions.height - offsets.top; this._elem.css('left', a); this._elem.css('bottom', b); break; case 'ne': var a = this._plotDimensions.width - offsets.right; var b = offsets.top; this._elem.css({left:a, top:b}); break; case 'e': var a = this._plotDimensions.width - offsets.right; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:a, top:b}); break; case 'se': var a = this._plotDimensions.width - offsets.right; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = this._plotDimensions.height - offsets.bottom; this._elem.css({left:a, top:b}); break; case 'sw': var a = this._plotDimensions.width - offsets.left; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; case 'w': var a = this._plotDimensions.width - offsets.left; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:a, top:b}); break; default: // same as 'se' var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; } } else { switch (this.location) { case 'nw': this._elem.css({left:0, top:offsets.top}); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; this._elem.css({left: a, top:offsets.top}); break; case 'ne': this._elem.css({right:0, top:offsets.top}); break; case 'e': var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:offsets.right, top:b}); break; case 'se': this._elem.css({right:offsets.right, bottom:offsets.bottom}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; this._elem.css({left: a, bottom:offsets.bottom}); break; case 'sw': this._elem.css({left:offsets.left, bottom:offsets.bottom}); break; case 'w': var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:offsets.left, top:b}); break; default: // same as 'se' this._elem.css({right:offsets.right, bottom:offsets.bottom}); break; } } } }; /** * Class: $.jqplot.ThemeEngine * Theme Engine provides a programatic way to change some of the more * common jqplot styling options such as fonts, colors and grid options. * A theme engine instance is created with each plot. The theme engine * manages a collection of themes which can be modified, added to, or * applied to the plot. * * The themeEngine class is not instantiated directly. * When a plot is initialized, the current plot options are scanned * an a default theme named "Default" is created. This theme is * used as the basis for other themes added to the theme engine and * is always available. * * A theme is a simple javascript object with styling parameters for * various entities of the plot. A theme has the form: * * * > { * > _name:f "Default", * > target: { * > backgroundColor: "transparent" * > }, * > legend: { * > textColor: null, * > fontFamily: null, * > fontSize: null, * > border: null, * > background: null * > }, * > title: { * > textColor: "rgb(102, 102, 102)", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", * > fontSize: "19.2px", * > textAlign: "center" * > }, * > seriesStyles: {}, * > series: [{ * > color: "#4bb2c5", * > lineWidth: 2.5, * > linePattern: "solid", * > shadow: true, * > fillColor: "#4bb2c5", * > showMarker: true, * > markerOptions: { * > color: "#4bb2c5", * > show: true, * > style: 'filledCircle', * > lineWidth: 1.5, * > size: 4, * > shadow: true * > } * > }], * > grid: { * > drawGridlines: true, * > gridLineColor: "#cccccc", * > gridLineWidth: 1, * > backgroundColor: "#fffdf6", * > borderColor: "#999999", * > borderWidth: 2, * > shadow: true * > }, * > axesStyles: { * > label: {}, * > ticks: {} * > }, * > axes: { * > xaxis: { * > borderColor: "#999999", * > borderWidth: 2, * > ticks: { * > show: true, * > showGridline: true, * > showLabel: true, * > showMark: true, * > size: 4, * > textColor: "", * > whiteSpace: "nowrap", * > fontSize: "12px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" * > }, * > label: { * > textColor: "rgb(102, 102, 102)", * > whiteSpace: "normal", * > fontSize: "14.6667px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", * > fontWeight: "400" * > } * > }, * > yaxis: { * > borderColor: "#999999", * > borderWidth: 2, * > ticks: { * > show: true, * > showGridline: true, * > showLabel: true, * > showMark: true, * > size: 4, * > textColor: "", * > whiteSpace: "nowrap", * > fontSize: "12px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" * > }, * > label: { * > textColor: null, * > whiteSpace: null, * > fontSize: null, * > fontFamily: null, * > fontWeight: null * > } * > }, * > x2axis: {... * > }, * > ... * > y9axis: {... * > } * > } * > } * * "seriesStyles" is a style object that will be applied to all series in the plot. * It will forcibly override any styles applied on the individual series. "axesStyles" is * a style object that will be applied to all axes in the plot. It will also forcibly * override any styles on the individual axes. * * The example shown above has series options for a line series. Options for other * series types are shown below: * * Bar Series: * * > { * > color: "#4bb2c5", * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > lineWidth: 2.5, * > shadow: true, * > barPadding: 2, * > barMargin: 10, * > barWidth: 15.09375, * > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"] * > } * * Pie Series: * * > { * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > padding: 20, * > sliceMargin: 0, * > fill: true, * > shadow: true, * > startAngle: 0, * > lineWidth: 2.5, * > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"] * > } * * Funnel Series: * * > { * > color: "#4bb2c5", * > lineWidth: 2, * > shadow: true, * > padding: { * > top: 20, * > right: 20, * > bottom: 20, * > left: 20 * > }, * > sectionMargin: 6, * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"] * > } * */ $.jqplot.ThemeEngine = function(){ // Group: Properties // // prop: themes // hash of themes managed by the theme engine. // Indexed by theme name. this.themes = {}; // prop: activeTheme // Pointer to currently active theme this.activeTheme=null; }; // called with scope of plot $.jqplot.ThemeEngine.prototype.init = function() { // get the Default theme from the current plot settings. var th = new $.jqplot.Theme({_name:'Default'}); var n, i, nn; for (n in th.target) { if (n == "textColor") { th.target[n] = this.target.css('color'); } else { th.target[n] = this.target.css(n); } } if (this.title.show && this.title._elem) { for (n in th.title) { if (n == "textColor") { th.title[n] = this.title._elem.css('color'); } else { th.title[n] = this.title._elem.css(n); } } } for (n in th.grid) { th.grid[n] = this.grid[n]; } if (th.grid.backgroundColor == null && this.grid.background != null) { th.grid.backgroundColor = this.grid.background; } if (this.legend.show && this.legend._elem) { for (n in th.legend) { if (n == 'textColor') { th.legend[n] = this.legend._elem.css('color'); } else { th.legend[n] = this.legend._elem.css(n); } } } var s; for (i=0; i<this.series.length; i++) { s = this.series[i]; if (s.renderer.constructor == $.jqplot.LineRenderer) { th.series.push(new LineSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.BarRenderer) { th.series.push(new BarSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.PieRenderer) { th.series.push(new PieSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.DonutRenderer) { th.series.push(new DonutSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.FunnelRenderer) { th.series.push(new FunnelSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) { th.series.push(new MeterSeriesProperties()); } else { th.series.push({}); } for (n in th.series[i]) { th.series[i][n] = s[n]; } } var a, ax; for (n in this.axes) { ax = this.axes[n]; a = th.axes[n] = new AxisProperties(); a.borderColor = ax.borderColor; a.borderWidth = ax.borderWidth; if (ax._ticks && ax._ticks[0]) { for (nn in a.ticks) { if (ax._ticks[0].hasOwnProperty(nn)) { a.ticks[nn] = ax._ticks[0][nn]; } else if (ax._ticks[0]._elem){ a.ticks[nn] = ax._ticks[0]._elem.css(nn); } } } if (ax._label && ax._label.show) { for (nn in a.label) { // a.label[nn] = ax._label._elem.css(nn); if (ax._label[nn]) { a.label[nn] = ax._label[nn]; } else if (ax._label._elem){ if (nn == 'textColor') { a.label[nn] = ax._label._elem.css('color'); } else { a.label[nn] = ax._label._elem.css(nn); } } } } } this.themeEngine._add(th); this.themeEngine.activeTheme = this.themeEngine.themes[th._name]; }; /** * Group: methods * * method: get * * Get and return the named theme or the active theme if no name given. * * parameter: * * name - name of theme to get. * * returns: * * Theme instance of given name. */ $.jqplot.ThemeEngine.prototype.get = function(name) { if (!name) { // return the active theme return this.activeTheme; } else { return this.themes[name]; } }; function numericalOrder(a,b) { return a-b; } /** * method: getThemeNames * * Return the list of theme names in this manager in alpha-numerical order. * * parameter: * * None * * returns: * * A the list of theme names in this manager in alpha-numerical order. */ $.jqplot.ThemeEngine.prototype.getThemeNames = function() { var tn = []; for (var n in this.themes) { tn.push(n); } return tn.sort(numericalOrder); }; /** * method: getThemes * * Return a list of themes in alpha-numerical order by name. * * parameter: * * None * * returns: * * A list of themes in alpha-numerical order by name. */ $.jqplot.ThemeEngine.prototype.getThemes = function() { var tn = []; var themes = []; for (var n in this.themes) { tn.push(n); } tn.sort(numericalOrder); for (var i=0; i<tn.length; i++) { themes.push(this.themes[tn[i]]); } return themes; }; $.jqplot.ThemeEngine.prototype.activate = function(plot, name) { // sometimes need to redraw whole plot. var redrawPlot = false; if (!name && this.activeTheme && this.activeTheme._name) { name = this.activeTheme._name; } if (!this.themes.hasOwnProperty(name)) { throw new Error("No theme of that name"); } else { var th = this.themes[name]; this.activeTheme = th; var val, checkBorderColor = false, checkBorderWidth = false; var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis']; for (i=0; i<arr.length; i++) { var ax = arr[i]; if (th.axesStyles.borderColor != null) { plot.axes[ax].borderColor = th.axesStyles.borderColor; } if (th.axesStyles.borderWidth != null) { plot.axes[ax].borderWidth = th.axesStyles.borderWidth; } } for (var axname in plot.axes) { var axis = plot.axes[axname]; if (axis.show) { var thaxis = th.axes[axname] || {}; var thaxstyle = th.axesStyles; var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle); val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor; if (thax.borderColor != null) { axis.borderColor = thax.borderColor; redrawPlot = true; } val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth; if (thax.borderWidth != null) { axis.borderWidth = thax.borderWidth; redrawPlot = true; } if (axis._ticks && axis._ticks[0]) { for (var nn in thax.ticks) { // val = null; // if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) { // val = th.axesStyles.ticks[nn]; // } // else if (thax.ticks[nn] != null){ // val = thax.ticks[nn] // } val = thax.ticks[nn]; if (val != null) { axis.tickOptions[nn] = val; axis._ticks = []; redrawPlot = true; } } } if (axis._label && axis._label.show) { for (var nn in thax.label) { // val = null; // if (th.axesStyles.label && th.axesStyles.label[nn] != null) { // val = th.axesStyles.label[nn]; // } // else if (thax.label && thax.label[nn] != null){ // val = thax.label[nn] // } val = thax.label[nn]; if (val != null) { axis.labelOptions[nn] = val; redrawPlot = true; } } } } } for (var n in th.grid) { if (th.grid[n] != null) { plot.grid[n] = th.grid[n]; } } if (!redrawPlot) { plot.grid.draw(); } if (plot.legend.show) { for (n in th.legend) { if (th.legend[n] != null) { plot.legend[n] = th.legend[n]; } } } if (plot.title.show) { for (n in th.title) { if (th.title[n] != null) { plot.title[n] = th.title[n]; } } } var i; for (i=0; i<th.series.length; i++) { var opts = {}; var redrawSeries = false; for (n in th.series[i]) { val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n]; if (val != null) { opts[n] = val; if (n == 'color') { plot.series[i].renderer.shapeRenderer.fillStyle = val; plot.series[i].renderer.shapeRenderer.strokeStyle = val; plot.series[i][n] = val; } else if ((n == 'lineWidth') || (n == 'linePattern')) { plot.series[i].renderer.shapeRenderer[n] = val; plot.series[i][n] = val; } else if (n == 'markerOptions') { merge (plot.series[i].markerOptions, val); merge (plot.series[i].markerRenderer, val); } else { plot.series[i][n] = val; } redrawPlot = true; } } } if (redrawPlot) { plot.target.empty(); plot.draw(); } for (n in th.target) { if (th.target[n] != null) { plot.target.css(n, th.target[n]); } } } }; $.jqplot.ThemeEngine.prototype._add = function(theme, name) { if (name) { theme._name = name; } if (!theme._name) { theme._name = Date.parse(new Date()); } if (!this.themes.hasOwnProperty(theme._name)) { this.themes[theme._name] = theme; } else { throw new Error("jqplot.ThemeEngine Error: Theme already in use"); } }; // method remove // Delete the named theme, return true on success, false on failure. /** * method: remove * * Remove the given theme from the themeEngine. * * parameters: * * name - name of the theme to remove. * * returns: * * true on success, false on failure. */ $.jqplot.ThemeEngine.prototype.remove = function(name) { if (name == 'Default') { return false; } return delete this.themes[name]; }; /** * method: newTheme * * Create a new theme based on the default theme, adding it the themeEngine. * * parameters: * * name - name of the new theme. * obj - optional object of styles to be applied to this new theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) { if (typeof(name) == 'object') { obj = obj || name; name = null; } if (obj && obj._name) { name = obj._name; } else { name = name || Date.parse(new Date()); } // var th = new $.jqplot.Theme(name); var th = this.copy(this.themes['Default']._name, name); $.jqplot.extend(th, obj); return th; }; // function clone(obj) { // return eval(obj.toSource()); // } function clone(obj){ if(obj == null || typeof(obj) != 'object'){ return obj; } var temp = new obj.constructor(); for(var key in obj){ temp[key] = clone(obj[key]); } return temp; } $.jqplot.clone = clone; function merge(obj1, obj2) { if (obj2 == null || typeof(obj2) != 'object') { return; } for (var key in obj2) { if (key == 'highlightColors') { obj1[key] = clone(obj2[key]); } if (obj2[key] != null && typeof(obj2[key]) == 'object') { if (!obj1.hasOwnProperty(key)) { obj1[key] = {}; } merge(obj1[key], obj2[key]); } else { obj1[key] = obj2[key]; } } } $.jqplot.merge = merge; // Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic $.jqplot.extend = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) { target = {}; } for ( ; i < length; i++ ){ // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( var name in options ) { var src = target[ name ], copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging object values if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { target[ name ] = $.jqplot.extend( deep, // Never move original objects, clone them src || ( copy.length != null ? [ ] : { } ) , copy ); } // Don't bring in undefined values else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; /** * method: rename * * Rename a theme. * * parameters: * * oldName - current name of the theme. * newName - desired name of the theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) { if (oldName == 'Default' || newName == 'Default') { throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default"); } if (this.themes.hasOwnProperty(newName)) { throw new Error ("jqplot.ThemeEngine Error: New name already in use."); } else if (this.themes.hasOwnProperty(oldName)) { var th = this.copy (oldName, newName); this.remove(oldName); return th; } throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid"); }; /** * method: copy * * Create a copy of an existing theme in the themeEngine, adding it the themeEngine. * * parameters: * * sourceName - name of the existing theme. * targetName - name of the copy. * obj - optional object of style parameter to apply to the new theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) { if (targetName == 'Default') { throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme"); } if (!this.themes.hasOwnProperty(sourceName)) { var s = "jqplot.ThemeEngine Error: Source name invalid"; throw new Error(s); } if (this.themes.hasOwnProperty(targetName)) { var s = "jqplot.ThemeEngine Error: Target name invalid"; throw new Error(s); } else { var th = clone(this.themes[sourceName]); th._name = targetName; $.jqplot.extend(true, th, obj); this._add(th); return th; } }; $.jqplot.Theme = function(name, obj) { if (typeof(name) == 'object') { obj = obj || name; name = null; } name = name || Date.parse(new Date()); this._name = name; this.target = { backgroundColor: null }; this.legend = { textColor: null, fontFamily: null, fontSize: null, border: null, background: null }; this.title = { textColor: null, fontFamily: null, fontSize: null, textAlign: null }; this.seriesStyles = {}; this.series = []; this.grid = { drawGridlines: null, gridLineColor: null, gridLineWidth: null, backgroundColor: null, borderColor: null, borderWidth: null, shadow: null }; this.axesStyles = {label:{}, ticks:{}}; this.axes = {}; if (typeof(obj) == 'string') { this._name = obj; } else if(typeof(obj) == 'object') { $.jqplot.extend(true, this, obj); } }; var AxisProperties = function() { this.borderColor = null; this.borderWidth = null; this.ticks = new AxisTicks(); this.label = new AxisLabel(); }; var AxisTicks = function() { this.show = null; this.showGridline = null; this.showLabel = null; this.showMark = null; this.size = null; this.textColor = null; this.whiteSpace = null; this.fontSize = null; this.fontFamily = null; }; var AxisLabel = function() { this.textColor = null; this.whiteSpace = null; this.fontSize = null; this.fontFamily = null; this.fontWeight = null; }; var LineSeriesProperties = function() { this.color=null; this.lineWidth=null; this.linePattern=null; this.shadow=null; this.fillColor=null; this.showMarker=null; this.markerOptions = new MarkerOptions(); }; var MarkerOptions = function() { this.show = null; this.style = null; this.lineWidth = null; this.size = null; this.color = null; this.shadow = null; }; var BarSeriesProperties = function() { this.color=null; this.seriesColors=null; this.lineWidth=null; this.shadow=null; this.barPadding=null; this.barMargin=null; this.barWidth=null; this.highlightColors=null; }; var PieSeriesProperties = function() { this.seriesColors=null; this.padding=null; this.sliceMargin=null; this.fill=null; this.shadow=null; this.startAngle=null; this.lineWidth=null; this.highlightColors=null; }; var DonutSeriesProperties = function() { this.seriesColors=null; this.padding=null; this.sliceMargin=null; this.fill=null; this.shadow=null; this.startAngle=null; this.lineWidth=null; this.innerDiameter=null; this.thickness=null; this.ringMargin=null; this.highlightColors=null; }; var FunnelSeriesProperties = function() { this.color=null; this.lineWidth=null; this.shadow=null; this.padding=null; this.sectionMargin=null; this.seriesColors=null; this.highlightColors=null; }; var MeterSeriesProperties = function() { this.padding=null; this.backgroundColor=null; this.ringColor=null; this.tickColor=null; this.ringWidth=null; this.intervalColors=null; this.intervalInnerRadius=null; this.intervalOuterRadius=null; this.hubRadius=null; this.needleThickness=null; this.needlePad=null; }; $.fn.jqplotChildText = function() { return $(this).contents().filter(function() { return this.nodeType == 3; // Node.TEXT_NODE not defined in I7 }).text(); }; // Returns font style as abbreviation for "font" property. $.fn.jqplotGetComputedFontStyle = function() { var css = window.getComputedStyle ? window.getComputedStyle(this[0]) : this[0].currentStyle; var attrs = css['font-style'] ? ['font-style', 'font-weight', 'font-size', 'font-family'] : ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily']; var style = []; for (var i=0 ; i < attrs.length; ++i) { var attr = String(css[attrs[i]]); if (attr && attr != 'normal') { style.push(attr); } } return style.join(' '); }; /** * Namespace: $.fn * jQuery namespace to attach functions to jQuery elements. * */ $.fn.jqplotToImageCanvas = function(options) { options = options || {}; var x_offset = (options.x_offset == null) ? 0 : options.x_offset; var y_offset = (options.y_offset == null) ? 0 : options.y_offset; var backgroundColor = (options.backgroundColor == null) ? 'rgb(255,255,255)' : options.backgroundColor; if ($(this).width() == 0 || $(this).height() == 0) { return null; } // excanvas and hence IE < 9 do not support toDataURL and cannot export images. if (!$.jqplot.support_canvas) { return null; } var newCanvas = document.createElement("canvas"); var h = $(this).outerHeight(true); var w = $(this).outerWidth(true); var offs = $(this).offset(); var plotleft = offs.left; var plottop = offs.top; var transx = 0, transy = 0; // have to check if any elements are hanging outside of plot area before rendering, // since changing width of canvas will erase canvas. var clses = ['jqplot-table-legend', 'jqplot-xaxis-tick', 'jqplot-x2axis-tick', 'jqplot-yaxis-tick', 'jqplot-y2axis-tick', 'jqplot-y3axis-tick', 'jqplot-y4axis-tick', 'jqplot-y5axis-tick', 'jqplot-y6axis-tick', 'jqplot-y7axis-tick', 'jqplot-y8axis-tick', 'jqplot-y9axis-tick', 'jqplot-xaxis-label', 'jqplot-x2axis-label', 'jqplot-yaxis-label', 'jqplot-y2axis-label', 'jqplot-y3axis-label', 'jqplot-y4axis-label', 'jqplot-y5axis-label', 'jqplot-y6axis-label', 'jqplot-y7axis-label', 'jqplot-y8axis-label', 'jqplot-y9axis-label' ]; var temptop, templeft, tempbottom, tempright; for (var i in clses) { $(this).find('.'+clses[i]).each(function() { temptop = $(this).offset().top - plottop; templeft = $(this).offset().left - plotleft; tempright = templeft + $(this).outerWidth(true) + transx; tempbottom = temptop + $(this).outerHeight(true) + transy; if (templeft < -transx) { w = w - transx - templeft; transx = -templeft; } if (temptop < -transy) { h = h - transy - temptop; transy = - temptop; } if (tempright > w) { w = tempright; } if (tempbottom > h) { h = tempbottom; } }); } newCanvas.width = w + Number(x_offset); newCanvas.height = h + Number(y_offset); var newContext = newCanvas.getContext("2d"); newContext.save(); newContext.fillStyle = backgroundColor; newContext.fillRect(0,0, newCanvas.width, newCanvas.height); newContext.restore(); newContext.translate(transx, transy); newContext.textAlign = 'left'; newContext.textBaseline = 'top'; function getLineheight(el) { var lineheight = parseInt($(el).css('line-height'), 10); if (isNaN(lineheight)) { lineheight = parseInt($(el).css('font-size'), 10) * 1.2; } return lineheight; } function writeWrappedText (el, context, text, left, top, canvasWidth) { var lineheight = getLineheight(el); var tagwidth = $(el).innerWidth(); var tagheight = $(el).innerHeight(); var words = text.split(/\s+/); var wl = words.length; var w = ''; var breaks = []; var temptop = top; var templeft = left; for (var i=0; i<wl; i++) { w += words[i]; if (context.measureText(w).width > tagwidth) { breaks.push(i); w = ''; } } if (breaks.length === 0) { // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(text, templeft, top); } else { w = words.slice(0, breaks[0]).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); temptop += lineheight; for (var i=1, l=breaks.length; i<l; i++) { w = words.slice(breaks[i-1], breaks[i]).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); temptop += lineheight; } w = words.slice(breaks[i-1], words.length).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); } } function _jqpToImage(el, x_offset, y_offset) { var tagname = el.tagName.toLowerCase(); var p = $(el).position(); var css = window.getComputedStyle ? window.getComputedStyle(el) : el.currentStyle; // for IE < 9 var left = x_offset + p.left + parseInt(css.marginLeft, 10) + parseInt(css.borderLeftWidth, 10) + parseInt(css.paddingLeft, 10); var top = y_offset + p.top + parseInt(css.marginTop, 10) + parseInt(css.borderTopWidth, 10)+ parseInt(css.paddingTop, 10); var w = newCanvas.width; // var left = x_offset + p.left + $(el).css('marginLeft') + $(el).css('borderLeftWidth') if ((tagname == 'div' || tagname == 'span') && !$(el).hasClass('jqplot-highlighter-tooltip')) { $(el).children().each(function() { _jqpToImage(this, left, top); }); var text = $(el).jqplotChildText(); if (text) { newContext.font = $(el).jqplotGetComputedFontStyle(); newContext.fillStyle = $(el).css('color'); writeWrappedText(el, newContext, text, left, top, w); } } // handle the standard table legend else if (tagname === 'table' && $(el).hasClass('jqplot-table-legend')) { newContext.strokeStyle = $(el).css('border-top-color'); newContext.fillStyle = $(el).css('background-color'); newContext.fillRect(left, top, $(el).innerWidth(), $(el).innerHeight()); if (parseInt($(el).css('border-top-width'), 10) > 0) { newContext.strokeRect(left, top, $(el).innerWidth(), $(el).innerHeight()); } // find all the swatches $(el).find('div.jqplot-table-legend-swatch-outline').each(function() { // get the first div and stroke it var elem = $(this); newContext.strokeStyle = elem.css('border-top-color'); var l = left + elem.position().left; var t = top + elem.position().top; newContext.strokeRect(l, t, elem.innerWidth(), elem.innerHeight()); // now fill the swatch l += parseInt(elem.css('padding-left'), 10); t += parseInt(elem.css('padding-top'), 10); var h = elem.innerHeight() - 2 * parseInt(elem.css('padding-top'), 10); var w = elem.innerWidth() - 2 * parseInt(elem.css('padding-left'), 10); var swatch = elem.children('div.jqplot-table-legend-swatch'); newContext.fillStyle = swatch.css('background-color'); newContext.fillRect(l, t, w, h); }); // now add text $(el).find('td.jqplot-table-legend-label').each(function(){ var elem = $(this); var l = left + elem.position().left; var t = top + elem.position().top + parseInt(elem.css('padding-top'), 10); newContext.font = elem.jqplotGetComputedFontStyle(); newContext.fillStyle = elem.css('color'); newContext.fillText(elem.text(), l, t); }); var elem = null; } else if (tagname == 'canvas') { newContext.drawImage(el, left, top); } } $(this).children().each(function() { _jqpToImage(this, x_offset, y_offset); }); return newCanvas; }; $.fn.jqplotToImageStr = function(options) { var imgCanvas = $(this).jqplotToImageCanvas(options); if (imgCanvas) { return imgCanvas.toDataURL("image/png"); } else { return null; } }; // create an <img> element and return it. // Should work on canvas supporting browsers. $.fn.jqplotToImageElem = function(options) { var elem = document.createElement("img"); var str = $(this).jqplotToImageStr(options); elem.src = str; return elem; }; // create an <img> element and return it. // Should work on canvas supporting browsers. $.fn.jqplotToImageElemStr = function(options) { var str = '<img src='+$(this).jqplotToImageStr(options)+' />'; return str; }; // Not gauranteed to work, even on canvas supporting browsers due to // limitations with location.href and browser support. $.fn.jqplotSaveImage = function() { var imgData = $(this).jqplotToImageStr({}); if (imgData) { window.location.href = imgData.replace("image/png", "image/octet-stream"); } }; // Not gauranteed to work, even on canvas supporting browsers due to // limitations with window.open and arbitrary data. $.fn.jqplotViewImage = function() { var imgStr = $(this).jqplotToImageElemStr({}); var imgData = $(this).jqplotToImageStr({}); if (imgStr) { var w = window.open(''); w.document.open("image/png"); w.document.write(imgStr); w.document.close(); w = null; } }; /** * @description * <p>Object with extended date parsing and formatting capabilities. * This library borrows many concepts and ideas from the Date Instance * Methods by Ken Snyder along with some parts of Ken's actual code.</p> * * <p>jsDate takes a different approach by not extending the built-in * Date Object, improving date parsing, allowing for multiple formatting * syntaxes and multiple and more easily expandable localization.</p> * * @author Chris Leonello * @date #date# * @version #VERSION# * @copyright (c) 2010 Chris Leonello * jsDate is currently available for use in all personal or commercial projects * under both the MIT and GPL version 2.0 licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * <p>Ken's origianl Date Instance Methods and copyright notice:</p> * <pre> * Ken Snyder (ken d snyder at gmail dot com) * 2008-09-10 * version 2.0.2 (http://kendsnyder.com/sandbox/date/) * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) * </pre> * * @class * @name jsDate * @param {String | Number | Array | Date Object | Options Object} arguments Optional arguments, either a parsable date/time string, * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], * a Date object, or an options object of form {syntax: "perl", date:some Date} where all options are optional. */ var jsDate = function () { this.syntax = jsDate.config.syntax; this._type = "jsDate"; this.proxy = new Date(); this.options = {}; this.locale = jsDate.regional.getLocale(); this.formatString = ''; this.defaultCentury = jsDate.config.defaultCentury; switch ( arguments.length ) { case 0: break; case 1: // other objects either won't have a _type property or, // if they do, it shouldn't be set to "jsDate", so // assume it is an options argument. if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { var opts = this.options = arguments[0]; this.syntax = opts.syntax || this.syntax; this.defaultCentury = opts.defaultCentury || this.defaultCentury; this.proxy = jsDate.createDate(opts.date); } else { this.proxy = jsDate.createDate(arguments[0]); } break; default: var a = []; for ( var i=0; i<arguments.length; i++ ) { a.push(arguments[i]); } // this should be the current date/time? this.proxy = new Date(); this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); if ( a.slice(3).length ) { this.proxy.setHours.apply( this.proxy, a.slice(3) ); } break; } }; /** * @namespace Configuration options that will be used as defaults for all instances on the page. * @property {String} defaultLocale The default locale to use [en]. * @property {String} syntax The default syntax to use [perl]. * @property {Number} defaultCentury The default centry for 2 digit dates. */ jsDate.config = { defaultLocale: 'en', syntax: 'perl', defaultCentury: 1900 }; /** * Add an arbitrary amount to the currently stored date * * @param {Number} number * @param {String} unit * @returns {jsDate} */ jsDate.prototype.add = function(number, unit) { var factor = multipliers[unit] || multipliers.day; if (typeof factor == 'number') { this.proxy.setTime(this.proxy.getTime() + (factor * number)); } else { factor.add(this, number); } return this; }; /** * Create a new jqplot.date object with the same date * * @returns {jsDate} */ jsDate.prototype.clone = function() { return new jsDate(this.proxy.getTime()); }; /** * Get the UTC TimeZone Offset of this date in milliseconds. * * @returns {Number} */ jsDate.prototype.getUtcOffset = function() { return this.proxy.getTimezoneOffset() * 60000; }; /** * Find the difference between this jsDate and another date. * * @param {String| Number| Array| jsDate Object| Date Object} dateObj * @param {String} unit * @param {Boolean} allowDecimal * @returns {Number} Number of units difference between dates. */ jsDate.prototype.diff = function(dateObj, unit, allowDecimal) { // ensure we have a Date object dateObj = new jsDate(dateObj); if (dateObj === null) { return null; } // get the multiplying factor integer or factor function var factor = multipliers[unit] || multipliers.day; if (typeof factor == 'number') { // multiply var unitDiff = (this.proxy.getTime() - dateObj.proxy.getTime()) / factor; } else { // run function var unitDiff = factor.diff(this.proxy, dateObj.proxy); } // if decimals are not allowed, round toward zero return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff)); }; /** * Get the abbreviated name of the current week day * * @returns {String} */ jsDate.prototype.getAbbrDayName = function() { return jsDate.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]; }; /** * Get the abbreviated name of the current month * * @returns {String} */ jsDate.prototype.getAbbrMonthName = function() { return jsDate.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]; }; /** * Get UPPER CASE AM or PM for the current time * * @returns {String} */ jsDate.prototype.getAMPM = function() { return this.proxy.getHours() >= 12 ? 'PM' : 'AM'; }; /** * Get lower case am or pm for the current time * * @returns {String} */ jsDate.prototype.getAmPm = function() { return this.proxy.getHours() >= 12 ? 'pm' : 'am'; }; /** * Get the century (19 for 20th Century) * * @returns {Integer} Century (19 for 20th century). */ jsDate.prototype.getCentury = function() { return parseInt(this.proxy.getFullYear()/100, 10); }; /** * Implements Date functionality */ jsDate.prototype.getDate = function() { return this.proxy.getDate(); }; /** * Implements Date functionality */ jsDate.prototype.getDay = function() { return this.proxy.getDay(); }; /** * Get the Day of week 1 (Monday) thru 7 (Sunday) * * @returns {Integer} Day of week 1 (Monday) thru 7 (Sunday) */ jsDate.prototype.getDayOfWeek = function() { var dow = this.proxy.getDay(); return dow===0?7:dow; }; /** * Get the day of the year * * @returns {Integer} 1 - 366, day of the year */ jsDate.prototype.getDayOfYear = function() { var d = this.proxy; var ms = d - new Date('' + d.getFullYear() + '/1/1 GMT'); ms += d.getTimezoneOffset()*60000; d = null; return parseInt(ms/60000/60/24, 10)+1; }; /** * Get the name of the current week day * * @returns {String} */ jsDate.prototype.getDayName = function() { return jsDate.regional[this.locale]["dayNames"][this.proxy.getDay()]; }; /** * Get the week number of the given year, starting with the first Sunday as the first week * @returns {Integer} Week number (13 for the 13th full week of the year). */ jsDate.prototype.getFullWeekOfYear = function() { var d = this.proxy; var doy = this.getDayOfYear(); var rdow = 6-d.getDay(); var woy = parseInt((doy+rdow)/7, 10); return woy; }; /** * Implements Date functionality */ jsDate.prototype.getFullYear = function() { return this.proxy.getFullYear(); }; /** * Get the GMT offset in hours and minutes (e.g. +06:30) * * @returns {String} */ jsDate.prototype.getGmtOffset = function() { // divide the minutes offset by 60 var hours = this.proxy.getTimezoneOffset() / 60; // decide if we are ahead of or behind GMT var prefix = hours < 0 ? '+' : '-'; // remove the negative sign if any hours = Math.abs(hours); // add the +/- to the padded number of hours to : to the padded minutes return prefix + addZeros(Math.floor(hours), 2) + ':' + addZeros((hours % 1) * 60, 2); }; /** * Implements Date functionality */ jsDate.prototype.getHours = function() { return this.proxy.getHours(); }; /** * Get the current hour on a 12-hour scheme * * @returns {Integer} */ jsDate.prototype.getHours12 = function() { var hours = this.proxy.getHours(); return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours); }; jsDate.prototype.getIsoWeek = function() { var d = this.proxy; var woy = d.getWeekOfYear(); var dow1_1 = (new Date('' + d.getFullYear() + '/1/1')).getDay(); // First week is 01 and not 00 as in the case of %U and %W, // so we add 1 to the final result except if day 1 of the year // is a Monday (then %W returns 01). // We also need to subtract 1 if the day 1 of the year is // Friday-Sunday, so the resulting equation becomes: var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1); if(idow == 53 && (new Date('' + d.getFullYear() + '/12/31')).getDay() < 4) { idow = 1; } else if(idow === 0) { d = new jsDate(new Date('' + (d.getFullYear()-1) + '/12/31')); idow = d.getIsoWeek(); } d = null; return idow; }; /** * Implements Date functionality */ jsDate.prototype.getMilliseconds = function() { return this.proxy.getMilliseconds(); }; /** * Implements Date functionality */ jsDate.prototype.getMinutes = function() { return this.proxy.getMinutes(); }; /** * Implements Date functionality */ jsDate.prototype.getMonth = function() { return this.proxy.getMonth(); }; /** * Get the name of the current month * * @returns {String} */ jsDate.prototype.getMonthName = function() { return jsDate.regional[this.locale]["monthNames"][this.proxy.getMonth()]; }; /** * Get the number of the current month, 1-12 * * @returns {Integer} */ jsDate.prototype.getMonthNumber = function() { return this.proxy.getMonth() + 1; }; /** * Implements Date functionality */ jsDate.prototype.getSeconds = function() { return this.proxy.getSeconds(); }; /** * Return a proper two-digit year integer * * @returns {Integer} */ jsDate.prototype.getShortYear = function() { return this.proxy.getYear() % 100; }; /** * Implements Date functionality */ jsDate.prototype.getTime = function() { return this.proxy.getTime(); }; /** * Get the timezone abbreviation * * @returns {String} Abbreviation for the timezone */ jsDate.prototype.getTimezoneAbbr = function() { return this.proxy.toString().replace(/^.*\(([^)]+)\)$/, '$1'); }; /** * Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time) * * @returns {String} */ jsDate.prototype.getTimezoneName = function() { var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString()); return match[1] || match[2] || 'GMT' + this.getGmtOffset(); }; /** * Implements Date functionality */ jsDate.prototype.getTimezoneOffset = function() { return this.proxy.getTimezoneOffset(); }; /** * Get the week number of the given year, starting with the first Monday as the first week * @returns {Integer} Week number (13 for the 13th week of the year). */ jsDate.prototype.getWeekOfYear = function() { var doy = this.getDayOfYear(); var rdow = 7 - this.getDayOfWeek(); var woy = parseInt((doy+rdow)/7, 10); return woy; }; /** * Get the current date as a Unix timestamp * * @returns {Integer} */ jsDate.prototype.getUnix = function() { return Math.round(this.proxy.getTime() / 1000, 0); }; /** * Implements Date functionality */ jsDate.prototype.getYear = function() { return this.proxy.getYear(); }; /** * Return a date one day ahead (or any other unit) * * @param {String} unit Optional, year | month | day | week | hour | minute | second | millisecond * @returns {jsDate} */ jsDate.prototype.next = function(unit) { unit = unit || 'day'; return this.clone().add(1, unit); }; /** * Set the jsDate instance to a new date. * * @param {String | Number | Array | Date Object | jsDate Object | Options Object} arguments Optional arguments, * either a parsable date/time string, * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], * a Date object, jsDate Object or an options object of form {syntax: "perl", date:some Date} where all options are optional. */ jsDate.prototype.set = function() { switch ( arguments.length ) { case 0: this.proxy = new Date(); break; case 1: // other objects either won't have a _type property or, // if they do, it shouldn't be set to "jsDate", so // assume it is an options argument. if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { var opts = this.options = arguments[0]; this.syntax = opts.syntax || this.syntax; this.defaultCentury = opts.defaultCentury || this.defaultCentury; this.proxy = jsDate.createDate(opts.date); } else { this.proxy = jsDate.createDate(arguments[0]); } break; default: var a = []; for ( var i=0; i<arguments.length; i++ ) { a.push(arguments[i]); } // this should be the current date/time this.proxy = new Date(); this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); if ( a.slice(3).length ) { this.proxy.setHours.apply( this.proxy, a.slice(3) ); } break; } return this; }; /** * Sets the day of the month for a specified date according to local time. * @param {Integer} dayValue An integer from 1 to 31, representing the day of the month. */ jsDate.prototype.setDate = function(n) { this.proxy.setDate(n); return this; }; /** * Sets the full year for a specified date according to local time. * @param {Integer} yearValue The numeric value of the year, for example, 1995. * @param {Integer} monthValue Optional, between 0 and 11 representing the months January through December. * @param {Integer} dayValue Optional, between 1 and 31 representing the day of the month. If you specify the dayValue parameter, you must also specify the monthValue. */ jsDate.prototype.setFullYear = function() { this.proxy.setFullYear.apply(this.proxy, arguments); return this; }; /** * Sets the hours for a specified date according to local time. * * @param {Integer} hoursValue An integer between 0 and 23, representing the hour. * @param {Integer} minutesValue Optional, An integer between 0 and 59, representing the minutes. * @param {Integer} secondsValue Optional, An integer between 0 and 59, representing the seconds. * If you specify the secondsValue parameter, you must also specify the minutesValue. * @param {Integer} msValue Optional, A number between 0 and 999, representing the milliseconds. * If you specify the msValue parameter, you must also specify the minutesValue and secondsValue. */ jsDate.prototype.setHours = function() { this.proxy.setHours.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMilliseconds = function(n) { this.proxy.setMilliseconds(n); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMinutes = function() { this.proxy.setMinutes.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMonth = function() { this.proxy.setMonth.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setSeconds = function() { this.proxy.setSeconds.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setTime = function(n) { this.proxy.setTime(n); return this; }; /** * Implements Date functionality */ jsDate.prototype.setYear = function() { this.proxy.setYear.apply(this.proxy, arguments); return this; }; /** * Provide a formatted string representation of this date. * * @param {String} formatString A format string. * See: {@link jsDate.formats}. * @returns {String} Date String. */ jsDate.prototype.strftime = function(formatString) { formatString = formatString || this.formatString || jsDate.regional[this.locale]['formatString']; return jsDate.strftime(this, formatString, this.syntax); }; /** * Return a String representation of this jsDate object. * @returns {String} Date string. */ jsDate.prototype.toString = function() { return this.proxy.toString(); }; /** * Convert the current date to an 8-digit integer (%Y%m%d) * * @returns {Integer} */ jsDate.prototype.toYmdInt = function() { return (this.proxy.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.proxy.getDate(); }; /** * @namespace Holds localizations for month/day names. * <p>jsDate attempts to detect locale when loaded and defaults to 'en'. * If a localization is detected which is not available, jsDate defaults to 'en'. * Additional localizations can be added after jsDate loads. After adding a localization, * call the jsDate.regional.getLocale() method. Currently, en, fr and de are defined.</p> * * <p>Localizations must be an object and have the following properties defined: monthNames, monthNamesShort, dayNames, dayNamesShort and Localizations are added like:</p> * <pre class="code"> * jsDate.regional['en'] = { * monthNames : 'January February March April May June July August September October November December'.split(' '), * monthNamesShort : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '), * dayNames : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '), * dayNamesShort : 'Sun Mon Tue Wed Thu Fri Sat'.split(' ') * }; * </pre> * <p>After adding localizations, call <code>jsDate.regional.getLocale();</code> to update the locale setting with the * new localizations.</p> */ jsDate.regional = { 'en': { monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], formatString: '%Y-%m-%d %H:%M:%S' }, 'fr': { monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'], monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'], dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], formatString: '%Y-%m-%d %H:%M:%S' }, 'de': { monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], formatString: '%Y-%m-%d %H:%M:%S' }, 'es': { monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', 'Jul','Ago','Sep','Oct','Nov','Dic'], dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'ru': { monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн','Июл','Авг','Сен','Окт','Ноя','Дек'], dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], formatString: '%Y-%m-%d %H:%M:%S' }, 'ar': { monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران','تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'], dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'], formatString: '%Y-%m-%d %H:%M:%S' }, 'pt': { monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'pt-BR': { monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' } }; // Set english variants to 'en' jsDate.regional['en-US'] = jsDate.regional['en-GB'] = jsDate.regional['en']; /** * Try to determine the users locale based on the lang attribute of the html page. Defaults to 'en' * if it cannot figure out a locale of if the locale does not have a localization defined. * @returns {String} locale */ jsDate.regional.getLocale = function () { var l = jsDate.config.defaultLocale; if ( document && document.getElementsByTagName('html') && document.getElementsByTagName('html')[0].lang ) { l = document.getElementsByTagName('html')[0].lang; if (!jsDate.regional.hasOwnProperty(l)) { l = jsDate.config.defaultLocale; } } return l; }; // ms in day var day = 24 * 60 * 60 * 1000; // padd a number with zeros var addZeros = function(num, digits) { num = String(num); var i = digits - num.length; var s = String(Math.pow(10, i)).slice(1); return s.concat(num); }; // representations used for calculating differences between dates. // This borrows heavily from Ken Snyder's work. var multipliers = { millisecond: 1, second: 1000, minute: 60 * 1000, hour: 60 * 60 * 1000, day: day, week: 7 * day, month: { // add a number of months add: function(d, number) { // add any years needed (increments of 12) multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12)); // ensure that we properly wrap betwen December and January // 11 % 12 = 11 // 12 % 12 = 0 var prevMonth = d.getMonth() + (number % 12); if (prevMonth == 12) { prevMonth = 0; d.setYear(d.getFullYear() + 1); } else if (prevMonth == -1) { prevMonth = 11; d.setYear(d.getFullYear() - 1); } d.setMonth(prevMonth); }, // get the number of months between two Date objects (decimal to the nearest day) diff: function(d1, d2) { // get the number of years var diffYears = d1.getFullYear() - d2.getFullYear(); // get the number of remaining months var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12); // get the number of remaining days var diffDays = d1.getDate() - d2.getDate(); // return the month difference with the days difference as a decimal return diffMonths + (diffDays / 30); } }, year: { // add a number of years add: function(d, number) { d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number)); }, // get the number of years between two Date objects (decimal to the nearest day) diff: function(d1, d2) { return multipliers.month.diff(d1, d2) / 12; } } }; // // Alias each multiplier with an 's' to allow 'year' and 'years' for example. // This comes from Ken Snyders work. // for (var unit in multipliers) { if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :| multipliers[unit + 's'] = multipliers[unit]; } } // // take a jsDate instance and a format code and return the formatted value. // This is a somewhat modified version of Ken Snyder's method. // var format = function(d, code, syntax) { // if shorcut codes are used, recursively expand those. if (jsDate.formats[syntax]["shortcuts"][code]) { return jsDate.strftime(d, jsDate.formats[syntax]["shortcuts"][code], syntax); } else { // get the format code function and addZeros() argument var getter = (jsDate.formats[syntax]["codes"][code] || '').split('.'); var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : ''; if (getter[1]) { nbr = addZeros(nbr, getter[1]); } return nbr; } }; /** * @static * Static function for convert a date to a string according to a given format. Also acts as namespace for strftime format codes. * <p>strftime formatting can be accomplished without creating a jsDate object by calling jsDate.strftime():</p> * <pre class="code"> * var formattedDate = jsDate.strftime('Feb 8, 2006 8:48:32', '%Y-%m-%d %H:%M:%S'); * </pre> * @param {String | Number | Array | jsDate Object | Date Object} date A parsable date string, JavaScript time stamp, Array of form [year, month, day, hours, minutes, seconds, milliseconds], jsDate Object or Date object. * @param {String} formatString String with embedded date formatting codes. * See: {@link jsDate.formats}. * @param {String} syntax Optional syntax to use [default perl]. * @param {String} locale Optional locale to use. * @returns {String} Formatted representation of the date. */ // // Logic as implemented here is very similar to Ken Snyder's Date Instance Methods. // jsDate.strftime = function(d, formatString, syntax, locale) { var syn = 'perl'; var loc = jsDate.regional.getLocale(); // check if syntax and locale are available or reversed if (syntax && jsDate.formats.hasOwnProperty(syntax)) { syn = syntax; } else if (syntax && jsDate.regional.hasOwnProperty(syntax)) { loc = syntax; } if (locale && jsDate.formats.hasOwnProperty(locale)) { syn = locale; } else if (locale && jsDate.regional.hasOwnProperty(locale)) { loc = locale; } if (get_type(d) != "[object Object]" || d._type != "jsDate") { d = new jsDate(d); d.locale = loc; } if (!formatString) { formatString = d.formatString || jsDate.regional[loc]['formatString']; } // default the format string to year-month-day var source = formatString || '%Y-%m-%d', result = '', match; // replace each format code while (source.length > 0) { if (match = source.match(jsDate.formats[syn].codes.matcher)) { result += source.slice(0, match.index); result += (match[1] || '') + format(d, match[2], syn); source = source.slice(match.index + match[0].length); } else { result += source; source = ''; } } return result; }; /** * @namespace * Namespace to hold format codes and format shortcuts. "perl" and "php" format codes * and shortcuts are defined by default. Additional codes and shortcuts can be * added like: * * <pre class="code"> * jsDate.formats["perl"] = { * "codes": { * matcher: /someregex/, * Y: "fullYear", // name of "get" method without the "get", * ..., // more codes * }, * "shortcuts": { * F: '%Y-%m-%d', * ..., // more shortcuts * } * }; * </pre> * * <p>Additionally, ISO and SQL shortcuts are defined and can be accesses via: * <code>jsDate.formats.ISO</code> and <code>jsDate.formats.SQL</code> */ jsDate.formats = { ISO:'%Y-%m-%dT%H:%M:%S.%N%G', SQL:'%Y-%m-%d %H:%M:%S' }; /** * Perl format codes and shortcuts for strftime. * * A hash (object) of codes where each code must be an array where the first member is * the name of a Date.prototype or jsDate.prototype function to call * and optionally a second member indicating the number to pass to addZeros() * * <p>The following format codes are defined:</p> * * <pre class="code"> * Code Result Description * == Years == * %Y 2008 Four-digit year * %y 08 Two-digit year * * == Months == * %m 09 Two-digit month * %#m 9 One or two-digit month * %B September Full month name * %b Sep Abbreviated month name * * == Days == * %d 05 Two-digit day of month * %#d 5 One or two-digit day of month * %e 5 One or two-digit day of month * %A Sunday Full name of the day of the week * %a Sun Abbreviated name of the day of the week * %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) * * == Hours == * %H 23 Hours in 24-hour format (two digits) * %#H 3 Hours in 24-hour integer format (one or two digits) * %I 11 Hours in 12-hour format (two digits) * %#I 3 Hours in 12-hour integer format (one or two digits) * %p PM AM or PM * * == Minutes == * %M 09 Minutes (two digits) * %#M 9 Minutes (one or two digits) * * == Seconds == * %S 02 Seconds (two digits) * %#S 2 Seconds (one or two digits) * %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) * * == Milliseconds == * %N 008 Milliseconds (three digits) * %#N 8 Milliseconds (one to three digits) * * == Timezone == * %O 360 difference in minutes between local time and GMT * %Z Mountain Standard Time Name of timezone as reported by browser * %G 06:00 Hours and minutes between GMT * * == Shortcuts == * %F 2008-03-26 %Y-%m-%d * %T 05:06:30 %H:%M:%S * %X 05:06:30 %H:%M:%S * %x 03/26/08 %m/%d/%y * %D 03/26/08 %m/%d/%y * %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y * %v 3-Sep-2008 %e-%b-%Y * %R 15:31 %H:%M * %r 03:31:00 PM %I:%M:%S %p * * == Characters == * %n \n Newline * %t \t Tab * %% % Percent Symbol * </pre> * * <p>Formatting shortcuts that will be translated into their longer version. * Be sure that format shortcuts do not refer to themselves: this will cause an infinite loop.</p> * * <p>Format codes and format shortcuts can be redefined after the jsDate * module is imported.</p> * * <p>Note that if you redefine the whole hash (object), you must supply a "matcher" * regex for the parser. The default matcher is:</p> * * <code>/()%(#?(%|[a-z]))/i</code> * * <p>which corresponds to the Perl syntax used by default.</p> * * <p>By customizing the matcher and format codes, nearly any strftime functionality is possible.</p> */ jsDate.formats.perl = { codes: { // // 2-part regex matcher for format codes // // first match must be the character before the code (to account for escaping) // second match must be the format code character(s) // matcher: /()%(#?(%|[a-z]))/i, // year Y: 'FullYear', y: 'ShortYear.2', // month m: 'MonthNumber.2', '#m': 'MonthNumber', B: 'MonthName', b: 'AbbrMonthName', // day d: 'Date.2', '#d': 'Date', e: 'Date', A: 'DayName', a: 'AbbrDayName', w: 'Day', // hours H: 'Hours.2', '#H': 'Hours', I: 'Hours12.2', '#I': 'Hours12', p: 'AMPM', // minutes M: 'Minutes.2', '#M': 'Minutes', // seconds S: 'Seconds.2', '#S': 'Seconds', s: 'Unix', // milliseconds N: 'Milliseconds.3', '#N': 'Milliseconds', // timezone O: 'TimezoneOffset', Z: 'TimezoneName', G: 'GmtOffset' }, shortcuts: { // date F: '%Y-%m-%d', // time T: '%H:%M:%S', X: '%H:%M:%S', // local format date x: '%m/%d/%y', D: '%m/%d/%y', // local format extended '#c': '%a %b %e %H:%M:%S %Y', // local format short v: '%e-%b-%Y', R: '%H:%M', r: '%I:%M:%S %p', // tab and newline t: '\t', n: '\n', '%': '%' } }; /** * PHP format codes and shortcuts for strftime. * * A hash (object) of codes where each code must be an array where the first member is * the name of a Date.prototype or jsDate.prototype function to call * and optionally a second member indicating the number to pass to addZeros() * * <p>The following format codes are defined:</p> * * <pre class="code"> * Code Result Description * === Days === * %a Sun through Sat An abbreviated textual representation of the day * %A Sunday - Saturday A full textual representation of the day * %d 01 to 31 Two-digit day of the month (with leading zeros) * %e 1 to 31 Day of the month, with a space preceding single digits. * %j 001 to 366 Day of the year, 3 digits with leading zeros * %u 1 - 7 (Mon - Sun) ISO-8601 numeric representation of the day of the week * %w 0 - 6 (Sun - Sat) Numeric representation of the day of the week * * === Week === * %U 13 Full Week number, starting with the first Sunday as the first week * %V 01 through 53 ISO-8601:1988 week number, starting with the first week of the year * with at least 4 weekdays, with Monday being the start of the week * %W 46 A numeric representation of the week of the year, * starting with the first Monday as the first week * === Month === * %b Jan through Dec Abbreviated month name, based on the locale * %B January - December Full month name, based on the locale * %h Jan through Dec Abbreviated month name, based on the locale (an alias of %b) * %m 01 - 12 (Jan - Dec) Two digit representation of the month * * === Year === * %C 19 Two digit century (year/100, truncated to an integer) * %y 09 for 2009 Two digit year * %Y 2038 Four digit year * * === Time === * %H 00 through 23 Two digit representation of the hour in 24-hour format * %I 01 through 12 Two digit representation of the hour in 12-hour format * %l 1 through 12 Hour in 12-hour format, with a space preceeding single digits * %M 00 through 59 Two digit representation of the minute * %p AM/PM UPPER-CASE 'AM' or 'PM' based on the given time * %P am/pm lower-case 'am' or 'pm' based on the given time * %r 09:34:17 PM Same as %I:%M:%S %p * %R 00:35 Same as %H:%M * %S 00 through 59 Two digit representation of the second * %T 21:34:17 Same as %H:%M:%S * %X 03:59:16 Preferred time representation based on locale, without the date * %z -0500 or EST Either the time zone offset from UTC or the abbreviation * %Z -0500 or EST The time zone offset/abbreviation option NOT given by %z * * === Time and Date === * %D 02/05/09 Same as %m/%d/%y * %F 2009-02-05 Same as %Y-%m-%d (commonly used in database datestamps) * %s 305815200 Unix Epoch Time timestamp (same as the time() function) * %x 02/05/09 Preferred date representation, without the time * * === Miscellaneous === * %n --- A newline character (\n) * %t --- A Tab character (\t) * %% --- A literal percentage character (%) * </pre> */ jsDate.formats.php = { codes: { // // 2-part regex matcher for format codes // // first match must be the character before the code (to account for escaping) // second match must be the format code character(s) // matcher: /()%((%|[a-z]))/i, // day a: 'AbbrDayName', A: 'DayName', d: 'Date.2', e: 'Date', j: 'DayOfYear.3', u: 'DayOfWeek', w: 'Day', // week U: 'FullWeekOfYear.2', V: 'IsoWeek.2', W: 'WeekOfYear.2', // month b: 'AbbrMonthName', B: 'MonthName', m: 'MonthNumber.2', h: 'AbbrMonthName', // year C: 'Century.2', y: 'ShortYear.2', Y: 'FullYear', // time H: 'Hours.2', I: 'Hours12.2', l: 'Hours12', p: 'AMPM', P: 'AmPm', M: 'Minutes.2', S: 'Seconds.2', s: 'Unix', O: 'TimezoneOffset', z: 'GmtOffset', Z: 'TimezoneAbbr' }, shortcuts: { D: '%m/%d/%y', F: '%Y-%m-%d', T: '%H:%M:%S', X: '%H:%M:%S', x: '%m/%d/%y', R: '%H:%M', r: '%I:%M:%S %p', t: '\t', n: '\n', '%': '%' } }; // // Conceptually, the logic implemented here is similar to Ken Snyder's Date Instance Methods. // I use his idea of a set of parsers which can be regular expressions or functions, // iterating through those, and then seeing if Date.parse() will create a date. // The parser expressions and functions are a little different and some bugs have been // worked out. Also, a lot of "pre-parsing" is done to fix implementation // variations of Date.parse() between browsers. // jsDate.createDate = function(date) { // if passing in multiple arguments, try Date constructor if (date == null) { return new Date(); } // If the passed value is already a date object, return it if (date instanceof Date) { return date; } // if (typeof date == 'number') return new Date(date * 1000); // If the passed value is an integer, interpret it as a javascript timestamp if (typeof date == 'number') { return new Date(date); } // Before passing strings into Date.parse(), have to normalize them for certain conditions. // If strings are not formatted staccording to the EcmaScript spec, results from Date parse will be implementation dependent. // // For example: // * FF and Opera assume 2 digit dates are pre y2k, Chome assumes <50 is pre y2k, 50+ is 21st century. // * Chrome will correctly parse '1984-1-25' into localtime, FF and Opera will not parse. // * Both FF, Chrome and Opera will parse '1984/1/25' into localtime. // remove leading and trailing spaces var parsable = String(date).replace(/^\s*(.+)\s*$/g, '$1'); // replace dahses (-) with slashes (/) in dates like n[nnn]/n[n]/n[nnn] parsable = parsable.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/, "$1/$2/$3"); ///////// // Need to check for '15-Dec-09' also. // FF will not parse, but Chrome will. // Chrome will set date to 2009 as well. ///////// // first check for 'dd-mmm-yyyy' or 'dd/mmm/yyyy' like '15-Dec-2010' parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i, "$1 $2 $3"); // Now check for 'dd-mmm-yy' or 'dd/mmm/yy' and normalize years to default century. var match = parsable.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i); if (match && match.length > 3) { var m3 = parseFloat(match[3]); var ny = jsDate.config.defaultCentury + m3; ny = String(ny); // now replace 2 digit year with 4 digit year parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i, match[1] +' '+ match[2] +' '+ ny); } // Check for '1/19/70 8:14PM' // where starts with mm/dd/yy or yy/mm/dd and have something after // Check if 1st postiion is greater than 31, assume it is year. // Assme all 2 digit years are 1900's. // Finally, change them into US style mm/dd/yyyy representations. match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/); function h1(parsable, match) { var m1 = parseFloat(match[1]); var m2 = parseFloat(match[2]); var m3 = parseFloat(match[3]); var cent = jsDate.config.defaultCentury; var ny, nd, nm, str; if (m1 > 31) { // first number is a year nd = m3; nm = m2; ny = cent + m1; } else { // last number is the year nd = m2; nm = m1; ny = cent + m3; } str = nm+'/'+nd+'/'+ny; // now replace 2 digit year with 4 digit year return parsable.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/, str); } if (match && match.length > 3) { parsable = h1(parsable, match); } // Now check for '1/19/70' with nothing after and do as above var match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/); if (match && match.length > 3) { parsable = h1(parsable, match); } var i = 0; var length = jsDate.matchers.length; var pattern, ms, current = parsable, obj; while (i < length) { ms = Date.parse(current); if (!isNaN(ms)) { return new Date(ms); } pattern = jsDate.matchers[i]; if (typeof pattern == 'function') { obj = pattern.call(jsDate, current); if (obj instanceof Date) { return obj; } } else { current = parsable.replace(pattern[0], pattern[1]); } i++; } return NaN; }; /** * @static * Handy static utility function to return the number of days in a given month. * @param {Integer} year Year * @param {Integer} month Month (1-12) * @returns {Integer} Number of days in the month. */ // // handy utility method Borrowed right from Ken Snyder's Date Instance Mehtods. // jsDate.daysInMonth = function(year, month) { if (month == 2) { return new Date(year, 1, 29).getDate() == 29 ? 29 : 28; } return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month]; }; // // An Array of regular expressions or functions that will attempt to match the date string. // Functions are called with scope of a jsDate instance. // jsDate.matchers = [ // convert dd.mmm.yyyy to mm/dd/yyyy (world date to US date). [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'], // convert yyyy-mm-dd to mm/dd/yyyy (ISO date to US date). [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'], // Handle 12 hour or 24 hour time with milliseconds am/pm and optional date part. function(str) { var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i); // opt. date hour opt. minute opt. second opt. msec opt. am or pm if (match) { if (match[1]) { var d = this.createDate(match[1]); if (isNaN(d)) { return; } } else { var d = new Date(); d.setMilliseconds(0); } var hour = parseFloat(match[2]); if (match[6]) { hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12); } d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000); return d; } else { return str; } }, // Handle ISO timestamp with time zone. function(str) { var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i); if (match) { if (match[1]) { var d = this.createDate(match[1]); if (isNaN(d)) { return; } } else { var d = new Date(); d.setMilliseconds(0); } var hour = parseFloat(match[2]); d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000); return d; } else { return str; } }, // Try to match ambiguous strings like 12/8/22. // Use FF date assumption that 2 digit years are 20th century (i.e. 1900's). // This may be redundant with pre processing of date already performed. function(str) { var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/); if (match) { var d = new Date(); var cent = jsDate.config.defaultCentury; var m1 = parseFloat(match[1]); var m3 = parseFloat(match[3]); var ny, nd, nm; if (m1 > 31) { // first number is a year nd = m3; ny = cent + m1; } else { // last number is the year nd = m1; ny = cent + m3; } var nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNamesShort"]); if (nm == -1) { nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNames"]); } d.setFullYear(ny, nm, nd); d.setHours(0,0,0,0); return d; } else { return str; } } ]; // // I think John Reisig published this method on his blog, ejohn. // function inArray( elem, array ) { if ( array.indexOf ) { return array.indexOf( elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { if ( array[ i ] === elem ) { return i; } } return -1; } // // Thanks to Kangax, Christian Sciberras and Stack Overflow for this method. // function get_type(thing){ if(thing===null) return "[object Null]"; // special case return Object.prototype.toString.call(thing); } $.jsDate = jsDate; /** * JavaScript printf/sprintf functions. * * This code has been adapted from the publicly available sprintf methods * by Ash Searle. His original header follows: * * This code is unrestricted: you are free to use it however you like. * * The functions should work as expected, performing left or right alignment, * truncating strings, outputting numbers with a required precision etc. * * For complex cases, these functions follow the Perl implementations of * (s)printf, allowing arguments to be passed out-of-order, and to set the * precision or length of the output based on arguments instead of fixed * numbers. * * See http://perldoc.perl.org/functions/sprintf.html for more information. * * Implemented: * - zero and space-padding * - right and left-alignment, * - base X prefix (binary, octal and hex) * - positive number prefix * - (minimum) width * - precision / truncation / maximum width * - out of order arguments * * Not implemented (yet): * - vector flag * - size (bytes, words, long-words etc.) * * Will not implement: * - %n or %p (no pass-by-reference in JavaScript) * * @version 2007.04.27 * @author Ash Searle * * You can see the original work and comments on his blog: * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js */ /** * @Modifications 2009.05.26 * @author Chris Leonello * * Added %p %P specifier * Acts like %g or %G but will not add more significant digits to the output than present in the input. * Example: * Format: '%.3p', Input: 0.012, Output: 0.012 * Format: '%.3g', Input: 0.012, Output: 0.0120 * Format: '%.4p', Input: 12.0, Output: 12.0 * Format: '%.4g', Input: 12.0, Output: 12.00 * Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5 * Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5 * * Example: * >>> $.jqplot.sprintf('%.2f, %d', 23.3452, 43.23) * "23.35, 43" * >>> $.jqplot.sprintf("no value: %n, decimal with thousands separator: %'d", 23.3452, 433524) * "no value: , decimal with thousands separator: 433,524" */ $.jqplot.sprintf = function() { function pad(str, len, chr, leftJustify) { var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); return leftJustify ? str + padding : padding + str; } function thousand_separate(value) { var value_str = new String(value); for (var i=10; i>0; i--) { if (value_str == (value_str = value_str.replace(/^(\d+)(\d{3})/, "$1"+$.jqplot.sprintf.thousandsSeparator+"$2"))) break; } return value_str; } function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) { var diff = minWidth - value.length; if (diff > 0) { var spchar = ' '; if (htmlSpace) { spchar = ' '; } if (leftJustify || !zeroPad) { value = pad(value, minWidth, spchar, leftJustify); } else { value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); } } return value; } function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) { // Note: casts negative numbers to positive ones var number = value >>> 0; prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || ''; value = prefix + pad(number.toString(base), precision || 0, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) { if (precision != null) { value = value.slice(0, precision); } return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace); } var a = arguments, i = 0, format = a[i++]; return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) { if (substring == '%%') { return '%'; } // parse flags var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false, thousandSeparation = false; for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) { case ' ': positivePrefix = ' '; break; case '+': positivePrefix = '+'; break; case '-': leftJustify = true; break; case '0': zeroPad = true; break; case '#': prefixBaseX = true; break; case '&': htmlSpace = true; break; case '\'': thousandSeparation = true; break; } // parameters may be null, undefined, empty-string or real valued // we want to ignore null, undefined and empty-string values if (!minWidth) { minWidth = 0; } else if (minWidth == '*') { minWidth = +a[i++]; } else if (minWidth.charAt(0) == '*') { minWidth = +a[minWidth.slice(1, -1)]; } else { minWidth = +minWidth; } // Note: undocumented perl feature: if (minWidth < 0) { minWidth = -minWidth; leftJustify = true; } if (!isFinite(minWidth)) { throw new Error('$.jqplot.sprintf: (minimum-)width must be finite'); } if (!precision) { precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0); } else if (precision == '*') { precision = +a[i++]; } else if (precision.charAt(0) == '*') { precision = +a[precision.slice(1, -1)]; } else { precision = +precision; } // grab value using valueIndex if required? var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; switch (type) { case 's': { if (value == null) { return ''; } return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace); } case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad,htmlSpace); case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase(); case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'i': { var number = parseInt(+value, 10); if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); value = prefix + pad(number_str, precision, '0', false); //value = prefix + pad(String(Math.abs(number)), precision, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } case 'd': { var number = Math.round(+value); if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); value = prefix + pad(number_str, precision, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': { var number = +value; if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; var number_str = Math.abs(number)[method](precision); number_str = thousandSeparation ? thousand_separate(number_str): number_str; value = prefix + number_str; return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); } case 'p': case 'P': { // make sure number is a number var number = +value; if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length; var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; if (Math.abs(number) < 1) { if (sd + zeros <= precision) { value = prefix + Math.abs(number).toPrecision(sd); } else { if (sd <= precision - 1) { value = prefix + Math.abs(number).toExponential(sd-1); } else { value = prefix + Math.abs(number).toExponential(precision-1); } } } else { var prec = (sd <= precision) ? sd : precision; value = prefix + Math.abs(number).toPrecision(prec); } var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2]; return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); } case 'n': return ''; default: return substring; } }); }; $.jqplot.sprintf.thousandsSeparator = ','; $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g; $.jqplot.getSignificantFigures = function(number) { var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); // total significant digits var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length; var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; // exponent var expn = parseInt(parts[1], 10); // digits to the left of the decimal place var dleft = (expn + 1 > 0) ? expn + 1 : 0; // digits to the right of the decimal place var dright = (sd <= dleft) ? 0 : sd - expn - 1; return {significantDigits: sd, digitsLeft: dleft, digitsRight: dright, zeros: zeros, exponent: expn} ; }; $.jqplot.getPrecision = function(number) { return $.jqplot.getSignificantFigures(number).digitsRight; }; })(jQuery); var backCompat = $.uiBackCompat !== false; $.jqplot.effects = { effect: {} }; // prefix used for storing data on .data() var dataSpace = "jqplot.storage."; /******************************************************************************/ /*********************************** EFFECTS **********************************/ /******************************************************************************/ $.extend( $.jqplot.effects, { version: "1.9pre", // Saves a set of properties in a data storage save: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); } } }, // Restores a set of previously saved properties from a data storage restore: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); } } }, setMode: function( el, mode ) { if (mode === "toggle") { mode = el.is( ":hidden" ) ? "show" : "hide"; } return mode; }, // Wraps the element around a wrapper that copies position properties createWrapper: function( element ) { // if the element is already wrapped, return it if ( element.parent().is( ".ui-effects-wrapper" )) { return element.parent(); } // wrap the element var props = { width: element.outerWidth(true), height: element.outerHeight(true), "float": element.css( "float" ) }, wrapper = $( "<div></div>" ) .addClass( "ui-effects-wrapper" ) .css({ fontSize: "100%", background: "transparent", border: "none", margin: 0, padding: 0 }), // Store the size in case width/height are defined in % - Fixes #5245 size = { width: element.width(), height: element.height() }, active = document.activeElement; element.wrap( wrapper ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).focus(); } wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element // transfer positioning properties to the wrapper if ( element.css( "position" ) === "static" ) { wrapper.css({ position: "relative" }); element.css({ position: "relative" }); } else { $.extend( props, { position: element.css( "position" ), zIndex: element.css( "z-index" ) }); $.each([ "top", "left", "bottom", "right" ], function(i, pos) { props[ pos ] = element.css( pos ); if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { props[ pos ] = "auto"; } }); element.css({ position: "relative", top: 0, left: 0, right: "auto", bottom: "auto" }); } element.css(size); return wrapper.css( props ).show(); }, removeWrapper: function( element ) { var active = document.activeElement; if ( element.parent().is( ".ui-effects-wrapper" ) ) { element.parent().replaceWith( element ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).focus(); } } return element; } }); // return an effect options object for the given parameters: function _normalizeArguments( effect, options, speed, callback ) { // short path for passing an effect options object: if ( $.isPlainObject( effect ) ) { return effect; } // convert to an object effect = { effect: effect }; // catch (effect) if ( options === undefined ) { options = {}; } // catch (effect, callback) if ( $.isFunction( options ) ) { callback = options; speed = null; options = {}; } // catch (effect, speed, ?) if ( $.type( options ) === "number" || $.fx.speeds[ options ]) { callback = speed; speed = options; options = {}; } // catch (effect, options, callback) if ( $.isFunction( speed ) ) { callback = speed; speed = null; } // add options to effect if ( options ) { $.extend( effect, options ); } speed = speed || options.duration; effect.duration = $.fx.off ? 0 : typeof speed === "number" ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; effect.complete = callback || options.complete; return effect; } function standardSpeed( speed ) { // valid standard speeds if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { return true; } // invalid strings - treat as "normal" speed if ( typeof speed === "string" && !$.jqplot.effects.effect[ speed ] ) { // TODO: remove in 2.0 (#7115) if ( backCompat && $.jqplot.effects[ speed ] ) { return false; } return true; } return false; } $.fn.extend({ jqplotEffect: function( effect, options, speed, callback ) { var args = _normalizeArguments.apply( this, arguments ), mode = args.mode, queue = args.queue, effectMethod = $.jqplot.effects.effect[ args.effect ], // DEPRECATED: remove in 2.0 (#7115) oldEffectMethod = !effectMethod && backCompat && $.jqplot.effects[ args.effect ]; if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { // delegate to the original method (e.g., .show()) if possible if ( mode ) { return this[ mode ]( args.duration, args.complete ); } else { return this.each( function() { if ( args.complete ) { args.complete.call( this ); } }); } } function run( next ) { var elem = $( this ), complete = args.complete, mode = args.mode; function done() { if ( $.isFunction( complete ) ) { complete.call( elem[0] ); } if ( $.isFunction( next ) ) { next(); } } // if the element is hiddden and mode is hide, // or element is visible and mode is show if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { done(); } else { effectMethod.call( elem[0], args, done ); } } // TODO: remove this check in 2.0, effectMethod will always be true if ( effectMethod ) { return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); } else { // DEPRECATED: remove in 2.0 (#7115) return oldEffectMethod.call(this, { options: args, duration: args.duration, callback: args.complete, mode: args.mode }); } } }); var rvertical = /up|down|vertical/, rpositivemotion = /up|left|vertical|horizontal/; $.jqplot.effects.effect.blind = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.jqplot.effects.setMode( el, o.mode || "hide" ), direction = o.direction || "up", vertical = rvertical.test( direction ), ref = vertical ? "height" : "width", ref2 = vertical ? "top" : "left", motion = rpositivemotion.test( direction ), animation = {}, show = mode === "show", wrapper, distance, top; // // if already wrapped, the wrapper's properties are my property. #6245 if ( el.parent().is( ".ui-effects-wrapper" ) ) { $.jqplot.effects.save( el.parent(), props ); } else { $.jqplot.effects.save( el, props ); } el.show(); top = parseInt(el.css('top'), 10); wrapper = $.jqplot.effects.createWrapper( el ).css({ overflow: "hidden" }); distance = vertical ? wrapper[ ref ]() + top : wrapper[ ref ](); animation[ ref ] = show ? String(distance) : '0'; if ( !motion ) { el .css( vertical ? "bottom" : "right", 0 ) .css( vertical ? "top" : "left", "" ) .css({ position: "absolute" }); animation[ ref2 ] = show ? '0' : String(distance); } // // start at 0 if we are showing if ( show ) { wrapper.css( ref, 0 ); if ( ! motion ) { wrapper.css( ref2, distance ); } } // // Animate wrapper.animate( animation, { duration: o.duration, easing: o.easing, queue: false, complete: function() { if ( mode === "hide" ) { el.hide(); } $.jqplot.effects.restore( el, props ); $.jqplot.effects.removeWrapper( el ); done(); } }); }; ������debian/README.Debian��������������������������������������������������������������������������������0000664�0000000�0000000�00000004632�12631352100�011227� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ntop admin password need to be set: =================================== When ntop is installed for the first time, you should be asked for a password to set as admin password for ntop. However, if it is not possible to interact with the user during installation, a random password will be set, in order to protect from unauthorized access. In the last case, if you want to access admin functionalities, you need to set a new password by reconfiguring the ntop package: # dpkg-reconfigure -plow ntop -- Ludovico Cavedon <cavedon@debian.org> Sun, 09 Jan 2011 12:45:10 -0800 ntop protocol list: =================== If you start ntop in daemon mode with the supplied init script it will automatically use /etc/ntop/protocol.list to choose which TCP Protocols should be monitored. The format of this file is simply: <label>=<protocol list> where label is used to symbolically identify the <protocol list>. The format of <protocol list> is <protocol>[|<protocol>], where <protocol> is either a valid protocol specified inside the /etc/services file or a numeric port range (e.g. 80, or 6000-6500). Dennis Schoen (Mon Dec 17 14:10:25 CET 2001) log and rotation: ================= Logs are placed in /var/log/ntop/ and will be rotated every week. The log rotation will restart the ntop server which will reset the ntop statistics. If you want to keep the statistics you have to edit or delete the /etc/logrotate.d/ntop file. upgrade notes: ============== Option names may have been changed between ntop versions. You can either change them in /etc/default/ntop or rerun the configuration using dpkg-reconfigure ntop. -- Ola Lundqvist <ola@tigereye.opal.dhs.org>, Fri Aug 6 21:45:02 2004 geolocation: =========== The current version of ntop does not display the geographic location and the AS number of the hosts. The reason is that the databases containing this information are non-DFSG incompatible because they are in binary only format, so they have been removed from the Debian package. You can get such databases by installing the geoip-database-contrib package from the contrib archive area. Alternatively, you can download them yourself from [1] and [2] and place them in /usr/share/ntop/. [1] http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoLiteCity.dat.gz [2] http://geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz -- Ludovico Cavedon <cavedon@debian.org> Sun, 16 Jan 2011 23:52:42 -0800 ������������������������������������������������������������������������������������������������������debian/ntop.preinst���������������������������������������������������������������������������������0000664�0000000�0000000�00000001675�12631352100�011560� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh set -e # Remove a no-longer used conffile rm_conffile() { local PKGNAME="$1" local CONFFILE="$2" [ -e "$CONFFILE" ] || return 0 local md5sum="$(md5sum $CONFFILE | sed -e 's/ .*//')" local old_md5sum="$(dpkg-query -W -f='${Conffiles}' $PKGNAME | \ sed -n -e "\' $CONFFILE ' { s/ obsolete$//; s/.* //; p }")" if [ "$md5sum" != "$old_md5sum" ]; then echo "Obsolete conffile $CONFFILE has been modified by you." echo "Saving as $CONFFILE.dpkg-bak ..." mv -f "$CONFFILE" "$CONFFILE".dpkg-bak else echo "Removing obsolete conffile $CONFFILE ..." rm -f "$CONFFILE" fi } case "$1" in install|upgrade) if dpkg --compare-versions "$2" le "3:3.3-14"; then rm_conffile ntop "/etc/ntop/AS-list.txt" rm_conffile ntop "/etc/ntop/etter.finger.os" rm_conffile ntop "/etc/ntop/oui.txt" rm_conffile ntop "/etc/ntop/p2c.opt.table" fi esac #DEBHELPER# �������������������������������������������������������������������debian/logcheck�������������������������������������������������������������������������������������0000664�0000000�0000000�00000003304�12631352100�010663� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ntop[^:]*: Extending TCP hash ntop[^:]*: Extending hash: ntop[^:]*: Found.*in URL ntop[^:]*: Shrinking hash: ntop[^:]*: Shrinking TCP hash ntop[^:]*: readLsofInfo completed ntop[^:]*: Index error idx= ntop[^:]*: Cleaning up... ntop[^:]*: Waiting until threads terminate... ntop[^:]*: Terminating Web connections... ntop[^:]*: Freeing hash host instances... ntop[^:]*: .* instances freed ntop[^:]*: Unloading plugins \(if any\)... ntop[^:]*: Done. ntop[^:]*: Thanks for using ntop[^:]*: .* packets received by filter on ntop[^:]*: Freeing device ntop[^:]*: .* packets dropped by ntop[^:]*: Bye bye: I'm becoming a daemon... ntop[^:]*: ntop v.* MT ntop[^:]*: Listening on ntop[^:]*: Copyright .* by Luca Deri ntop[^:]*: Get the freshest ntop from http://www.ntop.org/ ntop[^:]*: Parsing ntop rules... ntop[^:]*: Loading plugins \(if any\)... ntop[^:]*: Searching plugins in /usr/lib/ntop/ntop/plugins ntop[^:]*: Welcome to ntop[^:]*: Resetting traffic statistics... ntop[^:]*: Started thread ntop[^:]*: Initializing ntop[^:]*: Unable to create file /var/lib/ntop/ntop.access.log. Access log is disabled. ntop[^:]*: Waiting for HTTP connections on port ntop[^:]*: Sniffying... ntop[^:]*: Started thread ntop[^:]*: Sanity check failed ntop[^:]*: *CLEANUP: Locked purge mutex, continuing shutdown ntop[^:]*: *RRD: ntop[^:]*: *ntop is shutdown... ntop[^:]*: *============================ ntop[^:]*: *TERM: Removed pid file ntop[^:]*: *STATS: 0 packets dropped ntop[^:]*: *CLEANUP: Freeing device ntop[^:]*: *TEMP: ntop[^:]*: *PLUGIN_TERM: Unloading plugins ntop[^:]*: *FREE_HOST: ntop[^:]*: .*THREADMGMT: ntop[^:]*: *CLEANUP: ntop[^:]*: SIGPIPE: Handled .ignored. 0 errors ntop[^:]*: [[:space:]]*\*\*WARNING\*\* packet truncated ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/prng.c���������������������������������������������������������������������������������������0000664�0000000�0000000�00000035563�12631352100�010307� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/********************************************************************* prng: pseudo-random number generators and hashing routines G. Cormode 2003-2012 This program 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. ************************************************************************/ #include <math.h> #include <stdio.h> #include <stdlib.h> #include "prng.h" #define PI 3.141592653589793 long hash31(long long a, long long b, long long x) { long long result; long lresult; // return a hash of x using a and b mod (2^31 - 1) // may need to do another mod afterwards, or drop high bits // depending on d, number of bad guys // 2^31 - 1 = 2147483647 // result = ((long long) a)*((long long) x)+((long long) b); result=(a * x) + b; result = ((result >> HL) + result) & MOD; lresult=(long) result; return(lresult); } long fourwise(long long a, long long b, long long c, long long d, long long x) { long long result; long lresult; // returns values that are 4-wise independent by repeated calls // to the pairwise indpendent routine. result = hash31(hash31(hash31(a,b,x),c,x),d,x); lresult = (long) result; return lresult; } /*************************************************************************/ /* First, some pseudo-random number generators sourced from other places */ /*************************************************************************/ // There are *THREE* alternate implementations of PRNGs here. // One taken from Numerical Recipes in C, the second from www.agner.org // The third is an internal C random library, srand // The variable usenric controls which one is used: pick one // and stick with it, switching between the two will give unpredictable // results. This is controlled by the randinit procedure, call it with // usenric == 1 to use the Numerical Recipes gens // usenric == 2 to use the agner.org PRNGs or // usenric == 3 to use the inbuilt C routines // from the math library: extern double sqrt(double); // following definitions needed for the random number generator #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define NDIV (1+(IM-1)/NTAB) #define EPS 1.2e-7 #define RNMX (1.0-EPS) float ran1(prng_type * prng) { // A Random Number Generator that picks a uniform [0,1] random number // From Numerical Recipes, page 280 // Should be called with a NEGATIVE value of idum to initialize // subsequent calls should not alter idum int j; long k; float temp; if (prng->floatidum <= 0 || !prng->iy) { if (-(prng->floatidum) < 1) prng->floatidum=1; else prng->floatidum = -(prng->floatidum); for (j=NTAB+7;j>=0;j--) { k=(prng->floatidum)/IQ; prng->floatidum=IA*(prng->floatidum-k*IQ)-IR*k; if (prng->floatidum < 0) prng->floatidum+=IM; if (j<NTAB) prng->iv[j]=prng->floatidum; } prng->iy=prng->iv[0]; } k = (prng->floatidum)/IQ; prng->floatidum=IA*(prng->floatidum-k*IQ)-IR*k; if (prng->floatidum<0) prng->floatidum += IM; j = prng->iy/NDIV; prng->iy=prng->iv[j]; prng->iv[j]=prng->floatidum; if ((temp=AM*prng->iy) > RNMX) return RNMX; else return temp; } long ran2(prng_type * prng) { // A Random Number Generator that picks a uniform random number // from the range of long integers. // From Numerical Recipes, page 280 // Should be called with a NEGATIVE value of idum to initialize // subsequent calls should not alter idum // This is a hacked version of the above procedure, so proceed with // caution. int j; long k; if (prng->intidum <= 0 || !prng->iy) { if (-(prng->intidum) < 1) prng->intidum=1; else prng->intidum = -(prng->intidum); for (j=NTAB+7;j>=0;j--) { k=(prng->intidum)/IQ; prng->intidum=IA*(prng->intidum-k*IQ)-IR*k; if (prng->intidum < 0) prng->intidum+=IM; if (j<NTAB) prng->iv[j]=prng->intidum; } prng->iy=prng->iv[0]; } k = (prng->intidum)/IQ; prng->intidum=IA*(prng->intidum-k*IQ)-IR*k; if (prng->intidum<0) prng->intidum += IM; j = prng->iy/NDIV; prng->iy=prng->iv[j]; prng->iv[j]=prng->intidum; return prng->iy; } /**********************************************************************/ // Following routines are from www.agner.org /************************* RANROTB.C ******************** AgF 1999-03-03 * * Random Number generator 'RANROT' type B * * * * This is a lagged-Fibonacci type of random number generator with * * rotation of bits. The algorithm is: * * X[n] = ((X[n-j] rotl r1) + (X[n-k] rotl r2)) modulo 2^b * * * * The last k values of X are stored in a circular buffer named * * randbuffer. * * * * This version works with any integer size: 16, 32, 64 bits etc. * * The integers must be unsigned. The resolution depends on the integer * * size. * * * * Note that the function RanrotAInit must be called before the first * * call to RanrotA or iRanrotA * * * * The theory of the RANROT type of generators is described at * * www.agner.org/random/ranrot.htm * * * *************************************************************************/ // this should be almost verbatim from the above webpage. // although it's been hacked with a little bit... unsigned long rotl (unsigned long x, unsigned long r) { return (x << r) | (x >> (sizeof(x)*8-r));} /* define parameters (R1 and R2 must be smaller than the integer size): */ #define JJ 10 #define R1 5 #define R2 3 /* returns some random bits */ unsigned long ran3(prng_type * prng) { unsigned long x; /* generate next random number */ x = prng->randbuffer[prng->r_p1] = rotl(prng->randbuffer[prng->r_p2], R1) + rotl(prng->randbuffer[prng->r_p1], R2); /* rotate list pointers */ if (--prng->r_p1 < 0) prng->r_p1 = KK - 1; if (--prng->r_p2 < 0) prng->r_p2 = KK - 1; /* conversion to float */ return x; } /* returns a random number between 0 and 1 */ double ran4(prng_type * prng) { /* conversion to floating point type */ return (ran3(prng) * prng->scale); } /* this function initializes the random number generator. */ /* Must be called before the first call to RanrotA or iRanrotA */ void RanrotAInit (prng_type * prng, unsigned long seed) { int i; /* put semi-random numbers into the buffer */ for (i=0; i<KK; i++) { prng->randbuffer[i] = seed; seed = rotl(seed,5) + 97;} /* initialize pointers to circular buffer */ prng->r_p1 = 0; prng->r_p2 = JJ; /* randomize */ for (i = 0; i < 300; i++) ran3(prng); prng->scale = ldexp(1, -8*sizeof(unsigned long)); } /**********************************************************************/ /* These are wrapper procedures for the uniform random number gens */ /**********************************************************************/ long prng_int(prng_type * prng) { // returns a pseudo-random long integer. Initialise the generator // before use! long response=0; switch (prng->usenric) { case 1 : response=(ran2(prng)); break; case 2 : response=(ran3(prng)); break; case 3 : response=(lrand48()); break; } return response; } float prng_float(prng_type * prng) { // returns a pseudo-random float in the range [0.0,1.0]. // Initialise the generator before use! float result=0; switch (prng->usenric) { case 1 : result=(ran1(prng)); break; case 2 : result=(ran4(prng)); break; case 3 : result=(drand48()); break; } return result; } prng_type * prng_Init(long seed, int nric) { // Initialise the random number generators. nric determines // which algorithm to use, 1 for Numerical Recipes in C, // 0 for the other one. prng_type * result; result=(prng_type *) calloc(1,sizeof(prng_type)); result->iy=0; result->usenric=nric; result->floatidum=-1; result->intidum=-1; result->iset=0; // set a global variable to record which algorithm to use switch (nric) { case 2 : RanrotAInit(result,seed); break; case 1 : if (seed>0) { // to initialise the NRiC PRNGs, call it with a negative value // so make sure it gets a negative value! result->floatidum = -(seed); result->intidum = -(seed); } else { result->floatidum=seed; result->intidum=seed; } break; case 3 : srand48(seed); break; } prng_float(result); prng_int(result); // call the routines to actually initialise them return(result); } void prng_Reseed(prng_type * prng, long seed) { switch (prng->usenric) { case 2 : RanrotAInit(prng,seed); break; case 1 : if (seed>0) { // to initialise the NRiC PRNGs, call it with a negative value // so make sure it gets a negative value! prng->floatidum = -(seed); prng->intidum = -(seed); } else { prng->floatidum=seed; prng->intidum=seed; } break; case 3 : srand48(seed); break; } } void prng_Destroy(prng_type * prng) { free(prng); } /**********************************************************************/ /* Next, a load of routines that convert uniform random variables */ /* from [0,1] to stable distribitions, such as gaussian, levy or */ /* general */ /**********************************************************************/ double prng_normal(prng_type * prng) { // Pick random values distributed N(0,1) using the Box-Muller transform // Taken from numerical recipes in C p289 // picks two at a time, returns one per call (buffers the other) double fac,rsq,v1,v2; if (prng->iset == 0) { do { v1 = 2.0*prng_float(prng)-1.0; v2 = 2.0*prng_float(prng)-1.0; rsq=v1*v1+v2*v2; } while (rsq >= 1.0 || rsq == 0.0); fac = sqrt((double) -2.0*log((double)rsq)/rsq); prng->gset=v1*fac; prng->iset=1; return v2*fac; } else { prng->iset = 0; return prng->gset; } } double prng_stabledbn(prng_type * prng, double alpha) { // From 'stable distributions', John Nolan, manuscript, p24 // we set beta = 0 by analogy with the normal and cauchy case // identical to the above routine, but returns a double instead // of a long double (you'll see this a lot...) double theta, W, holder, left, right; theta=PI*(prng_float(prng) - 0.5); W = -log(prng_float(prng)); // takes natural log // printf("theta %Lf, W = %Lf \n", theta, W); // some notes on Nolan's notes: // if beta == 0 then c(alpha,beta)=1; theta_0 = 0 // expression reduces to sin alpha.theta / (cos theta) ^1/alpha // * (cos (theta - alpha theta)/W) ^(1-alpha)/alpha left = (sin(alpha*theta)/pow(cos(theta), 1.0/alpha)); right= pow(cos(theta*(1.0 - alpha))/W, ((1.0-alpha)/alpha)); holder=left*right; return(holder); } long double prng_cauchy(prng_type * prng) { // return a value from the cauchy distribution // using the formula in 'Stable Distributions', p23 // this is distributed Cauchy(1,0) return(tan(PI*(prng_float(prng) - 0.5))); } double prng_altstab(prng_type * prng, double p) { double u,v,result; u=prng_float(prng); v=prng_float(prng); result=pow(u,p); // result=exp(p*log(u)); if (v<0.5) result=-result; return(result); } /* long double levy() { // this would give the levy distribution, except it doesn't get used long double z; z=gasdev(); return (1.0/(z*z)); } */ double prng_stable(prng_type * prng, double alpha) { // wrapper for the stable distributions above: // call the appropriate routine based on the value of alpha given // initialising it with the seed in idum // randinit must be called before entering this procedure for // the first time since it uses the random generators if (alpha==2.0) return(prng_normal(prng)); else if (alpha==1.0) return(prng_cauchy(prng)); else if (alpha<0.01) return(prng_altstab(prng,-50.0)); else return (prng_stabledbn(prng,alpha)); } double zeta(long n, double theta) { // the zeta function, used by the below zipf function // (this is not often called from outside this library) // ... but have made it public now to speed things up int i; double ans=0.0; for (i=1; i <= n; i++) ans += pow(1./(double)i, theta); return(ans); } double fastzipf(double theta, long n, double zetan, prng_type * prng) { // this draws values from the zipf distribution // this is mainly useful for test generation purposes // n is range, theta is skewness parameter // theta = 0 gives uniform dbn, // theta > 1 gives highly skewed dbn. // original code due to Flip Korn, used with permission double alpha; double eta; double u; double uz; long double val; // randinit must be called before entering this procedure for // the first time since it uses the random generators alpha = 1. / (1. - theta); eta = (1. - pow(2./((double) n), 1. - theta)) / (1. - zeta(2,theta)/zetan); u = prng_float(prng); uz = u * zetan; if (uz < 1.) val = 1; else if (uz < (1. + pow(0.5, theta))) val = 2; else val = 1 + (long long)(n * pow(eta*u - eta + 1., alpha)); return(val); } /* long double zipf(double theta, long n) { // this draws values from the zipf distribution // this is mainly useful for test generation purposes // n is range, theta is skewness parameter // theta = 0 gives uniform dbn, // theta > 1 gives highly skewed dbn. double alpha; double zetan; double eta; double u; double uz; long double val; // randinit must be called before entering this procedure for // the first time since it uses the random generators alpha = 1. / (1. - theta); zetan = zeta(n, theta); eta = (1. - pow(2./n, 1. - theta)) / (1. - zeta(2.,theta)/zetan); u = randomfl(); uz = u * zetan; if (uz < 1.) val = 1; else if (uz < (1. + pow(0.5, theta))) val = 2; else val = 1 + (long long)(n * pow(eta*u - eta + 1., alpha)); return(val); } */ ���������������������������������������������������������������������������������������������������������������������������������������������debian/countmin.h�����������������������������������������������������������������������������������0000664�0000000�0000000�00000004041�12631352100�011165� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Two different structures: // 1 -- The basic CM Sketch // 2 -- The hierarchical CM Sketch: with log n levels, for range sums etc. #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) typedef struct CM_type{ long long count; int depth; int width; int ** counts; unsigned int *hasha, *hashb; } CM_type; typedef struct CMF_type{ // shadow of above stucture with floats double count; int depth; int width; double ** counts; unsigned int *hasha, *hashb; } CMF_type; extern CM_type * CM_Init(int, int, int); extern CM_type * CM_Copy(CM_type *); extern void CM_Destroy(CM_type *); extern int CM_Size(CM_type *); extern void CM_Update(CM_type *, unsigned int, int); extern int CM_PointEst(CM_type *, unsigned int); extern int CM_PointMed(CM_type *, unsigned int); extern long long CM_InnerProd(CM_type *, CM_type *); extern int CM_Residue(CM_type *, unsigned int *); extern long long CM_F2Est(CM_type *); extern CMF_type * CMF_Init(int, int, int); extern CMF_type * CMF_Copy(CMF_type *); extern void CMF_Destroy(CMF_type *); extern int CMF_Size(CMF_type *); extern void CMF_Update(CMF_type *, unsigned int, double); extern double CMF_InnerProd(CMF_type *, CMF_type *); extern double CMF_PointProd(CMF_type *, CMF_type *, unsigned int); typedef struct CMH_type{ long long count; int U; // size of the universe in bits int gran; // granularity: eg 1, 4 or 8 bits int levels; // function of U and gran int freelim; // up to which level to keep exact counts int depth; int width; int ** counts; unsigned int **hasha, **hashb; } CMH_type; extern CMH_type * CMH_Init(int, int, int, int); extern CMH_type * CMH_Copy(CMH_type *); extern void CMH_Destroy(CMH_type *); extern int CMH_Size(CMH_type *); extern void CMH_Update(CMH_type *, unsigned int, int); extern unsigned int * CMH_FindHH(CMH_type *, int); extern int CMH_Rangesum(CMH_type *, long long, long long); extern long long CMH_FindRange(CMH_type * cmh, int); extern long long CMH_Quantile(CMH_type *cmh,float); extern long long CMH_F2Est(CMH_type *); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/copyright������������������������������������������������������������������������������������0000664�0000000�0000000�00000031610�12631352100�011115� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: ntop Upstream-Contact: Luca Deri <deri@ntop.org> Source: http://www.ntop.org/download.html Files: * Copyright: 1998-2012, Luca Deri <deri@ntop.org> License: GPL-2+ Files: ssl.c Copyright: 1998-2010 Luca Deri <deri@ntop.org> License: GPL-2+ with OpenSSL exception In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. Files: fcUtils.c fcReport.c Copyright: 2003-2010, Luca Deri <deri@ntop.org> 2003 Dinesh G. Dutt <ddutt@cisco.com> License: GPL-2+ Files: autogen.sh Copyright: 2006-2010, Luca Deri <deri@ntop.org> 2004-06 Rocco Carbone <rocco@ntop.org> License: GPL-2+ Files: iface.c iface.h Copyright: 2003-2010, Luca Deri <deri@ntop.org> 2003, Abdelkader Lahmadi <Abdelkader.Lahmadi@loria.fr> 2003, Olivier Festor <Olivier.Festor@loria.fr> License: GPL-2+ Files: util.c Copyright: 1998-2010, Luca Deri <deri@ntop.org> 1991-1999, Free Software Foundation, Inc. License: GPL-2+ Files: countmin.h countmin.c prng.h prng.c Copyright: 2003-2004, 2010, 2012, G. Cormode License: GPL-2+ Files: utils/xmldump.awk utils/processstruct.awk AutoConfigureNtop linuxrelease config_h.shm utildl.c Copyright: 2002-2005, Burton M. Strauss III, <Burton@ntopSupport.com> License: GPL-2+ Files: utils/rrd-alarm/rrd_alarm.c Copyright: 2003, Daniele Sgandurra <sgandurr@cli.di.unipi.it> License: GPL-2+ Files: utils/getopt/* Copyright: 1987-200, Free Software Foundation, Inc. License: GPL-2+ Files: python/json/iphone/* Copyright: 2010, David Votino License: GPL-2+ Files: python/sankey.py Copyright: 2011, Tranchida Giulio License: GPL-2+ Files: NetFlow/netFlowClient.pl Copyright: 2003, Uli Staerk <uli@sinma.de> 2002, Luca Deri <deri@ntop.org> License: GPL-2+ Files: www/Perl/mapper.pl Copyright: 2010, Kevin M. Ernst <kernst+ntop@twentygrand.net> 2001-2010, Luca Deri <deri@ntop.org> License: GPL-2+ Files: html/zoom.js Copyright: 2004, Eric Steffen License: GPL-2+ Files: html/calendar*.js html/jscalendar* Copyright: 2002-2003, Mihai Bazon License: LGPL This script is distributed under the GNU Lesser General Public License. Read the entire license text here: http://www.gnu.org/licenses/lgpl.html . On Debian systems, the full text of the GNU General Public License can be found in the file `/usr/share/common-licenses/LGPL'. Files: html/graph_if.svg Copyright: 2004-2005, T. Lechat <dev@lechat.org> 2004-2005, Manuel Kasper <mk@neon1.net> 2004-2005, Jonathan Watt <jwatt@jwatt.org> License: 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. Redistributionss 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, BINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. Files: html/domLib.js html/domTT.js Copyright: 2002-2005, Dan Allen <dan.allen@mojavelinux.com> Jason Rust <jason@rustyparts.com> Josh Gross <josh@jportalhome.com> License: Apache-2.0 Files: html/JSCookMenu.js Copyright: 2002-2006, Heng Yuan License: MIT Files: html/jquery* Copyright: 2011, John Resig, http://jquery.com/ License: MIT or GPL-2 Files: html/jqplot/* debian/source/jquery.jqplot.js Copyright: 2009-2011, Chris Leonello License: MIT or GPL-2 Files: html/jqplot/excanvas.js Copyright: 2006, Google Inc. License: Apache-2.0 Files: html/jqplot/plugins/jqplot.json2.js Copyright: 2010, Chris Leonello 2010, http://www.JSON.org/ License: public-domain http://www.JSON.org/json2.js 2010-08-25 . Public Domain. . NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. . See http://www.JSON.org/js.html Files: html/d3.js Copyright: 2013, Michael Bostock License: BSD-3-clause Files: html/sankey*.js Copyright: 2010-2011, Thomas Counsell License: MIT Files: nDPI/* Copyright: 2011-2012, ntop.org 2009-2011, ipoque GmbH License: LGPL-3+ This file is part of OpenDPI, an open source deep packet inspection OpenDPI 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 3 of the License, or (at your option) any later version. OpenDPI 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 OpenDPI. If not, see <http://www.gnu.org/licenses/>. . On Debian systems, the full text of the GNU General Public License v3 can be found in the file `/usr/share/common-licenses/LGPL-3'. Files: nDPI/src/lib/protocols/teamviewer.c Copyright: 2013, Gianluca Costa xplico.org License: LGPL-3+ This module 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 3 of the License, or (at your option) any later version. . This module 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. If not, see <http://www.gnu.org/licenses/>. . On Debian systems, the full text of the GNU General Public License v3 can be found in the file `/usr/share/common-licenses/LGPL-3'. Files: 3rd_party/etter.finger.os.gz Copyright: 2001-2004, Alberto Ornaghi <alor@users.sourceforge.net> 2001-2004, Marco Valleri <crwm@freemail.it> License: GPL-2+ Files: packages/debian/* Copyright: Rocco Carbone 2007-2008, Massimo Torquati <torquati@ntop.org> 2003-2007, Luca Deri <deri@ntop.org> 1997-1999, Joey Hess License: GPL-2+ Files: packages/debian.official Copyright: 2000-2002, Dennis Schoen <dennis@cobolt.net> Luca Deri <deri@ntop.org> 1997-1999, Joey Hess License: GPL-2+ Files: packages/RedHat/ntop.init Copyright: 2003-2010, Luca Deri <deri@ntop.org> 2003-2005 Burton M. Strauss III <burton@ntopsupport.com> License: GPL-2+ Files: packages/suse/* Copyright: 2001, SuSE GmbH Nuernberg, Germany. License: GPL-2+ Files: packages/gentoo/* Copyright: 1999-2003, Gentoo Technologies, Inc. License: GPL-2+ Files: debian/* Copyright: 2010, Jordan Metzmeier <jordan@linuxgen.com> 2010, Ludovico Cavedon <cavedon@debian.org> 2003-2010, Ola Lundqvist <opal@debian.org> 2001-2003, Dennis Schoen <ds@teuto.net> License: GPL-2+ Files: debian/po/* Copyright: 2004, Software in the Public Interest 2006, Free Software Foundation, Inc. 2007, Noritada Kobayashi 2010, Jordan Metzmeier <jordan@linuxgen.com> 2010, Ludovico Cavedon <cavedon@debian.org> 2003-2010, Ola Lundqvist <opal@debian.org> 2001-2003, Dennis Schoen <ds@teuto.net> License: GPL-2+ License: GPL-2 This program 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. . 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 St, Fifth Floor, Boston, MA 02110-1301, USA. . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: GPL-2+ This program 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 St, Fifth Floor, Boston, MA 02110-1301, USA. . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: MIT 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. License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian systems, the full text of the Apache License, Version 2.0 can be found in the file `/usr/share/common-licenses/Apache-2.0'. License: BSD-3-clause 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. . * The name Michael Bostock may not be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 MICHAEL BOSTOCK 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. ������������������������������������������������������������������������������������������������������������������������debian/ntop.config����������������������������������������������������������������������������������0000664�0000000�0000000�00000004750�12631352100�011336� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # Copyright 2000,2001,2002 by Dennis Schoen <dennis@cobolt.net> # # This program 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., 59 Temple Place, Suite 330, Boston, # MA 02111-1307 USA. set -e # Source debconf library . /usr/share/debconf/confmodule if [ -e /etc/ntop/init.cfg ] && [ ! -e /var/lib/ntop/init.cfg ]; then cp -a /etc/ntop/init.cfg /etc/ntop/init.cfg.dpkg-old || true mv /etc/ntop/init.cfg /var/lib/ntop/init.cfg || true fi if [ -e /var/lib/ntop/init.cfg ]; then # Read current state from configuration file . /var/lib/ntop/init.cfg || true db_set ntop/user "$USER" db_set ntop/interfaces "$INTERFACES" fi if [ -z "$INTERFACES" ]; then db_input high ntop/interfaces || true else db_input medium ntop/interfaces || true fi db_input low ntop/user || true set_password() { while true; do db_input high ntop/admin_password || debconfret=$? if [ -n "$debconfret" ] && [ "$debconfret" -eq 30 ]; then # question will not be displayed # ask other questions in the queue and terminate db_go break fi db_input high ntop/admin_password_again || true db_go db_get ntop/admin_password if [ -z "$RET" ]; then db_input high ntop/password_empty db_fset ntop/admin_password seen false db_fset ntop/admin_password_again seen false else curpass=$RET db_get ntop/admin_password_again againpass=$RET if [ "$curpass" = "$againpass" ]; then break else db_input high ntop/password_mismatch fi fi done } if ! [ -f /var/lib/ntop/ntop_pw.db ]; then set_password else db_input low ntop/password_reset || true db_go db_get ntop/password_reset if [ "true" = "$RET" ]; then set_password else db_go fi fi ������������������������debian/countmin.c�����������������������������������������������������������������������������������0000664�0000000�0000000�00000051317�12631352100�011170� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************** Count-Min Sketches G. Cormode 2003,2004, 2010, 2012 Updated: 2004-06 Added a floating point sketch and support for inner product point estimation Initial version: 2003-12 This program 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. *********************************************************************/ #include <stdlib.h> #include "prng.h" #include "countmin.h" #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) double eps; /* 1+epsilon = approximation factor */ double delta; /* probability of failure */ /************************************************************************/ /* Routines to support Count-Min sketches */ /************************************************************************/ CM_type * CM_Init(int width, int depth, int seed) { // Initialize the sketch based on user-supplied size CM_type * cm; int j; prng_type * prng; cm=(CM_type *) malloc(sizeof(CM_type)); prng=prng_Init(-abs(seed),2); // initialize the generator to pick the hash functions if (cm && prng) { cm->depth=depth; cm->width=width; cm->count=0; cm->counts=(int **)calloc(sizeof(int *),cm->depth); cm->counts[0]=(int *)calloc(sizeof(int), cm->depth*cm->width); cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); if (cm->counts && cm->hasha && cm->hashb && cm->counts[0]) { for (j=0;j<depth;j++) { cm->hasha[j]=prng_int(prng) & MOD; cm->hashb[j]=prng_int(prng) & MOD; // pick the hash functions cm->counts[j]=(int *) cm->counts[0]+(j*cm->width); } } else cm=NULL; } if (prng) prng_Destroy(prng); return cm; } CM_type * CM_Copy(CM_type * cmold) { // create a new sketch with the same parameters as an existing one CM_type * cm; int j; if (!cmold) return(NULL); cm=(CM_type *) malloc(sizeof(CM_type)); if (cm) { cm->depth=cmold->depth; cm->width=cmold->width; cm->count=0; cm->counts=(int **)calloc(sizeof(int *),cm->depth); cm->counts[0]=(int *)calloc(sizeof(int), cm->depth*cm->width); cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); if (cm->counts && cm->hasha && cm->hashb && cm->counts[0]) { for (j=0;j<cm->depth;j++) { cm->hasha[j]=cmold->hasha[j]; cm->hashb[j]=cmold->hashb[j]; cm->counts[j]=(int *) cm->counts[0]+(j*cm->width); } } else cm=NULL; } return cm; } void CM_Destroy(CM_type * cm) { // get rid of a sketch and free up the space if (!cm) return; if (cm->counts) { if (cm->counts[0]) free(cm->counts[0]); free(cm->counts); cm->counts=NULL; } if (cm->hasha) free(cm->hasha); cm->hasha=NULL; if (cm->hashb) free(cm->hashb); cm->hashb=NULL; free(cm); cm=NULL; } int CM_Size(CM_type * cm) { // return the size of the sketch in bytes int counts, hashes, admin; if (!cm) return 0; admin=sizeof(CM_type); counts=cm->width*cm->depth*sizeof(int); hashes=cm->depth*2*sizeof(unsigned int); return(admin + hashes + counts); } void CM_Update(CM_type * cm, unsigned int item, int diff) { int j; if (!cm) return; cm->count+=diff; for (j=0;j<cm->depth;j++) cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],item) % cm->width]+=diff; // this can be done more efficiently if the width is a power of two } int CM_PointEst(CM_type * cm, unsigned int query) { // return an estimate of the count of an item by taking the minimum int j, ans; if (!cm) return 0; ans=cm->counts[0][hash31(cm->hasha[0],cm->hashb[0],query) % cm->width]; for (j=1;j<cm->depth;j++) ans=min(ans,cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width]); // this can be done more efficiently if the width is a power of two return (ans); } #if 0 int CM_PointMed(CM_type * cm, unsigned int query) { // return an estimate of the count by taking the median estimate // useful when counts can become negative // depth needs to be larger for this to work well int j, * ans, result=0; if (!cm) return 0; ans=(int *) calloc(1+cm->depth,sizeof(int)); for (j=0;j<cm->depth;j++) ans[j+1]=cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width]; if (cm->depth==1) result=ans[1]; else if (cm->depth==2) { //result=(ans[1]+ans[2])/2; if (abs(ans[1]) < abs(ans[2])) result=ans[1]; else result=ans[2]; // special tweak for small depth sketches } else result=(MedSelect(1+cm->depth/2,cm->depth,ans)); return result; // need to adjust for routine starting at 1 } #endif int CM_Compatible(CM_type * cm1, CM_type * cm2) { // test whether two sketches are comparable (have same parameters) int i; if (!cm1 || !cm2) return 0; if (cm1->width!=cm2->width) return 0; if (cm1->depth!=cm2->depth) return 0; for (i=0;i<cm1->depth;i++) { if (cm1->hasha[i]!=cm2->hasha[i]) return 0; if (cm1->hashb[i]!=cm2->hashb[i]) return 0; } return 1; } long long CM_InnerProd(CM_type * cm1, CM_type * cm2) { // Estimate the inner product of two vectors by comparing their sketches int i,j; long long result, tmp; result=0; if (CM_Compatible(cm1,cm2)) { for (i=0;i<cm1->width;i++) result+=cm1->counts[0][i]*cm2->counts[0][i]; for (j=1;j<cm1->depth;j++) { tmp=0; for (i=0;i<cm1->width;i++) tmp+=cm1->counts[j][i]*cm2->counts[j][i]; result=min(tmp,result); } } return result; } #if 0 long long CM_F2Est(CM_type * cm) { // Estimate the second frequency moment of the stream int i,j; long long result, tmp, *ans; if (!cm) return 0; ans=(long long *) calloc(1+cm->depth,sizeof(long long)); for (j=0;j<cm->depth;j++) { result=0; for (i=0;i<cm->width;i+=2) { tmp=(cm->counts[j][i]-cm->counts[j][i+1]); result+=tmp*tmp; } ans[j+1]=result; } result=LLMedSelect((cm->depth+1)/2,cm->depth,ans); return result; } #endif int CM_Residue(CM_type * cm, unsigned int * Q) { // CM_Residue computes the sum of everything left after the points // from Q have been removed // Q is a list of points, where Q[0] gives the length of the list char * bitmap; int i,j; int estimate=0, nextest; if (!cm) return 0; bitmap=(char *) calloc(cm->width,sizeof(char)); for (j=0;j<cm->depth;j++) { nextest=0; for (i=0;i<cm->width;i++) bitmap[i]=0; for (i=1;i<(int) Q[0];i++) bitmap[hash31(cm->hasha[j],cm->hashb[j],Q[i]) % cm->width]=1; for (i=0;i<cm->width;i++) if (bitmap[i]==0) nextest+=cm->counts[j][i]; estimate=max(estimate,nextest); } return(estimate); } /************************************************************************/ /* Routines to support Count-Min sketches with floating point data */ /************************************************************************/ CMF_type * CMF_Init(int width, int depth, int seed) { // Initialize the sketch based on user-supplied size CMF_type * cm; int j; prng_type * prng; cm=(CMF_type *) malloc(sizeof(CMF_type)); prng=prng_Init(-abs(seed),2); // initialize the generator to pick the hash functions if (cm && prng) { cm->depth=depth; cm->width=width; cm->count=0; cm->counts=(double **)calloc(sizeof(double *),cm->depth); cm->counts[0]=(double *)calloc(sizeof(double), cm->depth*cm->width); cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); if (cm->counts && cm->hasha && cm->hashb && cm->counts[0]) { for (j=0;j<depth;j++) { cm->hasha[j]=prng_int(prng) & MOD; cm->hashb[j]=prng_int(prng) & MOD; // pick the hash functions cm->counts[j]=(double *) cm->counts[0]+(j*cm->width); } } else cm=NULL; } if (prng) prng_Destroy(prng); return cm; } CMF_type * CMF_Copy(CMF_type * cmold) { // create a new sketch with the same parameters as an existing one CMF_type * cm; int j; if (!cmold) return(NULL); cm=(CMF_type *) malloc(sizeof(CMF_type)); if (cm) { cm->depth=cmold->depth; cm->width=cmold->width; cm->count=0; cm->counts=(double **)calloc(sizeof(double *),cm->depth); cm->counts[0]=(double *)calloc(sizeof(double), cm->depth*cm->width); cm->hasha=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); cm->hashb=(unsigned int *)calloc(sizeof(unsigned int),cm->depth); if (cm->counts && cm->hasha && cm->hashb && cm->counts[0]) { for (j=0;j<cm->depth;j++) { cm->hasha[j]=cmold->hasha[j]; cm->hashb[j]=cmold->hashb[j]; cm->counts[j]=(double *) cm->counts[0]+(j*cm->width); } } else cm=NULL; } return cm; } void CMF_Destroy(CMF_type * cm) { // get rid of a sketch and free up the space if (!cm) return; if (cm->counts) { if (cm->counts[0]) free(cm->counts[0]); free(cm->counts); cm->counts=NULL; } if (cm->hasha) free(cm->hasha); cm->hasha=NULL; if (cm->hashb) free(cm->hashb); cm->hashb=NULL; free(cm); cm=NULL; } int CMF_Size(CMF_type * cm) { // return the size of the sketch in bytes int counts, hashes, admin; if (!cm) return 0; admin=sizeof(CM_type); counts=cm->width*cm->depth*sizeof(double); hashes=cm->depth*2*sizeof(unsigned int); return(admin + hashes + counts); } void CMF_Update(CMF_type * cm, unsigned int item, double diff) { int j; if (!cm) return; cm->count+=diff; for (j=0;j<cm->depth;j++) cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],item) % cm->width]+=diff; // this can be done more efficiently if the width is a power of two } double CMF_PointEst(CMF_type * cm, unsigned int query) { // return an estimate of the count of an item by taking the minimum int j; double ans=0.; if (!cm) return 0; ans=cm->counts[0][hash31(cm->hasha[0],cm->hashb[0],query) % cm->width]; for (j=1;j<cm->depth;j++) ans=min(ans,cm->counts[j][hash31(cm->hasha[j],cm->hashb[j],query)%cm->width]); // this can be done more efficiently if the width is a power of two return (ans); } int CMF_Compatible(CMF_type * cm1, CMF_type * cm2) { // test whether two sketches are comparable (have same parameters) int i; if (!cm1 || !cm2) return 0; if (cm1->width!=cm2->width) return 0; if (cm1->depth!=cm2->depth) return 0; for (i=0;i<cm1->depth;i++) { if (cm1->hasha[i]!=cm2->hasha[i]) return 0; if (cm1->hashb[i]!=cm2->hashb[i]) return 0; } return 1; } double CMF_PointProd(CMF_type * cm1, CMF_type * cm2, unsigned int query) { // Estimate the inner product of two vectors by comparing their sketches int j, loc; double tmp, ans; ans=0.0; if (CMF_Compatible(cm1,cm2)) { loc=hash31(cm1->hasha[0],cm1->hashb[0],query) % cm1->width; ans=cm1->counts[0][loc]*cm2->counts[0][loc]; for (j=1;j<cm1->depth;j++) { loc=hash31(cm1->hasha[j],cm1->hashb[j],query) % cm1->width; tmp=cm1->counts[j][loc]*cm2->counts[j][loc]; ans=min(ans,tmp); } } return (ans); } double CMF_InnerProd(CMF_type * cm1, CMF_type * cm2) { // Estimate the inner product of two vectors by comparing their sketches int i,j; double tmp, result; result=0; if (CMF_Compatible(cm1,cm2)) { for (i=0;i<cm1->width;i++) result+=cm1->counts[0][i]*cm2->counts[0][i]; for (j=1;j<cm1->depth;j++) { tmp=0.0; for (i=0;i<cm1->width;i++) tmp+=cm1->counts[j][i]*cm2->counts[j][i]; result=min(tmp,result); } } return result; } /************************************************************************/ /* Routines to support hierarchical Count-Min sketches */ /************************************************************************/ CMH_type * CMH_Init(int width, int depth, int U, int gran) { // initialize a hierarchical set of sketches for range queries // heavy hitters or quantiles CMH_type * cmh; int i,j,k; prng_type * prng; if (U<=0 || U>32) return(NULL); // U is the log the size of the universe in bits if (gran>U || gran<1) return(NULL); // gran is the granularity to look at the universe in // check that the parameters make sense... cmh=(CMH_type *) calloc(1,sizeof(CMH_type)); prng=prng_Init(-12784,2); // initialize the generator for picking the hash functions if (cmh && prng) { cmh->depth=depth; cmh->width=width; cmh->count=0; cmh->U=U; cmh->gran=gran; cmh->levels=(int) ceil(((float) U)/((float) gran)); for (j=0;j<cmh->levels;j++) if ((long long) 1<<(cmh->gran*j) <= cmh->depth*cmh->width) cmh->freelim=j; //find the level up to which it is cheaper to keep exact counts cmh->freelim=cmh->levels-cmh->freelim; cmh->counts=(int **) calloc(sizeof(int *), 1+cmh->levels); cmh->hasha=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels); cmh->hashb=(unsigned int **)calloc(sizeof(unsigned int *),1+cmh->levels); j=1; for (i=cmh->levels-1;i>=0;i--) { if (i>=cmh->freelim) { // allocate space for representing things exactly at high levels cmh->counts[i]=(int *) calloc(1<<(cmh->gran*j),sizeof(int)); j++; cmh->hasha[i]=NULL; cmh->hashb[i]=NULL; } else { // allocate space for a sketch cmh->counts[i]=(int *)calloc(sizeof(int), cmh->depth*cmh->width); cmh->hasha[i]=(unsigned int *) calloc(sizeof(unsigned int),cmh->depth); cmh->hashb[i]=(unsigned int *) calloc(sizeof(unsigned int),cmh->depth); if (cmh->hasha[i] && cmh->hashb[i]) for (k=0;k<cmh->depth;k++) { // pick the hash functions cmh->hasha[i][k]=prng_int(prng) & MOD; cmh->hashb[i][k]=prng_int(prng) & MOD; } } } } if (prng) prng_Destroy(prng); return cmh; } void CMH_Destroy(CMH_type * cmh) { // free up the space int i; if (!cmh) return; for (i=0;i<cmh->levels;i++) { if (i>=cmh->freelim) { free(cmh->counts[i]); } else { free(cmh->hasha[i]); free(cmh->hashb[i]); free(cmh->counts[i]); } } free(cmh->counts); free(cmh->hasha); free(cmh->hashb); free(cmh); cmh=NULL; } void CMH_Update(CMH_type * cmh, unsigned int item, int diff) { // update with a new value int i,j,offset; if (!cmh) return; cmh->count+=diff; for (i=0;i<cmh->levels;i++) { offset=0; if (i>=cmh->freelim) { // level 0 = leaves, higher levels = internal nodes cmh->counts[i][item]+=diff; // keep exact counts at high levels in the hierarchy } else for (j=0;j<cmh->depth;j++) { cmh->counts[i][(hash31(cmh->hasha[i][j],cmh->hashb[i][j],item) % cmh->width) + offset]+=diff; // this can be done more efficiently if the width is a power of two offset+=cmh->width; } item>>=cmh->gran; } } int CMH_Size(CMH_type * cmh) { // return the size used in bytes int counts, hashes, admin,i; if (!cmh) return 0; admin=sizeof(CMH_type); counts=cmh->levels*sizeof(int **); for (i=0;i<cmh->levels;i++) if (i>=cmh->freelim) counts+=(1<<(cmh->gran*(cmh->levels-i)))*sizeof(int); else counts+=cmh->width*cmh->depth*sizeof(int); hashes=(cmh->levels-cmh->freelim)*cmh->depth*2*sizeof(unsigned int); hashes+=(cmh->levels)*sizeof(unsigned int *); return(admin + hashes + counts); } int CMH_count(CMH_type * cmh, int depth, unsigned int item) { // return an estimate of item at level depth int j; int offset; int estimate; if (depth>=cmh->levels) return(cmh->count); if (depth>=cmh->freelim) { // use an exact count if there is one return(cmh->counts[depth][item]); } // else, use the appropriate sketch to make an estimate offset=0; estimate=cmh->counts[depth][(hash31(cmh->hasha[depth][0], cmh->hashb[depth][0],item) % cmh->width) + offset]; for (j=1;j<cmh->depth;j++) { offset+=cmh->width; estimate=min(estimate, cmh->counts[depth][(hash31(cmh->hasha[depth][j], cmh->hashb[depth][j],item) % cmh->width) + offset]); } return(estimate); } void CMH_recursive(CMH_type * cmh, int depth, int start, int thresh, unsigned int * results) { // for finding heavy hitters, recursively descend looking // for ranges that exceed the threshold int i; int blocksize; int estcount; int itemshift; estcount=CMH_count(cmh,depth,start); if (estcount>=thresh) { if (depth==0) { if (results[0]<(unsigned int) cmh->width) { results[0]++; results[results[0]]=start; } } else { blocksize=1<<cmh->gran; itemshift=start<<cmh->gran; // assumes that gran is an exact multiple of the bit dept for (i=0;i<blocksize;i++) CMH_recursive(cmh,depth-1,itemshift+i,thresh,results); } } } unsigned int * CMH_FindHH(CMH_type * cmh, int thresh) { // find all items whose estimated count is greater than phi n unsigned int * results; results=(unsigned int *) calloc(cmh->width,sizeof(unsigned int)); results[0]=0; CMH_recursive(cmh,cmh->levels,0,thresh,results); return(results); } int CMH_Rangesum(CMH_type * cmh, long long start, long long end) { // compute a range sum: // start at bottom level // compute any estimates needed at each level // work upwards int depth, result; long long range, leftend, rightend; long long topend, i; topend=((long long) 1)<<cmh->U; end=min(topend,end); if ((end>topend) && (start==0)) { return cmh->count; } end+=1; // adjust for end effects result=0; for (depth=0;depth<=cmh->levels;depth++) { if (start==end) break; range=(end-start+1); if ((unsigned int) (end-start+1)<(((unsigned int) 1)<<cmh->gran)) { // if only a few nodes to probe at this level, probe them all for (i=start;i<end;i++) result+=CMH_count(cmh,depth,i); break; } else { // figure out what needs to be done at each end leftend=(((start>>cmh->gran)+1)<<cmh->gran) - start; if (leftend>= 1<<cmh->gran) leftend=0; rightend=(end)-((end>>cmh->gran)<<cmh->gran); if ((leftend>0) && (start<end)) for (i=0;i<leftend;i++) { result+=CMH_count(cmh,depth,start+i); } if ((rightend>0) && (start<end)) for (i=0;i<rightend;i++) { result+=CMH_count(cmh,depth,end-i-1); } start=start>>cmh->gran; if (leftend>0) start++; end=end>>cmh->gran; } } return result; } long long CMH_FindRange(CMH_type * cmh, int sum) { long long low, high, mid=0; int i, est=0; // find a range starting from zero that adds up to sum if (cmh->count<sum) return 1<<(cmh->U); low=0; high=((long long) 1)<<cmh->U; for (i=0;i<cmh->U;i++) { mid=(low+high)/2; est=CMH_Rangesum(cmh,0,(unsigned int) mid); if (est>sum) high=mid; else low=mid; } return mid; } long long CMH_AltFindRange(CMH_type * cmh, int sum) { long long low, high, mid=0,top; int i, est=0; // find a range starting from the right hand side that adds up to sum if (cmh->count<sum) return 1<<(cmh->U); low=0; top=((long long) 1)<<cmh->U; high=top; for (i=0;i<cmh->U;i++) { mid=(low+high)/2; est=CMH_Rangesum(cmh,mid,top); if (est<sum) high=mid; else low=mid; } return mid; } long long CMH_Quantile(CMH_type * cmh, float frac) { // find a quantile by doing the appropriate range search if (frac<0) return 0; if (frac>1) return 1<<cmh->U; return ((CMH_FindRange(cmh,(long long) (cmh->count*frac))+ CMH_AltFindRange(cmh,(long long) (cmh->count*(1-frac))))/2); // each result gives a lower/upper bound on the location of the quantile // with high probability, these will be close: only a small number of values // will be between the estimates. } long long CMH_F2Est(CMH_type * cmh) { // A heuristic for estimating the F2 of a stream // tends to overestimate a great deal on non-skewed streams int i,j,k; long long est, result; k=0; result=-1; for (i=0;i<cmh->depth;i++) { est=0; for (j=0;j<cmh->width;j++) { est+=(long long) cmh->counts[0][k] * (long long) cmh->counts[0][k]; k++; } if (result<0) result=est; else result=min(result,est); } return result; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/�������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�12631352110�010611� 5����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/versioncheck.patch�������������������������������������������������������������������0000664�0000000�0000000�00000015037�12631352101�014323� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: Fix handling and documentation of --skip-version-check command line option. Author: Ludovico Cavedon <cavedon@debian.org> Index: ntop/main.c =================================================================== --- ntop.orig/main.c 2014-03-01 01:21:04.150374408 -0800 +++ ntop/main.c 2014-03-01 01:21:04.146374323 -0800 @@ -153,7 +153,7 @@ fprintf(fp, " [--instance <name>] %sSet log name for this ntop instance\n", newLine); fprintf(fp, " [--p3p-cp] %sSet return value for p3p compact policy, header\n", newLine); fprintf(fp, " [--p3p-uri] %sSet return value for p3p policyref header\n", newLine); - fprintf(fp, " [--skip-version-check] %sSkip ntop version check\n", newLine); + fprintf(fp, " [--skip-version-check=yes] %sSkip ntop version check\n", newLine); fprintf(fp, " [--known-subnets <networks>] %sList of known subnets (separated by ,)\n", newLine); fprintf(fp, " %sIf the argument starts with @ it is assumed it is a file path\n", newLine); fprintf(fp, " %sE.g. 192.168.0.0/14=home,172.16.0.0/16=private\n", newLine); @@ -699,7 +699,8 @@ /* Periodic recheck of the version status */ if((myGlobals.checkVersionStatusAgain > 0) && (time(NULL) > myGlobals.checkVersionStatusAgain) && - (myGlobals.ntopRunState == FLAG_NTOPSTATE_RUN)) + (myGlobals.ntopRunState == FLAG_NTOPSTATE_RUN) && + !myGlobals.runningPref.skipVersionCheck) checkVersion(NULL); } Index: ntop/html/ntop.html =================================================================== --- ntop.orig/html/ntop.html 2014-03-01 01:21:04.150374408 -0800 +++ ntop/html/ntop.html 2014-03-01 01:21:04.146374323 -0800 @@ -86,7 +86,7 @@ [<b>--disable-mutexextrainfo</b>] [<b>--disable-ndpi</b>] [<b>--disable-python</b>] [<b>--instance</b>] [<b>--p3p-cp</b>] [<b>--p3p-uri</b>] -[<b>--skip-version-check</b>] [<b>--w3c</b>] +[<b>--skip-version-check=yes</b>] [<b>--w3c</b>] [<b>-4</b>|<b>--ipv4]</b> [<b>-6</b>|<b>--ipv6]</b></p> <p style="margin-left:11%; margin-top: 1em">Unix @@ -1161,7 +1161,7 @@ Read the docs/FAQ write-up.</p> -<p style="margin-left:11%;"><b>--skip-version-check</b></p> +<p style="margin-left:11%;"><b>--skip-version-check=yes</b></p> <p style="margin-left:12%;">By default, <b>ntop</b> accesses a remote file to periodically check if the most @@ -1358,7 +1358,7 @@ and recorded.</p> <p style="margin-left:11%; margin-top: 1em">You may request -- via the <b>--skip-version-check</b> run-time option - that +- via the <b>--skip-version-check=yes</b> run-time option - that this check be eliminated. If you use this option, no individually identifiable information is transmitted or recorded, because the entire retrieval and check is Index: ntop/html/privacyNotice.html =================================================================== --- ntop.orig/html/privacyNotice.html 2014-03-01 01:21:04.150374408 -0800 +++ ntop/html/privacyNotice.html 2014-03-01 01:21:04.146374323 -0800 @@ -85,7 +85,7 @@ information which identifies a specific <b>ntop</b> site. Accordingly, you are being notified that this individually identifiable information is being transmitted and recorded.</p> -<p>You may request - via the <i>--skip-version-check</i> run-time option - that +<p>You may request - via the <i>--skip-version-check=yes</i> run-time option - that this check be eliminated. If you use this option, no individually identifiable information is transmitted or recorded, because the entire retrieval and check is skipped.</p> Index: ntop/ntop.8 =================================================================== --- ntop.orig/ntop.8 2014-03-01 01:21:04.150374408 -0800 +++ ntop/ntop.8 2014-03-01 01:21:04.146374323 -0800 @@ -73,7 +73,7 @@ .RB [ --instance ] .RB [ --p3p-cp ] .RB [ --p3p-uri ] -.RB [ --skip-version-check ] +.RB [ --skip-version-check=yes ] .RB [ --w3c ] .RB [ -4 | --ipv4] .RB [ -6 | --ipv6] @@ -951,7 +951,7 @@ .B THIS OPTION IS OFFICIALLY UNSUPPORTED and used at your own risk. Read the docs/FAQ write-up. -.It --skip-version-check +.It --skip-version-check=yes By default, .B ntop accesses a remote file to periodically check if the most current version is running. @@ -1128,7 +1128,7 @@ information is being transmitted and recorded. You may request - via the -.B --skip-version-check +.B --skip-version-check=yes run-time option - that this check be eliminated. If you use this option, no individually identifiable information is transmitted or recorded, because the entire retrieval and check is skipped. Index: ntop/ntop.html =================================================================== --- ntop.orig/ntop.html 2014-03-01 01:21:04.150374408 -0800 +++ ntop/ntop.html 2014-03-01 01:21:04.150374408 -0800 @@ -86,7 +86,7 @@ [<b>--disable-mutexextrainfo</b>] [<b>--disable-ndpi</b>] [<b>--disable-python</b>] [<b>--instance</b>] [<b>--p3p-cp</b>] [<b>--p3p-uri</b>] -[<b>--skip-version-check</b>] [<b>--w3c</b>] +[<b>--skip-version-check=yes</b>] [<b>--w3c</b>] [<b>-4</b>|<b>--ipv4]</b> [<b>-6</b>|<b>--ipv6]</b></p> <p style="margin-left:11%; margin-top: 1em">Unix @@ -1161,7 +1161,7 @@ Read the docs/FAQ write-up.</p> -<p style="margin-left:11%;"><b>--skip-version-check</b></p> +<p style="margin-left:11%;"><b>--skip-version-check=yes</b></p> <p style="margin-left:12%;">By default, <b>ntop</b> accesses a remote file to periodically check if the most @@ -1358,7 +1358,7 @@ and recorded.</p> <p style="margin-left:11%; margin-top: 1em">You may request -- via the <b>--skip-version-check</b> run-time option - that +- via the <b>--skip-version-check=yes</b> run-time option - that this check be eliminated. If you use this option, no individually identifiable information is transmitted or recorded, because the entire retrieval and check is Index: ntop/globals-defines.h =================================================================== --- ntop.orig/globals-defines.h 2014-03-01 01:20:53.186142631 -0800 +++ ntop/globals-defines.h 2014-03-01 01:21:16.342632160 -0800 @@ -1923,7 +1923,7 @@ #define DEFAULT_NTOP_PRINTFCONLY FALSE #define DEFAULT_NTOP_NO_INVLUN_DISPLAY FALSE #define DEFAULT_NTOP_DISABLE_MUTEXINFO TRUE -#define DEFAULT_NTOP_SKIP_VERSION_CHECK TRUE +#define DEFAULT_NTOP_SKIP_VERSION_CHECK FALSE /* * --set-pcap-nonblocking option init �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/fix-manpage-errors.patch�������������������������������������������������������������0000664�0000000�0000000�00000011276�12631352101�015347� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: fix typos and syntax errors in ntop.8 manpage. Author: A. Costa <agcosta@gis.net>, Ola Lundqvist <opal@debian.org>, Jordan Metzmeier <jordan@linuxgen.com>, Ludovico Cavedon <cavedon@debian.org> Index: ntop/ntop.8 =================================================================== --- ntop.orig/ntop.8 2012-06-26 23:52:32.215050221 -0700 +++ ntop/ntop.8 2012-06-26 23:52:34.259073012 -0700 @@ -145,10 +145,10 @@ given: --trace-level 2 --trace-level 3 will run as --trace-level 3. Beginning with -.b ntop +.B ntop 3.1, many command-line options may also be set via the web browser interface. These changes take effect on the next run of -.b ntop +.B ntop and on each subsequent run until changed. @@ -323,7 +323,7 @@ .B ntop by the -f | --traffic-dump-file parameter. The dump is made after processing any filter expression ( -.b ntop +.B ntop never even sees filtered packets). The output file will be named @@ -476,7 +476,7 @@ .It2 -s --no-promiscuous Use this parameter to prevent -.b ntop +.B ntop from setting the interface(s) into promiscuous mode. An interface in promiscuous mode will accept ALL Ethernet frames, regardless of @@ -741,7 +741,7 @@ merges the data collected from all of the interfaces (NICs) it is monitoring into a single set of counters. -If you have a simple network, say a small LAN with a connection to the internet, +If you have a simple network, say a small LAN with a connection to the Internet, merging data is good as it gives you a better picture of the whole network. For larger, more complex networks, this may not be desirable. You may also have other reasons for wishing to monitor each interface separately, @@ -865,7 +865,7 @@ stores extra information about the locks and unlocks of the protective mutexes it uses. Since .B ntop uses fine-grained locking, this information is updated frequently. On some OSes, the system -calls used to collect this informatio (getpid() and gettimeofday()) are expensive. This option +calls used to collect this information (getpid() and gettimeofday()) are expensive. This option disables the extra information. It should have no processing impact on .B ntop - however should @@ -906,7 +906,7 @@ If present, a file of the form <instance>_ntop_logo.gif will be used instead of the normal ntop_logo.gif. This is tested for ONLY once, at the beginning of the -.b ntop +.B ntop run. The EXACT word(s) of the --instance flag are used, without testing if they make a proper file name. If - for any reason - the file is not found, an informational message is logged and the normal logo file is used. To construct your own logo, make it a 300x40 @@ -917,7 +917,7 @@ uses the dladdr() function. The original Solaris routine had a bug, replicated in FreeBSD (and possibly other places) where it uses the ARGV[0] value - which might be erroneous - instead of the actual file name. If the 'running from' value looks bogus but -the 'libaries in' value looks ok, go with the libarary. +the 'libraries in' value looks OK, go with the library. .It --p3p-cp .It --p3p-uri @@ -925,7 +925,7 @@ P3P is a W3C recommendation - http://www.w3.org/TR/P3P/ - for specifying personal information a site collects and what it does with the information. These parameters allow -.b ntop +.B ntop to return P3P information. We do not supply samples. .It --pcap_setnonblock @@ -939,12 +939,12 @@ This option sets the non-blocking option (assuming it's available in the version of libpcap that is installed). -While this works around the problem (by turing an interupt driven process into -a poll), it also MAY signifcantly increases the cpu usage of +While this works around the problem (by turning an interrupt driven process into +a poll), it also MAY significantly increase the CPU usage of .B ntop. Although it does not actually interfere with other work, seeing .B ntop -use 80-90% or more of the cpu is not uncommon - don't say we didn't warn you. +use 80-90% or more of the CPU is not uncommon - don't say we didn't warn you. .B THIS OPTION IS OFFICIALLY UNSUPPORTED and used at your own risk. Read the docs/FAQ write-up. @@ -968,7 +968,7 @@ .It --ssl-watchdog Enable a watchdog for -.b ntop +.B ntop webserver hangs. These usually happen when connecting with older browsers. The user gets nothing back and other users can't connect. Internally, packet processing continues but there is no way to access the data through the web server or shutdown ntop cleanly. @@ -1198,7 +1198,7 @@ which flags are being used. The libpcap, gdbm, openssl and zlib versions come from the strings returned by the various -inquiry functions (if they're availabe). +inquiry functions (if they're available). Here's a sample log record: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/libtoolize_check.patch���������������������������������������������������������������0000664�0000000�0000000�00000001432�12631352101�015143� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: check for libtoolize rather than libtool Author: Johannes Schauer <j.schauer@email.de> Forwarded: no --- ntop-5.0.1+dfsg1.orig/autogen.sh +++ ntop-5.0.1+dfsg1/autogen.sh @@ -169,7 +169,7 @@ done echo "1. Testing gnu tools...." -($LIBTOOL --version) < /dev/null > /dev/null 2>&1 || +($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || { echo echo "You must have libtool installed to compile $NAME." @@ -211,7 +211,7 @@ if test "$GNU_OR_DIE" -eq 0; then fi # Check versions... -libtoolversion=`$LIBTOOL --version < /dev/null 2>&1 | grep libtool | cut -d " " -f 4` +libtoolversion=`$LIBTOOLIZE --version < /dev/null 2>&1 | grep libtool | cut -d " " -f 4` echo " libtool ..... ${libtoolversion}" case "${libtoolversion}" in *1\.3\.[[45]]\-freebsd\-ports*) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/reduce-autogen-purged-files.patch����������������������������������������������������0000664�0000000�0000000�00000002535�12631352101�017132� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: reduce the amount of files purged by autogen.sh in order to make the output of the clean target closer to the original state. Author: Ludovico Cavedon <cavedon@debian.org> Index: ntop/autogen.sh =================================================================== --- ntop.orig/autogen.sh 2012-03-18 16:39:07.608056102 -0700 +++ ntop/autogen.sh 2012-03-18 16:39:23.152268241 -0700 @@ -120,29 +120,29 @@ rm -f libtool.m4.in rm -f config.guess - rm -f config.sub - rm -f install-sh +# rm -f config.sub +# rm -f install-sh rm -f ltconfig rm -f ltmain.sh - rm -f missing +# rm -f missing # rm -f mkinstalldirs - rm -f INSTALL - rm -f COPYING +# rm -f INSTALL +# rm -f COPYING rm -f texinfo.tex rm -f acinclude.m4 rm -f aclocal.m4 rm -f config.h.in - rm -f stamp-h.in +# rm -f stamp-h.in rm -f Makefile.in rm -f configure rm -f config.h - rm -f depcomp +# rm -f depcomp rm -f stamp.h rm -f libtool rm -f Makefile - rm -f stamp-h.in +# rm -f stamp-h.in rm -f stamp-h rm -f stamp-h1 @@ -155,11 +155,11 @@ rm -f Makefile rm -f Makefile.in - rm -f compile +# rm -f compile rm -f plugins/Makefile rm -f plugins/Makefile.in - rm -rf nDPI +# rm -rf nDPI rm -f *~ exit 0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/series�������������������������������������������������������������������������������0000664�0000000�0000000�00000000520�12631352101�012023� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fix-manpage-errors.patch fix-wget-during-build.patch dot-path.patch reduce-autogen-purged-files.patch change-plugin-dir.patch build-without-ntop-darwin.patch avoid-copy-maxmind-db.patch hostaname-in-man-description.patch netflow-plugin-links.patch kfreebsd-ftbfs.patch do-not-require-svn.patch versioncheck.patch libtoolize_check.patch ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/do-not-require-svn.patch�������������������������������������������������������������0000664�0000000�0000000�00000001616�12631352101�015314� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Descrition: Do not depend on SVN during autogen.sh Author: Ludovico Cavedon <cavedon@debian.org> Index: ntop/autogen.sh =================================================================== --- ntop.orig/autogen.sh 2012-02-26 11:25:15.852334414 -0800 +++ ntop/autogen.sh 2012-02-26 12:56:42.135169828 -0800 @@ -206,16 +206,6 @@ exit 1 fi -SVN=`find_command 'svn'` -($SVN --version) < /dev/null > /dev/null 2>&1 || -{ - echo - echo "You must have svn/subversion installed to compile $progname." - echo "Download the appropriate package for your distribution, or get the" - echo "source from http://subversion.tigris.org" - GNU_OR_DIE=0 -} - if test "$GNU_OR_DIE" -eq 0; then exit 1 fi @@ -432,7 +422,9 @@ if test -d nDPI; then echo "nDPI already available" else - svn co $NDPI_URL + #svn co $NDPI_URL + echo "nDPI not available. Exiting." + exit 1 fi dnl> nDPI compilation ������������������������������������������������������������������������������������������������������������������debian/patches/avoid-copy-maxmind-db.patch����������������������������������������������������������0000664�0000000�0000000�00000001306�12631352101�015722� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: avoid copying GeoIP*.dat files, as they have been removed from the DFSG-clean tarball. Author: Ludovico Cavedon <cavedon@debian.org> Forwarded: not-needed Index: ntop/Makefile.am =================================================================== --- ntop.orig/Makefile.am 2012-02-26 11:04:23.875929148 -0800 +++ ntop/Makefile.am 2012-02-26 11:04:32.440015909 -0800 @@ -67,9 +67,7 @@ NTOPDATA = ntop-cert.pem \ $(ETTER_PASSIVE) \ oui.txt.gz \ - specialMAC.txt.gz \ - GeoIPASNum.dat \ - GeoLiteCity.dat + specialMAC.txt.gz NTOPHTML = html html/*.js html/*.html html/*.gif html/*.jpg html/*.ico html/*.png \ html/*.css html/*.dtd \ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/kfreebsd-ftbfs.patch�����������������������������������������������������������������0000664�0000000�0000000�00000002364�12631352101�014526� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: Fix building under kFreeBSD. Author: Christoph Egger <christoph@debian.org> Forwarded: not-needed Bug-Debian: http://bugs.debian.org/636389 Reviewed-by: Ludovico Cavedon <cavedon@debian.org> Index: ntop/configure.in =================================================================== --- ntop.orig/configure.in 2012-02-26 11:03:40.231487001 -0800 +++ ntop/configure.in 2012-02-26 11:04:43.272125645 -0800 @@ -385,7 +385,7 @@ echo "* This appears to be ${DEFINEOS} (MacOSX)" ;; - *-*-freebsd*:* ) + *-*-*freebsd*:* ) DEFINEOS="FREEBSD" RELEASE=`utils/linuxrelease --release | sed -e 's/\.//' -e 's/-.*$//g'` echo "* This appears to be ${DEFINEOS} ${RELEASE}" Index: ntop/ntop.h =================================================================== --- ntop.orig/ntop.h 2012-02-25 19:26:19.414459081 -0800 +++ ntop/ntop.h 2012-02-26 11:04:43.300125929 -0800 @@ -80,7 +80,7 @@ #endif #endif -#ifdef LINUX +#if defined(__linux__) || defined(__GLIBC__) /* * This allows to hide the (minimal) differences between linux and BSD */ @@ -114,7 +114,7 @@ #endif #define _THREAD_SAFE -#if defined(__linux__) +#if defined(__linux__) || defined(__GLIBC__) #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/build-without-ntop-darwin.patch������������������������������������������������������0000664�0000000�0000000�00000001244�12631352101�016673� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: build without ompiling ntop_drawin.c, as it conatins non-DFSG compliant code. Author: Ludovico Cavedon <cavedon@debian.org> Index: ntop/Makefile.am =================================================================== --- ntop.orig/Makefile.am 2013-09-11 13:42:43.942948175 +0200 +++ ntop/Makefile.am 2013-09-11 13:42:43.934948175 +0200 @@ -128,7 +128,6 @@ plugin.c prefs.c protocols.c \ sessions.c term.c util.c utildl.c \ traffic.c vendor.c version.c \ - ntop_darwin.c \ prng.c countmin.c libntop_la_DEPENDENCIES = config.h ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/dot-path.patch�����������������������������������������������������������������������0000664�0000000�0000000�00000001156�12631352101�013355� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: fix location of dot binary. Author: Ola Lundqvist <opal@debian.org> Index: ntop/report.c =================================================================== --- ntop.orig/report.c 2013-09-11 13:42:37.750948472 +0200 +++ ntop/report.c 2013-09-11 13:42:37.746948472 +0200 @@ -2299,7 +2299,7 @@ if(fetchPrefsValue("dot.path", buf, sizeof(buf)) != -1) { snprintf(dotPath, sizeof(dotPath), "%s", buf); } else { - snprintf(dotPath, sizeof(dotPath), "/usr/local/bin/dot"); + snprintf(dotPath, sizeof(dotPath), "/usr/bin/dot"); storePrefsValue("dot.path", dotPath); /* Set the default */ } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/hostaname-in-man-description.patch���������������������������������������������������0000664�0000000�0000000�00000003607�12631352101�017315� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: add servername:port in the DESCRIPTION section of the man page, be less vague about the URL of ntop web interface Author: A. Costa <agcosta@gis.net> Bug-Debian: http://bugs.debian.org/466506 Bug-Debian: http://bugs.debian.org/466507 Index: ntop/ntop.8 =================================================================== --- ntop.orig/ntop.8 2012-06-26 23:52:34.259073012 -0700 +++ ntop/ntop.8 2012-06-26 23:52:50.275251562 -0700 @@ -106,14 +106,11 @@ .SH DESCRIPTION .B ntop -shows the current network usage. It displays a list of hosts that are -currently using the network and reports information concerning the (IP and non-IP) -traffic generated and received by each host. +shows the current network usage in a web browser, the default URL is 'http://localhost:3000'. +It displays a list of hosts that are currently using the network and reports +information concerning the (IP and non-IP) traffic generated and received by each host. .B ntop -may operate as a front-end collector (sFlow and/or netFlow plugins) or as a stand-alone -collector/display program. A web browser is needed to access the information captured by the -.B ntop -program. +may operate as a front-end collector (sFlow and/or netFlow plugins) or as a stand-alone program. .B ntop is a hybrid layer 2 / layer 3 network monitor, that is by default it uses the layer 2 Media @@ -577,7 +574,12 @@ For example, if started with -w 3000 (the default port), the URL to access .B ntop -is http://hostname:3000/. If started with a full specification, e.g. -w 192.168.1.1:3000, +is http://hostname:3000/, where "hostname" is the name or address of the +system where ntop is installed. For example, if +.B ntop +is installed on the local machine, the web interface can be accessed at +http://localhost:3000. +If started with a full specification, e.g. -w 192.168.1.1:3000, .B ntop listens on only that address/port combination. �������������������������������������������������������������������������������������������������������������������������debian/patches/change-plugin-dir.patch��������������������������������������������������������������0000664�0000000�0000000�00000002214�12631352101�015126� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: change plugin directory to $(libdir)/plugins, as libdir is already pointing to a private library diretory in the debian package. Author: Ludovico Cavedon <cavedon@debian.org> Index: ntop/configure.in =================================================================== --- ntop.orig/configure.in 2013-09-11 13:42:41.350948299 +0200 +++ ntop/configure.in 2013-09-11 13:42:41.350948299 +0200 @@ -1885,7 +1885,7 @@ AC_DEFINE_UNQUOTED(CFG_RUN_DIR,"$CFG_RUN_DIR", [Run files directory]) echo " Run directory is $CFG_RUN_DIR" -CFG_PLUGIN_DIR=$libdir/ntop/plugins +CFG_PLUGIN_DIR=$libdir/plugins CFG_PLUGIN_DIR=`( test "x$prefix" = xNONE && prefix=${ac_default_prefix} test "x$exec_prefix" = xNONE && exec_prefix=${prefix} Index: ntop/plugins/Makefile.am =================================================================== --- ntop.orig/plugins/Makefile.am 2013-09-11 13:42:41.350948299 +0200 +++ ntop/plugins/Makefile.am 2013-09-11 13:42:41.350948299 +0200 @@ -34,7 +34,7 @@ # # Where to install the plugin # -plugindir = $(libdir)/ntop/plugins +plugindir = $(libdir)/plugins INCLUDES = -I.. @INCS@ ${RRD_INC} -I ../@NDPI_INC@ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/fix-wget-during-build.patch����������������������������������������������������������0000664�0000000�0000000�00000007147�12631352101�015760� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Desription: do not download data files from the internet when building. Author: Jordan Metzmeier <jordan@linuxgen.com> Index: ntop/Makefile.am =================================================================== --- ntop.orig/Makefile.am 2013-09-11 13:42:31.998948748 +0200 +++ ntop/Makefile.am 2013-09-11 13:42:31.994948748 +0200 @@ -369,28 +369,7 @@ dnvt: @echo "" @echo "" - @echo -n "Preparing " - @if test -f oui.txt; then \ - rm -rf oui.txt; \ - fi - @if test -f oui.txt.gz.old; then \ - rm -rf oui.txt.gz.old; \ - fi; - @mv oui.txt.gz oui.txt.gz.old - @echo "(old oui.txt.gz file is now oui.txt.gz.old)" - @echo "" - @wget -c http://standards.ieee.org/regauth/oui/oui.txt - @gzip oui.txt - @echo "" - @echo "" - @echo -n "Old file lines were: " - @gunzip -c oui.txt.gz.old | wc -l - @echo -n "New file lines are: " - @gunzip -c oui.txt.gz | wc -l - @echo "" - @echo "" - @echo "New file is:" - @ls -l oui.txt.gz + @echo -n "Nothing to do here " # download the Novell SAP Protocol information table #dnsapt: @@ -400,43 +379,8 @@ dnetter: @echo "" @echo "" - @echo "Preparing " - @echo "" - - @if test -f $(ETTER_PASSIVE).old; then \ - echo "...Deleting prior file, $(ETTER_PASSIVE).old..."; \ - rm -rf $(ETTER_PASSIVE).old; \ - fi; - @if test -f $(ETTER_PASSIVE); then \ - echo "...Moving current $(ETTER_PASSIVE) to $(ETTER_PASSIVE).old"; \ - mv $(ETTER_PASSIVE) $(ETTER_PASSIVE).old; \ - fi; - @for file in $(ETTER_PASSIVE) $(ETTER_PASSIVE).gz \ - $(ETTER_PASSIVE_FILE) $(ETTER_PASSIVE_FILE).gz; do \ - if test -f $$file; then \ - echo "...Deleting prior file, $$file..."; \ - rm -rf $$file; \ - fi; \ - done - @echo "" - @echo "...Downloading new file..." - @wget -O $(ETTER_PASSIVE_FILE) \ - $(ETTER_PASSIVE_DOWNLOAD_FROM)/$(ETTER_PASSIVE_FILE)?$(ETTER_PASSIVE_DOWNLOAD_PARMS) - @echo "" - @echo "gziping downloaded file..." - @gzip $(ETTER_PASSIVE_FILE) - @echo "" - @echo "" - @if test -f $(ETTER_PASSIVE).old; then \ - echo -n "Old file lines were: "; \ - gunzip -c $(ETTER_PASSIVE).old | wc -l; \ - fi; - @echo -n "New file lines are: " - @gunzip -c $(ETTER_PASSIVE) | wc -l - @echo "" + @echo "Nothing to do here " @echo "" - @echo "New file is:" - @ls -l $(ETTER_PASSIVE) # ntop census census-fail: Index: ntop/autogen.sh =================================================================== --- ntop.orig/autogen.sh 2013-09-11 13:42:31.998948748 +0200 +++ ntop/autogen.sh 2013-09-11 13:42:31.994948748 +0200 @@ -202,16 +202,6 @@ GNU_OR_DIE=0 } -WGET=`find_command 'wget*'` -($WGET --version) < /dev/null > /dev/null 2>&1 || -{ - echo - echo "You must have wget installed to compile $progname." - echo "Download the appropriate package for your distribution, or get the" - echo "source tarball from ftp://ftp.gnu.org/pub/gnu/wget" - GNU_OR_DIE=0 -} - if test "$GNU_OR_DIE" -eq 0; then exit 1 fi Index: ntop/configure.in =================================================================== --- ntop.orig/configure.in 2013-09-11 13:42:31.998948748 +0200 +++ ntop/configure.in 2013-09-11 13:42:31.994948748 +0200 @@ -1745,7 +1745,7 @@ if test -f "3rd_party/GeoLiteCity.dat.gz"; then cp 3rd_party/GeoLiteCity.dat.gz . else - wget http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz + echo 'GeoLiteCity.dat.gz: file not found' fi gunzip GeoLiteCity.dat.gz @@ -1759,7 +1759,7 @@ if test -f "3rd_party/GeoIPASNum.dat.gz"; then cp 3rd_party/GeoIPASNum.dat.gz . else - wget http://www.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz + echo 'GeoIPASNum.dat.gz: file not found' fi gunzip GeoIPASNum.dat.gz �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/patches/netflow-plugin-links.patch�����������������������������������������������������������0000664�0000000�0000000�00000002155�12631352101�015725� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Description: fix links in NetFlow plugin description. Author: Ludovico Cavedon <cavedon@debian.org> Bug-Debian: http://bugs.debian.org/530334 Index: ntop/plugins/netflowPlugin.c =================================================================== --- ntop.orig/plugins/netflowPlugin.c 2012-06-26 23:52:31.687044334 -0700 +++ ntop/plugins/netflowPlugin.c 2012-06-26 23:52:53.003281968 -0700 @@ -122,8 +122,8 @@ "NetFlow", "This plugin is used to setup, activate and deactivate NetFlow support.<br>" "<b>ntop</b> can both collect and receive " - "<A HREF=http://www.cisco.com/warp/public/cc/pd/iosw/ioft/neflct/tech/napps_wp.htm>NetFlow</A> " - "V1/V5/V7/V9 and <A HREF=http://ipfix.doit.wisc.edu/>IPFIX</A> (draft) data.<br>" + "<A HREF=http://en.wikipedia.org/wiki/Netflow>NetFlow</A> " + "V1/V5/V7/V9 and <A HREF=http://en.wikipedia.org/wiki/IP_Flow_Information_Export>IPFIX</A> (draft) data.<br>" "<i>Received flow data is reported as a separate 'NIC' in the regular <b>ntop</b> " "reports.<br><em>Remember to <A HREF=/switch.html>switch</A> the reporting NIC.</em>", "4.4", /* version */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/control��������������������������������������������������������������������������������������0000664�0000000�0000000�00000007206�12631352100�010571� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Source: ntop Section: net Priority: optional Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> XSBC-Original-Maintainer: Ludovico Cavedon <cavedon@debian.org> Build-Depends-Indep: groff Build-Depends: debhelper (>= 8), libpcap0.8-dev, autoconf, automake, libgdbm-dev, libpng-dev, libncurses5-dev, libtool, libwrap0-dev, libgd2-noxpm-dev, libjpeg-dev, po-debconf, librrd-dev, python-dev, libgeoip-dev Standards-Version: 3.9.5 Homepage: http://www.ntop.org/ Vcs-Git: git://anonscm.debian.org/collab-maint/ntop.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/ntop.git Package: ntop Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ntop-data (= ${source:Version}), python-mako, net-tools, adduser, passwd Suggests: graphviz, gsfonts Description: display network usage in web browser ntop is a network traffic probe that shows the network usage, similar to what the popular top Unix command does. ntop is based on libpcap and it has been written in a portable way in order to virtually run on every Unix platform and on Win32 as well. . ntop users can use a web browser to navigate through ntop (that acts as a web server) traffic information and get a dump of the network status. In the latter case, ntop can be seen as a simple RMON-like agent with an embedded web interface. The use of: * a web interface * limited configuration and administration via the web interface * reduced CPU and memory usage (they vary according to network size and traffic) make ntop easy to use and suitable for monitoring various kind of networks. . This package contains the ntop daemon. Package: ntop-dbg Section: debug Priority: extra Architecture: any Depends: ${misc:Depends}, ntop (= ${binary:Version}), python-mako, net-tools, adduser, passwd Suggests: graphviz, gsfonts Description: display network usage in web browser (debug symbols) ntop is a network traffic probe that shows the network usage, similar to what the popular top Unix command does. ntop is based on libpcap and it has been written in a portable way in order to virtually run on every Unix platform and on Win32 as well. . ntop users can use a web browser to navigate through ntop (that acts as a web server) traffic information and get a dump of the network status. In the latter case, ntop can be seen as a simple RMON-like agent with an embedded web interface. The use of: * a web interface * limited configuration and administration via the web interface * reduced CPU and memory usage (they vary according to network size and traffic) make ntop easy to use and suitable for monitoring various kind of networks. . This package contains the debug symbols for the ntop daemon. Package: ntop-data Architecture: all Depends: ${misc:Depends} Recommends: ntop (>= ${source:Version}) Breaks: ntop (<< 3:4.0) Replaces: ntop (<< 3:4.0) Suggests: geoip-database-contrib, python, libjs-jquery, libjs-jquery-ui Description: display network usage in a web browser (data files) ntop users can use a web browser to navigate through ntop (that acts as a web server) traffic information and get a dump of the network status. In the latter case, ntop can be seen as a simple RMON-like agent with an embedded web interface. The use of: * a web interface * limited configuration and administration via the web interface * reduced CPU and memory usage (they vary according to network size and traffic) make ntop easy to use and suitable for monitoring various kind of networks. . ntop displays a summary of network usage by machines on your network in a web mode, which allows the display to be browsed with a web browser. . This package contains 3rd party data. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.templates�������������������������������������������������������������������������������0000664�0000000�0000000�00000002700�12631352100�012060� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Template: ntop/user Type: string Default: ntop _Description: User for the ntop process to run as: Please choose the login that should be used to execute the ntop process. The use of the root user is not allowed. . The account will be created if it does not already exist, but if you leave it blank, no login will be created and ntop will not run until manually configured. Template: ntop/interfaces Type: string Default: none _Description: Interfaces for ntop to listen on: Please enter a comma-separated list of interfaces that ntop should listen on. Template: ntop/admin_password Type: password _Description: Administrator password: Please choose a password to be used for the privileged user "admin" in ntop's web interface. Template: ntop/admin_password_again Type: password _Description: Re-enter password to verify: Please enter the same password again to verify that you have typed it correctly. Template: ntop/password_empty Type: error _Description: Empty password You entered an empty password, which is not allowed. Please choose a non-empty password. Template: ntop/password_mismatch Type: error _Description: Password input error The two passwords you entered were not the same. Please try again. Template: ntop/password_reset Type: boolean Default: false _Description: Set a new administrator password? A password for ntop's administrative web interface has already been set. . Please choose whether you want to change that password. ����������������������������������������������������������������debian/ntop.init������������������������������������������������������������������������������������0000664�0000000�0000000�00000010657�12631352100�011037� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh ### BEGIN INIT INFO # Provides: ntop # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Should-Start: $network # Should-Stop: $network # Short-Description: Start ntop daemon # Description: Enable services provided by ntop ### END INIT INFO DAEMON="/usr/sbin/ntop" NAME="ntop" DESC="network top daemon" INIT="/etc/default/$NAME" DEBCONFINIT="/var/lib/ntop/init.cfg" HOMEDIR="/var/lib/ntop" LOGDIR="/var/log/ntop" SCRIPTNAME=/etc/init.d/$NAME # Workaround for a rrd problem, see #471862. export LANG=C # end of workaround test -f $DAEMON || exit 0 . /lib/lsb/init-functions test -f $INIT || exit 0 . $INIT test -f $DEBCONFINIT || exit 0 . $DEBCONFINIT [ "$ENABLED" = "0" -o "$ENABLED" = "no" -o "$ENABLED" = "n" ] && exit 0 sanity_check() { # Sanity check, we expect USER And INTERFACES to be defined # (we could also set defaults for them before calling INIT...) if [ -z "$USER" ] ; then log_failure_msg "$NAME: USER is not defined, please run 'dpkg-reconfigure ntop'" >&2 return 1 fi if [ -z "$INTERFACES" ] ; then log_failure_msg "$NAME: INTERFACES is not defined, please run 'dpkg-reconfigure ntop'" >&2 return 1 fi return 0 } check_log_dir() { # Does the logging directory belong to the User running the application # If we cannot determine the logdir return without error # (we will not check it) [ -n "$LOGDIR" ] || return 0 [ -n "$USER" ] || return 0 if [ ! -e "$LOGDIR" ] ; then log_failure_msg "$NAME: logging directory $LOGDIR does not exist" return 1 elif [ ! -d "$LOGDIR" ] ; then log_failure_msg "$NAME: logging directory $LOGDIR does not exist" return 1 else real_log_user=`stat -c %U $LOGDIR` # An alternative way is to check if the the user can create # a file there... if [ "$real_log_user" != "$USER" ] ; then log_failure_msg "$NAME: logging directory $LOGDIR does not belong to the user $USER" return 1 fi fi return 0 } check_interfaces() { # Check the interface status, abort with error if a configured one is not # available [ -z "$INTERFACES" ] && return 0 for iface in $(echo $INTERFACES | awk -F , '{ for(i=1;i<=NF;i++) print $i }') do if [ "$iface" != "none" ] && ! netstat -i | grep "^$iface " >/dev/null; then log_warning_msg "$NAME: interface $iface is down" fi done return 0 } ntop_start() { retval=$( { { /sbin/start-stop-daemon --start --quiet --name $NAME --exec $DAEMON -- \ -d -L -u $USER -P $HOMEDIR \ --access-log-file=$LOGDIR/access.log -i "$INTERFACES" \ -p /etc/ntop/protocol.list \ -O $LOGDIR $GETOPT 2>&1; echo -n $? >&2 ; } | logger -p daemon.info -t ntop; } 2>&1 ) if [ "$retval" -eq 1 ]; then log_progress_msg "already running" return 0 fi if pidof $DAEMON > /dev/null ; then return 0 else # WARNING: This might introduce a race condition in some (fast) systems # Wait for a sec an try again sleep 1 if pidof $DAEMON > /dev/null ; then return 0 else return 1 fi fi } ntop_stop() { /sbin/start-stop-daemon --stop --quiet --oknodo --name $NAME --user $USER --retry 9 if pidof $DAEMON > /dev/null ; then # WARNING: This might introduce a race condition in some (fast) systems # Wait for a sec an try again sleep 1 if pidof $DAEMON > /dev/null ; then return 1 else return 0 fi else return 0 fi } case "$1" in start) if ! sanity_check || ! check_log_dir || ! check_interfaces; then exit 1 fi log_daemon_msg "Starting $DESC" "$NAME" if ntop_start; then log_end_msg 0 else log_end_msg 1 fi ;; stop) log_daemon_msg "Stopping $DESC" "$NAME" if ntop_stop; then log_end_msg 0 else log_end_msg 1 fi ;; restart | force-reload) if ! sanity_check || ! check_log_dir || ! check_interfaces; then exit 1 fi log_daemon_msg "Restarting $DESC" "$NAME" if ntop_stop && ntop_start; then log_end_msg 0 else log_end_msg 1 fi ;; reload | try-restart) log_action_msg "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" exit 3 ;; status) status_of_proc $DAEMON $NAME ;; *) log_action_msg "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" exit 1 ;; esac exit 0 ���������������������������������������������������������������������������������debian/protocol.list��������������������������������������������������������������������������������0000664�0000000�0000000�00000000576�12631352100�011727� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FTP=ftp|ftp-data,PROXY=3128|8080,HTTP=http|www|https,DNS=name|domain,Telnet=telnet|login,NBios-IP=netbios-ns|netbios-dgm|netbios-ssn,Mail=pop-2|pop-3|kpop|smtp|imap|imap2,SNMP=snmp|snmp-trap,NEWS=nntp,DHCP-BOOTP=67-68,NFS=mount|pcnfs|bwnfs|nfs|nfsd-status,X11=6000-6010,SSH=ssh,Gnutella=6346|6347|6348,Kazaa=1214,WinMX=6699|7730,eDonkey=4661-4665,Messenger=1863|5000|5001|5190-5193 ����������������������������������������������������������������������������������������������������������������������������������debian/watch����������������������������������������������������������������������������������������0000664�0000000�0000000�00000000155�12631352100�010213� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������version=3 opts=dversionmangle=s/(\+ndpi[0-9]+)?\+dfsg\d+$// \ http://sf.net/ntop/ntop-(.*)\.(?:tar\.gz|tgz) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/logrotate������������������������������������������������������������������������������������0000664�0000000�0000000�00000000222�12631352100�011100� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/var/log/ntop/*.log { weekly missingok rotate 4 # ntop doesn't handle SIGHUP copytruncate compress notifempty create 640 ntop adm } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.docs������������������������������������������������������������������������������������0000664�0000000�0000000�00000000131�12631352100�011006� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������docs/FAQ docs/HACKING docs/KNOWN_BUGS docs/README docs/TODO subnets.txt SUPPORT_NTOP.txt ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.default���������������������������������������������������������������������������������0000664�0000000�0000000�00000000443�12631352100�011510� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# In order to change thwe user ntop should run as or the interfaces it should # listen on, please run: # dpkg-reconfigure -plow ntop # set ENABLED to 0 if you want to avoid ntop being started at system boot ENABLED=1 # Additional ommand line options passed when invoking ntop GETOPT="" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/������������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�12631464525�007616� 5����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/gl.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011213�12631352100�010537� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Galician translation of ntop's debconf templates # This file is distributed under the same license as the ntop package. # Jacobo Tarrio <jtarrio@debian.org>, 2008. # Anxo outeiral <bassball93@gmail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: ntop\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-05-14 00:36+0100\n" "Last-Translator: Anxo Outeiral <bassball93@gmail.com>\n" "Language-Team: Galician <proxecto@trasno.net>\n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Usuario co que se executar ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Introduce o usuario co que se executar o proceso do ntop. O usuario root " "non est permitido." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Crearase a conta de usuario se non existe. Se deixas o campo baleiro, non se " "crear a conta e non se poder executar ntop at que se configure " "manualmente." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces polas que escoita o ntop:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Introduza unha lista de interfaces, separada por comas, nas que debe " "escoitar ntop." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Contrasinal do administrador:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Escolla un contrasinal para o usuario con privilexios admin na interface " "web do ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Volva a introducir o contrasinal para comprobalo:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Introduce o mesmo contrasinal de novo para comprobar que o introduciu de " "maneira vlida." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Contrasinal baleiro" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Introduciches un contrasinal baleiro, o cal non est permitido. Introduce de " "novo un contrasinal con algn carcter." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Erro ao introducir o contrasinal" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Os dous contrasinais que introduciches non son iguais. Tentao de novo." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Desexa establecer un novo contrasinal para o administrador?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Foi establecido o contrasinal para a interface de administracin do ntop. " #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Indique se desexas trocar ese contrasinal." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Hase crear o usuario indicado se non existe xa. Non escolla \"root\"; non " #~ "se recomenda e hase ignorar de tdolos xeitos." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Se introduce unha cadea baleira, non se ha crear ningn usuario no " #~ "sistema e ha ter que facer esta configuracin vostede mesmo." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Cal o nome do usuario co que executar o servizo ntop?" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/eu.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000010134�12631352100�010547� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# translation of ntop_3:4.0.3+dfsg1-3_eu.po to Basque # Ntop debconf templates basque translation # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Piarres Beobide <pi@beobide.net>, 2008. # Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2011. msgid "" msgstr "" "Project-Id-Version: ntop_3:4.0.3+dfsg1-3_eu\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-26 10:33+0100\n" "Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>\n" "Language-Team: Basque <debian-l10n-basque@lists.debian.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Erabiltzailea (ntop prozesua haren gisa exekutatzeko):" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Aukeratu ntop prozesua exekutatzeko erabili beharko litzatekeen erabiltzaile-" "izena. 'root' supererabiltzailea erabiltzea ez dago baimenduta." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Kontua sortu egingo da aurrez ez bada existitzen, hala ere, hutsik uzten " "baduzu ez da konturik sortuko eta 'ntop' ezingo da exekutatu eskuz " "konfiguratu arte." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfazeak (ntop-ek entzuteko):" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "'ntop'-ek entzun behar dituen interfazeak komaz bereizitako zerrenda batean " "idatzi." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Administratzailearen pasahitza:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Aukeratu \"admin\" administratzaileak erabiliko duen pasahitza ntop-en web " "bidezko interfazean." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Berretsi pasahitza:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "Sartu berriro pasahitz berdina ongi idatzi duzula egiaztatzeko." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Pasahitza hutsik" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Pasahitz hutsa sartu duzu, baina hori ez dago baimenduta. Aukeratu hutsa ez " "den pasahitz bat." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Pasahitzaren sarrerako errorea" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Sartutako bi pasahitzak ez dira berdinak. Saiatu berriro." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Ezarri administratzailearen pasahitz berria?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "'ntop' web bidez administratzeko pasahitza jadanik ezarri da." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Aukeratu pasahitza aldatzea nahi duzun edo ez." ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/nn.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000007477�12631352100�010571� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Norwegian Nynorsk translations for PACKAGE package. # Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Yngve Spjeld Landro <l10n@landro.net>, 2011. # msgid "" msgstr "" "Project-Id-Version: ntop\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-27 01:38+0100\n" "Last-Translator: Yngve Spjeld Landro <l10n@landro.net>\n" "Language-Team: Norwegian Nynorsk <i18n-nn@lister.ping.uio.no>\n" "Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\\n\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Ntop-prosessen skal kjøra som brukaren:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Vel korleis ein skal logga seg på for å utføra ntop-prosessen. Ein kan ikkje " "nytta root-brukaren." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Kontoen vil bli oppretta om han ikkje finst allereie. Om han er tom, vil det " "ikkje vera mogleg å logga på før ein har endra innstillingane for hand." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Ntop skal lytta til grensesnitta:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "Skriv inn ei kommadelt liste over grensesnitt ntop skal lytta til. " #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Administratorpassord:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Vel passordet til den priviligerte brukaren «admin» i ntop sitt " "vevgrensesnitt." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Skriv inn att passordet for å stadfesta det:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "Skriv inn att passordet for å stadfesta at du har skrive det rett." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Tomt passord" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Du brukte eit tomt passord. Det er ikkje tillate. Skriv eit nytt passord." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Passordskrivefeil" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Passorda du skreiv var ikkje like. Prøv igjen." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Lagra nytt administratorpassord?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Det finst allereie eit passord for ntop sitt administrative vevgrensesnitt." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Vel om du ønskjer å endra passordet." �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/pl.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000010166�12631352100�010556� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Translation of ntop debconf templates to Polish. # Copyright (C) 2011 # This file is distributed under the same license as the ntop package. # # Michał Kułach <michal.kulach@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2012-02-22 14:44+0100\n" "Last-Translator: Michał Kułach <michal.kulach@gmail.com>\n" "Language-Team: Polish <debian-l10n-polish@lists.debian.org>\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Użytkownik uruchamiający proces ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Proszę wybrać login, który będzie użyty do uruchamiania procesu ntop. Użycie " "konta roota jest niedozwolone." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Jeśli konto nie istnieje, zostanie utworzone; jeśli jednak pole zostanie " "pozostawione puste, login nie zostanie utworzony, a ntop nie uruchomi się, " "dopóki nie zostanie ręcznie skonfigurowany." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfejsy, na których będzie nasłuchiwał ntop:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Proszę wprowadzić listę interfejsów (oddzielonych przecinkami), na których " "powinien nasłuchiwać ntop." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Hasło administratora:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Proszę wprowadzić hasło, które będzie użyte dla uprzywilejowanego użytkownika " "\"admin\" w interfejsie WWW ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Proszę wprowadzić hasło ponownie:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Proszę wprowadzić to samo hasło ponownie, aby sprawdzić, czy zostało wpisane " "poprawnie." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Puste hasło" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Wprowadzono puste hasło, co nie jest dozwolone. Proszę wpisać niepuste hasło." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Błąd wprowadzania hasła" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Dwa hasła, które zostały wprowadzone, nie są identyczne. Proszę spróbować " "ponownie." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Ustawić nowe hasło administratora?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "Hasło administratora do interfejsu WWW ntop, zostało już ustawione." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Proszę wybrać, czy hasło ma zostać zmienione." ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/sv.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011327�12631352101�010574� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Swedish translation of the debconf template for ntop. # Copyright (C) 2011 Martin Bagge <brother@bsnet.se> # This file is distributed under the same license as the ntop package. # # Daniel Nylander <po@danielnylander.se>, 2005. # Martin Bagge <brother@bsnet.se>, 2011 msgid "" msgstr "" "Project-Id-Version: ntop 2:3.2rc1-1\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-26 11:41+0100\n" "Last-Translator: Martin Bagge / brother <brother@bsnet.se>\n" "Language-Team: Swedish <debian-l10n-swedish@lists.debian.org>\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Swedish\n" "X-Poedit-Country: Sweden\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Användarkonto som ntop-processen ska köras som:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "Please choose the login that should be used to execute the ntop process. The use of the root user is not allowed." msgstr "Ange vilket användarkonto som ska användas för att köra ntop-processen. Att använda root är inte tillåtet." #. Type: string #. Description #: ../ntop.templates:1001 msgid "The account will be created if it does not already exist, but if you leave it blank, no login will be created and ntop will not run until manually configured." msgstr "Användarkontot kommer att skapas om det inte redan existerar, lämnas fältet tomt kommer inget konto att skapas och ntop kommer inte att köras förrens du gjort inställningarna manuellt." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Gränssnitt som ntop ska lyssna på:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "Ange en kommaseparerad lista med gränssnitt som ntop ska lyssna på." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Adminstrationslösenord:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "Please choose a password to be used for the privileged user \"admin\" in ntop's web interface." msgstr "Ange ett lösenord som ska användas av den priviligerade användaren \"admin\" i ntops webbgränssnitt." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Upprepa lösenordet:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "Please enter the same password again to verify that you have typed it correctly." msgstr "Upprepa samma lösenord en gång till för att säkerställa att du skrev in det korrekt." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Tomt lösenord" #. Type: error #. Description #: ../ntop.templates:5001 msgid "You entered an empty password, which is not allowed. Please choose a non-empty password." msgstr "Du angav ett tomt lösenord, detta är inte tillåtet. Välj ett lösenord som inte är tomt." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Fel vid inmatning av lösenord" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "De båda lösenorden du angav stämmer inte överrens. Försök igen." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Ange ett nytt administrationslösenord?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "A password for ntop's administrative web interface has already been set." msgstr "Ett lösenord för ntops administrativa webbgränssnitt har redan satts." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Ange om du vill byta ut det lösenordet." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Den valda användaren kommer att skapas om den inte redan finns. Välj inte " #~ "root, det är inte rekommenderat och kommer att kunna användas." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Om du väljer en blank stäng kommer ingen användare att skapas på ditt " #~ "system och du måste göra den konfigurationen själv." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Vad är namnet på den användare som ntop-daemonen ska köras som?" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/fr.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011672�12631352100�010555� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Translation of ntop debconf template to French. # Copyright (C) 2011 Debian French l10n team <debian-l10n-french@lists.debian.org> # This file is distributed under the same license as the ntop package. # Translators: # Sylvain Archenault <sylvain.archenault@laposte.net>, 2010. # Steve R. Petruzzello <dlist@bluewin.ch>, 2011. # <bluestax@bluewin.ch>, 2011. msgid "" msgstr "" "Project-Id-Version: ntop 2:3.2rc1-1\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-28 21:36+0100\n" "Last-Translator: Steve R. Petruzzello <dlist@bluewin.ch>\n" "Language-Team: French <debian-l10n-french@lists.debian.org>\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Identifiant pour l'exécution de ntop :" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Veuillez choisir l'identifiant utilisé pour exécuter ntop. L'utilisation du " "superutilisateur (« root ») n'est pas autorisée." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "L'identifiant sera créé s'il n'existe pas, mais si vous laissez ce champ " "vide, aucun identifiant ne sera créé et ntop ne pourra pas être exécuté tant " "que vous n'en aurez pas créé un vous-même." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces sur lesquelles ntop sera à l'écoute :" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Veuillez indiquer, séparées par des virgules, la liste des interfaces sur " "lesquelles ntop doit être à l'écoute." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Mot de passe de l'administrateur :" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Veuillez choisir un mot de passe pour l'identifiant « admin » pour " "l'interface web de ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Confirmation du mot de passe :" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "Veuillez entrer le même mot de passe pour vérification." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Mot de passe vide" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Vous avez entré un mot de passe vide, ce qui n'est pas autorisé. Veuillez " "choisir un mot de passe non vide." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Erreur de saisie du mot de passe" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Les deux mots de passe que vous avez entrés sont différents. Veuillez " "recommencer." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Faut-il créer un nouveau mot de passe pour l'administrateur ?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "Un mot de passe pour l'interface web de ntop a déjà été créé." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Vous pouvez choisir de changer ce mot de passe." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "L'identifiant indiqué sera créé s'il n'existe pas. Vous ne devez pas " #~ "choisir le superutilisateur (« root »)." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Si vous laissez ce champ vide, aucun utilisateur ne sera créé sur le " #~ "système et vous devrez faire cette configuration vous-même." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Identifiant utilisé par le démon ntop:" ����������������������������������������������������������������������debian/po/cs.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011124�12631352100�010543� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Czech translation of ntop debconf messages. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the ntop package. # Miroslav Kure <kurem@debian.cz>, 2008, 2011 # msgid "" msgstr "" "Project-Id-Version: ntop\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-02-09 18:38+0100\n" "Last-Translator: Miroslav Kure <kurem@debian.cz>\n" "Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Uživatel, pod kterým má ntop běžet:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Vyberte přihlášení, pod kterým se má ntop spouštět. Není možné použít " "uživatele root." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Pokud zadaný uživatel ještě neexistuje, bude vytvořen. Jestliže ponecháte " "prázdné, uživatel se nevytvoří a než ho nastavíte, odmítne ntop pracovat." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Rozhraní, na kterých má ntop poslouchat:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Zadejte prosím mezerami oddělený seznam rozhraní, na kterých má ntop " "naslouchat." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Správcovské heslo:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Zvolte si heslo, které bude používat uživatel „admin“ ve webovém rozhraní " "ntopu." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Znovu zadejte heslo pro ověření:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Pro ověření, že jste heslo napsali správně, ho prosím zadejte ještě jednou." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Prázdné heslo" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Zadali jste prázdné heslo, což není povoleno. Zadejte prosím neprázdné " "heslo." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Chyba zadávání hesla" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Zadaná hesla nesouhlasí. Zkuste to prosím znovu." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Nastavit nové správcovské heslo?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Heslo pro správcovský přístup na webové rozhraní ntopu již bylo nastaveno." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Rozhodněte se, zda toto heslo chcete změnit." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Pokud zadaný uživatel neexistuje, bude vytvořen. Nezadávejte uživatele " #~ "root, protože to není dobrý nápad, který stejně bude ignorován." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Ponecháte-li prázdné, žádný uživatel se v systému nevytvoří a budete " #~ "muset tuto část nastavení provést sami." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Pod kterým uživatelem se má daemon ntop spouštět?" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/pt.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011413�12631352101�010563� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Portuguese translation of ntop's debconf messages. # Copyright (C) 2007 # This file is distributed under the same license as the ntop package. # Ricardo Silva <ardoric@gmail.com>, 2007. # msgid "" msgstr "" "Project-Id-Version: ntop 3:3.2-10\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2007-03-13 23:06+0000\n" "Last-Translator: Ricardo Silva <ardoric@gmail.com>\n" "Language-Team: Portuguese <traduz@debianpt.org>\n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Utilizador a utilizar para correr o processo ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Por favor escolha o utilizador que deve ser usado para executar o processo ntop. " "No permitido a escolha do utilizador root." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "A conta ser criada se ainda no existir, mas se deixar a opo em branco, " "no ser criado nenhum utilizador e o ntop no ser executado at que seja " "configurado manualmente." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces em que o ntop deve escutar:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Por favor introduza uma lista de interfaces separadas por vrgulas onde o " "ntop deva escutar." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Palavra-passe de administrador:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Por favor escolha a palavra passe a ser usada pelo utilizador privilegiado " "\"admin\" na interface web do ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Volte a introduzir a palavra passe para verificao:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Por favor volte a introduzir a mesma palavra passe de forma a verificarmos " "que a escreveu corretamente." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Palavra passe vazia" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Introduziu uma palavra passe vazia, o que no permitido. Por favor escolha " "uma palavra passe no vazia." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Erro na introduo da palavra passe" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "As duas palavras passe que introduziu no so iguais. Por favor tente de novo." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Definir uma nova palavra passe de administrador?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "J foi definida uma palavra passe para a interface web administrativa do ntop." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Por favor escolha se quer alterar essa palavra passe." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "O utilizador seleccionado ser criado se ainda no existir. No escolha " #~ "root, no recomendado e ser descartado de qualquer das formas." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Se introduzir uma string vazia no ser criado nenhum utilizador no " #~ "sistema e precisar de fazer essa configurao voc mesmo." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Qual o nome do utilizador com que correr o daemon ntop ?" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/es.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000013073�12631352100�010552� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ntop translation to spanish # Copyright (C) 2004 Software in the Public Interest # This file is distributed under the same license as the ntop package. # # Changes: # - Initial translation # Rudy Godoy <rudy@kernel-panik.org>, 2006 # Ricardo Fraile <rikr@esdebian.org>, 2011 # # # Traductores, si no conoce el formato PO, merece la pena leer la # documentación de gettext, especialmente las secciones dedicadas a este # formato, por ejemplo ejecutando: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Equipo de traducción al español, por favor lean antes de traducir # los siguientes documentos: # # - El proyecto de traducción de Debian al español # http://www.debian.org/intl/spanish/coordinacion # especialmente las notas de traducción en # http://www.debian.org/intl/spanish/notas # # - La guía de traducción de po's de debconf: # /usr/share/doc/po-debconf/README-trans # o http://www.debian.org/intl/l10n/po-debconf/README-trans # # msgid "" msgstr "" "Project-Id-Version: ntop 3.2\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-02-01 09:35+0100\n" "Last-Translator: Rudy Godoy <rudy@kernel-panik.org>\n" "Language-Team: Debian l10n Spanish Team <debian-l10n-spanish@lists.debian>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Usuario con el que se ejecutará ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Por favor, escoja el usuario con el que se ejecutará el proceso de ntop. " "Elusuario «root» no está permitido." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "La cuenta se creará si no existe, pero si la deja en blanco,no se crear" " ninguna cuenta y ntop no se ejecutará hasta que no seconfigure " "manualmente." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces en las que escuchará ntop:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Por favor introduzca la lista de las interfaces, separada por comas, en las " "que debe escuchar ntop." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Contraseña del administrador:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Por favor, escoja una contraseña para el usuario privilegiado «admin» en " "la intefaz web de ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Vuelva a introducir la contraseña para comprobarla:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Por favor, introduzca la misma contraseña nuevamente para comprobar que la " "ha introducido correctamente." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Contraseña vacía" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Ha introducido una contraseña vacía y no está permitido. Por favor, " "escojauna contraseña con contenido." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Error en la introducción de la contraseña" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Las dos contraseñas introducidas no son las mismas. Por favor, inténtelo " "de nuevo." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "¿Desea establecer una nueva contraseña para el administrador?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "La contraseña para la interfaz administrativa de ntop se ha definido." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Por favor, escoja si quiere cambiar la contraseña." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Se creará el usuario si no existe. No introduzca root, no se aconseja, " #~ "y si lo hace se descartará en cualquier caso." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "No se creará ningún usuario en el sistema si no introduce nada aquí, " #~ "por lo que usted tendrá que hacer la configuración necesaria." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "¿Cuál es el usuario que debe ejecutar el demonio ntop?" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/ja.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000010311�12631352100�010525� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Japanese debconf templates translation for ntop. # Copyright (C) 2007 Noritada Kobayashi # This file is distributed under the same license as the ntop package. # msgid "" msgstr "" "Project-Id-Version: ntop (debconf) 3:4.99.3\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-26 17:15+0900\n" "Last-Translator: Noritada Kobayashi <nori1@dolphin.c.u-tokyo.ac.jp>\n" "Language-Team: Japanese <debian-japanese@lists.debian.org>\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "ntop プロセスの実行ユーザ:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "ntop プロセスを実行するログイン名を選択してください。root ユーザの使用は許可さ" "れません。" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "指定のアカウントが存在しない場合は作成されます。空白にした場合は作成されず、手" "作業で設定するまで ntop は実行されません。" #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "ntop が待ち受けるインターフェース:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "ntop が待ち受けるインターフェース一覧をコンマで区切って入力してください。" #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "管理者パスワード:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "ntop のウェブインターフェイスについて権限のあるユーザ「admin」用のパスワードを" "選択してください。" #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "検証用にパスワードを再入力してください:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "正しく打ち込まれていることを検証するため、同一のパスワードを再び入力してくださ" "い。" #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "パスワードが空白です" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "入力されたパスワードが空白ですがこれは許可されません。空白でないパスワードを選" "択してください。" #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "パスワード入力エラー" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "入力された二つのパスワードが同一ではありません。やり直してください。" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "新しい管理者パスワードを設定しますか?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "ntop 管理用ウェブインターフェイスのパスワードは既に設定されています。" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "そのパスワードを変更するかどうか選択してください。" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/POTFILES.in�������������������������������������������������������������������������������0000664�0000000�0000000�00000000051�12631352100�011350� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[type: gettext/rfc822deb] ntop.templates ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/templates.pot�����������������������������������������������������������������������������0000664�0000000�0000000�00000005472�12631352100�012331� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/de.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011637�12631352100�010537� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Translation of ntop debconf templates to German # Copyright (C) Helge Kreutzmann <debian@helgefjell.de>, 2006, 2011. # This file is distributed under the same license as the ntop package. msgid "" msgstr "" "Project-Id-Version: ntop 3_4.0.3+dfsg1-\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-02-04 11:59+0100\n" "Last-Translator: Helge Kreutzmann <debian@helgefjell.de>\n" "Language-Team: de <debian-l10n-german@lists.debian.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Benutzer, unter dem der Ntop-Prozess laufen soll:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Bitte whlen Sie das Benutzerkonto aus, die zur Ausfhrung des Ntop-Prozesses " "verwandt werden soll. Die Verwendung des Benutzers root ist nicht erlaubt." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Falls das Konto noch nicht existiert, wird es erstellt. Falls Sie das Feld " "leer lassen, wird kein Benutzerkonto erstellt und Ntop wird erst laufen, wenn " "Sie es manuell konfiguriert haben." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Schnittstellen, auf denen Ntop auf Anfragen warten soll:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Bitte geben Sie eine durch Kommata getrennte Liste von Schnittstellen an, auf " "denen Ntop auf Anfragen warten soll." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Passwort des Administrators:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Bitte whlen Sie ein Passwort aus, das fr den privilegierten Benutzer " "admin in der Webschnittstelle von Ntop verwandt wird." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Wiederholung der Passworteingabe zur berprfung:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Bitte geben Sie das gleiche Passwort erneut ein, um zu berprfen, dass Sie " "es korrekt eingegeben haben." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Leeres Passwort" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Sie haben ein leeres Passwort eingegeben. Das ist nicht erlaubt. Bitte whlen " "sie ein nichtleeres Passwort." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Passworteingabefehler" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Die zwei eingegebenen Passwrter waren nicht identisch. Bitte versuchen Sie " "es erneut." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Neues administratives Passwort setzen?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Fr Ntops administrative Webschnittstelle wurde bereits ein Passwort gesetzt." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Bitte whlen Sie aus, ob Sie dieses Passwort ndern mchten." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Der ausgewhlte Benutzer wird erstellt, falls er noch nicht verfgbar " #~ "ist. Whlen Sie nicht root, es ist nicht empfohlen und wird sowieso " #~ "verworfen." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Falls Sie eine leere Zeichenkette auswhlen, wird kein Benutzer im System " #~ "erstellt und Sie werden das selber konfigurieren mssen." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "" #~ "Wie lautet der Name des Benutzers, unter dem der ntop-Daemon laufen soll?" �������������������������������������������������������������������������������������������������debian/po/sk.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000007767�12631352100�010575� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Slovak translations for ntop package # Slovenské preklady pre balík ntop. # Copyright (C) 2011 THE ntop'S COPYRIGHT HOLDER # This file is distributed under the same license as the ntop package. # Automatically generated, 2011. # Slavko <linux@slavino.sk>, 2011. # msgid "" msgstr "" "Project-Id-Version: ntop 4.0.3+dfsg1-3\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-04-10 12:19+0200\n" "Last-Translator: Slavko <linux@slavino.sk>\n" "Language-Team: Slovak <nomail>\n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Používateľ, pod ktorým bude ntop spúšťaný:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Prosím vyberte používateľa, ktorý má byť použitý na spúšťanie procesu ntop. " "Používateľ „root” nie je dovolený." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Ak zadaný používateľ neexistuje, bude mu vytvorený účet, ak ale necháte pole " "prázdne, nebude vytvorený žiadny účet a ntop sa nespustí, kým nebude " "manuálne nastavený." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Rozhrania, na ktorý má ntop počúvať:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Prosím zadajte čiarkou oddelený zoznam rozhraní, na ktorých má ntop počúvať." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Heslo administrátora:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Prosím zadajte heslo, ktoré bude používať určený administrátor vo webovom " "rozhraní ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Zopakujte heslo, na overenie:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Prosím zadajte znova rovnaké heslo, na overenie, že ste ho napísali správne." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Prázdne heslo" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Zvolili ste si prázdne heslo, čo nie je dovolené. Prosím zvoľte neprázdne " "heslo." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Chyba zadávania hesla" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Zadané heslá sa nezhodujú. Prosím skúste znova." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Nastaviť nové heslo administrátora?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "Heslo administračného webového rozhrania ntop už je nastavené." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Prosím vyberte si, či chcete heslo zmeniť." ���������debian/po/pt_BR.po����������������������������������������������������������������������������������0000664�0000000�0000000�00000011624�12631352100�011151� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ntop Brazilian Portuguese translation # Copyright (C) 2007 THE ntop'S COPYRIGHT HOLDER # This file is distributed under the same license as the ntop package. # # Jose Figueiredo <deb.gnulinux@gmail.com>, 2007. # Felipe Augusto van de Wiel (faw) <faw@debian.org>, 2008. # Eder L. Marques <eder@edermarques.net>, 2011. msgid "" msgstr "" "Project-Id-Version: ntop 3:3.2-10.1\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-05-21 21:02-0300\n" "Last-Translator: Eder L. Marques <eder@edermarques.net>\n" "Language-Team: Brazilian Portuguese <debian-l10n-portuguese@lists.debian." "org>\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Usuário com o qual o processo ntop deve ser executado:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Por favor, escolha o login que deve ser usado para executar o processo ntop. " "O uso do usuário \"root\" não é permitido." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "A conta será criada se ela ainda não existir, mas se você deixar esse campo " "em branco, nenhum login será criado e o ntop não executará até que seja " "configurado manualmente." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces que o ntop deve escutar:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Por favor, informe uma lista separada por vírgulas das interfaces que o ntop " "deve escutar." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Senha do administrador:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Por favor, escolha uma senha para ser usada pelo usuário privilegiado \"admin" "\" na interface web do ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Redigite a senha para verificação:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Por favor, digite a mesma senha novamente para que seja verificado que você " "a digitou corretamente." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Senha em branco" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Você deixou a senha em branco, o que não é permitido. Por favor, escolha uma " "senha que não seja em branco." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Erro de entrada de senha" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "As duas senhas que você digitou não coincidem. Por favor, tente novamente." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Configurar uma nova senha de administrador?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Uma senha para a interface web administrativa do ntop já foi configurada." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Por favor, escolha se você deseja alterar essa senha." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "O usuário escolhido será criado se não estiver disponível. Não escolha o " #~ "usuário root, isto não é recomendado e de qualquer forma será descartado." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Se você escolher uma string vazia, nenhum usuário será criado no sistema " #~ "e você mesmo precisará fazer esta configuração." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Qual é o nome do usuário que executará o daemon ntop?" ������������������������������������������������������������������������������������������������������������debian/po/ru.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000013351�12631352101�010571� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# translation of ru.po to Russian # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the ntop package. # # Yuri Kozlov <yuray@komyakino.ru>, 2009, 2011. msgid "" msgstr "" "Project-Id-Version: ntop 3:4.0.3+dfsg1-3\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-02-04 12:47+0300\n" "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n" "Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Пользователь, с правами будет работать процесс ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Введите имя учётной записи, которая должна использоваться для запуска " "процесса ntop. Пользователь root недопустим." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Если учётная запись не существует, то она будет создана, но если ничего не " "вводить, то учётная запись создана не будет и ntop не будет работать, пока " "вы не выполните настройку вручную." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Интерфейсы, которые будет прослушивать ntop:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Введите сетевые интерфейсы (через запятую), которые должен прослушивать ntop." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Пароль администратора:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Введите пароль привилегированного пользователя \"admin\", который будет " "использоваться в веб-интерфейсе ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Введите пароль ещё раз для проверки:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Введите тот же самый пароль ещё раз, чтобы убедиться в правильности ввода." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Пустой пароль" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "Был введён пустой пароль, что запрещено. Введите не пустой пароль." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Ошибка ввода пароля" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Два введённых пароля не совпали. Попробуйте ещё раз." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Установить новый пароль администратора?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "Пароль для веб-интерфейса управления ntop уже задан." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Укажите, хотите ли вы изменить этот пароль." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Указанный пользователь будет создан, если его нет в системе. Не " #~ "указывайте root, так как это не рекомендуется и всё равно не сработает." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Если вы оставите пустую строку, то никаких пользователей создано не будет " #~ "и вам придётся выполнить эту настройку вручную." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "С правами какого пользователя будет работать служба ntop?" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/nl.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000010066�12631352100�010553� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Dutch translation of ntop debconf templates. # Copyright (C) 2006-2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the ntop package. # Esther <ehanko@xs4all.nl>, 2006. # Jeroen Schot <schot@a-eskwadraat.nl>, 2011. # msgid "" msgstr "" "Project-Id-Version: ntop 3:4.1.0+dfsg1-1\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-11-25 16:15+0100\n" "Last-Translator: Jeroen Schot <schot@a-eskwadraat.nl>\n" "Language-Team: Debian l10n Dutch <debian-l10n-dutch@lists.debian.org>\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Het ntop-proces uitvoeren door gebruiker: " #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Geef de inlognaam op die moet worden gebruikt om het ntp-proces uit te " "voeren. Het is niet toegestaan om de beheerdersaccount 'root' te kiezen." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "De account zal worden aangemaakt als deze nog niet bestaat. U kunt dit veld " "ook leeg laten, in dat geval zal er geen account worden aangemaakt en zal " "ntop niet worden uitgevoerd totdat u deze handmatig heeft ingesteld." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfaces waarom ntop moet luisteren:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Voer een met komma's gescheiden lijst in van interfaces waarop ntop moet " "luisteren." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Beheerderswachtwoord:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Kies een wachtwoord voor de speciale gebruiker 'admin' op ntop's " "webinterface." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Voer het wachtwoord nogmaals in ter controle:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Voer hetzelfde wachtwoord nogmaals in om te controleren dat u het zonder " "fouten heeft getikt." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Leeg wachtwoord" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "U heeft een leeg wachtwoord ingevoerd, dit is niet toegestaan. Kies een niet-" "leeg wachtwoord." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Invoerfout bij wachtwoord" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "De twee wachtwoorden die u heeft ingevoerd verschillen. Probeer het nogmaals." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Nieuw beheerderswachtwoord instellen?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Er is al een wachtwoord ingesteld voor de beheerderswebinterface van ntop." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Geef aan of u dit wachwoord wilt wijzigen." ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/da.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000007766�12631352101�010544� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# danish translation ntop. # Copyright (C) 2011 ntop og nedenstående oversættere. # This file is distributed under the same license as the ntop package. # Joe Hansen (joedalton2@yahoo.dk), 2011. # msgid "" msgstr "" "Project-Id-Version: ntop\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-26 19:25+0200\n" "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n" "Language-Team: Danish <debian-l10n-danish@lists.debian.org>\n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Bruger som ntop-processen skal køre som:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Vælg venligst logindet som skal bruges til at køre ntop-processen. Brugen af " "administratorbrugeren (root) er ikke tilladt." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Kontoen vil blive oprettet, hvis den ikke allerede findes, men hvis du " "efterlader den tom, vil der ikke blive oprettet et logind og ntop vil ikke " "køre, før den er blevet manuelt konfigureret." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Grænseflader som ntop skal lytte på:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Indtast venligst en kommaadskilt liste af grænseflader som ntop skal lytte " "på." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Adgangskode for administrator:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Vælg venligst en adgangskode som skal bruges for den priviligerede bruger " "»admin« i ntops internetbrugerflade." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Genindtast adgangskoden for verificering:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Indtast venligst den samme adgangskode igen for at verificere at du har " "indtastet den korrekt." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Blank adgangskode" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "Du indtastede en blank adgangskode, hvilket ikke er tilladt. Vælg venligst " "en adgangskode som ikke er blank." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Inddatafejl for adgangskode" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "De to indtastede adgangskoder var ikke ens. Prøv igen." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Angiv en ny administratoradgangskode?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "En adgangskode for ntops administrative internetbrugerflade er allerede " "blevet angivet." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Vælg venligst hvorvidt du ønsker at ændre denne adgangskode." ����������debian/po/fi.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000007507�12631352100�010546� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Translation of the ntop debconf strings to Finnish # Copyright (C) 2010 # This file is distributed under the same license as the ntop package. # Esko Arajärvi <edu@iki.fi>, 2011. msgid "" msgstr "" "Project-Id-Version: ntop\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-02-22 21:48+0300\n" "Last-Translator: Esko Arajärvi <edu@iki.fi>\n" "Language-Team: debian-10n-finnish@lists.debian.org\n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Virtaal 0.6.1\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Käyttäjä, jolla ntop-prosessi ajetaan:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Valitse käyttäjätunnus, jota käytetään ajettaessa ntop-prosessia. " "Pääkäyttäjätunnusta ei hyväksytä." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "Käyttäjätunnus luodaan, jos sitä ei jo ole olemassa. Jos jätät kentän " "tyhjäksi, mitään tunnusta ei luoda, eikä ntopia ajeta ennen kuin sen " "asetukset tehdään käsin." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Liitännät, joita ntop kuuntelee:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Anna pilkuin eroteltu luettelo liitännöistä, joita ntopin tulisi kuunnella." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Ylläpitäjän salasana:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "Anna salasana ntopin verkkokäyttöliittymän ylläpitotunnukselle ”admin”." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Salasanan varmistus:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "Syötä salasana uudelleen varmistaaksesi, että kirjoitit sen oikein." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Tyhjä salasana" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "Annoit tyhjän salasana. Tämä ei ole sallittua. Valitse uusi salasana." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Salasanat eivät täsmää" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Annetut salasanat eivät täsmää. Yritä uudelleen." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Vaihdetaanko ylläpitäjän salasana?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Ohjelman ntop verkkokäyttöliittymän ylläpitäjän salasana on jo asetettu." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Valitse haluatko vaihtaa salasanan." �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/po/it.po�������������������������������������������������������������������������������������0000664�0000000�0000000�00000011507�12631352100�010557� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Italian (it) translation of debconf templates for ntop # Copyright (C) 2006 Free Software Foundation, Inc. # This file is distributed under the same license as the ntop package. # Luca Monducci <luca.mo@tiscali.it>, 2006. # Ludovico Cavedon <cavedon@debian.org>, 2011. # msgid "" msgstr "" "Project-Id-Version: ntop italian debconf templates\n" "Report-Msgid-Bugs-To: ntop@packages.debian.org\n" "POT-Creation-Date: 2011-01-26 00:15-0800\n" "PO-Revision-Date: 2011-01-26 00:16-0800\n" "Last-Translator: Ludovico Cavedon <cavedon@debian.org>\n" "Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #. Type: string #. Description #: ../ntop.templates:1001 msgid "User for the ntop process to run as:" msgstr "Utente sotto il quale eseguire il processo ntop:" #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "Please choose the login that should be used to execute the ntop process. The " "use of the root user is not allowed." msgstr "" "Scegliere l'utente da user per eseguire il processo ntop. Non è possibile " "usare l'utente root." #. Type: string #. Description #: ../ntop.templates:1001 msgid "" "The account will be created if it does not already exist, but if you leave " "it blank, no login will be created and ntop will not run until manually " "configured." msgstr "" "L'account sarà creato nel caso non esista già, ma se lo si lascia in bianco, " "nessun account verrà creato e ntop non potrà essere avviato fino a quando " "non sarà configurato manualmente." #. Type: string #. Description #: ../ntop.templates:2001 msgid "Interfaces for ntop to listen on:" msgstr "Interfacce su cui ntop deve mettersi in ascolto:" #. Type: string #. Description #: ../ntop.templates:2001 msgid "" "Please enter a comma-separated list of interfaces that ntop should listen on." msgstr "" "Inserire l'elenco delle interfacce, separate con una virgola, su cui ntop " "deve stare in ascolto." #. Type: password #. Description #: ../ntop.templates:3001 msgid "Administrator password:" msgstr "Password di amministratore:" #. Type: password #. Description #: ../ntop.templates:3001 msgid "" "Please choose a password to be used for the privileged user \"admin\" in " "ntop's web interface." msgstr "" "Scegliere una password da usare per l'utente privilegiato \"admin\" " "dell'interfaccia web di ntop." #. Type: password #. Description #: ../ntop.templates:4001 msgid "Re-enter password to verify:" msgstr "Reinserire la password per verifica:" #. Type: password #. Description #: ../ntop.templates:4001 msgid "" "Please enter the same password again to verify that you have typed it " "correctly." msgstr "" "Inserire di nuovo la stessa password per verificare che sia stata digitata " "correttamente." #. Type: error #. Description #: ../ntop.templates:5001 msgid "Empty password" msgstr "Password vuota" #. Type: error #. Description #: ../ntop.templates:5001 msgid "" "You entered an empty password, which is not allowed. Please choose a non-" "empty password." msgstr "" "È stata inserita una password vuota, che non è permessa. Per favore " "scegliere una password non vuota." #. Type: error #. Description #: ../ntop.templates:6001 msgid "Password input error" msgstr "Errore nell'inserimento della password" #. Type: error #. Description #: ../ntop.templates:6001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Le due password inserite non sono uguali. Per favore riprovare." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Set a new administrator password?" msgstr "Impostare a nuova password di amministratore?" #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "" "A password for ntop's administrative web interface has already been set." msgstr "" "Una password di amministratore per l'interfaccia web di ntop è già stata " "impostata." #. Type: boolean #. Description #: ../ntop.templates:7001 msgid "Please choose whether you want to change that password." msgstr "Scegliere se si vuole cambiare tale password." #~ msgid "" #~ "The selected user will be created if not already available. Don't choose " #~ "root, it is not recommended and will be discarded anyway." #~ msgstr "" #~ "Se l'utente scelto non esiste viene creato. Non scegliere root, non solo " #~ "non consigliato ma viene comunque rifiutato." #~ msgid "" #~ "If you select an empty string no user will be created on the system and " #~ "you will need to do that configuration yourself." #~ msgstr "" #~ "Se si lascia in bianco il nome, non verr creato nessun utente ma questa " #~ "configurazione dovr poi essere fatta manualmente." #~ msgid "Which is the name of the user to run the ntop daemon as ?" #~ msgstr "Nome dell'utente con cui eseguire ntop in modalit demone" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.manpages��������������������������������������������������������������������������������0000664�0000000�0000000�00000000007�12631352100�011653� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ntop.8 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/get-orig-source.sh���������������������������������������������������������������������������0000664�0000000�0000000�00000003654�12631352100�012540� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh set -e DEB_UPSTREAM_VERSION=$1 DEB_SOURCE_VERSION=$2 NDPI_REV=$3 UPSTREAM_DIR=$(echo -n $DEB_UPSTREAM_VERSION | sed -e 's/+rc[0-9]*//') curdir=$(dirname $0) if [ ! -f ../ntop_$DEB_SOURCE_VERSION.orig.tar.gz ]; then if [ ! -f ntop_$DEB_UPSTREAM_VERSION.orig.tar.gz ]; then uscan --noconf --force-download --rename --download-current-version --destdir=. fi rm -rf ntop-$DEB_UPSTREAM_VERSION rm -rf ntop-$UPSTREAM_DIR rm -rf ntop-$DEB_SOURCE_VERSION tar zxf ntop_$DEB_UPSTREAM_VERSION.orig.tar.gz rm ntop_$DEB_UPSTREAM_VERSION.orig.tar.gz # remove files not DFSG-compliant rm ntop-$UPSTREAM_DIR/ntop_darwin.* rm ntop-$UPSTREAM_DIR/ntop_win32.* rm ntop-$UPSTREAM_DIR/packages/Win32/ntop-VC6-project.zip # remove binary-onyl files from MaxMind rm ntop-$UPSTREAM_DIR/3rd_party/Geo*.dat.gz # replace non-DFSG countmin with the GPL one rm ntop-$UPSTREAM_DIR/countmin.[ch] rm ntop-$UPSTREAM_DIR/prng.[ch] cp $curdir/countmin.[ch] ntop-$UPSTREAM_DIR/ cp $curdir/prng.[ch] ntop-$UPSTREAM_DIR/ # remove non-DFSG-compliant part of ntop.h ed ntop-$UPSTREAM_DIR/ntop.h > /dev/null <<EOF /Declaration of POSIX directory browsing functions and types for Win32. ?/\* \** \*/?,/\/\* \** \*\//d wq EOF # remove old and incorrect license statement from protocols.c ed ntop-$UPSTREAM_DIR/protocols.c > /dev/null <<EOF /The Regents of the University of California. All rights reserved. ?/\*?,/\*\//d wq EOF mv ntop-$UPSTREAM_DIR ntop-$DEB_SOURCE_VERSION if [ -n "$NDPI_REV" ]; then cd ntop-$DEB_SOURCE_VERSION rm -fr nDPI svn export -r $NDPI_REV https://svn.ntop.org/svn/ntop/trunk/nDPI/ cd .. fi GZIP=--best tar -cz --owner root --group root --mode a+rX \ -f ntop_$DEB_SOURCE_VERSION.orig.tar.gz ntop-$DEB_SOURCE_VERSION mv ntop_$DEB_SOURCE_VERSION.orig.tar.gz .. rm -fr ntop-$DEB_SOURCE_VERSION fi ������������������������������������������������������������������������������������debian/ntop.prerm�����������������������������������������������������������������������������������0000664�0000000�0000000�00000000036�12631352100�011207� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh set -e #DEBHELPER# ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/source/��������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�12631352110�010462� 5����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/source/format��������������������������������������������������������������������������������0000664�0000000�0000000�00000000014�12631352101�011670� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3.0 (quilt) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.postrm����������������������������������������������������������������������������������0000664�0000000�0000000�00000000536�12631352100�011413� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh set -e if [ "$1" = "purge" ] ; then # source debconf library if [ -f /usr/share/debconf/confmodule ] ; then . /usr/share/debconf/confmodule db_purge fi # remove stored data if [ -d /var/lib/ntop ] ; then rm -rf /var/lib/ntop; fi if [ -d /var/log/ntop ] ; then rm -rf /var/log/ntop; fi fi #DEBHELPER# ������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/NEWS�����������������������������������������������������������������������������������������0000664�0000000�0000000�00000002232�12631352100�007657� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ntop (3:5.0.1+dfsg1-1) unstable; urgency=low Ntop 5.0.1 is the last released version of ntop and it is no longer supported by upstream, who moved development to ntopng [1]. Therefore this will be the last upload of the ntop deb package (except for minor bug fixes), and it will be removed once ntopng is ready to replace it. [1] http://bugs.debian.org/714820 -- Ludovico Cavedon <cavedon@debian.org> Thu, 12 Sep 2013 10:24:45 +0200 ntop (3:4.99.3+ndpi5517+dfsg1-1) unstable; urgency=low Upstream replaced the graph library with a DFSG compatible one. Therefore this version re-gained graphs support and no longer suggests ntop-graphs (which was never created anyway). -- Ludovico Cavedon <cavedon@debian.org> Tue, 26 Jun 2012 23:36:15 -0700 ntop (3:4.99.0-rc+ndpi5237+dfsg1-1) unstable; urgency=low Graphs have been removed from this Debian package of ntop because the library used to genierate them is not DFSG compatible. Such library, released under the Creative Commons Non-Commercial License, will be packaged under ntop-graphs package in the non-free section. -- Ludovico Cavedon <cavedon@debian.org> Sun, 18 Mar 2012 18:56:20 -0700 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop-data.links������������������������������������������������������������������������������0000664�0000000�0000000�00000000471�12631352100�012114� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/share/javascript/jquery-ui/css/smoothness/jquery-ui-1.10.1.custom.css usr/share/ntop/html/jquery-ui-1.8.16.custom.css usr/share/javascript/jquery-ui/ui/jquery-ui.custom.min.js usr/share/ntop/html/jquery-ui-1.8.16.custom.min.js usr/share/javascript/jquery/jquery.min.js usr/share/ntop/html/jquery-1.7.2.min.js �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.dirs������������������������������������������������������������������������������������0000664�0000000�0000000�00000000032�12631352100�011017� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������var/lib/ntop var/log/ntop ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debian/ntop.postinst��������������������������������������������������������������������������������0000664�0000000�0000000�00000005647�12631352100�011762� 0����������������������������������������������������������������������������������������������������ustar ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # Copyright 2001,2002 by Dennis Schoen <ds@teuto.net> # # This program 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., 59 Temple Place, Suite 330, Boston, # MA 02111-1307 USA. set -e # Source debconf library . /usr/share/debconf/confmodule # Get ntop user db_get ntop/user USER=$RET INITCFG=/var/lib/ntop/init.cfg db_get ntop/interfaces INTERFACES=$RET logdir=/var/log/ntop libdir=/var/lib/ntop # Create the log dir if ! [ -d "$logdir" ]; then mkdir -p "$logdir" fi # avoid logrotate errors if the ntop package is removed without even starting # ntop (see bug #602890) touch $logdir/access.log chown -f root:root "$libdir" chown -f root:root "$libdir"/*.db || true chown -f root:root "$libdir"/*.cfg || true chmod 770 "$libdir" chgrp -Rf adm "$logdir" chmod 2750 "$logdir" if [ -n "$USER" ] ; then # Creating ntop group if he isn't already there if ! grep -q ^"$USER": /etc/passwd; then echo Adding system user: "$USER". adduser --system --group --home /var/lib/ntop --no-create-home --quiet "$USER" fi if ! grep -q ^"$USER": /etc/group; then # some older versions of the ntop package did not create the ntop group echo Adding system group: "$USER". addgroup --system "$USER" usermod -g "$USER" "$USER" fi # make status dir owned by user if grep -q ^"$USER": /etc/passwd; then # $libdir contains the init.cfg and password file, should not be writable by the ntop user, # but we need the ntop user to be able to create directories inside there chown -f root:$USER "$libdir" # set sticky bit (rwxrwx--T) so only root can remove/rename the init.cfg file chmod -f +t "$libdir" chown -Rf "$USER" "$logdir" fi fi echo USER=\"$USER\" > "$INITCFG" echo INTERFACES=\"$INTERFACES\" >> "$INITCFG" db_get ntop/admin_password if [ -n "$RET" ]; then adminpass="$RET" db_set ntop/admin_password "" db_set ntop/admin_password_again "" db_fset ntop/admin_password seen false db_fset ntop/admin_password_again seen false db_reset ntop/password_reset db_fset ntop/password_reset seen false rm -f /var/lib/ntop/ntop_pw.db ntop --set-admin-password="$adminpass" elif ! [ -f /var/lib/ntop/ntop_pw.db ]; then adminpass=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | md5sum | cut -c 1-16) ntop --set-admin-password="$adminpass" fi db_stop #DEBHELPER# ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������