diff options
Diffstat (limited to 'gnu/packages/patches')
30 files changed, 2531 insertions, 36 deletions
diff --git a/gnu/packages/patches/a2ps-CVE-2001-1593.patch b/gnu/packages/patches/a2ps-CVE-2001-1593.patch new file mode 100644 index 0000000000..17b7e7d932 --- /dev/null +++ b/gnu/packages/patches/a2ps-CVE-2001-1593.patch @@ -0,0 +1,69 @@ +Index: b/lib/routines.c +=================================================================== +--- a/lib/routines.c ++++ b/lib/routines.c +@@ -242,3 +242,50 @@ + /* Don't complain if you can't unlink. Who cares of a tmp file? */ + unlink (filename); + } ++ ++/* ++ * Securely generate a temp file, and make sure it gets ++ * deleted upon exit. ++ */ ++static char ** tempfiles; ++static unsigned ntempfiles; ++ ++static void ++cleanup_tempfiles() ++{ ++ while (ntempfiles--) ++ unlink(tempfiles[ntempfiles]); ++} ++ ++char * ++safe_tempnam(const char *pfx) ++{ ++ char *dirname, *filename; ++ int fd; ++ ++ if (!(dirname = getenv("TMPDIR"))) ++ dirname = "/tmp"; ++ ++ tempfiles = (char **) realloc(tempfiles, ++ (ntempfiles+1) * sizeof(char *)); ++ if (tempfiles == NULL) ++ return NULL; ++ ++ filename = malloc(strlen(dirname) + strlen(pfx) + sizeof("/XXXXXX")); ++ if (!filename) ++ return NULL; ++ ++ sprintf(filename, "%s/%sXXXXXX", dirname, pfx); ++ ++ if ((fd = mkstemp(filename)) < 0) { ++ free(filename); ++ return NULL; ++ } ++ close(fd); ++ ++ if (ntempfiles == 0) ++ atexit(cleanup_tempfiles); ++ tempfiles[ntempfiles++] = filename; ++ ++ return filename; ++} +Index: b/lib/routines.h +=================================================================== +--- a/lib/routines.h ++++ b/lib/routines.h +@@ -255,7 +255,8 @@ + /* If _STR_ is not defined, give it a tempname in _TMPDIR_ */ + #define tempname_ensure(Str) \ + do { \ +- (Str) = (Str) ? (Str) : tempnam (NULL, "a2_"); \ ++ (Str) = (Str) ? (Str) : safe_tempnam("a2_"); \ + } while (0) ++char * safe_tempnam(const char *); + + #endif diff --git a/gnu/packages/patches/a2ps-CVE-2014-0466.patch b/gnu/packages/patches/a2ps-CVE-2014-0466.patch new file mode 100644 index 0000000000..85199e35b0 --- /dev/null +++ b/gnu/packages/patches/a2ps-CVE-2014-0466.patch @@ -0,0 +1,30 @@ +Description: CVE-2014-0466: fixps does not invoke gs with -dSAFER + A malicious PostScript file could delete files with the privileges of + the invoking user. +Origin: vendor +Bug-Debian: http://bugs.debian.org/742902 +Author: Salvatore Bonaccorso <carnil@debian.org> +Last-Update: 2014-03-28 + +--- a/contrib/fixps.in ++++ b/contrib/fixps.in +@@ -389,7 +389,7 @@ + eval "$command" ;; + gs) + $verbose "$program: making a full rewrite of the file ($gs)." >&2 +- $gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=- -c save pop -f $file ;; ++ $gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=- -c save pop -f $file ;; + esac + ) + fi +--- a/contrib/fixps.m4 ++++ b/contrib/fixps.m4 +@@ -307,7 +307,7 @@ + eval "$command" ;; + gs) + $verbose "$program: making a full rewrite of the file ($gs)." >&2 +- $gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=- -c save pop -f $file ;; ++ $gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=- -c save pop -f $file ;; + esac + ) + fi diff --git a/gnu/packages/patches/antiword-CVE-2014-8123.patch b/gnu/packages/patches/antiword-CVE-2014-8123.patch new file mode 100644 index 0000000000..d8d346a634 --- /dev/null +++ b/gnu/packages/patches/antiword-CVE-2014-8123.patch @@ -0,0 +1,21 @@ +Description: Add check for buffer overflow with malformed input files + This was later re-found and became CVE-2014-8123. +Author: <eriks@debian.org> +Bug-Debian: http://bugs.debian.org/407015 +Bug-Debian: https://bugs.debian.org/771768 +Forwarded: http://seclists.org/oss-sec/2014/q4/870 +Last-Update: 2016-01-11 + +--- antiword-0.37~/wordole.c 2005-08-26 21:49:57.000000000 +0200 ++++ antiword-0.37/wordole.c 2009-06-03 22:31:15.948014682 +0200 +@@ -259,6 +259,10 @@ + } + tNameSize = (size_t)usGetWord(0x40, aucBytes); + tNameSize = (tNameSize + 1) / 2; ++ if ( tNameSize > sizeof(atPPSlist[iIndex].szName)) { ++ werr(0, "Name Size of PPS %d is too large", iIndex); ++ tNameSize = sizeof(atPPSlist[iIndex].szName); ++ } + vName2String(atPPSlist[iIndex].szName, aucBytes, tNameSize); + atPPSlist[iIndex].ucType = ucGetByte(0x42, aucBytes); + if (atPPSlist[iIndex].ucType == 5) { diff --git a/gnu/packages/patches/devil-CVE-2009-3994.patch b/gnu/packages/patches/devil-CVE-2009-3994.patch new file mode 100644 index 0000000000..e009a95c44 --- /dev/null +++ b/gnu/packages/patches/devil-CVE-2009-3994.patch @@ -0,0 +1,24 @@ +Fix CVE-2009-3994 (buffer overflow in GetUID() allows remote DOS or +arbitrary code execution via crafted DICOM file). + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3994 + +Copied from Fedora +https://pkgs.fedoraproject.org/cgit/rpms/DevIL.git/tree/DevIL-1.7.8-CVE-2009-3994.patch?id=9c656a75393d6c455aef9f4968fbbee9c53f4fdb + +diff -up devil-1.7.8/src-IL/src/il_dicom.c~ devil-1.7.8/src-IL/src/il_dicom.c +--- devil-1.7.8/src-IL/src/il_dicom.c~ 2009-03-08 08:10:09.000000000 +0100 ++++ devil-1.7.8/src-IL/src/il_dicom.c 2009-12-03 12:07:45.000000000 +0100 +@@ -427,9 +427,11 @@ ILboolean GetUID(ILubyte *UID) + return IL_FALSE; + + ValLen = GetLittleUShort(); ++ if (ValLen > 64) ++ return IL_FALSE; + if (iread(UID, ValLen, 1) != 1) + return IL_FALSE; +- UID[64] = 0; // Just to make sure that our string is terminated. ++ UID[ValLen] = 0; // Just to make sure that our string is terminated. + + return IL_TRUE; + } diff --git a/gnu/packages/patches/emacs-fix-scheme-indent-function.patch b/gnu/packages/patches/emacs-fix-scheme-indent-function.patch new file mode 100644 index 0000000000..c5a426802c --- /dev/null +++ b/gnu/packages/patches/emacs-fix-scheme-indent-function.patch @@ -0,0 +1,29 @@ +Fix 'scheme-indent-function' to indent s-expressions starting with a keyword +properly, like this: + +(#:foo 1 + #:bar 2) + +instead of like this: + +(#:foo 1 + #:bar 2) + +The fix is made by Mark H Weaver <mhw@netris.org>: +<http://www.netris.org/~mhw/scheme-indent-function.el> + +--- a/lisp/progmodes/scheme.el ++++ b/lisp/progmodes/scheme.el +@@ -482,6 +482,12 @@ + (> (length function) 3) + (string-match "\\`def" function))) + (lisp-indent-defform state indent-point)) ++ ((and (null method) ++ (> (length function) 1) ++ ;; The '#' in '#:' seems to get lost, not sure why ++ (string-match "\\`:" function)) ++ (let ((lisp-body-indent 1)) ++ (lisp-indent-defform state indent-point))) + ((integerp method) + (lisp-indent-specform method state + indent-point normal-indent)) diff --git a/gnu/packages/patches/gd-CVE-2016-3074.patch b/gnu/packages/patches/gd-CVE-2016-3074.patch deleted file mode 100644 index a90c51d77b..0000000000 --- a/gnu/packages/patches/gd-CVE-2016-3074.patch +++ /dev/null @@ -1,36 +0,0 @@ -Adapted from upstream commit 2bb97f407c1145c850416a3bfbcc8cf124e68a19 -(gd2: handle corrupt images better (CVE-2016-3074)). - -This patch omits the upstream changes to '.gitignore', and the test -added in files 'tests/Makefile.am', 'tests/gd2/gd2_read_corrupt.c', and -'tests/gd2/invalid_neg_size.gd2'. - -We omit the test because its input data, -'tests/gd2/invalid_neg_size.gd2', is provided as a binary Git diff, -which is not supported by `patch`. - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3074 -https://github.com/libgd/libgd/commit/2bb97f407c1145c850416a3bfbcc8cf124e68a19 ---- - .gitignore | 1 + - src/gd_gd2.c | 2 ++ - tests/Makefile.am | 3 ++- - tests/gd2/gd2_read_corrupt.c | 25 +++++++++++++++++++++++++ - tests/gd2/invalid_neg_size.gd2 | Bin 0 -> 1676 bytes - 5 files changed, 30 insertions(+), 1 deletion(-) - create mode 100644 tests/gd2/gd2_read_corrupt.c - create mode 100644 tests/gd2/invalid_neg_size.gd2 - -diff --git a/src/gd_gd2.c b/src/gd_gd2.c -index 6f28461..a50b33d 100644 ---- a/src/gd_gd2.c -+++ b/src/gd_gd2.c -@@ -165,6 +165,8 @@ _gd2GetHeader (gdIOCtxPtr in, int *sx, int *sy, - if (gdGetInt (&cidx[i].size, in) != 1) { - goto fail2; - }; -+ if (cidx[i].offset < 0 || cidx[i].size < 0) -+ goto fail2; - }; - *chunkIdx = cidx; - }; diff --git a/gnu/packages/patches/gegl-CVE-2012-4433.patch b/gnu/packages/patches/gegl-CVE-2012-4433.patch new file mode 100644 index 0000000000..7352b78dba --- /dev/null +++ b/gnu/packages/patches/gegl-CVE-2012-4433.patch @@ -0,0 +1,117 @@ +From: Michael Gilbert <mgilbert@debian.org> +Date: Mon, 9 Sep 2013 17:34:32 +0200 +Subject: Fix_CVE-2012-4433 + +Multiple buffer overflow issues. + +Closes: #692435 +--- + operations/external/ppm-load.c | 62 ++++++++++++++++++++++++++++++++++++------ + 1 file changed, 53 insertions(+), 9 deletions(-) + +diff --git a/operations/external/ppm-load.c b/operations/external/ppm-load.c +index efe6d56..465096d 100644 +--- a/operations/external/ppm-load.c ++++ b/operations/external/ppm-load.c +@@ -36,6 +36,7 @@ gegl_chant_file_path (path, _("File"), "", _("Path of file to load.")) + #include "gegl-chant.h" + #include <stdio.h> + #include <stdlib.h> ++#include <errno.h> + + typedef enum { + PIXMAP_ASCII = 51, +@@ -44,8 +45,8 @@ typedef enum { + + typedef struct { + map_type type; +- gint width; +- gint height; ++ glong width; ++ glong height; + gsize numsamples; /* width * height * channels */ + gsize bpc; /* bytes per channel */ + guchar *data; +@@ -82,12 +83,33 @@ ppm_load_read_header(FILE *fp, + } + + /* Get Width and Height */ +- img->width = strtol (header,&ptr,0); +- img->height = atoi (ptr); +- img->numsamples = img->width * img->height * CHANNEL_COUNT; ++ errno = 0; ++ img->width = strtol (header,&ptr,10); ++ if (errno) ++ { ++ g_warning ("Error reading width: %s", strerror(errno)); ++ return FALSE; ++ } ++ else if (img->width < 0) ++ { ++ g_warning ("Error: width is negative"); ++ return FALSE; ++ } ++ ++ img->height = strtol (ptr,&ptr,10); ++ if (errno) ++ { ++ g_warning ("Error reading height: %s", strerror(errno)); ++ return FALSE; ++ } ++ else if (img->width < 0) ++ { ++ g_warning ("Error: height is negative"); ++ return FALSE; ++ } + + fgets (header,MAX_CHARS_IN_ROW,fp); +- maxval = strtol (header,&ptr,0); ++ maxval = strtol (header,&ptr,10); + + if ((maxval != 255) && (maxval != 65535)) + { +@@ -109,6 +131,16 @@ ppm_load_read_header(FILE *fp, + g_warning ("%s: Programmer stupidity error", G_STRLOC); + } + ++ /* Later on, img->numsamples is multiplied with img->bpc to allocate ++ * memory. Ensure it doesn't overflow. */ ++ if (!img->width || !img->height || ++ G_MAXSIZE / img->width / img->height / CHANNEL_COUNT < img->bpc) ++ { ++ g_warning ("Illegal width/height: %ld/%ld", img->width, img->height); ++ return FALSE; ++ } ++ img->numsamples = img->width * img->height * CHANNEL_COUNT; ++ + return TRUE; + } + +@@ -229,12 +261,24 @@ process (GeglOperation *operation, + if (!ppm_load_read_header (fp, &img)) + goto out; + +- rect.height = img.height; +- rect.width = img.width; +- + /* Allocating Array Size */ ++ ++ /* Should use g_try_malloc(), but this causes crashes elsewhere because the ++ * error signalled by returning FALSE isn't properly acted upon. Therefore ++ * g_malloc() is used here which aborts if the requested memory size can't be ++ * allocated causing a controlled crash. */ + img.data = (guchar*) g_malloc (img.numsamples * img.bpc); + ++ /* No-op without g_try_malloc(), see above. */ ++ if (! img.data) ++ { ++ g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.numsamples * img.bpc)); ++ goto out; ++ } ++ ++ rect.height = img.height; ++ rect.width = img.width; ++ + switch (img.bpc) + { + case 1: diff --git a/gnu/packages/patches/icedtea-remove-overrides.patch b/gnu/packages/patches/icedtea-remove-overrides.patch new file mode 100644 index 0000000000..e4d68a9e58 --- /dev/null +++ b/gnu/packages/patches/icedtea-remove-overrides.patch @@ -0,0 +1,291 @@ +Upstream patch: +http://icedtea.classpath.org/hg/icedtea6/rev/60be25a84f2d + +Fixes build failure: +http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=2954 + +Changes to the files 'NEWS' and 'ChangeLog' are omitted here. + +# HG changeset patch +# User Andrew John Hughes <gnu.andrew@redhat.com> +# Date 1463144538 -3600 +# Node ID 60be25a84f2dd2bce8ff277cc3854cca1b3f7931 +# Parent c23ceebb80a19a33316f1e743eb93bdf79aac220 +PR2954: ecj/override.patch is missing new @Overrides in RMIJRMPServerImpl.java + +2016-05-13 Andrew John Hughes <gnu.andrew@redhat.com> + + PR2954: ecj/override.patch is missing new + @Overrides in RMIJRMPServerImpl.java + * patches/ecj/override.patch: + Add cases in RMIJRMPServerImpl and others + which show up when source/target 5 is + used in the rt-class-files pre-build. + * patches/openjdk/8014205-blank_swing_dialogs_windows.patch: + Remove addition of @Override. + +diff -r c23ceebb80a1 -r 60be25a84f2d patches/ecj/override.patch +--- a/patches/ecj/override.patch Sun May 08 21:28:21 2016 +0100 ++++ b/patches/ecj/override.patch Fri May 13 14:02:18 2016 +0100 +@@ -362,3 +362,240 @@ + public Class<?> run() { + try { + ReflectUtil.checkPackageAccess(className); ++diff -r 545db1dd8c2a src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java ++--- openjdk-ecj/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Thu May 12 01:30:54 2016 +0100 ++@@ -1870,7 +1870,6 @@ ++ ++ private ModifiableClassLoaderRepository getInstantiatorCLR() { ++ return AccessController.doPrivileged(new PrivilegedAction<ModifiableClassLoaderRepository>() { ++- @Override ++ public ModifiableClassLoaderRepository run() { ++ return instantiator != null ? instantiator.getClassLoaderRepository() : null; ++ } ++diff -r 545db1dd8c2a src/share/classes/com/sun/media/sound/Platform.java ++--- openjdk-ecj/jdk/src/share/classes/com/sun/media/sound/Platform.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/com/sun/media/sound/Platform.java Thu May 12 01:30:54 2016 +0100 ++@@ -160,7 +160,6 @@ ++ try { ++ // load the main library ++ AccessController.doPrivileged(new PrivilegedAction<Void>() { ++- @Override ++ public Void run() { ++ System.loadLibrary(libNameMain); ++ return null; ++@@ -182,7 +181,6 @@ ++ final String lib = st.nextToken(); ++ try { ++ AccessController.doPrivileged(new PrivilegedAction<Void>() { ++- @Override ++ public Void run() { ++ System.loadLibrary(lib); ++ return null; ++diff -r 545db1dd8c2a src/share/classes/java/awt/EventQueue.java ++--- openjdk-ecj/jdk/src/share/classes/java/awt/EventQueue.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/java/awt/EventQueue.java Thu May 12 01:30:54 2016 +0100 ++@@ -190,7 +190,6 @@ ++ EventQueue.invokeAndWait(source, r); ++ } ++ ++- @Override ++ public long getMostRecentEventTime(EventQueue eventQueue) { ++ return eventQueue.getMostRecentEventTimeImpl(); ++ } ++diff -r 545db1dd8c2a src/share/classes/java/io/ObjectInputStream.java ++--- openjdk-ecj/jdk/src/share/classes/java/io/ObjectInputStream.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/java/io/ObjectInputStream.java Thu May 12 01:30:54 2016 +0100 ++@@ -3571,7 +3571,6 @@ ++ } ++ static { ++ SharedSecrets.setJavaObjectInputStreamAccess(new JavaObjectInputStreamAccess() { ++- @Override ++ public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) { ++ ObjectInputStream.setValidator(ois, validator); ++ } ++diff -r 545db1dd8c2a src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java ++--- openjdk-ecj/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java Thu May 12 01:30:54 2016 +0100 ++@@ -64,7 +64,6 @@ ++ final String propName = "sun.rmi.server.invocationhandler.allowFinalizeInvocation"; ++ String allowProp = java.security.AccessController.doPrivileged( ++ new PrivilegedAction<String>() { ++- @Override ++ public String run() { ++ return System.getProperty(propName); ++ } ++diff -r 545db1dd8c2a src/share/classes/sun/awt/image/SunVolatileImage.java ++--- openjdk-ecj/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java Thu May 12 01:30:54 2016 +0100 ++@@ -262,7 +262,6 @@ ++ * ++ * @see sun.java2d.DestSurfaceProvider#getDestSurface ++ */ ++- @Override ++ public Surface getDestSurface() { ++ return volSurfaceManager.getPrimarySurfaceData(); ++ } ++diff -r 545db1dd8c2a src/share/classes/sun/java2d/SunGraphics2D.java ++--- openjdk-ecj/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Thu May 12 01:30:54 2016 +0100 ++@@ -3294,7 +3294,6 @@ ++ * ++ * @see sun.java2d.DestSurfaceProvider#getDestSurface ++ */ ++- @Override ++ public Surface getDestSurface() { ++ return surfaceData; ++ } ++diff -r 545db1dd8c2a src/share/classes/sun/rmi/server/UnicastServerRef.java ++--- openjdk-ecj/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java Thu May 12 01:30:54 2016 +0100 ++@@ -630,12 +630,10 @@ ++ this.callID = callID; ++ } ++ ++- @Override ++ public void validateDescriptor(ObjectStreamClass descriptor) { ++ descriptorCheck.check(method, descriptor, parameterIndex, callID); ++ } ++ ++- @Override ++ public void checkProxyInterfaceNames(String[] ifaces) { ++ descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID); ++ } ++diff -r 545db1dd8c2a src/share/classes/sun/rmi/transport/Transport.java ++--- openjdk-ecj/jdk/src/share/classes/sun/rmi/transport/Transport.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/sun/rmi/transport/Transport.java Thu May 12 01:30:54 2016 +0100 ++@@ -133,7 +133,6 @@ ++ */ ++ private static void setContextClassLoader(final ClassLoader ccl) { ++ AccessController.doPrivileged(new PrivilegedAction<Void> () { ++- @Override ++ public Void run() { ++ Thread.currentThread().setContextClassLoader(ccl); ++ return null; ++diff -r 545db1dd8c2a src/share/classes/sun/rmi/transport/tcp/TCPTransport.java ++--- openjdk-ecj/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Thu May 12 01:30:54 2016 +0100 ++@@ -676,7 +676,6 @@ ++ connectionCount.incrementAndGet() + ++ ")-" + remoteHost); ++ AccessController.doPrivileged(new PrivilegedAction<Void>() { ++- @Override ++ public Void run() { ++ run0(); ++ return null; ++diff -r 545db1dd8c2a src/solaris/classes/sun/java2d/opengl/GLXGraphicsConfig.java ++--- openjdk-ecj/jdk/src/solaris/classes/sun/java2d/opengl/GLXGraphicsConfig.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/solaris/classes/sun/java2d/opengl/GLXGraphicsConfig.java Thu May 12 01:30:54 2016 +0100 ++@@ -92,7 +92,6 @@ ++ return this; ++ } ++ ++- @Override ++ public SurfaceData createManagedSurface(int w, int h, int transparency) { ++ return GLXSurfaceData.createData(this, w, h, ++ getColorModel(transparency), ++@@ -165,12 +164,10 @@ ++ * Returns true if the provided capability bit is present for this config. ++ * See OGLContext.java for a list of supported capabilities. ++ */ ++- @Override ++ public final boolean isCapPresent(int cap) { ++ return ((oglCaps.getCaps() & cap) != 0); ++ } ++ ++- @Override ++ public final long getNativeConfigInfo() { ++ return pConfigInfo; ++ } ++@@ -180,7 +177,6 @@ ++ * ++ * @see sun.java2d.pipe.hw.BufferedContextProvider#getContext ++ */ ++- @Override ++ public final OGLContext getContext() { ++ return context; ++ } ++@@ -394,7 +390,6 @@ ++ * ++ * @see sun.java2d.pipe.hw.AccelGraphicsConfig#createCompatibleVolatileImage ++ */ ++- @Override ++ public VolatileImage ++ createCompatibleVolatileImage(int width, int height, ++ int transparency, int type) ++@@ -434,17 +429,14 @@ ++ * ++ * @see sun.java2d.pipe.hw.AccelGraphicsConfig#getContextCapabilities ++ */ ++- @Override ++ public ContextCapabilities getContextCapabilities() { ++ return oglCaps; ++ } ++ ++- @Override ++ public void addDeviceEventListener(AccelDeviceEventListener l) { ++ AccelDeviceEventNotifier.addListener(l, screen.getScreen()); ++ } ++ ++- @Override ++ public void removeDeviceEventListener(AccelDeviceEventListener l) { ++ AccelDeviceEventNotifier.removeListener(l); ++ } ++diff -r 545db1dd8c2a src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java ++--- openjdk-ecj/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed May 04 23:23:55 2016 +0100 +++++ openjdk-ecj/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Thu May 12 01:51:42 2016 +0100 ++@@ -236,7 +236,6 @@ ++ final MBeanInstantiator fInstantiator = instantiator; ++ this.secureClr = new ++ SecureClassLoaderRepository(AccessController.doPrivileged(new PrivilegedAction<ClassLoaderRepository>() { ++- @Override ++ public ClassLoaderRepository run() { ++ return fInstantiator.getClassLoaderRepository(); ++ } ++@@ -1257,7 +1256,6 @@ ++ ClassLoader myLoader = outerShell.getClass().getClassLoader(); ++ final ModifiableClassLoaderRepository loaders = AccessController.doPrivileged(new PrivilegedAction<ModifiableClassLoaderRepository>() { ++ ++- @Override ++ public ModifiableClassLoaderRepository run() { ++ return instantiator.getClassLoaderRepository(); ++ } ++diff -r b72e7b89dda9 src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java ++--- openjdk-ecj/jdk/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Thu Sep 08 11:00:33 2011 -0700 +++++ openjdk-ecj/jdk/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Thu May 12 16:39:37 2016 +0100 ++@@ -227,17 +227,14 @@ ++ allowedTypes = credentialsTypes; ++ } ++ ++- @Override ++ public String getVersion() throws RemoteException { ++ return impl.getVersion(); ++ } ++ ++- @Override ++ public RMIConnection newClient(Object credentials) throws IOException { ++ return impl.newClient(credentials); ++ } ++ ++- @Override ++ public void check(Method method, ObjectStreamClass descriptor, ++ int paramIndex, int callID) { ++ ++@@ -247,7 +244,6 @@ ++ } ++ } ++ ++- @Override ++ public void checkProxyClass(Method method, String[] ifaces, ++ int paramIndex, int callID) { ++ if (ifaces != null && ifaces.length > 0) { ++@@ -259,7 +255,6 @@ ++ } ++ } ++ ++- @Override ++ public void end(int callID) { ++ /* Do nothing */ ++ } +diff -r c23ceebb80a1 -r 60be25a84f2d patches/openjdk/8014205-blank_swing_dialogs_windows.patch +--- a/patches/openjdk/8014205-blank_swing_dialogs_windows.patch Sun May 08 21:28:21 2016 +0100 ++++ b/patches/openjdk/8014205-blank_swing_dialogs_windows.patch Fri May 13 14:02:18 2016 +0100 +@@ -116,7 +116,7 @@ + { + if (numBands == 3 && !ccm.hasAlpha()) { + imageType = TYPE_3BYTE_BGR; +-@@ -804,6 +801,27 @@ ++@@ -804,6 +801,26 @@ + } // else if ((raster instanceof ByteComponentRaster) && + } + +@@ -129,7 +129,6 @@ + + new PrivilegedAction<Boolean>() + + { + + +-+ @Override + + public Boolean run() { + + final ClassLoader std = System.class.getClassLoader(); + + + diff --git a/gnu/packages/patches/id3lib-CVE-2007-4460.patch b/gnu/packages/patches/id3lib-CVE-2007-4460.patch new file mode 100644 index 0000000000..36c84179fc --- /dev/null +++ b/gnu/packages/patches/id3lib-CVE-2007-4460.patch @@ -0,0 +1,54 @@ +This patch fixes an issues where temporary files were created in an insecure +way. + +It was first intruduced in version 3.8.3-7 and fixes +http://bugs.debian.org/438540 +--- a/src/tag_file.cpp ++++ b/src/tag_file.cpp +@@ -242,8 +242,8 @@ + strcpy(sTempFile, filename.c_str()); + strcat(sTempFile, sTmpSuffix.c_str()); + +-#if ((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) +- // This section is for Windows folk && gcc 3.x folk ++#if !defined(HAVE_MKSTEMP) ++ // This section is for Windows folk + fstream tmpOut; + createFile(sTempFile, tmpOut); + +@@ -257,7 +257,7 @@ + tmpOut.write((char *)tmpBuffer, nBytes); + } + +-#else //((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) ++#else //!defined(HAVE_MKSTEMP) + + // else we gotta make a temp file, copy the tag into it, copy the + // rest of the old file after the tag, delete the old file, rename +@@ -270,7 +270,7 @@ + //ID3_THROW_DESC(ID3E_NoFile, "couldn't open temp file"); + } + +- ofstream tmpOut(fd); ++ ofstream tmpOut(sTempFile); + if (!tmpOut) + { + tmpOut.close(); +@@ -285,14 +285,14 @@ + uchar tmpBuffer[BUFSIZ]; + while (file) + { +- file.read(tmpBuffer, BUFSIZ); ++ file.read((char *)tmpBuffer, BUFSIZ); + size_t nBytes = file.gcount(); +- tmpOut.write(tmpBuffer, nBytes); ++ tmpOut.write((char *)tmpBuffer, nBytes); + } + + close(fd); //closes the file + +-#endif ////((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) ++#endif ////!defined(HAVE_MKSTEMP) + + tmpOut.close(); + file.close(); diff --git a/gnu/packages/patches/jansson-CVE-2016-4425.patch b/gnu/packages/patches/jansson-CVE-2016-4425.patch new file mode 100644 index 0000000000..ebe9aa7809 --- /dev/null +++ b/gnu/packages/patches/jansson-CVE-2016-4425.patch @@ -0,0 +1,125 @@ +From 64ce0ad3731ebd77e02897b07920eadd0e2cc318 Mon Sep 17 00:00:00 2001 +From: Dmitry Janushkevich <gauri@tut.by> +Date: Mon, 2 May 2016 13:59:26 +0200 +Subject: [PATCH] Fix for issue #282 + +The fix limits recursion depths when parsing arrays and objects. +The limit is configurable via the `JSON_PARSER_MAX_DEPTH` setting +within `jansson_config.h` and is set by default to 2048. + +Update the RFC conformance document to note the limit; the RFC +allows limits to be set by the implementation so nothing has +actually changed w.r.t. conformance state. + +Reported by Gustavo Grieco. +--- + android/jansson_config.h | 4 ++++ + cmake/jansson_config.h.cmake | 4 ++++ + doc/conformance.rst | 10 ++++++++++ + src/jansson_config.h.in | 4 ++++ + src/load.c | 10 ++++++++++ + test/suites/invalid/recursion-depth/error | 2 ++ + test/suites/invalid/recursion-depth/input | 1 + + 7 files changed, 35 insertions(+) + create mode 100644 test/suites/invalid/recursion-depth/error + create mode 100644 test/suites/invalid/recursion-depth/input + +--- a/android/jansson_config.h ++++ b/android/jansson_config.h +@@ -36,4 +36,8 @@ + otherwise to 0. */ + #define JSON_HAVE_LOCALECONV 0 + ++/* Maximum recursion depth for parsing JSON input. ++ This limits the depth of e.g. array-within-array constructions. */ ++#define JSON_PARSER_MAX_DEPTH 2048 ++ + #endif +--- a/cmake/jansson_config.h.cmake ++++ b/cmake/jansson_config.h.cmake +@@ -60,5 +60,9 @@ + #define JSON_HAVE_LOCALECONV @JSON_HAVE_LOCALECONV@ + + ++/* Maximum recursion depth for parsing JSON input. ++ This limits the depth of e.g. array-within-array constructions. */ ++#define JSON_PARSER_MAX_DEPTH 2048 ++ + + #endif +--- a/doc/conformance.rst ++++ b/doc/conformance.rst +@@ -108,3 +108,13 @@ + are implicitly handled via the ordinary C type coercion rules (subject + to overflow semantics). Also, no support or hooks are provided for any + supplemental "bignum" type add-on packages. ++ ++Depth of nested values ++---------------------- ++ ++To avoid stack exhaustion, Jansson currently limits the nesting depth ++for arrays and objects to a certain value (default: 2048), defined as ++a macro ``JSON_PARSER_MAX_DEPTH`` within ``jansson_config.h``. ++ ++The limit is allowed to be set by the RFC; there is no recommended value ++or required minimum depth to be supported. +--- a/src/jansson_config.h.in ++++ b/src/jansson_config.h.in +@@ -36,4 +36,8 @@ + otherwise to 0. */ + #define JSON_HAVE_LOCALECONV @json_have_localeconv@ + ++/* Maximum recursion depth for parsing JSON input. ++ This limits the depth of e.g. array-within-array constructions. */ ++#define JSON_PARSER_MAX_DEPTH 2048 ++ + #endif +--- a/src/load.c ++++ b/src/load.c +@@ -61,6 +61,7 @@ + typedef struct { + stream_t stream; + strbuffer_t saved_text; ++ size_t depth; + int token; + union { + struct { +@@ -800,6 +801,12 @@ + json_t *json; + double value; + ++ lex->depth++; ++ if(lex->depth > JSON_PARSER_MAX_DEPTH) { ++ error_set(error, lex, "maximum parsing depth reached"); ++ return NULL; ++ } ++ + switch(lex->token) { + case TOKEN_STRING: { + const char *value = lex->value.string.val; +@@ -870,6 +877,7 @@ + if(!json) + return NULL; + ++ lex->depth--; + return json; + } + +@@ -877,6 +885,8 @@ + { + json_t *result; + ++ lex->depth = 0; ++ + lex_scan(lex, error); + if(!(flags & JSON_DECODE_ANY)) { + if(lex->token != '[' && lex->token != '{') { +--- /dev/null ++++ b/test/suites/invalid/recursion-depth/error +@@ -0,0 +1,2 @@ ++1 2049 2049 ++maximum parsing depth reached near '[' +--- /dev/null ++++ b/test/suites/invalid/recursion-depth/input +@@ -0,0 +1 @@ ++[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ diff --git a/gnu/packages/patches/libtar-CVE-2013-4420.patch b/gnu/packages/patches/libtar-CVE-2013-4420.patch new file mode 100644 index 0000000000..cc64711ae9 --- /dev/null +++ b/gnu/packages/patches/libtar-CVE-2013-4420.patch @@ -0,0 +1,118 @@ +Author: Raphael Geissert <geissert@debian.org> +Bug-Debian: https://bugs.debian.org/731860 +Description: Avoid directory traversal when extracting archives + by skipping over leading slashes and any prefix containing ".." components. +Forwarded: yes + +--- a/lib/decode.c ++++ b/lib/decode.c +@@ -22,6 +22,36 @@ + #endif + + ++char * ++safer_name_suffix (char const *file_name) ++{ ++ char const *p, *t; ++ p = t = file_name; ++ while (*p == '/') t = ++p; ++ while (*p) ++ { ++ while (p[0] == '.' && p[0] == p[1] && p[2] == '/') ++ { ++ p += 3; ++ t = p; ++ } ++ /* advance pointer past the next slash */ ++ while (*p && (p++)[0] != '/'); ++ } ++ ++ if (!*t) ++ { ++ t = "."; ++ } ++ ++ if (t != file_name) ++ { ++ /* TODO: warn somehow that the path was modified */ ++ } ++ return (char*)t; ++} ++ ++ + /* determine full path name */ + char * + th_get_pathname(TAR *t) +@@ -29,17 +59,17 @@ th_get_pathname(TAR *t) + static char filename[MAXPATHLEN]; + + if (t->th_buf.gnu_longname) +- return t->th_buf.gnu_longname; ++ return safer_name_suffix(t->th_buf.gnu_longname); + + if (t->th_buf.prefix[0] != '\0') + { + snprintf(filename, sizeof(filename), "%.155s/%.100s", + t->th_buf.prefix, t->th_buf.name); +- return filename; ++ return safer_name_suffix(filename); + } + + snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name); +- return filename; ++ return safer_name_suffix(filename); + } + + +--- a/lib/extract.c ++++ b/lib/extract.c +@@ -298,14 +298,14 @@ tar_extract_hardlink(TAR * t, char *real + if (mkdirhier(dirname(filename)) == -1) + return -1; + libtar_hashptr_reset(&hp); +- if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t), ++ if (libtar_hash_getkey(t->h, &hp, safer_name_suffix(th_get_linkname(t)), + (libtar_matchfunc_t)libtar_str_match) != 0) + { + lnp = (char *)libtar_hashptr_data(&hp); + linktgt = &lnp[strlen(lnp) + 1]; + } + else +- linktgt = th_get_linkname(t); ++ linktgt = safer_name_suffix(th_get_linkname(t)); + + #ifdef DEBUG + printf(" ==> extracting: %s (link to %s)\n", filename, linktgt); +@@ -343,9 +343,9 @@ tar_extract_symlink(TAR *t, char *realna + + #ifdef DEBUG + printf(" ==> extracting: %s (symlink to %s)\n", +- filename, th_get_linkname(t)); ++ filename, safer_name_suffix(th_get_linkname(t))); + #endif +- if (symlink(th_get_linkname(t), filename) == -1) ++ if (symlink(safer_name_suffix(th_get_linkname(t)), filename) == -1) + { + #ifdef DEBUG + perror("symlink()"); +--- a/lib/internal.h ++++ b/lib/internal.h +@@ -15,3 +15,4 @@ + + #include <libtar.h> + ++char* safer_name_suffix(char const*); +--- a/lib/output.c ++++ b/lib/output.c +@@ -123,9 +123,9 @@ th_print_long_ls(TAR *t) + else + printf(" link to "); + if ((t->options & TAR_GNU) && t->th_buf.gnu_longlink != NULL) +- printf("%s", t->th_buf.gnu_longlink); ++ printf("%s", safer_name_suffix(t->th_buf.gnu_longlink)); + else +- printf("%.100s", t->th_buf.linkname); ++ printf("%.100s", safer_name_suffix(t->th_buf.linkname)); + } + + putchar('\n'); diff --git a/gnu/packages/patches/libyaml-CVE-2014-9130.patch b/gnu/packages/patches/libyaml-CVE-2014-9130.patch new file mode 100644 index 0000000000..800358c0d6 --- /dev/null +++ b/gnu/packages/patches/libyaml-CVE-2014-9130.patch @@ -0,0 +1,30 @@ +Fixes CVE-2014-9130 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-9130 + +Upstream source: +https://bitbucket.org/xi/libyaml/commits/2b9156756423e967cfd09a61d125d883fca6f4f2 + +# HG changeset patch +# User Kirill Simonov <xi@resolvent.net> +# Date 1417197312 21600 +# Node ID 2b9156756423e967cfd09a61d125d883fca6f4f2 +# Parent 053f53a381ff6adbbc93a31ab7fdee06a16c8a33 +Removed invalid simple key assertion (thank to Jonathan Gray). + +diff --git a/src/scanner.c b/src/scanner.c +--- a/src/scanner.c ++++ b/src/scanner.c +@@ -1106,13 +1106,6 @@ + && parser->indent == (ptrdiff_t)parser->mark.column); + + /* +- * A simple key is required only when it is the first token in the current +- * line. Therefore it is always allowed. But we add a check anyway. +- */ +- +- assert(parser->simple_key_allowed || !required); /* Impossible. */ +- +- /* + * If the current position may start a simple key, save it. + */ + diff --git a/gnu/packages/patches/lua-CVE-2014-5461.patch b/gnu/packages/patches/lua-CVE-2014-5461.patch new file mode 100644 index 0000000000..bc72ef14ad --- /dev/null +++ b/gnu/packages/patches/lua-CVE-2014-5461.patch @@ -0,0 +1,20 @@ +From: Enrico Tassi <gareuselesinge@debian.org> +Date: Tue, 26 Aug 2014 16:20:55 +0200 +Subject: Fix stack overflow in vararg functions + +--- + src/ldo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ldo.c b/src/ldo.c +index d1bf786..30333bf 100644 +--- a/src/ldo.c ++++ b/src/ldo.c +@@ -274,7 +274,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; +- luaD_checkstack(L, p->maxstacksize); ++ luaD_checkstack(L, p->maxstacksize + p->numparams); + func = restorestack(L, funcr); + base = func + 1; diff --git a/gnu/packages/patches/mcrypt-CVE-2012-4409.patch b/gnu/packages/patches/mcrypt-CVE-2012-4409.patch new file mode 100644 index 0000000000..60cf8e0430 --- /dev/null +++ b/gnu/packages/patches/mcrypt-CVE-2012-4409.patch @@ -0,0 +1,33 @@ +From 4876e3a692739bb9ca00d0f500fd5f4b3eb16ce3 Mon Sep 17 00:00:00 2001 +From: Tom Callaway <spot@fedoraproject.org> +Date: Fri, 7 Sep 2012 11:39:29 -0400 +Subject: apply fix for CVE-2012-4409 (thanks to Raphael Geissert) + +--- + mcrypt-CVE-2012-4409.patch | 12 ++++++++++++ + mcrypt.spec | 10 +++++++++- + 2 files changed, 21 insertions(+), 1 deletion(-) + create mode 100644 mcrypt-CVE-2012-4409.patch + +diff --git a/mcrypt-CVE-2012-4409.patch b/mcrypt-CVE-2012-4409.patch +new file mode 100644 +index 0000000..747f428 +--- /dev/null ++++ b/mcrypt-CVE-2012-4409.patch +@@ -0,0 +1,12 @@ ++diff -up mcrypt-2.6.8/src/extra.c.CVE-2012-4409 mcrypt-2.6.8/src/extra.c ++--- mcrypt-2.6.8/src/extra.c.CVE-2012-4409 2012-09-07 11:00:55.906870746 -0400 +++++ mcrypt-2.6.8/src/extra.c 2012-09-07 11:00:27.967858365 -0400 ++@@ -242,6 +242,8 @@ int check_file_head(FILE * fstream, char ++ if (m_getbit(0, sflag) != 0) { /* if the first bit is set */ ++ *salt_size = m_setbit(0, sflag, 0); ++ if (*salt_size > 0) { +++ if (*salt_size > sizeof(tmp_buf)) +++ err_quit(_("Salt is too long\n")); ++ fread(tmp_buf, 1, *salt_size, ++ fstream); ++ memmove(salt, tmp_buf, *salt_size); + +-- +cgit v0.12 + diff --git a/gnu/packages/patches/mcrypt-CVE-2012-4426.patch b/gnu/packages/patches/mcrypt-CVE-2012-4426.patch new file mode 100644 index 0000000000..61c197b0c9 --- /dev/null +++ b/gnu/packages/patches/mcrypt-CVE-2012-4426.patch @@ -0,0 +1,36 @@ +diff --git a/mcrypt-CVE-2012-4426.patch b/mcrypt-CVE-2012-4426.patch +new file mode 100644 +index 0000000..747f428 +--- mcrypt-2.6.8/src/errors.c ++++ mcrypt-2.6.8/src/errors.c +@@ -25,24 +25,24 @@ + + void err_quit(char *errmsg) + { +- fprintf(stderr, errmsg); ++ fprintf(stderr, "%s", errmsg); + exit(-1); + } + + void err_warn(char *errmsg) + { + if (quiet <= 1) +- fprintf(stderr, errmsg); ++ fprintf(stderr, "%s", errmsg); + } + + void err_info(char *errmsg) + { + if (quiet == 0) +- fprintf(stderr, errmsg); ++ fprintf(stderr, "%s", errmsg); + } + + void err_crit(char *errmsg) + { + if (quiet <= 2) +- fprintf(stderr, errmsg); ++ fprintf(stderr, "%s", errmsg); + } + +--- diff --git a/gnu/packages/patches/mcrypt-CVE-2012-4527.patch b/gnu/packages/patches/mcrypt-CVE-2012-4527.patch new file mode 100644 index 0000000000..d931dd174b --- /dev/null +++ b/gnu/packages/patches/mcrypt-CVE-2012-4527.patch @@ -0,0 +1,111 @@ +From b0716eac4e800a0ea53e1b949250f671702f28a0 Mon Sep 17 00:00:00 2001 +From: Tom Callaway <spot@fedoraproject.org> +Date: Tue, 30 Oct 2012 15:39:24 -0400 +Subject: apply workaround to CVE-2012-4527 + +--- + mcrypt-CVE-2012-4527-80-width-patch | 91 +++++++++++++++++++++++++++++++++++++ + mcrypt.spec | 10 +++- + 2 files changed, 100 insertions(+), 1 deletion(-) + create mode 100644 mcrypt-CVE-2012-4527-80-width-patch + +diff --git a/mcrypt-CVE-2012-4527-80-width-patch b/mcrypt-CVE-2012-4527-80-width-patch +new file mode 100644 +index 0000000..0eb94d8 +--- /dev/null ++++ b/mcrypt-CVE-2012-4527-80-width-patch +@@ -0,0 +1,91 @@ ++--- mcrypt-2.6.8.orig/src/mcrypt.c +++++ mcrypt-2.6.8/src/mcrypt.c ++@@ -41,6 +41,8 @@ ++ # include <time.h> ++ #endif ++ +++#define WIDTH 80 +++ ++ static char rcsid[] = ++ "$Id: mcrypt.c,v 1.2 2007/11/07 17:10:21 nmav Exp $"; ++ ++@@ -482,7 +484,7 @@ ++ #ifdef HAVE_STAT ++ if (stream_flag == FALSE) { ++ if (is_normal_file(file[i]) == FALSE) { ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("%s: %s is not a regular file. Skipping...\n"), ++ program_name, file[i]); ++@@ -501,7 +503,7 @@ ++ dinfile = file[i]; ++ if ((isatty(fileno((FILE *) (stdin))) == 1) ++ && (stream_flag == TRUE) && (force == 0)) { /* not a tty */ ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("%s: Encrypted data will not be read from a terminal.\n"), ++ program_name); ++@@ -520,7 +522,7 @@ ++ einfile = file[i]; ++ if ((isatty(fileno((FILE *) (stdout))) == 1) ++ && (stream_flag == TRUE) && (force == 0)) { /* not a tty */ ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("%s: Encrypted data will not be written to a terminal.\n"), ++ program_name); ++@@ -544,7 +546,7 @@ ++ strcpy(outfile, einfile); ++ /* if file has already the .nc ignore it */ ++ if (strstr(outfile, ".nc") != NULL) { ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("%s: file %s has the .nc suffix... skipping...\n"), ++ program_name, outfile); ++@@ -590,10 +592,10 @@ ++ ++ if (x == 0) { ++ if (stream_flag == FALSE) { ++- sprintf(tmperr, _("File %s was decrypted.\n"), dinfile); +++ snprintf(tmperr, WIDTH, _("File %s was decrypted.\n"), dinfile); ++ err_warn(tmperr); ++ } else { ++- sprintf(tmperr, _("Stdin was decrypted.\n")); +++ snprintf(tmperr, WIDTH, _("Stdin was decrypted.\n")); ++ err_warn(tmperr); ++ } ++ #ifdef HAVE_STAT ++@@ -610,7 +612,7 @@ ++ ++ } else { ++ if (stream_flag == FALSE) { ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("File %s was NOT decrypted successfully.\n"), ++ dinfile); ++@@ -636,10 +638,10 @@ ++ ++ if (x == 0) { ++ if (stream_flag == FALSE) { ++- sprintf(tmperr, _("File %s was encrypted.\n"), einfile); +++ snprintf(tmperr, WIDTH, _("File %s was encrypted.\n"), einfile); ++ err_warn(tmperr); ++ } else { ++- sprintf(tmperr, _("Stdin was encrypted.\n")); +++ snprintf(tmperr, WIDTH, _("Stdin was encrypted.\n")); ++ err_warn(tmperr); ++ } ++ #ifdef HAVE_STAT ++@@ -655,7 +657,7 @@ ++ ++ } else { ++ if (stream_flag == FALSE) { ++- sprintf(tmperr, +++ snprintf(tmperr, WIDTH, ++ _ ++ ("File %s was NOT encrypted successfully.\n"), ++ einfile); +-- +cgit v0.12 + diff --git a/gnu/packages/patches/pcre2-CVE-2016-3191.patch b/gnu/packages/patches/pcre2-CVE-2016-3191.patch new file mode 100644 index 0000000000..80f9d3d4f1 --- /dev/null +++ b/gnu/packages/patches/pcre2-CVE-2016-3191.patch @@ -0,0 +1,179 @@ +Fixes CVE-2016-3191 (remote execution of arbitrary code or denial of +service (stack-based buffer overflow) via a crafted regular expression). + +See <https://bugzilla.redhat.com/show_bug.cgi?id=1311503>. + +This is svn r489 at <svn://vcs.exim.org/pcre2/code>, omitting the +changes to 'testdata/testoutput8-16-4', which does not exist in the +source tarball. + +git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@489 6239d852-aaf2-0410-a92c-79f79f948069 +--- + ChangeLog | 4 ++++ + src/pcre2_compile.c | 16 ++++++++++++++-- + testdata/testinput8 | 2 ++ + testdata/testoutput8-16-2 | 3 +++ + testdata/testoutput8-16-3 | 3 +++ + testdata/testoutput8-16-4 | 3 +++ + testdata/testoutput8-32-2 | 3 +++ + testdata/testoutput8-32-3 | 3 +++ + testdata/testoutput8-32-4 | 3 +++ + testdata/testoutput8-8-2 | 3 +++ + testdata/testoutput8-8-3 | 3 +++ + testdata/testoutput8-8-4 | 3 +++ + 12 files changed, 47 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3ce0207..65e333e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -58,6 +58,10 @@ some head-scratching the next time this happens. + assertion, caused pcre2test to output a very large number of spaces when the + callout was taken, making the program appearing to loop. + ++12. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply ++nested set of parentheses of sufficient size caused an overflow of the ++compiling workspace (which was diagnosed, but of course is not desirable). ++ + + Version 10.21 12-January-2016 + ----------------------------- +diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c +index e33d620..887fbfd 100644 +--- a/src/pcre2_compile.c ++++ b/src/pcre2_compile.c +@@ -5901,10 +5901,22 @@ for (;; ptr++) + goto FAILED; + } + cb->had_accept = TRUE; ++ ++ /* In the first pass, just accumulate the length required; ++ otherwise hitting (*ACCEPT) inside many nested parentheses can ++ cause workspace overflow. */ ++ + for (oc = cb->open_caps; oc != NULL; oc = oc->next) + { +- *code++ = OP_CLOSE; +- PUT2INC(code, 0, oc->number); ++ if (lengthptr != NULL) ++ { ++ *lengthptr += CU2BYTES(1) + IMM2_SIZE; ++ } ++ else ++ { ++ *code++ = OP_CLOSE; ++ PUT2INC(code, 0, oc->number); ++ } + } + setverb = *code++ = + (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; +diff --git a/testdata/testinput8 b/testdata/testinput8 +index ca3b1b9..7e2a1f0 100644 +--- a/testdata/testinput8 ++++ b/testdata/testinput8 +@@ -182,4 +182,6 @@ + + /((?1)(?2)(?3)(?4)(?5)(?6)(?7)(?8)(?9)(?9)(?8)(?7)(?6)(?5)(?4)(?3)(?2)(?1)(?0)){2,}()()()()()()()()()/debug + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++ + # End of testinput8 +diff --git a/testdata/testoutput8-16-2 b/testdata/testoutput8-16-2 +index 05669bb..a5e8dec 100644 +--- a/testdata/testoutput8-16-2 ++++ b/testdata/testoutput8-16-2 +@@ -1027,4 +1027,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 186 at offset 490: regular expression is too complicated ++ + # End of testinput8 +diff --git a/testdata/testoutput8-16-3 b/testdata/testoutput8-16-3 +index 31884e1..36133b3 100644 +--- a/testdata/testoutput8-16-3 ++++ b/testdata/testoutput8-16-3 +@@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-32-2 b/testdata/testoutput8-32-2 +index babd0c7..99c4fad 100644 +--- a/testdata/testoutput8-32-2 ++++ b/testdata/testoutput8-32-2 +@@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-32-3 b/testdata/testoutput8-32-3 +index babd0c7..99c4fad 100644 +--- a/testdata/testoutput8-32-3 ++++ b/testdata/testoutput8-32-3 +@@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-32-4 b/testdata/testoutput8-32-4 +index babd0c7..99c4fad 100644 +--- a/testdata/testoutput8-32-4 ++++ b/testdata/testoutput8-32-4 +@@ -1023,4 +1023,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-8-2 b/testdata/testoutput8-8-2 +index 6a9aa0a..6dc1f42 100644 +--- a/testdata/testoutput8-8-2 ++++ b/testdata/testoutput8-8-2 +@@ -1026,4 +1026,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-8-3 b/testdata/testoutput8-8-3 +index 2fe1168..ae14946 100644 +--- a/testdata/testoutput8-8-3 ++++ b/testdata/testoutput8-8-3 +@@ -1024,4 +1024,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +diff --git a/testdata/testoutput8-8-4 b/testdata/testoutput8-8-4 +index 91993b2..6c79956 100644 +--- a/testdata/testoutput8-8-4 ++++ b/testdata/testoutput8-8-4 +@@ -1022,4 +1022,7 @@ Capturing subpattern count = 10 + May match empty string + Subject length lower bound = 0 + ++/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ ++Failed: error 114 at offset 509: missing closing parenthesis ++ + # End of testinput8 +-- +2.8.3 + diff --git a/gnu/packages/patches/procmail-CVE-2014-3618.patch b/gnu/packages/patches/procmail-CVE-2014-3618.patch new file mode 100644 index 0000000000..e3f2759738 --- /dev/null +++ b/gnu/packages/patches/procmail-CVE-2014-3618.patch @@ -0,0 +1,26 @@ +Fixes CVE-2014-3618 (heap overflow in formisc.c allowing denial of +service and potential remote execution of arbitrary code). +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3618 + +Source: +http://seclists.org/oss-sec/2014/q3/495 + +Adopted by Debian as patch '27': +https://sources.debian.net/src/procmail/3.22-25/debian/patches/27/ + +--- a/src/formisc.c ++++ b/src/formisc.c +@@ -84,12 +84,11 @@ + case '"':*target++=delim='"';start++; + } + ;{ int i; +- do ++ while(*start) + if((i= *target++= *start++)==delim) /* corresponding delimiter? */ + break; + else if(i=='\\'&&*start) /* skip quoted character */ + *target++= *start++; +- while(*start); /* anything? */ + } + hitspc=2; + } diff --git a/gnu/packages/patches/rpm-CVE-2014-8118.patch b/gnu/packages/patches/rpm-CVE-2014-8118.patch new file mode 100644 index 0000000000..5fdb0f0eb2 --- /dev/null +++ b/gnu/packages/patches/rpm-CVE-2014-8118.patch @@ -0,0 +1,25 @@ +Fix CVE-2014-8118 (integer overflow allowing arbitrary remote code +execution via crafted CPIO header). + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8118 + +Source: +https://bugzilla.redhat.com/attachment.cgi?id=962159&action=diff + +Adopted by Debian: +http://anonscm.debian.org/cgit/collab-maint/rpm.git/plain/debian/patches/CVE-2014-8118.patch + +diff --git a/lib/cpio.c b/lib/cpio.c +index 253ff0f..600633a 100644 +--- a/lib/cpio.c ++++ b/lib/cpio.c +@@ -399,6 +399,9 @@ int rpmcpioHeaderRead(rpmcpio_t cpio, char ** path, int * fx) + + GET_NUM_FIELD(hdr.filesize, fsize); + GET_NUM_FIELD(hdr.namesize, nameSize); ++ if (nameSize <= 0 || nameSize > 4096) { ++ return RPMERR_BAD_HEADER; ++ } + + char name[nameSize + 1]; + read = Fread(name, nameSize, 1, cpio->fd); diff --git a/gnu/packages/patches/rush-CVE-2013-6889.patch b/gnu/packages/patches/rush-CVE-2013-6889.patch new file mode 100644 index 0000000000..862528a12c --- /dev/null +++ b/gnu/packages/patches/rush-CVE-2013-6889.patch @@ -0,0 +1,23 @@ +commit 00bdccd429517f12dbf37ab4397ddec3e51a2738 +Author: Mats Erik Andersson <gnu@gisladisker.se> +Date: Mon Jan 20 13:33:52 2014 +0200 + + Protect against CVE-2013-6889 (tiny change). + + Reset the effective user identification in testing mode. + +diff --git a/src/rush.c b/src/rush.c +index 45d737a..dc6518e 100644 +--- a/src/rush.c ++++ b/src/rush.c +@@ -980,6 +980,10 @@ main(int argc, char **argv) + } else if (argc > optind) + die(usage_error, NULL, _("invalid command line")); + ++ /* Relinquish root privileges in test mode */ ++ if (lint_option) ++ setuid(getuid()); ++ + if (test_user_name) { + struct passwd *pw = getpwnam(test_user_name); + if (!pw) diff --git a/gnu/packages/patches/t1lib-CVE-2010-2642.patch b/gnu/packages/patches/t1lib-CVE-2010-2642.patch new file mode 100644 index 0000000000..cd54889585 --- /dev/null +++ b/gnu/packages/patches/t1lib-CVE-2010-2642.patch @@ -0,0 +1,24 @@ +diff --git a/lib/t1lib/parseAFM.c b/lib/t1lib/parseAFM.c +index 6a31d7f..ba64541 100644 +--- a/lib/t1lib/parseAFM.c ++++ b/lib/t1lib/parseAFM.c +@@ -199,7 +199,9 @@ static char *token(stream) + idx = 0; + + while (ch != EOF && ch != ' ' && ch != CR && ch != LF && +- ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';'){ ++ ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';' ++ && idx < (MAX_NAME -1)) ++ { + ident[idx++] = ch; + ch = fgetc(stream); + } /* while */ +@@ -235,7 +237,7 @@ static char *linetoken(stream) + while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); + + idx = 0; +- while (ch != EOF && ch != CR && ch != LF && ch != CTRL_Z) ++ while (ch != EOF && ch != CR && ch != LF && ch != CTRL_Z && idx < (MAX_NAME - 1)) + { + ident[idx++] = ch; + ch = fgetc(stream); diff --git a/gnu/packages/patches/t1lib-CVE-2011-0764.patch b/gnu/packages/patches/t1lib-CVE-2011-0764.patch new file mode 100644 index 0000000000..c2d9e173b7 --- /dev/null +++ b/gnu/packages/patches/t1lib-CVE-2011-0764.patch @@ -0,0 +1,32 @@ +Description: Don't lookup previous point if there isn't any +Author: Marc Deslauriers <marc.deslauriers@canonical.com> +Forwarded: no + +Index: t1lib-5.1.2/lib/type1/type1.c +=================================================================== +--- t1lib-5.1.2.orig/lib/type1/type1.c 2011-12-13 14:24:14.280965637 -0600 ++++ t1lib-5.1.2/lib/type1/type1.c 2011-12-13 14:25:25.893320747 -0600 +@@ -1700,6 +1700,7 @@ + long pindex = 0; + + /* compute hinting for previous segment! */ ++ if (ppoints == NULL) Error0i("RLineTo: No previous point!\n"); + FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx, dy); + + /* Allocate a new path point and pre-setup data */ +@@ -1728,6 +1729,7 @@ + long pindex = 0; + + /* compute hinting for previous point! */ ++ if (ppoints == NULL) Error0i("RRCurveTo: No previous point!\n"); + FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx1, dy1); + + /* Allocate three new path points and pre-setup data */ +@@ -1903,6 +1905,7 @@ + FindStems( currx, curry, 0, 0, dx, dy); + } + else { ++ if (ppoints == NULL) Error0i("RMoveTo: No previous point!\n"); + FindStems( currx, curry, ppoints[numppoints-2].x, ppoints[numppoints-2].y, dx, dy); + } + diff --git a/gnu/packages/patches/t1lib-CVE-2011-1552+CVE-2011-1553+CVE-2011-1554.patch b/gnu/packages/patches/t1lib-CVE-2011-1552+CVE-2011-1553+CVE-2011-1554.patch new file mode 100644 index 0000000000..aaa31f7b93 --- /dev/null +++ b/gnu/packages/patches/t1lib-CVE-2011-1552+CVE-2011-1553+CVE-2011-1554.patch @@ -0,0 +1,133 @@ +Author: Jaroslav Å karvada <jskarvad@redhat.com> +Description: Fix more crashes on oversized fonts +Bug-Redhat: http://bugzilla.redhat.com/show_bug.cgi?id=692909 +Index: t1lib-5.1.2/lib/type1/lines.c +=================================================================== +--- t1lib-5.1.2.orig/lib/type1/lines.c 2007-12-23 09:49:42.000000000 -0600 ++++ t1lib-5.1.2/lib/type1/lines.c 2012-01-17 14:15:08.000000000 -0600 +@@ -67,6 +67,10 @@ + None. + */ + ++#define BITS (sizeof(LONG)*8) ++#define HIGHTEST(p) (((p)>>(BITS-2)) != 0) /* includes sign bit */ ++#define TOOBIG(xy) ((xy < 0) ? HIGHTEST(-xy) : HIGHTEST(xy)) ++ + /* + :h2.StepLine() - Produces Run Ends for a Line After Checks + +@@ -84,6 +88,9 @@ + IfTrace4((LineDebug > 0), ".....StepLine: (%d,%d) to (%d,%d)\n", + x1, y1, x2, y2); + ++ if ( TOOBIG(x1) || TOOBIG(x2) || TOOBIG(y1) || TOOBIG(y2)) ++ abort("Lines this big not supported", 49); ++ + dy = y2 - y1; + + /* +Index: t1lib-5.1.2/lib/type1/objects.c +=================================================================== +--- t1lib-5.1.2.orig/lib/type1/objects.c 2007-12-23 09:49:42.000000000 -0600 ++++ t1lib-5.1.2/lib/type1/objects.c 2012-01-17 14:15:08.000000000 -0600 +@@ -1137,12 +1137,13 @@ + "Context: out of them", /* 46 */ + "MatrixInvert: can't", /* 47 */ + "xiStub called", /* 48 */ +- "Illegal access type1 abort() message" /* 49 */ ++ "Lines this big not supported", /* 49 */ ++ "Illegal access type1 abort() message" /* 50 */ + }; + +- /* no is valid from 1 to 48 */ +- if ( (number<1)||(number>48)) +- number=49; ++ /* no is valid from 1 to 49 */ ++ if ( (number<1)||(number>49)) ++ number=50; + return( err_msgs[number-1]); + + } +Index: t1lib-5.1.2/lib/type1/type1.c +=================================================================== +--- t1lib-5.1.2.orig/lib/type1/type1.c 2012-01-17 14:13:28.000000000 -0600 ++++ t1lib-5.1.2/lib/type1/type1.c 2012-01-17 14:19:54.000000000 -0600 +@@ -1012,6 +1012,7 @@ + double nextdtana = 0.0; /* tangent of post-delta against horizontal line */ + double nextdtanb = 0.0; /* tangent of post-delta against vertical line */ + ++ if (ppoints == NULL || numppoints < 1) Error0v("FindStems: No previous point!\n"); + + /* setup default hinted position */ + ppoints[numppoints-1].ax = ppoints[numppoints-1].x; +@@ -1289,7 +1290,7 @@ + static int DoRead(CodeP) + int *CodeP; + { +- if (strindex >= CharStringP->len) return(FALSE); /* end of string */ ++ if (!CharStringP || strindex >= CharStringP->len) return(FALSE); /* end of string */ + /* We handle the non-documented Adobe convention to use lenIV=-1 to + suppress charstring encryption. */ + if (blues->lenIV==-1) { +@@ -1700,7 +1701,7 @@ + long pindex = 0; + + /* compute hinting for previous segment! */ +- if (ppoints == NULL) Error0i("RLineTo: No previous point!\n"); ++ if (ppoints == NULL || numppoints < 2) Error0i("RLineTo: No previous point!\n"); + FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx, dy); + + /* Allocate a new path point and pre-setup data */ +@@ -1729,7 +1730,7 @@ + long pindex = 0; + + /* compute hinting for previous point! */ +- if (ppoints == NULL) Error0i("RRCurveTo: No previous point!\n"); ++ if (ppoints == NULL || numppoints < 2) Error0i("RRCurveTo: No previous point!\n"); + FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx1, dy1); + + /* Allocate three new path points and pre-setup data */ +@@ -1788,7 +1789,9 @@ + long tmpind; + double deltax = 0.0; + double deltay = 0.0; +- ++ ++ if (ppoints == NULL || numppoints < 1) Error0i("DoClosePath: No previous point!"); ++ + /* If this ClosePath command together with the starting point of this + path completes to a segment aligned to a stem, we would miss + hinting for this point. --> Check and explicitly care for this! */ +@@ -1803,6 +1806,7 @@ + deltax = ppoints[i].x - ppoints[numppoints-1].x; + deltay = ppoints[i].y - ppoints[numppoints-1].y; + ++ if (ppoints == NULL || numppoints <= i + 1) Error0i("DoClosePath: No previous point!"); + /* save nummppoints and reset to move point */ + tmpind = numppoints; + numppoints = i + 1; +@@ -1905,7 +1909,7 @@ + FindStems( currx, curry, 0, 0, dx, dy); + } + else { +- if (ppoints == NULL) Error0i("RMoveTo: No previous point!\n"); ++ if (ppoints == NULL || numppoints < 2) Error0i("RMoveTo: No previous point!\n"); + FindStems( currx, curry, ppoints[numppoints-2].x, ppoints[numppoints-2].y, dx, dy); + } + +@@ -2155,6 +2159,7 @@ + DOUBLE cx, cy; + DOUBLE ex, ey; + ++ if (ppoints == NULL || numppoints < 8) Error0v("FlxProc: No previous point!"); + + /* Our PPOINT list now contains 7 moveto commands which + are about to be consumed by the Flex mechanism. --> Remove these +@@ -2324,6 +2329,7 @@ + /* Returns currentpoint on stack */ + static void FlxProc2() + { ++ if (ppoints == NULL || numppoints < 1) Error0v("FlxProc2: No previous point!"); + /* Push CurrentPoint on fake PostScript stack */ + PSFakePush( ppoints[numppoints-1].x); + PSFakePush( ppoints[numppoints-1].y); diff --git a/gnu/packages/patches/vorbis-tools-CVE-2014-9638+CVE-2014-9639.patch b/gnu/packages/patches/vorbis-tools-CVE-2014-9638+CVE-2014-9639.patch new file mode 100644 index 0000000000..6e389dd59e --- /dev/null +++ b/gnu/packages/patches/vorbis-tools-CVE-2014-9638+CVE-2014-9639.patch @@ -0,0 +1,83 @@ +From: Petter Reinholdtsen <pere@debian.org> +Date: Tue, 22 Sep 2015 15:14:06 +0200 +Subject: oggenc: validate count of channels in the header (CVE-2014-9638 & + CVE-2014-9639) + +Author: Kamil Dudka <kdudka@redhat.com> +Origin: http://lists.xiph.org/pipermail/vorbis-dev/2015-February/020423.html +Bug: https://trac.xiph.org/ticket/2136 +Bug: https://trac.xiph.org/ticket/2137 +Bug-Debian: https://bugs.debian.org/776086 +Forwarded: not-needed +Reviewed-By: Petter Reinholdtsen <pere@hungry.com> +Last-Update: 2015-09-22 +--- + oggenc/audio.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/oggenc/audio.c b/oggenc/audio.c +index 05e42b3..1b3f179 100644 +--- a/oggenc/audio.c ++++ b/oggenc/audio.c +@@ -13,6 +13,7 @@ + #include <config.h> + #endif + ++#include <limits.h> + #include <stdlib.h> + #include <stdio.h> + #include <string.h> +@@ -251,6 +252,7 @@ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen) + aiff_fmt format; + aifffile *aiff = malloc(sizeof(aifffile)); + int i; ++ long channels; + + if(buf[11]=='C') + aifc=1; +@@ -277,11 +279,16 @@ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen) + return 0; + } + +- format.channels = READ_U16_BE(buffer); ++ format.channels = channels = READ_U16_BE(buffer); + format.totalframes = READ_U32_BE(buffer+2); + format.samplesize = READ_U16_BE(buffer+6); + format.rate = (int)read_IEEE80(buffer+8); + ++ if(channels <= 0L || SHRT_MAX < channels) ++ { ++ fprintf(stderr, _("Warning: Unsupported count of channels in AIFF header\n")); ++ return 0; ++ } + aiff->bigendian = 1; + + if(aifc) +@@ -412,6 +419,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen) + wav_fmt format; + wavfile *wav = malloc(sizeof(wavfile)); + int i; ++ long channels; + + /* Ok. At this point, we know we have a WAV file. Now we have to detect + * whether we support the subtype, and we have to find the actual data +@@ -449,12 +457,18 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen) + } + + format.format = READ_U16_LE(buf); +- format.channels = READ_U16_LE(buf+2); ++ format.channels = channels = READ_U16_LE(buf+2); + format.samplerate = READ_U32_LE(buf+4); + format.bytespersec = READ_U32_LE(buf+8); + format.align = READ_U16_LE(buf+12); + format.samplesize = READ_U16_LE(buf+14); + ++ if(channels <= 0L || SHRT_MAX < channels) ++ { ++ fprintf(stderr, _("Warning: Unsupported count of channels in WAV header\n")); ++ return 0; ++ } ++ + if(format.format == -2) /* WAVE_FORMAT_EXTENSIBLE */ + { + if(len<40) diff --git a/gnu/packages/patches/vorbis-tools-CVE-2014-9640.patch b/gnu/packages/patches/vorbis-tools-CVE-2014-9640.patch new file mode 100644 index 0000000000..97d18e0db7 --- /dev/null +++ b/gnu/packages/patches/vorbis-tools-CVE-2014-9640.patch @@ -0,0 +1,29 @@ +Index: vorbis-tools/oggenc/oggenc.c +=================================================================== +--- vorbis-tools/oggenc/oggenc.c (revision 19116) ++++ vorbis-tools/oggenc/oggenc.c (revision 19117) +@@ -98,4 +98,6 @@ + 0,0,0.f, + 0, 0, 0, 0, 0}; ++ input_format raw_format = {NULL, 0, raw_open, wav_close, "raw", ++ N_("RAW file reader")}; + + int i; +@@ -240,6 +242,4 @@ + if(opt.rawmode) + { +- input_format raw_format = {NULL, 0, raw_open, wav_close, "raw", +- N_("RAW file reader")}; + + enc_opts.rate=opt.raw_samplerate; +Index: vorbis-tools/oggenc/skeleton.h +=================================================================== +--- vorbis-tools/oggenc/skeleton.h (revision 19116) ++++ vorbis-tools/oggenc/skeleton.h (revision 19117) +@@ -42,5 +42,5 @@ + ogg_int64_t start_granule; /* start granule value */ + ogg_uint32_t preroll; /* preroll */ +- unsigned char granule_shift; // a 8-bit field /* 1 byte value holding the granule shift */ ++ unsigned char granule_shift; /* 1 byte value holding the granule shift */ + char *message_header_fields; /* holds all the message header fields */ + /* current total size of the message header fields, for realloc purpose, initially zero */ diff --git a/gnu/packages/patches/vte-CVE-2012-2738-pt1.patch b/gnu/packages/patches/vte-CVE-2012-2738-pt1.patch new file mode 100644 index 0000000000..fd45407939 --- /dev/null +++ b/gnu/packages/patches/vte-CVE-2012-2738-pt1.patch @@ -0,0 +1,40 @@ +From feeee4b5832b17641e505b7083e0d299fdae318e Mon Sep 17 00:00:00 2001 +From: Christian Persch <chpe@gnome.org> +Date: Sat, 19 May 2012 17:36:09 +0000 +Subject: emulation: Limit integer arguments to 65535 + +To guard against malicious sequences containing excessively big numbers, +limit all parsed numbers to 16 bit range. Doing this here in the parsing +routine is a catch-all guard; this doesn't preclude enforcing +more stringent limits in the handlers themselves. + +https://bugzilla.gnome.org/show_bug.cgi?id=676090 +--- +diff --git a/src/table.c b/src/table.c +index 140e8c8..85cf631 100644 +--- a/src/table.c ++++ b/src/table.c +@@ -550,7 +550,7 @@ _vte_table_extract_numbers(GValueArray **array, + if (G_UNLIKELY (*array == NULL)) { + *array = g_value_array_new(1); + } +- g_value_set_long(&value, total); ++ g_value_set_long(&value, CLAMP (total, 0, G_MAXUSHORT)); + g_value_array_append(*array, &value); + } while (i++ < arginfo->length); + g_value_unset(&value); +diff --git a/src/vteseq.c b/src/vteseq.c +index 457c06a..46def5b 100644 +--- a/src/vteseq.c ++++ b/src/vteseq.c +@@ -557,7 +557,7 @@ vte_sequence_handler_multiple(VteTerminal *terminal, + GValueArray *params, + VteTerminalSequenceHandler handler) + { +- vte_sequence_handler_multiple_limited(terminal, params, handler, G_MAXLONG); ++ vte_sequence_handler_multiple_limited(terminal, params, handler, G_MAXUSHORT); + } + + static void +-- +cgit v0.9.0.2 diff --git a/gnu/packages/patches/vte-CVE-2012-2738-pt2.patch b/gnu/packages/patches/vte-CVE-2012-2738-pt2.patch new file mode 100644 index 0000000000..e98fd35b95 --- /dev/null +++ b/gnu/packages/patches/vte-CVE-2012-2738-pt2.patch @@ -0,0 +1,82 @@ +From 98ce2f265f986fb88c38d508286bb5e3716b9e74 Mon Sep 17 00:00:00 2001 +From: Christian Persch <chpe@gnome.org> +Date: Sat, 19 May 2012 18:04:12 +0000 +Subject: emulation: Limit repetitions + +Don't allow malicious sequences to cause excessive repetitions. + +https://bugzilla.gnome.org/show_bug.cgi?id=676090 +--- +diff --git a/src/vteseq.c b/src/vteseq.c +index 46def5b..7fb4707 100644 +--- a/src/vteseq.c ++++ b/src/vteseq.c +@@ -1397,7 +1397,7 @@ vte_sequence_handler_dc (VteTerminal *terminal, GValueArray *params) + static void + vte_sequence_handler_DC (VteTerminal *terminal, GValueArray *params) + { +- vte_sequence_handler_multiple(terminal, params, vte_sequence_handler_dc); ++ vte_sequence_handler_multiple_r(terminal, params, vte_sequence_handler_dc); + } + + /* Delete a line at the current cursor position. */ +@@ -1790,7 +1790,7 @@ vte_sequence_handler_reverse_index (VteTerminal *terminal, GValueArray *params) + static void + vte_sequence_handler_RI (VteTerminal *terminal, GValueArray *params) + { +- vte_sequence_handler_multiple(terminal, params, vte_sequence_handler_nd); ++ vte_sequence_handler_multiple_r(terminal, params, vte_sequence_handler_nd); + } + + /* Save cursor (position). */ +@@ -2782,8 +2782,7 @@ vte_sequence_handler_insert_lines (VteTerminal *terminal, GValueArray *params) + { + GValue *value; + VteScreen *screen; +- long param, end, row; +- int i; ++ long param, end, row, i, limit; + screen = terminal->pvt->screen; + /* The default is one. */ + param = 1; +@@ -2801,7 +2800,13 @@ vte_sequence_handler_insert_lines (VteTerminal *terminal, GValueArray *params) + } else { + end = screen->insert_delta + terminal->row_count - 1; + } +- /* Insert the new lines at the cursor. */ ++ ++ /* Only allow to insert as many lines as there are between this row ++ * and the end of the scrolling region. See bug #676090. ++ */ ++ limit = end - row + 1; ++ param = MIN (param, limit); ++ + for (i = 0; i < param; i++) { + /* Clear a line off the end of the region and add one to the + * top of the region. */ +@@ -2822,8 +2827,7 @@ vte_sequence_handler_delete_lines (VteTerminal *terminal, GValueArray *params) + { + GValue *value; + VteScreen *screen; +- long param, end, row; +- int i; ++ long param, end, row, i, limit; + + screen = terminal->pvt->screen; + /* The default is one. */ +@@ -2842,6 +2846,13 @@ vte_sequence_handler_delete_lines (VteTerminal *terminal, GValueArray *params) + } else { + end = screen->insert_delta + terminal->row_count - 1; + } ++ ++ /* Only allow to delete as many lines as there are between this row ++ * and the end of the scrolling region. See bug #676090. ++ */ ++ limit = end - row + 1; ++ param = MIN (param, limit); ++ + /* Clear them from below the current cursor. */ + for (i = 0; i < param; i++) { + /* Insert a line at the end of the region and remove one from +-- +cgit v0.9.0.2 diff --git a/gnu/packages/patches/wordnet-CVE-2008-2149.patch b/gnu/packages/patches/wordnet-CVE-2008-2149.patch new file mode 100644 index 0000000000..9828efa4bc --- /dev/null +++ b/gnu/packages/patches/wordnet-CVE-2008-2149.patch @@ -0,0 +1,19 @@ +Fix CVE-2008-2149: buffer overflows by limiting the length of the string in sprintf +format string +Closes: #481186 (CVE-2008-2149) +Please note: The WordNet code contains several other occurences of potentially +exploitable functions like strcpy()/strcat()/... and so even if there are no +known exploits the code needs a full security audit. + +--- a/src/wn.c ++++ b/src/wn.c +@@ -206,7 +206,8 @@ static int searchwn(int ac, char *av[]) + outsenses += do_search(av[1], optptr->pos, optptr->search, + whichsense, optptr->label); + } else { +- sprintf(tmpbuf, "wn: invalid search option: %s\n", av[j]); ++ /* Fix CVE-2008-2149: buffer overflows Andreas Tille <tille@debian.org> */ ++ sprintf(tmpbuf, "wn: invalid search option: %.200s\n", av[j]); + display_message(tmpbuf); + errcount++; + } diff --git a/gnu/packages/patches/wordnet-CVE-2008-3908-pt1.patch b/gnu/packages/patches/wordnet-CVE-2008-3908-pt1.patch new file mode 100644 index 0000000000..a2e796b535 --- /dev/null +++ b/gnu/packages/patches/wordnet-CVE-2008-3908-pt1.patch @@ -0,0 +1,710 @@ +Author: Anton Gladky <gladk@debian.org> +LastChanged: Tue, 26 Feb 2013 20:40:25 +0100 +BugDebian: http://bugs.debian.org/700914 +Description: This patch was created by oCert according to + http://www.ocert.org/advisories/ocert-2008-014.html + and can be downloaded from + http://www.ocert.org/analysis/2008-014/wordnet.patch + Unfortunately the original patch had a problem which + caused 'wordnet test -synsn' to fail. The critical + part of the patch was removed from the whole patch + set and is moved to 51_overflows_memcpy.patch which + uses memcpy instead of the formerly used strcpy. + +--- a/lib/binsrch.c ++++ b/lib/binsrch.c +@@ -28,7 +28,7 @@ char *read_index(long offset, FILE *fp) + char *linep; + + linep = line; +- line[0] = '0'; ++ line[0] = '\0'; + + fseek( fp, offset, SEEK_SET ); + fgets(linep, LINE_LEN, fp); +@@ -58,6 +58,8 @@ char *bin_search(char *searchkey, FILE * + last_bin_search_offset = ftell( fp ); + fgets(linep, LINE_LEN, fp); + length = (int)(strchr(linep, ' ') - linep); ++ if (length > (sizeof(key) - 1)) ++ return(NULL); + strncpy(key, linep, length); + key[length] = '\0'; + if(strcmp(key, searchkey) < 0) { +@@ -110,6 +112,8 @@ static int bin_search_key(char *searchke + line[length++] = c; + if (getc(fp) == EOF) { /* only 1 line in file */ + length = (int)(strchr(linep, ' ') - linep); ++ if (length > (sizeof(key) - 1)) ++ return(0); + strncpy(key, linep, length); + key[length] = '\0'; + if(strcmp(key, searchkey) > 0) { +@@ -132,6 +136,8 @@ static int bin_search_key(char *searchke + if (fgets(linep, LINE_LEN, fp) != NULL) { + offset2 = ftell(fp); /* offset at start of next line */ + length = (int)(strchr(linep, ' ') - linep); ++ if (length > (sizeof(key) - 1)) ++ return(0); + strncpy(key, linep, length); + key[length] = '\0'; + if(strcmp(key, searchkey) < 0) { /* further in file */ +--- a/lib/morph.c ++++ b/lib/morph.c +@@ -51,21 +51,21 @@ static struct { + char *str; + int strlen; + } prepositions[NUMPREPS] = { +- "to", 2, +- "at", 2, +- "of", 2, +- "on", 2, +- "off", 3, +- "in", 2, +- "out", 3, +- "up", 2, +- "down", 4, +- "from", 4, +- "with", 4, +- "into", 4, +- "for", 3, +- "about", 5, +- "between", 7, ++ { "to", 2 }, ++ { "at", 2 }, ++ { "of", 2 }, ++ { "on", 2 }, ++ { "off", 3 }, ++ { "in", 2 }, ++ { "out", 3 }, ++ { "up", 2 }, ++ { "down", 4 }, ++ { "from", 4 }, ++ { "with", 4 }, ++ { "into", 4 }, ++ { "for", 3 }, ++ { "about", 5 }, ++ { "between", 7 } + }; + + static FILE *exc_fps[NUMPARTS + 1]; +@@ -144,18 +144,19 @@ static int do_init(void) + } else + sprintf(searchdir, DEFAULTPATH); + #else +- if ((env = getenv("WNSEARCHDIR")) != NULL) +- strcpy(searchdir, env); +- else if ((env = getenv("WNHOME")) != NULL) +- sprintf(searchdir, "%s%s", env, DICTDIR); +- else ++ if ((env = getenv("WNSEARCHDIR")) != NULL) { ++ snprintf(searchdir, sizeof(searchdir), "%s", env); ++ } else if ((env = getenv("WNHOME")) != NULL) { ++ snprintf(searchdir, sizeof(searchdir), "%s%s", env, DICTDIR); ++ } else { + strcpy(searchdir, DEFAULTPATH); ++ } + #endif + + for (i = 1; i <= NUMPARTS; i++) { +- sprintf(fname, EXCFILE, searchdir, partnames[i]); ++ snprintf(fname, sizeof(fname), EXCFILE, searchdir, partnames[i]); + if ((exc_fps[i] = fopen(fname, "r")) == NULL) { +- sprintf(msgbuf, ++ snprintf(msgbuf, sizeof(msgbuf), + "WordNet library error: Can't open exception file(%s)\n\n", + fname); + display_message(msgbuf); +@@ -178,13 +179,16 @@ char *morphstr(char *origstr, int pos) + int prep; + char *end_idx1, *end_idx2; + char *append; +- ++ + if (pos == SATELLITE) + pos = ADJ; + + /* First time through for this string */ + + if (origstr != NULL) { ++ if (strlen(origstr) > WORDBUF - 1) ++ return(NULL); ++ + /* Assume string hasn't had spaces substitued with '_' */ + strtolower(strsubst(strcpy(str, origstr), ' ', '_')); + searchstr[0] = '\0'; +@@ -232,7 +236,7 @@ char *morphstr(char *origstr, int pos) + if (end_idx < 0) return(NULL); /* shouldn't do this */ + strncpy(word, str + st_idx, end_idx - st_idx); + word[end_idx - st_idx] = '\0'; +- if(tmp = morphword(word, pos)) ++ if ((tmp = morphword(word, pos)) != NULL) + strcat(searchstr,tmp); + else + strcat(searchstr,word); +@@ -240,7 +244,7 @@ char *morphstr(char *origstr, int pos) + st_idx = end_idx + 1; + } + +- if(tmp = morphword(strcpy(word, str + st_idx), pos)) ++ if ((tmp = morphword(strcpy(word, str + st_idx), pos)) != NULL) + strcat(searchstr,tmp); + else + strcat(searchstr,word); +@@ -270,16 +274,15 @@ char *morphword(char *word, int pos) + { + int offset, cnt; + int i; +- static char retval[WORDBUF]; +- char *tmp, tmpbuf[WORDBUF], *end; +- +- sprintf(retval,""); +- sprintf(tmpbuf, ""); +- end = ""; +- ++ static char retval[WORDBUF] = ""; ++ char *tmp, tmpbuf[WORDBUF] = "", *end = ""; ++ + if(word == NULL) + return(NULL); + ++ if (strlen(word) > WORDBUF - 1) ++ return(NULL); ++ + /* first look for word on exception list */ + + if((tmp = exc_lookup(word, pos)) != NULL) +@@ -335,7 +338,10 @@ static char *wordbase(char *word, int en + { + char *pt1; + static char copy[WORDBUF]; +- ++ ++ if (strlen(word) > WORDBUF - 1) ++ return(NULL); ++ + strcpy(copy, word); + if(strend(copy,sufx[ender])) { + pt1=strchr(copy,'\0'); +@@ -368,13 +374,14 @@ static char *exc_lookup(char *word, int + { + static char line[WORDBUF], *beglp, *endlp; + char *excline; +- int found = 0; + + if (exc_fps[pos] == NULL) + return(NULL); + + /* first time through load line from exception file */ + if(word != NULL){ ++ if (strlen(word) > WORDBUF - 1) ++ return(NULL); + if ((excline = bin_search(word, exc_fps[pos])) != NULL) { + strcpy(line, excline); + endlp = strchr(line,' '); +@@ -403,6 +410,9 @@ static char *morphprep(char *s) + char word[WORDBUF], end[WORDBUF]; + static char retval[WORDBUF]; + ++ if (strlen(s) > WORDBUF - 1) ++ return (NULL); ++ + /* Assume that the verb is the first word in the phrase. Strip it + off, check for validity, then try various morphs with the + rest of the phrase tacked on, trying to find a match. */ +@@ -410,7 +420,7 @@ static char *morphprep(char *s) + rest = strchr(s, '_'); + last = strrchr(s, '_'); + if (rest != last) { /* more than 2 words */ +- if (lastwd = morphword(last + 1, NOUN)) { ++ if ((lastwd = morphword(last + 1, NOUN)) != NULL) { + strncpy(end, rest, last - rest + 1); + end[last-rest+1] = '\0'; + strcat(end, lastwd); +--- a/lib/search.c ++++ b/lib/search.c +@@ -13,6 +13,7 @@ + #include <stdlib.h> + #include <string.h> + #include <assert.h> ++#include <limits.h> + + #include "wn.h" + +@@ -119,33 +120,22 @@ IndexPtr parse_index(long offset, int db + if ( !line ) + line = read_index( offset, indexfps[dbase] ); + +- idx = (IndexPtr)malloc(sizeof(Index)); ++ idx = (IndexPtr)calloc(1, sizeof(Index)); + assert(idx); + + /* set offset of entry in index file */ + idx->idxoffset = offset; + +- idx->wd='\0'; +- idx->pos='\0'; +- idx->off_cnt=0; +- idx->tagged_cnt = 0; +- idx->sense_cnt=0; +- idx->offset='\0'; +- idx->ptruse_cnt=0; +- idx->ptruse='\0'; +- + /* get the word */ + ptrtok=strtok(line," \n"); + +- idx->wd = malloc(strlen(ptrtok) + 1); ++ idx->wd = strdup(ptrtok); + assert(idx->wd); +- strcpy(idx->wd, ptrtok); + + /* get the part of speech */ + ptrtok=strtok(NULL," \n"); +- idx->pos = malloc(strlen(ptrtok) + 1); ++ idx->pos = strdup(ptrtok); + assert(idx->pos); +- strcpy(idx->pos, ptrtok); + + /* get the collins count */ + ptrtok=strtok(NULL," \n"); +@@ -154,7 +144,12 @@ IndexPtr parse_index(long offset, int db + /* get the number of pointers types */ + ptrtok=strtok(NULL," \n"); + idx->ptruse_cnt = atoi(ptrtok); +- ++ ++ if (idx->ptruse_cnt < 0 || (unsigned int)idx->ptruse_cnt > UINT_MAX/sizeof(int)) { ++ free_index(idx); ++ return(NULL); ++ } ++ + if (idx->ptruse_cnt) { + idx->ptruse = (int *) malloc(idx->ptruse_cnt * (sizeof(int))); + assert(idx->ptruse); +@@ -173,9 +168,14 @@ IndexPtr parse_index(long offset, int db + /* get the number of senses that are tagged */ + ptrtok=strtok(NULL," \n"); + idx->tagged_cnt = atoi(ptrtok); +- ++ ++ if (idx->off_cnt < 0 || (unsigned long)idx->off_cnt > ULONG_MAX/sizeof(long)) { ++ free_index(idx); ++ return(NULL); ++ } ++ + /* make space for the offsets */ +- idx->offset = (long *) malloc(idx->off_cnt * (sizeof(long))); ++ idx->offset = (unsigned long *) malloc(idx->off_cnt * sizeof(long)); + assert(idx->offset); + + /* get the offsets */ +@@ -197,15 +197,21 @@ IndexPtr getindex(char *searchstr, int d + char strings[MAX_FORMS][WORDBUF]; /* vector of search strings */ + static IndexPtr offsets[MAX_FORMS]; + static int offset; +- ++ + /* This works like strrok(): if passed with a non-null string, + prepare vector of search strings and offsets. If string + is null, look at current list of offsets and return next + one, or NULL if no more alternatives for this word. */ + + if (searchstr != NULL) { ++ /* Bail out if the input is too long for us to handle */ ++ if (strlen(searchstr) > (WORDBUF - 1)) { ++ strcpy(msgbuf, "WordNet library error: search term is too long\n"); ++ display_message(msgbuf); ++ return(NULL); ++ } + +- offset = 0; ++ offset = 0; + strtolower(searchstr); + for (i = 0; i < MAX_FORMS; i++) { + strcpy(strings[i], searchstr); +@@ -229,11 +235,11 @@ IndexPtr getindex(char *searchstr, int d + /* Get offset of first entry. Then eliminate duplicates + and get offsets of unique strings. */ + +- if (strings[0][0] != NULL) ++ if (strings[0] != NULL) + offsets[0] = index_lookup(strings[0], dbase); + + for (i = 1; i < MAX_FORMS; i++) +- if ((strings[i][0]) != NULL && (strcmp(strings[0], strings[i]))) ++ if (strings[i] != NULL && (strcmp(strings[0], strings[i]))) + offsets[i] = index_lookup(strings[i], dbase); + } + +@@ -272,7 +278,7 @@ SynsetPtr read_synset(int dbase, long bo + SynsetPtr parse_synset(FILE *fp, int dbase, char *word) + { + static char line[LINEBUF]; +- char tbuf[SMLINEBUF]; ++ char tbuf[SMLINEBUF] = ""; + char *ptrtok; + char *tmpptr; + int foundpert = 0; +@@ -286,33 +292,11 @@ SynsetPtr parse_synset(FILE *fp, int dba + if ((tmpptr = fgets(line, LINEBUF, fp)) == NULL) + return(NULL); + +- synptr = (SynsetPtr)malloc(sizeof(Synset)); ++ synptr = (SynsetPtr)calloc(1, sizeof(Synset)); + assert(synptr); +- +- synptr->hereiam = 0; ++ + synptr->sstype = DONT_KNOW; +- synptr->fnum = 0; +- synptr->pos = '\0'; +- synptr->wcount = 0; +- synptr->words = '\0'; +- synptr->whichword = 0; +- synptr->ptrcount = 0; +- synptr->ptrtyp = '\0'; +- synptr->ptroff = '\0'; +- synptr->ppos = '\0'; +- synptr->pto = '\0'; +- synptr->pfrm = '\0'; +- synptr->fcount = 0; +- synptr->frmid = '\0'; +- synptr->frmto = '\0'; +- synptr->defn = '\0'; +- synptr->key = 0; +- synptr->nextss = NULL; +- synptr->nextform = NULL; + synptr->searchtype = -1; +- synptr->ptrlist = NULL; +- synptr->headword = NULL; +- synptr->headsense = 0; + + ptrtok = line; + +@@ -322,7 +306,7 @@ SynsetPtr parse_synset(FILE *fp, int dba + + /* sanity check - make sure starting file offset matches first field */ + if (synptr->hereiam != loc) { +- sprintf(msgbuf, "WordNet library error: no synset at location %d\n", ++ sprintf(msgbuf, "WordNet library error: no synset at location %ld\n", + loc); + display_message(msgbuf); + free(synptr); +@@ -335,16 +319,20 @@ SynsetPtr parse_synset(FILE *fp, int dba + + /* looking at POS */ + ptrtok = strtok(NULL, " \n"); +- synptr->pos = malloc(strlen(ptrtok) + 1); ++ synptr->pos = strdup(ptrtok); + assert(synptr->pos); +- strcpy(synptr->pos, ptrtok); + if (getsstype(synptr->pos) == SATELLITE) + synptr->sstype = INDIRECT_ANT; + + /* looking at numwords */ + ptrtok = strtok(NULL, " \n"); + synptr->wcount = strtol(ptrtok, NULL, 16); +- ++ ++ if (synptr->wcount < 0 || (unsigned int)synptr->wcount > UINT_MAX/sizeof(char *)) { ++ free_syns(synptr); ++ return(NULL); ++ } ++ + synptr->words = (char **)malloc(synptr->wcount * sizeof(char *)); + assert(synptr->words); + synptr->wnsns = (int *)malloc(synptr->wcount * sizeof(int)); +@@ -354,9 +342,8 @@ SynsetPtr parse_synset(FILE *fp, int dba + + for (i = 0; i < synptr->wcount; i++) { + ptrtok = strtok(NULL, " \n"); +- synptr->words[i] = malloc(strlen(ptrtok) + 1); ++ synptr->words[i] = strdup(ptrtok); + assert(synptr->words[i]); +- strcpy(synptr->words[i], ptrtok); + + /* is this the word we're looking for? */ + +@@ -371,6 +358,12 @@ SynsetPtr parse_synset(FILE *fp, int dba + ptrtok = strtok(NULL," \n"); + synptr->ptrcount = atoi(ptrtok); + ++ /* Should we check for long here as well? */ ++ if (synptr->ptrcount < 0 || (unsigned int)synptr->ptrcount > UINT_MAX/sizeof(int)) { ++ free_syns(synptr); ++ return(NULL); ++ } ++ + if (synptr->ptrcount) { + + /* alloc storage for the pointers */ +@@ -455,21 +448,23 @@ SynsetPtr parse_synset(FILE *fp, int dba + ptrtok = strtok(NULL," \n"); + if (ptrtok) { + ptrtok = strtok(NULL," \n"); +- sprintf(tbuf, ""); + while (ptrtok != NULL) { ++ if (strlen(ptrtok) + strlen(tbuf) + 1 + 1 > sizeof(tbuf)) { ++ free_syns(synptr); ++ return(NULL); ++ } + strcat(tbuf,ptrtok); + ptrtok = strtok(NULL, " \n"); + if(ptrtok) + strcat(tbuf," "); + } +- assert((1 + strlen(tbuf)) < sizeof(tbuf)); +- synptr->defn = malloc(strlen(tbuf) + 4); ++ synptr->defn = malloc(strlen(tbuf) + 3); + assert(synptr->defn); + sprintf(synptr->defn,"(%s)",tbuf); + } + + if (keyindexfp) { /* we have unique keys */ +- sprintf(tmpbuf, "%c:%8.8d", partchars[dbase], synptr->hereiam); ++ sprintf(tmpbuf, "%c:%8.8ld", partchars[dbase], synptr->hereiam); + synptr->key = GetKeyForOffset(tmpbuf); + } + +@@ -635,7 +630,7 @@ static void traceptrs(SynsetPtr synptr, + + if ((ptrtyp == PERTPTR || ptrtyp == PPLPTR) && + synptr->pto[i] != 0) { +- sprintf(tbuf, " (Sense %d)\n", ++ snprintf(tbuf, sizeof(tbuf), " (Sense %d)\n", + cursyn->wnsns[synptr->pto[i] - 1]); + printsynset(prefix, cursyn, tbuf, DEFOFF, synptr->pto[i], + SKIP_ANTS, PRINT_MARKER); +@@ -656,7 +651,7 @@ static void traceptrs(SynsetPtr synptr, + traceptrs(cursyn, HYPERPTR, getpos(cursyn->pos), 0); + } + } else if (ptrtyp == ANTPTR && dbase != ADJ && synptr->pto[i] != 0) { +- sprintf(tbuf, " (Sense %d)\n", ++ snprintf(tbuf, sizeof(tbuf), " (Sense %d)\n", + cursyn->wnsns[synptr->pto[i] - 1]); + printsynset(prefix, cursyn, tbuf, DEFOFF, synptr->pto[i], + SKIP_ANTS, PRINT_MARKER); +@@ -817,7 +812,7 @@ static void tracenomins(SynsetPtr synptr + + cursyn = read_synset(synptr->ppos[i], synptr->ptroff[i], ""); + +- sprintf(tbuf, "#%d\n", ++ snprintf(tbuf, sizeof(tbuf), "#%d\n", + cursyn->wnsns[synptr->pto[i] - 1]); + printsynset(prefix, cursyn, tbuf, DEFOFF, synptr->pto[i], + SKIP_ANTS, SKIP_MARKER); +@@ -989,12 +984,12 @@ void getexample(char *offset, char *wd) + char sentbuf[512]; + + if (vsentfilefp != NULL) { +- if (line = bin_search(offset, vsentfilefp)) { ++ if ((line = bin_search(offset, vsentfilefp)) != NULL) { + while(*line != ' ') + line++; + + printbuffer(" EX: "); +- sprintf(sentbuf, line, wd); ++ snprintf(sentbuf, sizeof(sentbuf), line, wd); + printbuffer(sentbuf); + } + } +@@ -1011,7 +1006,7 @@ int findexample(SynsetPtr synptr) + if (vidxfilefp != NULL) { + wdnum = synptr->whichword - 1; + +- sprintf(tbuf,"%s%%%-1.1d:%-2.2d:%-2.2d::", ++ snprintf(tbuf, sizeof(tbuf), "%s%%%-1.1d:%-2.2d:%-2.2d::", + synptr->words[wdnum], + getpos(synptr->pos), + synptr->fnum, +@@ -1124,7 +1119,7 @@ static void freq_word(IndexPtr index) + if (cnt >= 17 && cnt <= 32) familiar = 6; + if (cnt > 32 ) familiar = 7; + +- sprintf(tmpbuf, ++ snprintf(tmpbuf, sizeof(tmpbuf), + "\n%s used as %s is %s (polysemy count = %d)\n", + index->wd, a_an[getpos(index->pos)], freqcats[familiar], cnt); + printbuffer(tmpbuf); +@@ -1147,6 +1142,9 @@ void wngrep (char *word_passed, int pos) + } + rewind(inputfile); + ++ if (strlen(word_passed) + 1 > sizeof(word)) ++ return; ++ + strcpy (word, word_passed); + ToLowerCase(word); /* map to lower case for index file search */ + strsubst (word, ' ', '_'); /* replace spaces with underscores */ +@@ -1169,7 +1167,7 @@ void wngrep (char *word_passed, int pos) + ((line[loc + wordlen] == '-') || (line[loc + wordlen] == '_'))) + ) { + strsubst (line, '_', ' '); +- sprintf (tmpbuf, "%s\n", line); ++ snprintf (tmpbuf, sizeof(tmpbuf), "%s\n", line); + printbuffer (tmpbuf); + break; + } +@@ -1683,9 +1681,8 @@ SynsetPtr traceptrs_ds(SynsetPtr synptr, + cursyn = read_synset(synptr->ppos[i], + synptr->ptroff[i], + ""); +- synptr->headword = malloc(strlen(cursyn->words[0]) + 1); ++ synptr->headword = strdup(cursyn->words[0]); + assert(synptr->headword); +- strcpy(synptr->headword, cursyn->words[0]); + synptr->headsense = cursyn->lexid[0]; + free_synset(cursyn); + break; +@@ -2013,7 +2010,7 @@ static int getsearchsense(SynsetPtr synp + strsubst(strcpy(wdbuf, synptr->words[whichword - 1]), ' ', '_'); + strtolower(wdbuf); + +- if (idx = index_lookup(wdbuf, getpos(synptr->pos))) { ++ if ((idx = index_lookup(wdbuf, getpos(synptr->pos))) != NULL) { + for (i = 0; i < idx->off_cnt; i++) + if (idx->offset[i] == synptr->hereiam) { + free_index(idx); +@@ -2037,7 +2034,7 @@ static void printsynset(char *head, Syns + by flags */ + + if (offsetflag) /* print synset offset */ +- sprintf(tbuf + strlen(tbuf),"{%8.8d} ", synptr->hereiam); ++ sprintf(tbuf + strlen(tbuf),"{%8.8ld} ", synptr->hereiam); + if (fileinfoflag) { /* print lexicographer file information */ + sprintf(tbuf + strlen(tbuf), "<%s> ", lexfiles[synptr->fnum]); + prlexid = 1; /* print lexicographer id after word */ +@@ -2072,7 +2069,7 @@ static void printantsynset(SynsetPtr syn + tbuf[0] = '\0'; + + if (offsetflag) +- sprintf(tbuf,"{%8.8d} ", synptr->hereiam); ++ sprintf(tbuf,"{%8.8ld} ", synptr->hereiam); + if (fileinfoflag) { + sprintf(tbuf + strlen(tbuf),"<%s> ", lexfiles[synptr->fnum]); + prlexid = 1; +--- a/lib/wnutil.c ++++ b/lib/wnutil.c +@@ -48,7 +48,7 @@ int wninit(void) + char *env; + + if (!done) { +- if (env = getenv("WNDBVERSION")) { ++ if ((env = getenv("WNDBVERSION")) != NULL) { + wnrelease = strdup(env); /* set release */ + assert(wnrelease); + } +@@ -70,7 +70,7 @@ int re_wninit(void) + + closefps(); + +- if (env = getenv("WNDBVERSION")) { ++ if ((env = getenv("WNDBVERSION")) != NULL) { + wnrelease = strdup(env); /* set release */ + assert(wnrelease); + } +@@ -149,25 +149,25 @@ static int do_init(void) + sprintf(searchdir, DEFAULTPATH); + #else + if ((env = getenv("WNSEARCHDIR")) != NULL) +- strcpy(searchdir, env); ++ snprintf(searchdir, sizeof(searchdir), "%s", env); + else if ((env = getenv("WNHOME")) != NULL) +- sprintf(searchdir, "%s%s", env, DICTDIR); ++ snprintf(searchdir, sizeof(searchdir), "%s%s", env, DICTDIR); + else + strcpy(searchdir, DEFAULTPATH); + #endif + + for (i = 1; i < NUMPARTS + 1; i++) { +- sprintf(tmpbuf, DATAFILE, searchdir, partnames[i]); ++ snprintf(tmpbuf, sizeof(tmpbuf), DATAFILE, searchdir, partnames[i]); + if((datafps[i] = fopen(tmpbuf, "r")) == NULL) { +- sprintf(msgbuf, ++ snprintf(msgbuf, sizeof(msgbuf), + "WordNet library error: Can't open datafile(%s)\n", + tmpbuf); + display_message(msgbuf); + openerr = -1; + } +- sprintf(tmpbuf, INDEXFILE, searchdir, partnames[i]); ++ snprintf(tmpbuf, sizeof(tmpbuf), INDEXFILE, searchdir, partnames[i]); + if((indexfps[i] = fopen(tmpbuf, "r")) == NULL) { +- sprintf(msgbuf, ++ snprintf(msgbuf, sizeof(msgbuf), + "WordNet library error: Can't open indexfile(%s)\n", + tmpbuf); + display_message(msgbuf); +@@ -178,35 +178,35 @@ static int do_init(void) + /* This file isn't used by the library and doesn't have to + be present. No error is reported if the open fails. */ + +- sprintf(tmpbuf, SENSEIDXFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), SENSEIDXFILE, searchdir); + sensefp = fopen(tmpbuf, "r"); + + /* If this file isn't present, the runtime code will skip printint out + the number of times each sense was tagged. */ + +- sprintf(tmpbuf, CNTLISTFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), CNTLISTFILE, searchdir); + cntlistfp = fopen(tmpbuf, "r"); + + /* This file doesn't have to be present. No error is reported if the + open fails. */ + +- sprintf(tmpbuf, KEYIDXFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), KEYIDXFILE, searchdir); + keyindexfp = fopen(tmpbuf, "r"); + +- sprintf(tmpbuf, REVKEYIDXFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), REVKEYIDXFILE, searchdir); + revkeyindexfp = fopen(tmpbuf, "r"); + +- sprintf(tmpbuf, VRBSENTFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), VRBSENTFILE, searchdir); + if ((vsentfilefp = fopen(tmpbuf, "r")) == NULL) { +- sprintf(msgbuf, ++ snprintf(msgbuf, sizeof(msgbuf), + "WordNet library warning: Can't open verb example sentence file(%s)\n", + tmpbuf); + display_message(msgbuf); + } + +- sprintf(tmpbuf, VRBIDXFILE, searchdir); ++ snprintf(tmpbuf, sizeof(tmpbuf), VRBIDXFILE, searchdir); + if ((vidxfilefp = fopen(tmpbuf, "r")) == NULL) { +- sprintf(msgbuf, ++ snprintf(msgbuf, sizeof(msgbuf), + "WordNet library warning: Can't open verb example sentence index file(%s)\n", + tmpbuf); + display_message(msgbuf); +--- a/src/wn.c ++++ b/src/wn.c +@@ -131,7 +131,7 @@ static void printusage(), printlicense() + printsearches(char *, int, unsigned long); + static int error_message(char *); + +-main(int argc,char *argv[]) ++int main(int argc,char *argv[]) + { + display_message = error_message; + +@@ -228,14 +228,14 @@ static int do_search(char *searchword, i + printf("\n%s of %s %s\n%s", + label, partnames[pos], searchword, outbuf); + +- if (morphword = morphstr(searchword, pos)) ++ if ((morphword = morphstr(searchword, pos)) != NULL) + do { + outbuf = findtheinfo(morphword, pos, search, whichsense); + totsenses += wnresults.printcnt; + if (strlen(outbuf) > 0) + printf("\n%s of %s %s\n%s", + label, partnames[pos], morphword, outbuf); +- } while (morphword = morphstr(NULL, pos)); ++ } while ((morphword = morphstr(NULL, pos)) != NULL); + + return(totsenses); + } diff --git a/gnu/packages/patches/wordnet-CVE-2008-3908-pt2.patch b/gnu/packages/patches/wordnet-CVE-2008-3908-pt2.patch new file mode 100644 index 0000000000..2ef2239a7f --- /dev/null +++ b/gnu/packages/patches/wordnet-CVE-2008-3908-pt2.patch @@ -0,0 +1,18 @@ +This patch was created by oCert according to + http://www.ocert.org/advisories/ocert-2008-014.html +Unfortunately the original patch contained a bug which was +later fixed by the issuer of the patch Rob Holland <rob@ocert.org> +This part was now separated in this file. + +--- a/lib/search.c ++++ b/lib/search.c +@@ -1568,7 +1568,8 @@ char *findtheinfo(char *searchstr, int d + bufstart[0] = '\n'; + bufstart++; + } +- strncpy(bufstart, tmpbuf, strlen(tmpbuf)); ++ /* Avoid writing a trailing \0 after the string */ ++ memcpy(bufstart, tmpbuf, strlen(tmpbuf)); + bufstart = searchbuffer + strlen(searchbuffer); + } + } |