From 33657b9465a62615ae6b389c7d39d8270f41cbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 22 Jan 2024 00:30:44 -0300 Subject: [PATCH 1/5] python3-scipy: update to 1.12.0. --- srcpkgs/python3-scipy/patches/19909.patch | 40 +++++++++++++++++++ .../python3-scipy/patches/dep-versions.patch | 23 ----------- srcpkgs/python3-scipy/template | 13 ++++-- 3 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 srcpkgs/python3-scipy/patches/19909.patch delete mode 100644 srcpkgs/python3-scipy/patches/dep-versions.patch diff --git a/srcpkgs/python3-scipy/patches/19909.patch b/srcpkgs/python3-scipy/patches/19909.patch new file mode 100644 index 0000000000000..b861d2b96c33c --- /dev/null +++ b/srcpkgs/python3-scipy/patches/19909.patch @@ -0,0 +1,40 @@ +See: https://github.com/scipy/scipy/pull/19909 + +From 8c96a1f742335bca283aae418763aaba62c03378 Mon Sep 17 00:00:00 2001 +From: Ilhan Polat +Date: Thu, 18 Jan 2024 14:47:42 +0100 +Subject: [PATCH] MAINT:linalg:Adjust lwork/liwork changes OpenBLAS 0.3.26 + +See https://github.com/Reference-LAPACK/lapack/pull/942 +--- + scipy/linalg/flapack_sym_herm.pyf.src | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/scipy/linalg/flapack_sym_herm.pyf.src b/scipy/linalg/flapack_sym_herm.pyf.src +index f07dbaecbc72..af04e0d8d8d8 100644 +--- a/scipy/linalg/flapack_sym_herm.pyf.src ++++ b/scipy/linalg/flapack_sym_herm.pyf.src +@@ -762,8 +762,8 @@ subroutine syevr(compute_v,range,lower,n,a,lda,vl,vu,il,iu,abstol,w,z,m + optional,intent(in) :: vl=0.0 + optional,intent(in),check(vu>=vl),depend(vl) :: vu=1.0 + intent(in) :: abstol=0.0 +- integer optional,intent(in),depend(n),check(lwork>=max(1,26*n)||lwork==-1) :: lwork=max(26*n,1) +- integer optional,intent(in),depend(n),check(liwork>=max(1,10*n)||liwork==-1):: liwork= max(1,10*n) ++ integer optional,intent(in),depend(n),check(lwork>=(n <= 1 ? 1 : max(1,26*n))||lwork==-1) :: lwork=max(26*n,1) ++ integer optional,intent(in),depend(n),check(liwork>=(n <= 1 ? 1 : max(1,10*n))||liwork==-1):: liwork= max(1,10*n) + + integer intent(hide),depend(a) :: n=shape(a,0) + integer intent(hide),depend(n) :: lda=max(1,n) +@@ -832,9 +832,9 @@ subroutine heevr(compute_v,range,lower,n,a,lda,vl,vu,il,iu,abstol,w,z, + optional,intent(in) :: vl=0.0 + optional,intent(in),check(vu>vl),depend(vl) :: vu=1.0 + intent(in) :: abstol=0.0 +- integer optional,intent(in),depend(n),check(lwork>=max(2*n,1)||lwork==-1) :: lwork=max(2*n,1) +- integer optional,intent(in),depend(n),check(lrwork>=max(24*n,1)||lrwork==-1) :: lrwork=max(24*n,1) +- integer optional,intent(in),depend(n),check(liwork>=max(1,10*n)||liwork==-1):: liwork= max(1,10*n) ++ integer optional,intent(in),depend(n),check(lwork>=(n <= 1 ? 1 : max(1,2*n))||lwork==-1) :: lwork=max(2*n,1) ++ integer optional,intent(in),depend(n),check(lrwork>=(n <= 1 ? 1 : max(1,24*n))||lrwork==-1) :: lrwork=max(24*n,1) ++ integer optional,intent(in),depend(n),check(liwork>=(n <= 1 ? 1 : max(1,10*n))||liwork==-1):: liwork= max(1,10*n) + + integer intent(hide),depend(a) :: n=shape(a,0) + integer intent(hide),depend(n) :: lda=max(1,n) diff --git a/srcpkgs/python3-scipy/patches/dep-versions.patch b/srcpkgs/python3-scipy/patches/dep-versions.patch deleted file mode 100644 index ac62f0b7fb069..0000000000000 --- a/srcpkgs/python3-scipy/patches/dep-versions.patch +++ /dev/null @@ -1,23 +0,0 @@ -Several dependencies have needlessly restrictive version requirements, which -causes build failures against more up-to-date Void packages. - ---- a/pyproject.toml -+++ b/pyproject.toml -@@ -11,13 +11,13 @@ - build-backend = 'mesonpy' - requires = [ - # Reason for `<`: future-proofing (0.14.0 released and known to work) -- "meson-python>=0.12.1,<0.15.0", -+ "meson-python>=0.12.1", - # Reason for `<`: we want to build the 1.11.x releases with 0.29.x (too many changes in 3.0) -- "Cython>=0.29.35,<3.0", # when updating version, also update check in meson.build -+ "Cython>=0.29.35", - # Reason for `<`: future-proofing (2.11.1 is the most recent version) -- "pybind11>=2.10.4,<2.11.1", -+ "pybind11>=2.10.4", - # Reason for `<`: future-proofing (0.14.0 released and known to work) -- "pythran>=0.12.0,<0.15.0", -+ "pythran>=0.12.0", - - # NumPy dependencies - to update these, sync from - # https://github.com/scipy/oldest-supported-numpy/, and then diff --git a/srcpkgs/python3-scipy/template b/srcpkgs/python3-scipy/template index 88128aaa3a3bb..3915ca79f5f0e 100644 --- a/srcpkgs/python3-scipy/template +++ b/srcpkgs/python3-scipy/template @@ -1,6 +1,6 @@ # Template file for 'python3-scipy' pkgname=python3-scipy -version=1.11.4 +version=1.12.0 revision=1 build_style=python3-pep517 build_helper="meson numpy" @@ -12,13 +12,16 @@ hostmakedepends="python3-meson-python python3-Cython python3-pybind11 makedepends="python3-devel python3-pybind11 python3-numpy pythran $(vopt_if openblas openblas-devel "lapack-devel cblas-devel")" depends="python3-numpy" +checkdepends="python3-pytest python3-pytest-xdist python3-hypothesis python3-pooch + python3-matplotlib python3-mpmath python3-psutil python3-sympy" short_desc="Scientific library for Python3" maintainer="Andrew J. Hesford " license="BSD-3-Clause" homepage="https://scipy.org/" distfiles="${PYPI_SITE}/s/scipy/scipy-${version}.tar.gz" -checksum=90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa -make_check="no" # Tests need an installed copy to run and meson makes this tough +checksum=4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3 +# must be tested from site dir of installed version (see dev.py:739) +make_check_pre='eval env -C "${testdir}/${py3_sitelib}"' build_options="openblas" @@ -37,6 +40,10 @@ if [ "$build_option_openblas" ]; then esac fi +if [ "$XBPS_CHECK_PKGS" != full ]; then + make_check_args="-m 'not slow'" +fi + post_install() { vlicense LICENSE.txt } From 9636e16498b909625f23fe93b9e02c9613dba8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 22 Jan 2024 00:34:32 -0300 Subject: [PATCH 2/5] sagemath: patch for scipy 1.12. See: https://github.com/sagemath/sage/pull/37123 Also apply a few minor fixes. --- srcpkgs/sagemath/files/sage_conf.py | 1 + .../patches/36862-giac_1.9.0-73.patch | 15 ++ ...fix_save_session_when_cython_changes.patch | 182 ++++++++++++++++++ .../sagemath/patches/37123-scipy_1.12.patch | 26 +++ srcpkgs/sagemath/patches/get_patches | 7 +- srcpkgs/sagemath/template | 8 +- 6 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch create mode 100644 srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch create mode 100644 srcpkgs/sagemath/patches/37123-scipy_1.12.patch diff --git a/srcpkgs/sagemath/files/sage_conf.py b/srcpkgs/sagemath/files/sage_conf.py index bc5388de8956d..b5b2360311844 100644 --- a/srcpkgs/sagemath/files/sage_conf.py +++ b/srcpkgs/sagemath/files/sage_conf.py @@ -1,3 +1,4 @@ # configuration for sage on void linux SAGE_SHARE = "/usr/share/sagemath" GAP_SHARE_DIR = "/usr/share/gap" +JMOL_DIR = "/usr/share/jmol" diff --git a/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch b/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch new file mode 100644 index 0000000000000..8eb2c20a34c52 --- /dev/null +++ b/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch @@ -0,0 +1,15 @@ +diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py +index dfaafb4353f..8d62ade24c8 100644 +--- a/src/sage/calculus/calculus.py ++++ b/src/sage/calculus/calculus.py +@@ -568,8 +568,8 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): + + An example of this summation with Giac:: + +- sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac') +- (pi*e^(2*pi) - pi*e^(-2*pi))/(e^(2*pi) + e^(-2*pi) - 2) ++ sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac').factor() ++ pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) + + The same summation is solved by SymPy:: + diff --git a/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch b/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch new file mode 100644 index 0000000000000..c3e6c05502621 --- /dev/null +++ b/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch @@ -0,0 +1,182 @@ +diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py +index efd28d10abe..56a9fe5e8f6 100644 +--- a/src/sage/doctest/forker.py ++++ b/src/sage/doctest/forker.py +@@ -2477,19 +2477,6 @@ class DocTestTask(): + ['cputime', 'err', 'failures', 'optionals', 'tests', 'walltime', 'walltime_skips'] + """ + +- extra_globals = {} +- """ +- Extra objects to place in the global namespace in which tests are run. +- Normally this should be empty but there are special cases where it may +- be useful. +- +- For example, in Sage versions 9.1 and earlier, on Python 3 add +- ``long`` as an alias for ``int`` so that tests that use the +- ``long`` built-in (of which there are many) still pass. We did +- this so that the test suite could run on Python 3 while Python 2 +- was still the default. +- """ +- + def __init__(self, source): + """ + Initialization. +@@ -2614,10 +2601,6 @@ def _run(self, runner, options, results): + # Remove '__package__' item from the globals since it is not + # always in the globals in an actual Sage session. + dict_all.pop('__package__', None) +- +- # Add any other special globals for testing purposes only +- dict_all.update(self.extra_globals) +- + sage_namespace = RecordingDict(dict_all) + sage_namespace['__name__'] = '__main__' + doctests, extras = self.source.create_doctests(sage_namespace) +diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx +index 31454dac993..53b732309da 100644 +--- a/src/sage/misc/session.pyx ++++ b/src/sage/misc/session.pyx +@@ -27,7 +27,7 @@ This saves a dictionary with ``w`` as one of the keys:: + + sage: z = load(os.path.join(d.name, 'session')) + sage: list(z) +- ['d', 'w'] ++ ['w', 'd'] + sage: z['w'] + 2/3 + +@@ -68,11 +68,12 @@ AUTHOR: + import builtins + import types + +-# We want the caller's locals, but locals() is emulated in Cython +-cdef caller_locals = builtins.locals +- + # Sage imports + from sage.misc.persist import load, save, loads, dumps ++from sage.misc.lazy_import import LazyImport ++ ++# We want the caller's locals, but locals() is emulated in Cython ++cdef caller_locals = builtins.locals + + # This module-scope variables is used to save the + # global state of the sage environment at the moment +@@ -80,7 +81,6 @@ from sage.misc.persist import load, save, loads, dumps + + state_at_init = None + +-CythonFunctionType = type(lambda: None) + + def init(state=None): + """ +@@ -163,9 +163,13 @@ def _is_new_var(x, v, hidden): + # definitely new. + if x not in state_at_init: + return True ++ # A lazy import that was there at init time is not new ++ if isinstance(v, LazyImport): ++ return False + # A variable could also be new even if it was there at init, say if + # its value changed. +- return x not in state_at_init or state_at_init[x] is not v ++ return state_at_init[x] is not v ++ + + def show_identifiers(hidden=False): + r""" +@@ -196,7 +200,7 @@ def show_identifiers(hidden=False): + sage: a = 10 + sage: factor = 20 + sage: show_identifiers() +- ['a', 'factor'] ++ ['factor', 'a'] + + To get the actual value of a variable from the list, use the + :func:`globals()` function.:: +@@ -210,7 +214,7 @@ def show_identifiers(hidden=False): + + sage: _hello = 10 + sage: show_identifiers() +- ['a', 'factor'] ++ ['factor', 'a'] + sage: '_hello' in show_identifiers(hidden=True) + True + +@@ -218,19 +222,13 @@ def show_identifiers(hidden=False): + least in command line mode.:: + + sage: show_identifiers(hidden=True) # random output +- ['__', '_i', '_6', '_4', '_3', '_1', '_ii', '__doc__', '__builtins__', '___', '_9', '__name__', '_', 'a', '_i12', '_i14', 'factor', '__file__', '_hello', '_i13', '_i11', '_i10', '_i15', '_i5', '_13', '_10', '_iii', '_i9', '_i8', '_i7', '_i6', '_i4', '_i3', '_i2', '_i1', '_init_cmdline', '_14'] ++ ['__builtin__', '_ih', '_oh', '_dh', 'exit', 'quit', '_', '__', '___', ++ '_i', '_ii', '_iii', '_i1', 'factor', '_i2', '_2', '_i3', 'a', '_i4', ++ '_i5', '_5', '_i6', '_6', '_i7', '_hello', '_i8', '_8', '_i9', '_9', ++ '_i10'] + """ +- from sage.doctest.forker import DocTestTask + state = caller_locals() +- # Ignore extra variables injected into the global namespace by the doctest +- # runner +- _none = object() +- +- def _in_extra_globals(name, val): +- return val == DocTestTask.extra_globals.get(name, _none) +- +- return sorted([x for x, v in state.items() if _is_new_var(x, v, hidden) +- and not _in_extra_globals(x, v)]) ++ return [x for x, v in state.items() if _is_new_var(x, v, hidden)] + + + def save_session(name='sage_session', verbose=False): +@@ -293,28 +291,44 @@ def save_session(name='sage_session', verbose=False): + sage: f = lambda x : x^2 + sage: save_session(tmp_f) + sage: save_session(tmp_f, verbose=True) +- Saving... +- Not saving f: f is a function, method, class or type + ... ++ Not saving f: f is a function or method + + Something similar happens for cython-defined functions:: + + sage: g = cython_lambda('double x', 'x*x + 1.5') + sage: save_session(tmp_f, verbose=True) +- Saving... +- Not saving g: g is a function, method, class or type + ... ++ Not saving g: g is a cython function or method ++ ++ And the same for a lazy import:: ++ ++ sage: from sage.misc.lazy_import import LazyImport ++ sage: lazy_ZZ = LazyImport('sage.rings.integer_ring', 'ZZ') ++ sage: save_session(tmp_f, verbose=True) ++ ... ++ Not saving lazy_ZZ: lazy_ZZ is a lazy import + """ + state = caller_locals() + # This dict D will contain the session -- as a dict -- that we will save to disk. + D = {} + # We iterate only over the new variables that were defined in this + # session, since those are the only ones we will save. +- for k in show_identifiers(hidden = True): ++ for k in show_identifiers(hidden=True): + try: + x = state[k] +- if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType, CythonFunctionType, type)): +- raise TypeError('{} is a function, method, class or type'.format(k)) ++ ++ if isinstance(x, type): ++ raise TypeError('{} is a class or type'.format(k)) ++ ++ if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType)): ++ raise TypeError('{} is a function or method'.format(k)) ++ ++ if getattr(type(x), '__name__', None) == 'cython_function_or_method': ++ raise TypeError('{} is a cython function or method'.format(k)) ++ ++ if isinstance(x, LazyImport): ++ raise TypeError('{} is a lazy import'.format(k)) + + # We attempt to pickle *and* unpickle every variable to + # make *certain* that we can pickled D at the end below. diff --git a/srcpkgs/sagemath/patches/37123-scipy_1.12.patch b/srcpkgs/sagemath/patches/37123-scipy_1.12.patch new file mode 100644 index 0000000000000..3973b55cdbd51 --- /dev/null +++ b/srcpkgs/sagemath/patches/37123-scipy_1.12.patch @@ -0,0 +1,26 @@ +diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx +index 5d19067f2ed..97e50fb2616 100644 +--- a/src/sage/matrix/matrix_double_dense.pyx ++++ b/src/sage/matrix/matrix_double_dense.pyx +@@ -867,7 +867,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): + # set cutoff as RDF element + if eps == 'auto': + if scipy is None: import scipy +- eps = 2*max(self._nrows, self._ncols)*scipy.finfo(float).eps*sv[0] ++ eps = 2*max(self._nrows, self._ncols)*numpy.finfo(float).eps*sv[0] + eps = RDF(eps) + # locate non-zero entries + rank = 0 +diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py +index 708d440a205..9f973c6bd69 100644 +--- a/src/sage/numerical/optimize.py ++++ b/src/sage/numerical/optimize.py +@@ -426,7 +426,7 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", + hess = func.hessian() + hess_fast = [ [fast_callable(a, vars=var_names, domain=float) for a in row] for row in hess] + hessian = lambda p: [[a(*p) for a in row] for row in hess_fast] +- from scipy import dot ++ from numpy import dot + hessian_p = lambda p,v: dot(numpy.array(hessian(p)),v) + min = optimize.fmin_ncg(f, [float(_) for _ in x0], fprime=gradient, + fhess=hessian, fhess_p=hessian_p, disp=verbose, **args) diff --git a/srcpkgs/sagemath/patches/get_patches b/srcpkgs/sagemath/patches/get_patches index a552b402727d3..b7836e27910d5 100755 --- a/srcpkgs/sagemath/patches/get_patches +++ b/srcpkgs/sagemath/patches/get_patches @@ -20,6 +20,11 @@ get_pr() { # run from patches dir cd $(dirname "$0") -# needs review +# all merged in 10.3.beta6 or before get_pr 35848 "flintlib 3.0" get_pr 36769 "fix jmol detect" +get_pr 36862 "giac 1.9.0-73" +get_pr 37004 "fix save_session when cython changes" + +# positive review +get_pr 37123 "scipy 1.12" diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index 5d5bdccd70a25..7bc92e7c10735 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,7 +1,7 @@ # Template file for 'sagemath' pkgname=sagemath version=10.2 -revision=1 +revision=2 build_wrksrc=pkgs/sagemath-standard build_style=python3-module _bindir=/usr/lib/sagemath/$version/bin @@ -15,7 +15,7 @@ makedepends="boost-devel brial-devel cliquer-devel ecl eclib-devel mpfr-devel ntl-devel openblas-devel pari-devel planarity-devel python3-cypari2 python3-cysignals python3-devel python3-gmpy2 python3-memory_allocator python3-numpy rankwidth-devel singular symmetrica-devel" -depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran gd-devel +depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran meson gd-devel gfan giac gsl-devel gzip libpng-devel linbox-devel m4ri-devel maxima-ecl mpfr-devel nauty ntl-devel palp pari-devel pari-elldata-small pari-galdata pari-galpol-small pari-seadata-small pkg-config python3-Cython python3-cypari2 @@ -26,7 +26,7 @@ depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran gd-devel python3-sympy python3-traitlets sage-data-combinatorial_designs sage-data-conway_polynomials sage-data-elliptic_curves sage-data-graphs sage-data-polytopes_db sympow tachyon threejs-sage" -checkdepends="$depends pythran python3-Sphinx meson" +checkdepends="$depends pythran python3-Sphinx" short_desc="Open source mathematics software" maintainer="Gonzalo Tornaría " license="GPL-2.0-or-later" @@ -34,7 +34,7 @@ homepage="https://www.sagemath.org/" changelog="https://github.com/sagemath/sage/releases" distfiles="https://github.com/sagemath/sage/archive/refs/tags/$version.tar.gz" checksum=e7125f13495e1068edab73735aca7f9b2c655688096e9d109e628c023e76411f -nocross="due to ntl (eclib), fflas-ffpack, givaro, linbox, sympow, maxima" +nocross="due to ntl (eclib, singular), fflas-ffpack, givaro, linbox, sympow, maxima" post_patch() { # git tree needs bootstrapping From afafc84d2c396f56970a784bb6a0acf14b5c884c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Thu, 14 Dec 2023 09:08:28 -0300 Subject: [PATCH 3/5] New package: python3-conway-polynomials-0.9 --- srcpkgs/python3-conway-polynomials/template | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 srcpkgs/python3-conway-polynomials/template diff --git a/srcpkgs/python3-conway-polynomials/template b/srcpkgs/python3-conway-polynomials/template new file mode 100644 index 0000000000000..11766521e26db --- /dev/null +++ b/srcpkgs/python3-conway-polynomials/template @@ -0,0 +1,16 @@ +# Template file for 'python3-conway-polynomials' +pkgname=python3-conway-polynomials +version=0.9 +revision=1 +build_style=python3-pep517 +make_check_args="--doctest-modules --doctest-glob=README.rst" +hostmakedepends="python3-setuptools python3-wheel" +depends="python3" +checkdepends="python3-pytest" +short_desc="Python interface to Frank Lübeck's Conway polynomial database" +maintainer="Gonzalo Tornaría " +license="Public Domain, GPL-3.0-or-later" +homepage="https://github.com/sagemath/conway-polynomials" +changelog="https://github.com/sagemath/conway-polynomials/raw/master/NEWS" +distfiles="${PYPI_SITE}/c/conway-polynomials/conway-polynomials-${version}.tar.gz" +checksum=6ed2300609bce79f0175d5b8546858eec02854f8be3237db8d1449ccccc1c581 From 7a43dbd1789605e6e406cc4a63997c9cd8730e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sat, 9 Dec 2023 11:21:58 -0300 Subject: [PATCH 4/5] sagemath: update to 10.3.beta5. --- srcpkgs/sagemath/files/sage_conf.py | 2 +- .../sagemath/patches/35848-flintlib_3.0.patch | 1867 ----------------- .../patches/36769-fix_jmol_detect.patch | 92 - .../patches/36862-giac_1.9.0-73.patch | 15 - ...e_features_for_simpler_configuration.patch | 1509 +++++++++++++ srcpkgs/sagemath/patches/get_patches | 6 +- srcpkgs/sagemath/template | 17 +- srcpkgs/sagemath/update | 6 +- 8 files changed, 1525 insertions(+), 1989 deletions(-) delete mode 100644 srcpkgs/sagemath/patches/35848-flintlib_3.0.patch delete mode 100644 srcpkgs/sagemath/patches/36769-fix_jmol_detect.patch delete mode 100644 srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch create mode 100644 srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch diff --git a/srcpkgs/sagemath/files/sage_conf.py b/srcpkgs/sagemath/files/sage_conf.py index b5b2360311844..d9ff901ac40e5 100644 --- a/srcpkgs/sagemath/files/sage_conf.py +++ b/srcpkgs/sagemath/files/sage_conf.py @@ -1,4 +1,4 @@ # configuration for sage on void linux SAGE_SHARE = "/usr/share/sagemath" -GAP_SHARE_DIR = "/usr/share/gap" JMOL_DIR = "/usr/share/jmol" +THREEJS_DIR = "/usr/share/sagemath/threejs-sage" diff --git a/srcpkgs/sagemath/patches/35848-flintlib_3.0.patch b/srcpkgs/sagemath/patches/35848-flintlib_3.0.patch deleted file mode 100644 index 2cad28134f6e6..0000000000000 --- a/srcpkgs/sagemath/patches/35848-flintlib_3.0.patch +++ /dev/null @@ -1,1867 +0,0 @@ -diff --git a/build/pkgs/antic/SPKG.rst b/build/pkgs/antic/SPKG.rst -deleted file mode 100644 -index d6c32377957..00000000000 ---- a/build/pkgs/antic/SPKG.rst -+++ /dev/null -@@ -1,18 +0,0 @@ --antic: Algebraic Number Theory In C --=================================== -- --Description ------------- -- --Algebraic Number Theory In C -- --License --------- -- --LGPL 2.1 -- --Upstream Contact ------------------ -- --https://github.com/wbhart/antic -- -diff --git a/build/pkgs/antic/checksums.ini b/build/pkgs/antic/checksums.ini -deleted file mode 100644 -index fc8711ecd13..00000000000 ---- a/build/pkgs/antic/checksums.ini -+++ /dev/null -@@ -1,5 +0,0 @@ --tarball=antic-VERSION.tar.gz --sha1=940d8ea2c3512b9d49ee3101cf043f777764bd8f --md5=4e896420dd6344b53b307871efb2cbb4 --cksum=1938565125 --upstream_url=https://github.com/wbhart/antic/archive/refs/tags/vVERSION.tar.gz -diff --git a/build/pkgs/antic/dependencies b/build/pkgs/antic/dependencies -deleted file mode 100644 -index c95d2836ce5..00000000000 ---- a/build/pkgs/antic/dependencies -+++ /dev/null -@@ -1,4 +0,0 @@ --$(MP_LIBRARY) mpfr flint -- ------------ --All lines of this file are ignored except the first. -diff --git a/build/pkgs/antic/distros/arch.txt b/build/pkgs/antic/distros/arch.txt -deleted file mode 100644 -index 83c7cab14e4..00000000000 ---- a/build/pkgs/antic/distros/arch.txt -+++ /dev/null -@@ -1 +0,0 @@ --antic -diff --git a/build/pkgs/antic/distros/conda.txt b/build/pkgs/antic/distros/conda.txt -deleted file mode 100644 -index 83c7cab14e4..00000000000 ---- a/build/pkgs/antic/distros/conda.txt -+++ /dev/null -@@ -1 +0,0 @@ --antic -diff --git a/build/pkgs/antic/distros/debian.txt b/build/pkgs/antic/distros/debian.txt -deleted file mode 100644 -index 8fdcd3e5721..00000000000 ---- a/build/pkgs/antic/distros/debian.txt -+++ /dev/null -@@ -1 +0,0 @@ --libantic-dev -diff --git a/build/pkgs/antic/distros/fedora.txt b/build/pkgs/antic/distros/fedora.txt -deleted file mode 100644 -index 1b16da9f64b..00000000000 ---- a/build/pkgs/antic/distros/fedora.txt -+++ /dev/null -@@ -1 +0,0 @@ --antic-devel -diff --git a/build/pkgs/antic/distros/freebsd.txt b/build/pkgs/antic/distros/freebsd.txt -deleted file mode 100644 -index 116ff3a26f3..00000000000 ---- a/build/pkgs/antic/distros/freebsd.txt -+++ /dev/null -@@ -1 +0,0 @@ --math/antic -diff --git a/build/pkgs/antic/distros/opensuse.txt b/build/pkgs/antic/distros/opensuse.txt -deleted file mode 100644 -index 1b16da9f64b..00000000000 ---- a/build/pkgs/antic/distros/opensuse.txt -+++ /dev/null -@@ -1 +0,0 @@ --antic-devel -diff --git a/build/pkgs/antic/distros/repology.txt b/build/pkgs/antic/distros/repology.txt -deleted file mode 100644 -index 83c7cab14e4..00000000000 ---- a/build/pkgs/antic/distros/repology.txt -+++ /dev/null -@@ -1 +0,0 @@ --antic -diff --git a/build/pkgs/antic/package-version.txt b/build/pkgs/antic/package-version.txt -deleted file mode 100644 -index 3a4036fb450..00000000000 ---- a/build/pkgs/antic/package-version.txt -+++ /dev/null -@@ -1 +0,0 @@ --0.2.5 -diff --git a/build/pkgs/antic/spkg-install.in b/build/pkgs/antic/spkg-install.in -deleted file mode 100644 -index c57fa884a20..00000000000 ---- a/build/pkgs/antic/spkg-install.in -+++ /dev/null -@@ -1,19 +0,0 @@ --cd src -- --# Copied from build/pkgs/flint/spkg-install.in: --# Trac #29607: We must always supply --with-gmp, --with-mpfr, --# --with-ntl because otherwise FLINT's configure script uses --# /usr/local, which is always wrong. --# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. --# The value $SAGE_LOCAL is always a safe choice even if the library --# is coming from the system and is found using what is in --# LIBRARY_PATH or LDFLAGS etc. --./configure \ -- --disable-static \ -- --prefix="$SAGE_LOCAL" \ -- --with-gmp="$SAGE_LOCAL" \ -- --with-mpfr="$SAGE_LOCAL" \ -- --with-flint="$SAGE_LOCAL" || sdh_die "Error: Failed to configure antic." -- --sdh_make verbose --sdh_make_install -diff --git a/build/pkgs/antic/type b/build/pkgs/antic/type -deleted file mode 100644 -index 134d9bc32d5..00000000000 ---- a/build/pkgs/antic/type -+++ /dev/null -@@ -1 +0,0 @@ --optional -diff --git a/build/pkgs/arb/SPKG.rst b/build/pkgs/arb/SPKG.rst -deleted file mode 100644 -index cff49ddb95b..00000000000 ---- a/build/pkgs/arb/SPKG.rst -+++ /dev/null -@@ -1,27 +0,0 @@ --arb: Arbitrary-precision floating-point ball arithmetic --======================================================= -- --Description ------------- -- --Arb is a C library for arbitrary-precision floating-point ball --arithmetic, developed by Fredrik Johansson --(fredrik.johansson@gmail.com). It supports efficient high-precision --computation with polynomials, power series, matrices and special --functions over the real and complex numbers, with automatic, rigorous --error control. -- --License --------- -- --GNU General Public License v2+ -- -- --Upstream Contact ------------------ -- -- - Fredrik Johansson: fredrik.johansson@gmail.com -- -- - https://arblib.org/ -- -- - http://github.com/fredrik-johansson/arb/ -diff --git a/build/pkgs/arb/checksums.ini b/build/pkgs/arb/checksums.ini -deleted file mode 100644 -index 80ef43dad5d..00000000000 ---- a/build/pkgs/arb/checksums.ini -+++ /dev/null -@@ -1,5 +0,0 @@ --tarball=arb-VERSION.tar.gz --sha1=a1efe035dd3af3613dd685971a156f652b86ff63 --md5=9b369e29f93cdf2d4f90b57a92526cce --cksum=64252121 --upstream_url=https://github.com/fredrik-johansson/arb/archive/VERSION.tar.gz -diff --git a/build/pkgs/arb/dependencies b/build/pkgs/arb/dependencies -deleted file mode 100644 -index c95d2836ce5..00000000000 ---- a/build/pkgs/arb/dependencies -+++ /dev/null -@@ -1,4 +0,0 @@ --$(MP_LIBRARY) mpfr flint -- ------------ --All lines of this file are ignored except the first. -diff --git a/build/pkgs/arb/distros/arch.txt b/build/pkgs/arb/distros/arch.txt -deleted file mode 100644 -index 86c41dbaa5f..00000000000 ---- a/build/pkgs/arb/distros/arch.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb -diff --git a/build/pkgs/arb/distros/conda.txt b/build/pkgs/arb/distros/conda.txt -deleted file mode 100644 -index 86c41dbaa5f..00000000000 ---- a/build/pkgs/arb/distros/conda.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb -diff --git a/build/pkgs/arb/distros/debian.txt b/build/pkgs/arb/distros/debian.txt -deleted file mode 100644 -index 9fe71110712..00000000000 ---- a/build/pkgs/arb/distros/debian.txt -+++ /dev/null -@@ -1 +0,0 @@ --libflint-arb-dev -diff --git a/build/pkgs/arb/distros/fedora.txt b/build/pkgs/arb/distros/fedora.txt -deleted file mode 100644 -index 76794404627..00000000000 ---- a/build/pkgs/arb/distros/fedora.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb arb-devel -diff --git a/build/pkgs/arb/distros/freebsd.txt b/build/pkgs/arb/distros/freebsd.txt -deleted file mode 100644 -index 2ef8c7cec0f..00000000000 ---- a/build/pkgs/arb/distros/freebsd.txt -+++ /dev/null -@@ -1 +0,0 @@ --math/arb -diff --git a/build/pkgs/arb/distros/gentoo.txt b/build/pkgs/arb/distros/gentoo.txt -deleted file mode 100644 -index 58e3d4f8008..00000000000 ---- a/build/pkgs/arb/distros/gentoo.txt -+++ /dev/null -@@ -1 +0,0 @@ --sci-mathematics/arb -diff --git a/build/pkgs/arb/distros/homebrew.txt b/build/pkgs/arb/distros/homebrew.txt -deleted file mode 100644 -index 86c41dbaa5f..00000000000 ---- a/build/pkgs/arb/distros/homebrew.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb -diff --git a/build/pkgs/arb/distros/nix.txt b/build/pkgs/arb/distros/nix.txt -deleted file mode 100644 -index 86c41dbaa5f..00000000000 ---- a/build/pkgs/arb/distros/nix.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb -diff --git a/build/pkgs/arb/distros/opensuse.txt b/build/pkgs/arb/distros/opensuse.txt -deleted file mode 100644 -index 3319855150c..00000000000 ---- a/build/pkgs/arb/distros/opensuse.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb-devel -diff --git a/build/pkgs/arb/distros/repology.txt b/build/pkgs/arb/distros/repology.txt -deleted file mode 100644 -index 179c9d507e1..00000000000 ---- a/build/pkgs/arb/distros/repology.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb-fp -diff --git a/build/pkgs/arb/distros/void.txt b/build/pkgs/arb/distros/void.txt -deleted file mode 100644 -index 3319855150c..00000000000 ---- a/build/pkgs/arb/distros/void.txt -+++ /dev/null -@@ -1 +0,0 @@ --arb-devel -diff --git a/build/pkgs/arb/package-version.txt b/build/pkgs/arb/package-version.txt -deleted file mode 100644 -index e9763f6bfed..00000000000 ---- a/build/pkgs/arb/package-version.txt -+++ /dev/null -@@ -1 +0,0 @@ --2.23.0 -diff --git a/build/pkgs/arb/spkg-check.in b/build/pkgs/arb/spkg-check.in -deleted file mode 100644 -index 27cd9419538..00000000000 ---- a/build/pkgs/arb/spkg-check.in -+++ /dev/null -@@ -1,2 +0,0 @@ --cd src --$MAKE check -diff --git a/build/pkgs/arb/spkg-configure.m4 b/build/pkgs/arb/spkg-configure.m4 -deleted file mode 100644 -index ef2dd0aac4a..00000000000 ---- a/build/pkgs/arb/spkg-configure.m4 -+++ /dev/null -@@ -1,23 +0,0 @@ --SAGE_SPKG_CONFIGURE([arb], [ -- AC_REQUIRE([SAGE_SPKG_CONFIGURE_FLINT]) -- SAGE_ARB_LIBRARY="arb" -- AC_MSG_CHECKING([installing flint? ]) -- if test x$sage_spkg_install_flint = xyes; then -- AC_MSG_RESULT([yes; install arb as well]) -- sage_spkg_install_arb=yes -- else -- AC_CHECK_HEADER(arb.h, [ -- dnl below function added in version 2.16 of arb -- AC_CHECK_LIB([arb], [acb_mat_eig_simple], [], -- [dnl in Debian the name of dylib is different. -- AC_CHECK_LIB([flint-arb], [acb_mat_eig_simple], -- [SAGE_ARB_LIBRARY="flint-arb"], [sage_spkg_install_arb=yes])]) -- ], [sage_spkg_install_arb=yes]) -- fi --], [], [], [ -- if test x$sage_spkg_install_arb = xyes; then -- AC_SUBST(SAGE_ARB_LIBRARY,["arb"]) -- else -- AC_SUBST(SAGE_ARB_LIBRARY,[$SAGE_ARB_LIBRARY]) -- fi --]) -diff --git a/build/pkgs/arb/spkg-install.in b/build/pkgs/arb/spkg-install.in -deleted file mode 100644 -index 9322f04c912..00000000000 ---- a/build/pkgs/arb/spkg-install.in -+++ /dev/null -@@ -1,17 +0,0 @@ --cd src -- --# Trac #29607: We must always supply --with-gmp, --with-mpfr, --# --with-flint because otherwise ARB's configure script uses --# /usr/local, which is always wrong. --# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. --# The value $SAGE_LOCAL is always a safe choice even if the library --# is coming from the system and is found using what is in --# LIBRARY_PATH or LDFLAGS etc. --./configure --disable-static --prefix="$SAGE_LOCAL" \ -- --with-gmp="$SAGE_LOCAL" \ -- --with-mpfr="$SAGE_LOCAL" \ -- --with-flint="$SAGE_LOCAL" || \ -- sdh_die "Error configuring arb." -- --sdh_make verbose --sdh_make_install -diff --git a/build/pkgs/arb/type b/build/pkgs/arb/type -deleted file mode 100644 -index a6a7b9cd726..00000000000 ---- a/build/pkgs/arb/type -+++ /dev/null -@@ -1 +0,0 @@ --standard -diff --git a/build/pkgs/e_antic/dependencies b/build/pkgs/e_antic/dependencies -index fea1ffbda45..8e977a55c13 100644 ---- a/build/pkgs/e_antic/dependencies -+++ b/build/pkgs/e_antic/dependencies -@@ -1,4 +1,4 @@ --$(MP_LIBRARY) flint arb antic boost_cropped -+$(MP_LIBRARY) flint boost_cropped - - ---------- - All lines of this file are ignored except the first. -diff --git a/build/pkgs/flint/SPKG.rst b/build/pkgs/flint/SPKG.rst -index f91de70d1ff..d9dcea0903b 100644 ---- a/build/pkgs/flint/SPKG.rst -+++ b/build/pkgs/flint/SPKG.rst -@@ -4,8 +4,8 @@ flint: Fast Library for Number Theory - Description - ----------- - --FLINT is a C library for doing number theory, maintained by William --Hart. -+FLINT is a C library for doing number theory, maintained by -+Fredrik Johansson. - - Website: http://www.flintlib.org - -@@ -20,4 +20,4 @@ Upstream Contact - - - flint-devel Gougle Group - (http://groups.google.co.uk/group/flint-devel) --- William Hart -+- Fredrik Johansson -diff --git a/build/pkgs/flint/checksums.ini b/build/pkgs/flint/checksums.ini -index 3d449d98064..ab836606657 100644 ---- a/build/pkgs/flint/checksums.ini -+++ b/build/pkgs/flint/checksums.ini -@@ -1,5 +1,5 @@ - tarball=flint-VERSION.tar.gz --sha1=63d90f8242c8f8ab4011fbcfb44b86c154f43abd --md5=c2d3cec326438f159a530c66eb07fafe --cksum=4244948341 --upstream_url=http://flintlib.org/flint-VERSION.tar.gz -+sha1=65be9297c06edd7e24f20874b7bd6130cee56723 -+md5=5189f67b0ec12e4a54d6782851642b81 -+cksum=172350473 -+upstream_url=https://github.com/flintlib/flint/releases/download/vVERSION/flint-VERSION.tar.gz -diff --git a/build/pkgs/flint/dependencies b/build/pkgs/flint/dependencies -index 385df4faa7d..1108dc4fb21 100644 ---- a/build/pkgs/flint/dependencies -+++ b/build/pkgs/flint/dependencies -@@ -1,4 +1,4 @@ --$(MP_LIBRARY) mpfr ntl -+$(MP_LIBRARY) mpfr - - ---------- - All lines of this file are ignored except the first. -diff --git a/build/pkgs/flint/package-version.txt b/build/pkgs/flint/package-version.txt -index c8e38b61405..cb2b00e4f7a 100644 ---- a/build/pkgs/flint/package-version.txt -+++ b/build/pkgs/flint/package-version.txt -@@ -1 +1 @@ --2.9.0 -+3.0.1 -diff --git a/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch b/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch -new file mode 100644 -index 00000000000..48a32f5d894 ---- /dev/null -+++ b/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch -@@ -0,0 +1,106 @@ -+From 54277f054f13254898c9a57c2c7eb869877e1252 Mon Sep 17 00:00:00 2001 -+From: Marc Mezzarobba -+Date: Mon, 13 Nov 2023 10:23:54 +0100 -+Subject: [PATCH] Makefile.in: fix handling of $DESTDIR -+ -+--- -+ Makefile.in | 54 ++++++++++++++++++++++++++--------------------------- -+ 1 file changed, 27 insertions(+), 27 deletions(-) -+ -+diff --git a/Makefile.in b/Makefile.in -+index 08db6837c..2827b9da1 100644 -+--- a/Makefile.in -++++ b/Makefile.in -+@@ -34,9 +34,9 @@ FLINT_SOLIB:=@FLINT_SOLIB@ -+ prefix:=@prefix@ -+ exec_prefix:=@exec_prefix@ -+ -+-INCLUDEDIR:=$(DESTDIR)@includedir@ -+-LIBDIR:=$(DESTDIR)@libdir@ -+-BINDIR:=$(DESTDIR)@bindir@ -++INCLUDEDIR:=@includedir@ -++LIBDIR:=@libdir@ -++BINDIR:=@bindir@ -+ PKGCONFIGDIR:=$(LIBDIR)/pkgconfig -+ -+ HOST_OS:=@host_os@ -+@@ -202,10 +202,10 @@ BUILD_DIRS += \ -+ endif -+ -+ INSTALL_DIRS := \ -+- $(LIBDIR) $(INCLUDEDIR)/flint \ -+- $(PKGCONFIGDIR) -++ $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCLUDEDIR)/flint \ -++ $(DESTDIR)$(PKGCONFIGDIR) -+ ifneq ($(FLINT_DLLLIB),0) -+-INSTALL_DIRS += $(BINDIR) -++INSTALL_DIRS += $(DESTDIR)$(BINDIR) -+ endif -+ -+ ################################################################################ -+@@ -722,41 +722,41 @@ distclean: clean -+ ################################################################################ -+ -+ install: library | $(INSTALL_DIRS) -+- $(CP) flint.pc $(PKGCONFIGDIR)/flint.pc -++ $(CP) flint.pc $(DESTDIR)$(PKGCONFIGDIR)/flint.pc -+ ifneq ($(SHARED), 0) -+ ifneq ($(FLINT_DLLLIB),0) -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(BINDIR) -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(BINDIR) -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(BINDIR) -+- $(CP) $(FLINT_DIR)/$(FLINT_IMPLIB) $(LIBDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(DESTDIR)$(BINDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(DESTDIR)$(BINDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(BINDIR) -++ $(CP) $(FLINT_DIR)/$(FLINT_IMPLIB) $(DESTDIR)$(LIBDIR) -+ else -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(LIBDIR) -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(LIBDIR) -+- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(LIBDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(DESTDIR)$(LIBDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(DESTDIR)$(LIBDIR) -++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(LIBDIR) -+ endif -+ ifneq ($(FLINT_DYLIB),0) -+- install_name_tool -id $(LIBDIR)/$(FLINT_LIB_FULL) $(LIBDIR)/$(FLINT_LIB) -++ install_name_tool -id $(LIBDIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB) -+ endif -+ endif -+ ifneq ($(STATIC), 0) -+- $(CP) $(FLINT_DIR)/$(FLINT_LIB_STATIC) $(LIBDIR) -++ $(CP) $(FLINT_DIR)/$(FLINT_LIB_STATIC) $(DESTDIR)$(LIBDIR) -+ endif -+- $(CP) $(HEADERS) $(INCLUDEDIR)/flint -++ $(CP) $(HEADERS) $(DESTDIR)$(INCLUDEDIR)/flint -+ -+ uninstall: -+- $(RM_F) $(PKGCONFIGDIR)/flint.pc -++ $(RM_F) $(DESTDIR)$(PKGCONFIGDIR)/flint.pc -+ ifneq ($(FLINT_DLLLIB),0) -+- $(RM_F) $(BINDIR)/$(FLINT_LIB) -+- $(RM_F) $(BINDIR)/$(FLINT_LIB_MAJOR) -+- $(RM_F) $(BINDIR)/$(FLINT_LIB_FULL) -+- $(RM_F) $(LIBDIR)/$(FLINT_IMPLIB) -++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB) -++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB_MAJOR) -++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB_FULL) -++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_IMPLIB) -+ else -+- $(RM_F) $(LIBDIR)/$(FLINT_LIB) -+- $(RM_F) $(LIBDIR)/$(FLINT_LIB_MAJOR) -+- $(RM_F) $(LIBDIR)/$(FLINT_LIB_FULL) -++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB) -++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_MAJOR) -++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_FULL) -+ endif -+- $(RM_F) $(LIBDIR)/$(FLINT_LIB_STATIC) -+- $(RM_RF) $(INCLUDEDIR)/flint -++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_STATIC) -++ $(RM_RF) $(DESTDIR)$(INCLUDEDIR)/flint -+ -+ ################################################################################ -+ # maintainer stuff -+-- -+2.42.0 -+ -diff --git a/build/pkgs/flint/spkg-build.in b/build/pkgs/flint/spkg-build.in -new file mode 100644 -index 00000000000..ffb822c8a97 ---- /dev/null -+++ b/build/pkgs/flint/spkg-build.in -@@ -0,0 +1,3 @@ -+cd src -+sdh_configure -+sdh_make -diff --git a/build/pkgs/flint/spkg-configure.m4 b/build/pkgs/flint/spkg-configure.m4 -index a58108c9d6e..9576e4cc1e9 100644 ---- a/build/pkgs/flint/spkg-configure.m4 -+++ b/build/pkgs/flint/spkg-configure.m4 -@@ -1,25 +1,8 @@ - SAGE_SPKG_CONFIGURE([flint], [ -- SAGE_SPKG_DEPCHECK([mpfr ntl], [ -+ SAGE_SPKG_DEPCHECK([mpfr], [ - AC_CHECK_HEADER(flint/flint.h, [ -- dnl flint_parallel_binary_splitting appears in Flint 2.9.0, needed by arb 2.23 -- AC_SEARCH_LIBS([flint_parallel_binary_splitting], [flint], [ -- dnl check that NTL is linked in -- AC_SEARCH_LIBS([fmpz_poly_get_ZZX], [flint], [ -- -- AC_MSG_CHECKING([that GC is not enabled in Flint... ]) -- AC_RUN_IFELSE([ -- AC_LANG_PROGRAM([[#include ]], [ -- [#ifdef HAVE_GC] -- [return HAVE_GC;] -- [#else] -- [return 0;] -- [#endif]])], -- [AC_MSG_RESULT([GC not enabled. Good.])], -- [AC_MSG_RESULT([GC enabled. Incompatible with Sage.]) -- sage_spkg_install_flint=yes], -- [AC_MSG_RESULT(["cross compiling. assuming GC is not enabled"])]) -- ], [sage_spkg_install_flint=yes]) -- ], [sage_spkg_install_flint=yes]) -+ dnl gr_get_fexpr appears in Flint 3.0 -+ AC_SEARCH_LIBS([gr_get_fexpr], [flint], [], [sage_spkg_install_flint=yes]) - ], [sage_spkg_install_flint=yes]) - ]) - ], [], [], [ -diff --git a/build/pkgs/flint/spkg-install.in b/build/pkgs/flint/spkg-install.in -index eacd7b6e491..3ea8c053669 100644 ---- a/build/pkgs/flint/spkg-install.in -+++ b/build/pkgs/flint/spkg-install.in -@@ -1,36 +1,2 @@ --############################################################################### --# --# FLINT Sage install script --# --############################################################################### --if [ "$SAGE_DEBUG" = "yes" ]; then -- echo "Building a debug version of FLINT." -- FLINT_TUNE=" $FLINT_TUNE"; export FLINT_TUNE -- FLINT_CONFIGURE="--enable-assert $FLINT_CONFIGURE" --fi -- - cd src -- --echo "Configuring FLINT." --# Trac #29607: We must always supply --with-gmp, --with-mpfr, --# --with-ntl because otherwise FLINT's configure script uses --# /usr/local, which is always wrong. --# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. --# The value $SAGE_LOCAL is always a safe choice even if the library --# is coming from the system and is found using what is in --# LIBRARY_PATH or LDFLAGS etc. --./configure \ -- --disable-static \ -- --prefix="$SAGE_LOCAL" \ -- --with-gmp="$SAGE_LOCAL" \ -- --with-mpfr="$SAGE_LOCAL" \ -- --with-ntl="$SAGE_LOCAL" \ -- $FLINT_CONFIGURE || sdh_die "Error: Failed to configure FLINT." -- --sdh_make verbose -- --echo "Deleting old FLINT files." --rm -f $SAGE_LOCAL/lib/libflint* --rm -rf $SAGE_LOCAL/include/flint -- - sdh_make_install -diff --git a/build/pkgs/gmp/spkg-configure.m4 b/build/pkgs/gmp/spkg-configure.m4 -index 61d7c5f3b2f..4000200db2c 100644 ---- a/build/pkgs/gmp/spkg-configure.m4 -+++ b/build/pkgs/gmp/spkg-configure.m4 -@@ -2,8 +2,10 @@ SAGE_SPKG_CONFIGURE([gmp], [ - sage_spkg_install_gmp=no - AC_CHECK_HEADER(gmp.h, [], [sage_spkg_install_gmp=yes]) - AC_CHECK_HEADER(gmpxx.h, [], [sage_spkg_install_gmp=yes]) -- dnl mpq_cmp_z appeared in GMP 6.1.0 and is used by pynac -- AC_SEARCH_LIBS([__gmpq_cmp_z], [gmp], [], -+ dnl mpn_gcd_11 appeared in GMP 6.2.1 -+ dnl It is undocumented but is used by Flint when built with default -+ dnl flags. -+ AC_SEARCH_LIBS([__gmpn_gcd_11], [gmp], [], - [sage_spkg_install_gmp=yes]) - ], [], [], [ - if test x$sage_spkg_install_gmp = xyes; then -diff --git a/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch b/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch -new file mode 100644 -index 00000000000..27a642a13b0 ---- /dev/null -+++ b/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch -@@ -0,0 +1,53 @@ -+From fe730579476de0b2d4181a38efa7f63dff9c81d7 Mon Sep 17 00:00:00 2001 -+From: Marc Mezzarobba -+Date: Tue, 12 Sep 2023 08:23:08 +0200 -+Subject: [PATCH] Make msolve build with flint3 -+ -+--- -+ src/fglm/berlekamp_massey.c | 3 +++ -+ src/fglm/data_fglm.c | 7 +++++-- -+ 2 files changed, 8 insertions(+), 2 deletions(-) -+ -+diff --git a/src/fglm/berlekamp_massey.c b/src/fglm/berlekamp_massey.c -+index b0f2052..998af1c 100644 -+--- a/src/fglm/berlekamp_massey.c -++++ b/src/fglm/berlekamp_massey.c -+@@ -30,6 +30,9 @@ -+ */ -+ -+ #include -++#if __FLINT_VERSION >= 3 -++# include -++#endif -+ //#include "nmod_poly.h" -+ //#include "mpn_extras.h" -+ -+diff --git a/src/fglm/data_fglm.c b/src/fglm/data_fglm.c -+index 0726760..0e1da6f 100644 -+--- a/src/fglm/data_fglm.c -++++ b/src/fglm/data_fglm.c -+@@ -24,6 +24,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ -+ typedef uint32_t szmat_t; -+@@ -299,9 +300,11 @@ static inline void nmod_poly_set_prime(nmod_poly_t poly, -+ mp_limb_t ninv = n_preinvert_limb(prime); -+ poly->mod.n = prime; -+ poly->mod.ninv = ninv; -++#if __FLINT_VERSION < 3 -+ count_leading_zeros(poly->mod.norm, prime); -+- /* poly->mod.norm = flint_clz(prime); */ -+- -++#else -++ poly->mod.norm = flint_clz(prime); -++#endif -+ } -+ -+ static inline void fglm_param_set_prime(param_t *param, mp_limb_t prime){ -+-- -+2.40.1 -+ -diff --git a/build/pkgs/sagelib/dependencies b/build/pkgs/sagelib/dependencies -index 5dc2efe1d31..fa6e98df7db 100644 ---- a/build/pkgs/sagelib/dependencies -+++ b/build/pkgs/sagelib/dependencies -@@ -1,4 +1,4 @@ --FORCE $(SCRIPTS) arb boost_cropped $(BLAS) brial cliquer cypari cysignals cython ecl eclib ecm flint libgd gap giac givaro glpk gmpy2 gsl iml importlib_metadata importlib_resources jupyter_core lcalc lrcalc_python libbraiding libhomfly libpng linbox m4ri m4rie memory_allocator mpc mpfi mpfr $(MP_LIBRARY) ntl numpy pari pip pkgconfig planarity ppl pplpy primesieve primecount primecountpy pycygwin $(PYTHON) requests rw sage_conf singular symmetrica typing_extensions $(PCFILES) | $(PYTHON_TOOLCHAIN) sage_setup $(PYTHON) pythran -+FORCE $(SCRIPTS) boost_cropped $(BLAS) brial cliquer cypari cysignals cython ecl eclib ecm flint libgd gap giac givaro glpk gmpy2 gsl iml importlib_metadata importlib_resources jupyter_core lcalc lrcalc_python libbraiding libhomfly libpng linbox m4ri m4rie memory_allocator mpc mpfi mpfr $(MP_LIBRARY) ntl numpy pari pip pkgconfig planarity ppl pplpy primesieve primecount primecountpy pycygwin $(PYTHON) requests rw sage_conf singular symmetrica typing_extensions $(PCFILES) | $(PYTHON_TOOLCHAIN) sage_setup $(PYTHON) pythran - - ---------- - All lines of this file are ignored except the first. -diff --git a/build/pkgs/symengine/dependencies b/build/pkgs/symengine/dependencies -index 1fc34963eda..7795d486018 100644 ---- a/build/pkgs/symengine/dependencies -+++ b/build/pkgs/symengine/dependencies -@@ -1,4 +1,4 @@ --$(MP_LIBRARY) arb ecm flint mpc mpfr | cmake -+$(MP_LIBRARY) ecm flint mpc mpfr | cmake - - ---------- - All lines of this file are ignored except the first. -diff --git a/pkgs/sage-conf/_sage_conf/_conf.py.in b/pkgs/sage-conf/_sage_conf/_conf.py.in -index 87b27ca05cb..895d6572d1e 100644 ---- a/pkgs/sage-conf/_sage_conf/_conf.py.in -+++ b/pkgs/sage-conf/_sage_conf/_conf.py.in -@@ -19,8 +19,6 @@ MAXIMA_FAS = "@SAGE_MAXIMA_FAS@".replace('${prefix}', SAGE_LOCAL) - # Delete this line if your ECL can load Kenzo without further prodding. - KENZO_FAS = "@SAGE_KENZO_FAS@".replace('${prefix}', SAGE_LOCAL) - --ARB_LIBRARY = "@SAGE_ARB_LIBRARY@" -- - NTL_INCDIR = "@NTL_INCDIR@" - NTL_LIBDIR = "@NTL_LIBDIR@" - -diff --git a/src/sage/env.py b/src/sage/env.py -index 4515e90e912..9ab6b1e1864 100644 ---- a/src/sage/env.py -+++ b/src/sage/env.py -@@ -223,7 +223,6 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st - FOURTITWO_PPI = var("FOURTITWO_PPI") - FOURTITWO_CIRCUITS = var("FOURTITWO_CIRCUITS") - FOURTITWO_GROEBNER = var("FOURTITWO_GROEBNER") --ARB_LIBRARY = var("ARB_LIBRARY", "arb") - CBLAS_PC_MODULES = var("CBLAS_PC_MODULES", "cblas:openblas:blas") - ECL_CONFIG = var("ECL_CONFIG", "ecl-config") - NTL_INCDIR = var("NTL_INCDIR") -@@ -356,8 +355,7 @@ def cython_aliases(required_modules=None, - sage: cython_aliases() - {...} - sage: sorted(cython_aliases().keys()) -- ['ARB_LIBRARY', -- 'CBLAS_CFLAGS', -+ ['CBLAS_CFLAGS', - ..., - 'ZLIB_LIBRARIES'] - sage: cython_aliases(required_modules=('module-that-is-assumed-to-not-exist')) -@@ -475,8 +473,6 @@ def uname_specific(name, value, alternative): - if "LINBOX_CFLAGS" in aliases: - aliases["LINBOX_CFLAGS"].append("-std=gnu++11") - -- aliases["ARB_LIBRARY"] = ARB_LIBRARY -- - # TODO: Remove Cygwin hack by installing a suitable cblas.pc - if os.path.exists('/usr/lib/libblas.dll.a'): - aliases["CBLAS_LIBS"] = ['gslcblas'] -diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py -index bc34d35dd1c..4097d3512b9 100644 ---- a/src/sage/features/sagemath.py -+++ b/src/sage/features/sagemath.py -@@ -777,7 +777,7 @@ class sage__rings__number_field(JoinFeature): - A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.number_field`. - - Number fields are implemented in Sage using a complicated mixture of various libraries, -- including :ref:`arb `, :ref:`FLINT `, :ref:`GAP `, -+ including :ref:`FLINT `, :ref:`GAP `, - :ref:`MPFI `, :ref:`NTL `, and :ref:`PARI `. - - EXAMPLES: -diff --git a/src/sage/libs/arb/acb.pxd b/src/sage/libs/arb/acb.pxd -index 5148dc43991..851488d803a 100644 ---- a/src/sage/libs/arb/acb.pxd -+++ b/src/sage/libs/arb/acb.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb.h - - from sage.libs.arb.types cimport * -@@ -152,10 +152,6 @@ cdef extern from "arb_wrap.h": - void acb_sech(acb_t s, const acb_t z, long prec) - void acb_csch(acb_t c, const acb_t z, long prec) - -- void acb_rising_ui_bs(acb_t z, const acb_t x, unsigned long n, long prec) -- void acb_rising_ui_rs(acb_t z, const acb_t x, unsigned long n, unsigned long step, long prec) -- void acb_rising_ui_rec(acb_t z, const acb_t x, unsigned long n, long prec) -- void acb_rising_ui(acb_t z, const acb_t x, unsigned long n, long prec) - void acb_rising(acb_t z, const acb_t x, const acb_t n, long prec) - - void acb_gamma(acb_t y, const acb_t x, long prec) -diff --git a/src/sage/libs/arb/acb_calc.pxd b/src/sage/libs/arb/acb_calc.pxd -index a5dbf360b5e..67bd2ed57dc 100644 ---- a/src/sage/libs/arb/acb_calc.pxd -+++ b/src/sage/libs/arb/acb_calc.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb_calc.h - - from sage.libs.arb.types cimport * -diff --git a/src/sage/libs/arb/acb_elliptic.pxd b/src/sage/libs/arb/acb_elliptic.pxd -index 176f68df00e..e3480e9f73b 100644 ---- a/src/sage/libs/arb/acb_elliptic.pxd -+++ b/src/sage/libs/arb/acb_elliptic.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb_elliptic.h - - from sage.libs.arb.types cimport * -diff --git a/src/sage/libs/arb/acb_hypgeom.pxd b/src/sage/libs/arb/acb_hypgeom.pxd -index 418e766f10d..c43e5c0623b 100644 ---- a/src/sage/libs/arb/acb_hypgeom.pxd -+++ b/src/sage/libs/arb/acb_hypgeom.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb_hypgeom.h - - from sage.libs.arb.types cimport * -diff --git a/src/sage/libs/arb/acb_modular.pxd b/src/sage/libs/arb/acb_modular.pxd -index c708e9bf97d..cdc413c92da 100644 ---- a/src/sage/libs/arb/acb_modular.pxd -+++ b/src/sage/libs/arb/acb_modular.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb_modular.h - - from sage.libs.arb.types cimport * -diff --git a/src/sage/libs/arb/acb_poly.pxd b/src/sage/libs/arb/acb_poly.pxd -index 69f4320055b..ae02757ffd9 100644 ---- a/src/sage/libs/arb/acb_poly.pxd -+++ b/src/sage/libs/arb/acb_poly.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = acb_poly.h - - from sage.libs.arb.types cimport * -@@ -79,24 +79,10 @@ cdef extern from "arb_wrap.h": - void _acb_poly_divrem(acb_ptr Q, acb_ptr R, acb_srcptr A, long lenA, acb_srcptr B, long lenB, long prec) - bint acb_poly_divrem(acb_poly_t Q, acb_poly_t R, const acb_poly_t A, const acb_poly_t B, long prec) - void _acb_poly_div_root(acb_ptr Q, acb_t R, acb_srcptr A, long len, const acb_t c, long prec) -- void _acb_poly_taylor_shift_horner(acb_ptr g, const acb_t c, long n, long prec) -- void acb_poly_taylor_shift_horner(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) -- void _acb_poly_taylor_shift_divconquer(acb_ptr g, const acb_t c, long n, long prec) -- void acb_poly_taylor_shift_divconquer(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) -- void _acb_poly_taylor_shift_convolution(acb_ptr g, const acb_t c, long n, long prec) -- void acb_poly_taylor_shift_convolution(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) - void _acb_poly_taylor_shift(acb_ptr g, const acb_t c, long n, long prec) - void acb_poly_taylor_shift(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) -- void _acb_poly_compose_horner(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) -- void acb_poly_compose_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) -- void _acb_poly_compose_divconquer(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) -- void acb_poly_compose_divconquer(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) - void _acb_poly_compose(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) - void acb_poly_compose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) -- void _acb_poly_compose_series_horner(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) -- void acb_poly_compose_series_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) -- void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) -- void acb_poly_compose_series_brent_kung(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) - void _acb_poly_compose_series(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) - void acb_poly_compose_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) - void _acb_poly_revert_series_lagrange(acb_ptr h, acb_srcptr f, long flen, long n, long prec) -@@ -161,10 +147,6 @@ cdef extern from "arb_wrap.h": - void acb_poly_exp_series_basecase(acb_poly_t f, const acb_poly_t h, long n, long prec) - void _acb_poly_exp_series(acb_ptr f, acb_srcptr h, long hlen, long n, long prec) - void acb_poly_exp_series(acb_poly_t f, const acb_poly_t h, long n, long prec) -- void _acb_poly_sin_cos_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec, int times_pi) -- void acb_poly_sin_cos_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec, int times_pi) -- void _acb_poly_sin_cos_series_tangent(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec, int times_pi) -- void acb_poly_sin_cos_series_tangent(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec, int times_pi) - void _acb_poly_sin_cos_series(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec) - void acb_poly_sin_cos_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec) - void _acb_poly_sin_series(acb_ptr s, acb_srcptr h, long hlen, long n, long prec) -diff --git a/src/sage/libs/arb/arb.pxd b/src/sage/libs/arb/arb.pxd -index c82b94de30f..acd232ab816 100644 ---- a/src/sage/libs/arb/arb.pxd -+++ b/src/sage/libs/arb/arb.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = arb.h - - from sage.libs.arb.types cimport * -@@ -224,15 +224,8 @@ cdef extern from "arb_wrap.h": - - void arb_lambertw(arb_t res, const arb_t x, int flags, long prec) - -- void arb_rising_ui_bs(arb_t z, const arb_t x, unsigned long n, long prec) -- void arb_rising_ui_rs(arb_t z, const arb_t x, unsigned long n, unsigned long step, long prec) -- void arb_rising_ui_rec(arb_t z, const arb_t x, unsigned long n, long prec) -- void arb_rising_ui(arb_t z, const arb_t x, unsigned long n, long prec) - void arb_rising(arb_t z, const arb_t x, const arb_t n, long prec) - void arb_rising_fmpq_ui(arb_t z, const fmpq_t x, unsigned long n, long prec) -- void arb_rising2_ui_bs(arb_t u, arb_t v, const arb_t x, unsigned long n, long prec) -- void arb_rising2_ui_rs(arb_t u, arb_t v, const arb_t x, unsigned long n, unsigned long step, long prec) -- void arb_rising2_ui(arb_t u, arb_t v, const arb_t x, unsigned long n, long prec) - void arb_fac_ui(arb_t z, unsigned long n, long prec) - void arb_bin_ui(arb_t z, const arb_t n, unsigned long k, long prec) - void arb_bin_uiui(arb_t z, unsigned long n, unsigned long k, long prec) -diff --git a/src/sage/libs/arb/arb_fmpz_poly.pxd b/src/sage/libs/arb/arb_fmpz_poly.pxd -index 079f76e9d9e..55daa705238 100644 ---- a/src/sage/libs/arb/arb_fmpz_poly.pxd -+++ b/src/sage/libs/arb/arb_fmpz_poly.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = arb_fmpz_poly.h - - from sage.libs.arb.types cimport * -@@ -22,5 +22,4 @@ cdef extern from "arb_wrap.h": - unsigned long arb_fmpz_poly_deflation(const fmpz_poly_t poly) - void arb_fmpz_poly_deflate(fmpz_poly_t res, const fmpz_poly_t poly, unsigned long deflation) - void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, long prec) -- void arb_fmpz_poly_cos_minpoly(fmpz_poly_t res, unsigned long n) - void arb_fmpz_poly_gauss_period_minpoly(fmpz_poly_t res, unsigned long q, unsigned long n) -diff --git a/src/sage/libs/arb/arb_hypgeom.pxd b/src/sage/libs/arb/arb_hypgeom.pxd -index fb1c40ddaa8..139b987d669 100644 ---- a/src/sage/libs/arb/arb_hypgeom.pxd -+++ b/src/sage/libs/arb/arb_hypgeom.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = arb_hypgeom.h - - from sage.libs.flint.types cimport fmpz_t -diff --git a/src/sage/libs/arb/arb_wrap.h b/src/sage/libs/arb/arb_wrap.h -index 49997075ee5..488bb376d5e 100644 ---- a/src/sage/libs/arb/arb_wrap.h -+++ b/src/sage/libs/arb/arb_wrap.h -@@ -5,25 +5,27 @@ - * by arb, most of which rely on flint's ulong and slong defines. - */ - -+#include -+ - #undef ulong - #undef slong - - #define ulong mp_limb_t - #define slong mp_limb_signed_t - --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #undef ulong - #undef slong -diff --git a/src/sage/libs/arb/arf.pxd b/src/sage/libs/arb/arf.pxd -index b8b83fefcdc..84778fe9f09 100644 ---- a/src/sage/libs/arb/arf.pxd -+++ b/src/sage/libs/arb/arf.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = arf.h - - from sage.libs.arb.types cimport * -@@ -30,7 +30,6 @@ cdef extern from "arb_wrap.h": - void arf_set_ui(arf_t y, unsigned long x) - void arf_set_si(arf_t y, long x) - void arf_set_mpfr(arf_t y, const mpfr_t x) -- # void arf_set_fmpr(arf_t y, const fmpr_t x) - void arf_set_d(arf_t y, double x) - void arf_swap(arf_t y, arf_t x) - void arf_init_set_ui(arf_t y, unsigned long x) -@@ -46,7 +45,6 @@ cdef extern from "arb_wrap.h": - int arf_set_round_fmpz_2exp(arf_t y, const fmpz_t x, const fmpz_t e, long prec, arf_rnd_t rnd) - void arf_get_fmpz_2exp(fmpz_t m, fmpz_t e, const arf_t x) - double arf_get_d(const arf_t x, arf_rnd_t rnd) -- # void arf_get_fmpr(fmpr_t y, const arf_t x) - int arf_get_mpfr(mpfr_t y, const arf_t x, mpfr_rnd_t rnd) - void arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) - long arf_get_si(const arf_t x, arf_rnd_t rnd) -diff --git a/src/sage/libs/arb/bernoulli.pxd b/src/sage/libs/arb/bernoulli.pxd -index f859ebfb8d7..95a84dd5179 100644 ---- a/src/sage/libs/arb/bernoulli.pxd -+++ b/src/sage/libs/arb/bernoulli.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = bernoulli.h - - from sage.libs.flint.types cimport fmpq_t, ulong -diff --git a/src/sage/libs/arb/mag.pxd b/src/sage/libs/arb/mag.pxd -index d5d8693ea8f..69dfb990ae0 100644 ---- a/src/sage/libs/arb/mag.pxd -+++ b/src/sage/libs/arb/mag.pxd -@@ -1,4 +1,4 @@ --# distutils: libraries = gmp flint ARB_LIBRARY -+# distutils: libraries = gmp flint - # distutils: depends = mag.h - - from sage.libs.arb.types cimport * -@@ -27,13 +27,11 @@ cdef extern from "arb_wrap.h": - # void mag_randtest(mag_t x, flint_rand_t state, long expbits) - # void mag_randtest_special(mag_t x, flint_rand_t state, long expbits) - void mag_set_d(mag_t y, double x) -- # void mag_set_fmpr(mag_t y, const fmpr_t x) - void mag_set_ui(mag_t y, unsigned long x) - void mag_set_fmpz(mag_t y, const fmpz_t x) - void mag_set_d_2exp_fmpz(mag_t z, double x, const fmpz_t y) - void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t x, const fmpz_t y) - void mag_set_ui_2exp_si(mag_t z, unsigned long x, long y) -- # void mag_get_fmpr(fmpr_t y, const mag_t x) - void mag_get_fmpq(fmpq_t y, const mag_t x) - void mag_set_ui_lower(mag_t z, unsigned long x) - void mag_set_fmpz_lower(mag_t z, const fmpz_t x) -diff --git a/src/sage/libs/flint/flint_wrap.h b/src/sage/libs/flint/flint_wrap.h -index 266535c3835..4db72b97660 100644 ---- a/src/sage/libs/flint/flint_wrap.h -+++ b/src/sage/libs/flint/flint_wrap.h -@@ -15,6 +15,7 @@ - */ - - #include -+#include - - /* Save previous definition of ulong if any, as pari also uses it */ - /* Should work on GCC, clang, MSVC */ -@@ -33,6 +34,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -47,6 +49,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/sage/libs/flint/fmpq.pxd b/src/sage/libs/flint/fmpq.pxd -index 5e64c82102f..0616c0a7408 100644 ---- a/src/sage/libs/flint/fmpq.pxd -+++ b/src/sage/libs/flint/fmpq.pxd -@@ -12,6 +12,8 @@ cdef extern from "flint_wrap.h": - fmpz * fmpq_denref(fmpq_t) - void fmpq_init(fmpq_t) - void fmpq_clear(fmpq_t) -+ void fmpq_init_set_readonly(fmpq_t, const mpq_t) -+ void fmpq_clear_readonly(fmpq_t) - void fmpq_one(fmpq_t) - void fmpq_zero(fmpq_t) - bint fmpq_is_zero(fmpq_t) -diff --git a/src/sage/libs/flint/fmpq_poly.pxd b/src/sage/libs/flint/fmpq_poly.pxd -index 6050c487835..afa16e5bbdd 100644 ---- a/src/sage/libs/flint/fmpq_poly.pxd -+++ b/src/sage/libs/flint/fmpq_poly.pxd -@@ -30,6 +30,9 @@ cdef extern from "flint_wrap.h": - void fmpq_poly_canonicalise(fmpq_poly_t) - int fmpq_poly_is_canonical(const fmpq_poly_t) - -+ void _fmpq_poly_set_length(fmpq_poly_t, slong) -+ void _fmpq_poly_normalise(fmpq_poly_t) -+ - # Polynomial parameters - slong fmpq_poly_degree(const fmpq_poly_t) - ulong fmpq_poly_length(const fmpq_poly_t) -@@ -46,10 +49,7 @@ cdef extern from "flint_wrap.h": - void fmpq_poly_set_ui(fmpq_poly_t, ulong) - void fmpq_poly_set_fmpz(fmpq_poly_t, const fmpz_t) - void fmpq_poly_set_fmpq(fmpq_poly_t, const fmpq_t) -- void fmpq_poly_set_mpz(fmpq_poly_t, const mpz_t) -- void fmpq_poly_set_mpq(fmpq_poly_t, const mpq_t) - void fmpq_poly_set_fmpz_poly(fmpq_poly_t, const fmpz_poly_t) -- void fmpq_poly_set_array_mpq(fmpq_poly_t, const mpq_t *, slong) - - void fmpq_poly_set_str(fmpq_poly_t, const char *) - char *fmpq_poly_get_str(const fmpq_poly_t) -@@ -67,7 +67,6 @@ cdef extern from "flint_wrap.h": - void fmpq_poly_reverse(fmpq_poly_t, const fmpq_poly_t, slong) - - void fmpq_poly_get_coeff_fmpq(fmpq_t, const fmpq_poly_t, slong) -- void fmpq_poly_get_coeff_mpq(mpq_t, const fmpq_poly_t, slong) - void fmpq_poly_get_coeff_si(slong, const fmpq_poly_t, slong) - void fmpq_poly_get_coeff_ui(ulong, const fmpq_poly_t, slong) - -@@ -75,8 +74,6 @@ cdef extern from "flint_wrap.h": - void fmpq_poly_set_coeff_ui(fmpq_poly_t, slong, ulong) - void fmpq_poly_set_coeff_fmpz(fmpq_poly_t, slong, const fmpz_t) - void fmpq_poly_set_coeff_fmpq(fmpq_poly_t, slong, const fmpq_t) -- void fmpq_poly_set_coeff_mpz(fmpq_poly_t, slong, const mpz_t) -- void fmpq_poly_set_coeff_mpq(fmpq_poly_t, slong, const mpq_t) - - # Comparison - int fmpq_poly_equal(const fmpq_poly_t, const fmpq_poly_t) -@@ -100,8 +97,6 @@ cdef extern from "flint_wrap.h": - fmpq_poly_t, const fmpq_poly_t, const fmpz_t) - void fmpq_poly_scalar_mul_fmpq( - fmpq_poly_t, const fmpq_poly_t, const fmpq_t) -- void fmpq_poly_scalar_mul_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) -- void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) - - void fmpq_poly_scalar_div_si(fmpq_poly_t, const fmpq_poly_t, slong) - void fmpq_poly_scalar_div_ui(fmpq_poly_t, const fmpq_poly_t, ulong) -@@ -109,8 +104,6 @@ cdef extern from "flint_wrap.h": - fmpq_poly_t, const fmpq_poly_t, const fmpz_t) - void fmpq_poly_scalar_div_fmpq( - fmpq_poly_t, const fmpq_poly_t, const fmpq_t) -- void fmpq_poly_scalar_div_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) -- void fmpq_poly_scalar_div_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) - - # Multiplication - void fmpq_poly_mul(fmpq_poly_t, const fmpq_poly_t, const fmpq_poly_t) -@@ -155,8 +148,6 @@ cdef extern from "flint_wrap.h": - # Evaluation - void fmpq_poly_evaluate_fmpz(fmpq_t, const fmpq_poly_t, const fmpz_t) - void fmpq_poly_evaluate_fmpq(fmpq_t, const fmpq_poly_t, const fmpq_t) -- void fmpq_poly_evaluate_mpz(mpq_t, const fmpq_poly_t, const mpz_t) -- void fmpq_poly_evaluate_mpq(mpq_t, const fmpq_poly_t, const mpq_t) - - # Composition - void fmpq_poly_compose(fmpq_poly_t, const fmpq_poly_t, const fmpq_poly_t) -@@ -189,3 +180,11 @@ cdef extern from "flint_wrap.h": - # since the fmpq_poly header seems to be lacking this inline function - cdef inline sage_fmpq_poly_max_limbs(const fmpq_poly_t poly) noexcept: - return _fmpz_vec_max_limbs(fmpq_poly_numref(poly), fmpq_poly_length(poly)) -+ -+# functions removed from flint but still needed in sage -+cdef void fmpq_poly_scalar_mul_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) -+cdef void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) -+cdef void fmpq_poly_set_coeff_mpq(fmpq_poly_t, slong, const mpq_t) -+cdef void fmpq_poly_get_coeff_mpq(mpq_t, const fmpq_poly_t, slong) -+cdef void fmpq_poly_set_mpz(fmpq_poly_t, const mpz_t) -+cdef void fmpq_poly_set_mpq(fmpq_poly_t, const mpq_t) -diff --git a/src/sage/libs/flint/fmpq_poly.pyx b/src/sage/libs/flint/fmpq_poly.pyx -new file mode 100644 -index 00000000000..3b8a0cf0c51 ---- /dev/null -+++ b/src/sage/libs/flint/fmpq_poly.pyx -@@ -0,0 +1,45 @@ -+# Functions removed from flint but still needed in Sage. Code adapted from -+# earlier versions of flint. -+ -+from sage.libs.gmp.mpq cimport * -+from sage.libs.flint.fmpz cimport * -+from sage.libs.flint.fmpq cimport * -+ -+cdef void fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop, const fmpq_poly_t op, const mpz_t c): -+ cdef fmpz_t f -+ fmpz_init_set_readonly(f, c) -+ fmpq_poly_scalar_mul_fmpz(rop, op, f) -+ fmpz_clear_readonly(f) -+ -+cdef void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c): -+ cdef fmpq_t f -+ fmpq_init_set_readonly(f, c) -+ fmpq_poly_scalar_mul_fmpq(rop, op, f) -+ fmpq_clear_readonly(f) -+ -+cdef void fmpq_poly_set_coeff_mpq(fmpq_poly_t poly, slong n, const mpq_t x): -+ cdef fmpq_t t -+ fmpq_init_set_readonly(t, x) -+ fmpq_poly_set_coeff_fmpq(poly, n, t) -+ fmpq_clear_readonly(t) -+ -+cdef void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n): -+ cdef fmpq_t t -+ fmpq_init(t) -+ fmpq_poly_get_coeff_fmpq(t, poly, n) -+ fmpq_get_mpq(x, t) -+ fmpq_clear(t) -+ -+cdef void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x): -+ fmpq_poly_fit_length(poly, 1) -+ fmpz_set_mpz(fmpq_poly_numref(poly), mpq_numref(x)) -+ fmpz_set_mpz(fmpq_poly_denref(poly), mpq_denref(x)) -+ _fmpq_poly_set_length(poly, 1) -+ _fmpq_poly_normalise(poly) -+ -+cdef void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x): -+ fmpq_poly_fit_length(poly, 1) -+ fmpz_set_mpz(fmpq_poly_numref(poly), x) -+ fmpz_one(fmpq_poly_denref(poly)) -+ _fmpq_poly_set_length(poly, 1) -+ _fmpq_poly_normalise(poly) -diff --git a/src/sage/libs/flint/fmpz.pxd b/src/sage/libs/flint/fmpz.pxd -index 01058d0f130..b97fbe1eae0 100644 ---- a/src/sage/libs/flint/fmpz.pxd -+++ b/src/sage/libs/flint/fmpz.pxd -@@ -16,6 +16,9 @@ cdef extern from "flint_wrap.h": - void fmpz_init_set(fmpz_t, fmpz_t) - void fmpz_init_set_ui(fmpz_t, ulong) - -+ void fmpz_init_set_readonly(fmpz_t, const mpz_t) -+ void fmpz_clear_readonly(fmpz_t) -+ - # Conversion - void fmpz_set(fmpz_t f, fmpz_t g) - void fmpz_set_ui(fmpz_t, ulong) -diff --git a/src/sage/libs/flint/fmpz_mod_poly.pxd b/src/sage/libs/flint/fmpz_mod_poly.pxd -index 24b653eb3b7..2727246da98 100644 ---- a/src/sage/libs/flint/fmpz_mod_poly.pxd -+++ b/src/sage/libs/flint/fmpz_mod_poly.pxd -@@ -67,13 +67,6 @@ cdef extern from "flint_wrap.h": - void fmpz_mod_poly_get_coeff_fmpz(fmpz_t x, const fmpz_mod_poly_t poly, - slong n, const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_set_coeff_mpz(fmpz_mod_poly_t poly, -- slong n, const mpz_t x, const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_get_coeff_mpz(mpz_t x, -- const fmpz_mod_poly_t poly, slong n, const fmpz_mod_ctx_t ctx) -- -- - void _fmpz_mod_poly_shift_left(fmpz * res, const fmpz * poly, - slong len, slong n) - -@@ -194,14 +187,6 @@ cdef extern from "flint_wrap.h": - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_poly_t Binv, const fmpz_mod_ctx_t ctx) -- - void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, - fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_poly_t Binv, const fmpz_mod_ctx_t ctx) -@@ -213,10 +198,6 @@ cdef extern from "flint_wrap.h": - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, -- fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- - void fmpz_mod_poly_divrem(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - -@@ -254,40 +235,13 @@ cdef extern from "flint_wrap.h": - void fmpz_mod_poly_make_monic_f(fmpz_t f, fmpz_mod_poly_t res, - const fmpz_mod_poly_t poly, const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- - void fmpz_mod_poly_gcd_f(fmpz_t f, fmpz_mod_poly_t G, const fmpz_mod_poly_t A, - const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_gcd_hgcd(fmpz_mod_poly_t G, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- -- - void fmpz_mod_poly_gcd(fmpz_mod_poly_t G, const fmpz_mod_poly_t A, - const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - - -- void fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, -- fmpz_mod_poly_t S, fmpz_mod_poly_t T, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_xgcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, -- fmpz_mod_poly_t S, fmpz_mod_poly_t T, -- const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_xgcd_hgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, -- fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, -- const fmpz_mod_ctx_t ctx) -- - void fmpz_mod_poly_xgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) -@@ -361,14 +315,6 @@ cdef extern from "flint_wrap.h": - const fmpz_mod_poly_t poly, const fmpz * xs, slong n, - const fmpz_mod_ctx_t ctx) - -- void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, -- const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, -- const fmpz_mod_ctx_t ctx) -- -- void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, -- const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, -- const fmpz_mod_ctx_t ctx) -- - void fmpz_mod_poly_compose(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, - const fmpz_mod_poly_t poly2, const fmpz_mod_ctx_t ctx) - -diff --git a/src/sage/libs/flint/fmpz_poly.pxd b/src/sage/libs/flint/fmpz_poly.pxd -index 18b36672d30..c8bc6d3ca0a 100644 ---- a/src/sage/libs/flint/fmpz_poly.pxd -+++ b/src/sage/libs/flint/fmpz_poly.pxd -@@ -28,7 +28,6 @@ cdef extern from "flint_wrap.h": - void fmpz_poly_set_ui(fmpz_poly_t, ulong) - void fmpz_poly_set_si(fmpz_poly_t, slong) - void fmpz_poly_set_fmpz(fmpz_poly_t, const fmpz_t) -- void fmpz_poly_set_mpz(fmpz_poly_t, const mpz_t) - int fmpz_poly_set_str(fmpz_poly_t, const char *) - - char *fmpz_poly_get_str(const fmpz_poly_t) -@@ -70,7 +69,6 @@ cdef extern from "flint_wrap.h": - # Scalar multiplication and division - void fmpz_poly_scalar_mul_fmpz( - fmpz_poly_t, const fmpz_poly_t, const fmpz_t) -- void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) - void fmpz_poly_scalar_mul_si(fmpz_poly_t, const fmpz_poly_t, slong) - void fmpz_poly_scalar_mul_ui(fmpz_poly_t, const fmpz_poly_t, ulong) - void fmpz_poly_scalar_mul_2exp(fmpz_poly_t, const fmpz_poly_t, ulong) -@@ -310,12 +308,14 @@ cdef extern from "flint_wrap.h": - fmpz_poly_t, - const fmpz_poly_t, const fmpz_t, const nmod_poly_t, int) - -- # Some functions for backwards compatibility -- void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -- void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -- void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -- void fmpz_poly_set_coeff_mpz(fmpz_poly_t, slong, const mpz_t) -- void fmpz_poly_get_coeff_mpz(mpz_t, const fmpz_poly_t, slong) -+ -+# functions removed from flint but still needed in sage -+cdef void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -+cdef void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -+cdef void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) -+cdef void fmpz_poly_set_coeff_mpz(fmpz_poly_t, slong, const mpz_t) -+cdef void fmpz_poly_get_coeff_mpz(mpz_t, const fmpz_poly_t, slong) -+cdef void fmpz_poly_set_mpz(fmpz_poly_t, const mpz_t) - - - # Wrapper Cython class -diff --git a/src/sage/libs/flint/fmpz_poly.pyx b/src/sage/libs/flint/fmpz_poly.pyx -index 74915b37612..cfcbea9090c 100644 ---- a/src/sage/libs/flint/fmpz_poly.pyx -+++ b/src/sage/libs/flint/fmpz_poly.pyx -@@ -25,10 +25,10 @@ from cysignals.memory cimport sig_free - - from sage.arith.long cimport pyobject_to_long - from sage.cpython.string cimport char_to_str, str_to_bytes -+from sage.libs.flint.fmpz cimport * - from sage.structure.sage_object cimport SageObject - from sage.rings.integer cimport Integer - -- - cdef class Fmpz_poly(SageObject): - - def __cinit__(self): -@@ -455,3 +455,44 @@ cdef class Fmpz_poly(SageObject): - """ - from sage.rings.integer_ring import ZZ - return ZZ[var](self.list()) -+ -+ -+# Functions removed from flint but still needed in Sage. Code adapted from -+# earlier versions of flint. -+ -+cdef void fmpz_poly_scalar_mul_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): -+ cdef fmpz_t f -+ fmpz_init_set_readonly(f, c) -+ fmpz_poly_scalar_mul_fmpz(rop, op, f) -+ fmpz_clear_readonly(f) -+ -+cdef void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): -+ cdef fmpz_t f -+ fmpz_init_set_readonly(f, c) -+ fmpz_poly_scalar_divexact_fmpz(rop, op, f) -+ fmpz_clear_readonly(f) -+ -+cdef void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): -+ cdef fmpz_t f -+ fmpz_init_set_readonly(f, c) -+ fmpz_poly_scalar_fdiv_fmpz(rop, op, f) -+ fmpz_clear_readonly(f) -+ -+cdef void fmpz_poly_set_coeff_mpz(fmpz_poly_t poly, slong n, const mpz_t x): -+ cdef fmpz_t t -+ fmpz_init_set_readonly(t, x) -+ fmpz_poly_set_coeff_fmpz(poly, n, t) -+ fmpz_clear_readonly(t) -+ -+cdef void fmpz_poly_get_coeff_mpz(mpz_t x, const fmpz_poly_t poly, slong n): -+ cdef fmpz_t t -+ fmpz_init(t) -+ fmpz_poly_get_coeff_fmpz(t, poly, n) -+ fmpz_get_mpz(x, t) -+ fmpz_clear(t) -+ -+cdef void fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t x): -+ fmpz_poly_fit_length(poly, 1) -+ fmpz_set_mpz(poly.coeffs, x) -+ _fmpz_poly_set_length(poly, 1) -+ _fmpz_poly_normalise(poly) -diff --git a/src/sage/libs/flint/fmpz_poly_q.pxd b/src/sage/libs/flint/fmpz_poly_q.pxd -index 846542dc0d8..63c13355bf6 100644 ---- a/src/sage/libs/flint/fmpz_poly_q.pxd -+++ b/src/sage/libs/flint/fmpz_poly_q.pxd -@@ -49,11 +49,7 @@ cdef extern from "flint_wrap.h": - - #* Scalar multiplication and division ****************************************/ - void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) -- void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x) -- void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x) - void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) -- void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x) -- void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x) - - #* Multiplication and division ***********************************************/ - void fmpz_poly_q_mul(fmpz_poly_q_t rop, -@@ -67,9 +63,6 @@ cdef extern from "flint_wrap.h": - #* Derivative ****************************************************************/ - void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op) - -- #* Evaluation ****************************************************************/ -- int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a) -- - #* Input and output **********************************************************/ - int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s) - char * fmpz_poly_q_get_str(const fmpz_poly_q_t op) -diff --git a/src/sage/libs/linbox/linbox_flint_interface.pyx b/src/sage/libs/linbox/linbox_flint_interface.pyx -index 1979ac0f0a4..37a340c457f 100644 ---- a/src/sage/libs/linbox/linbox_flint_interface.pyx -+++ b/src/sage/libs/linbox/linbox_flint_interface.pyx -@@ -33,6 +33,7 @@ and C. Pernet. The functions available are: - # https://www.gnu.org/licenses/ - # **************************************************************************** - -+from sage.libs.gmp.types cimport mpz_t - from sage.libs.flint.types cimport fmpz_t - from sage.libs.flint.fmpz cimport fmpz_get_mpz, fmpz_set_mpz - from sage.libs.flint.fmpz_mat cimport fmpz_mat_entry, fmpz_mat_nrows, fmpz_mat_ncols -@@ -80,11 +81,13 @@ cdef void fmpz_poly_set_linbox(fmpz_poly_t p, PolynomialRing_integer.Element& q) - (the .pxd file) in order to keep the header C-compatible - """ - cdef size_t i -+ cdef mpz_t tmp - - fmpz_poly_fit_length(p, q.size()) - - for i in range(q.size()): -- fmpz_poly_set_coeff_mpz(p, i, q[i].get_mpz_const()) -+ tmp = q[i].get_mpz_const() -+ fmpz_poly_set_coeff_mpz(p, i, tmp) - - _fmpz_poly_set_length(p, q.size()) - -diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx -index e5414abdd9e..2f0131f4064 100644 ---- a/src/sage/matrix/matrix_complex_ball_dense.pyx -+++ b/src/sage/matrix/matrix_complex_ball_dense.pyx -@@ -1,4 +1,4 @@ --# distutils: libraries = ARB_LIBRARY -+# distutils: libraries = flint - r""" - Arbitrary precision complex ball matrices using Arb - -diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx -index 27f5cdfac0f..6c5c20dbc6b 100644 ---- a/src/sage/matrix/matrix_integer_sparse.pyx -+++ b/src/sage/matrix/matrix_integer_sparse.pyx -@@ -847,6 +847,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): - sage: matrix(ZZ, 1, 1, sparse=True)._charpoly_linbox() - x - """ -+ cdef mpz_t tmp - if self._nrows != self._ncols: - raise ArithmeticError('only valid for square matrix') - -@@ -869,7 +870,8 @@ cdef class Matrix_integer_sparse(Matrix_sparse): - cdef size_t i - fmpz_poly_fit_length(g._poly, p.size()) - for i in range(p.size()): -- fmpz_poly_set_coeff_mpz(g._poly, i, p[0][i].get_mpz_const()) -+ tmp = p[0][i].get_mpz_const() -+ fmpz_poly_set_coeff_mpz(g._poly, i, tmp) - _fmpz_poly_set_length(g._poly, p.size()) - - del M -@@ -966,9 +968,11 @@ cdef class Matrix_integer_sparse(Matrix_sparse): - sig_off() - - cdef size_t i -+ cdef mpz_t tmp - fmpz_poly_fit_length(g._poly, p.size()) - for i in range(p.size()): -- fmpz_poly_set_coeff_mpz(g._poly, i, p[0][i].get_mpz_const()) -+ tmp = p[0][i].get_mpz_const() -+ fmpz_poly_set_coeff_mpz(g._poly, i, tmp) - _fmpz_poly_set_length(g._poly, p.size()) - - del M -diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx -index 1e3085c9215..0786de7fc81 100644 ---- a/src/sage/rings/complex_arb.pyx -+++ b/src/sage/rings/complex_arb.pyx -@@ -1360,12 +1360,13 @@ cdef class ComplexBall(RingElement): - sage: CBF100(-3r) - -3.000000000000000000000000000000 - -- sage: ComplexBall(CBF100, 10^100) -- 1.000000000000000000000000000000e+100 - sage: ComplexBall(CBF100, CIF(1, 2)) - 1.000000000000000000000000000000 + 2.000000000000000000000000000000*I - sage: ComplexBall(CBF100, RBF(1/3), RBF(1)) - [0.3333333333333333 +/- ...e-17] + 1.000000000000000000000000000000*I -+ sage: ComplexBall(CBF100, 10^100) -+ [1.000000000000000000000000000000e+100 +/- ...] -+ - sage: NF. = QuadraticField(-1, embedding=CC(0, -1)) - sage: CBF(a) - -1.000000000000000*I -@@ -3009,7 +3010,7 @@ cdef class ComplexBall(RingElement): - sage: CBF(1).rising_factorial(2**64) - [+/- ...e+347382171326740403407] - sage: ComplexBallField(128)(1).rising_factorial(2**64) -- [2.343691126796861348e+347382171305201285713 +/- ...e+347382171305201285694] -+ [2.34369112679686134...e+347382171305201285713 +/- ...] - sage: CBF(1/2).rising_factorial(CBF(2,3)) # abs tol 1e-15 - [-0.123060451458124 +/- 3.06e-16] + [0.0406412631676552 +/- 7.57e-17]*I - -diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx -index 04eaefc9fed..d99f0d3b98c 100644 ---- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx -+++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx -@@ -222,7 +222,7 @@ cdef class Polynomial_rational_flint(Polynomial): - cdef unsigned long n - cdef Rational c - cdef list L1 -- cdef mpq_t * L2 -+ cdef fmpq_t q - - Polynomial.__init__(self, parent, is_gen=is_gen) - -@@ -253,14 +253,11 @@ cdef class Polynomial_rational_flint(Polynomial): - L1 = [e if isinstance(e, Rational) else Rational(e) for e in x] - n = len(x) - sig_on() -- L2 = check_allocarray(n, sizeof(mpq_t)) -+ fmpq_poly_fit_length(self._poly, n) - for deg from 0 <= deg < n: -- mpq_init(L2[deg]) -- mpq_set(L2[deg], ( L1[deg]).value) -- fmpq_poly_set_array_mpq(self._poly, L2, n) -- for deg from 0 <= deg < n: -- mpq_clear(L2[deg]) -- sig_free(L2) -+ fmpq_init_set_readonly(q, ( L1[deg]).value) -+ fmpq_poly_set_coeff_fmpq(self._poly, deg, q) -+ fmpq_clear_readonly(q) - sig_off() - - # deg = 0 -@@ -435,6 +432,7 @@ cdef class Polynomial_rational_flint(Polynomial): - utmost care. - """ - cdef bint do_sig = _do_sig(self._poly) -+ cdef fmpz_t tmpfz - - if isinstance(value, int): - if do_sig: sig_str("FLINT exception") -@@ -442,7 +440,9 @@ cdef class Polynomial_rational_flint(Polynomial): - if do_sig: sig_off() - elif isinstance(value, Integer): - if do_sig: sig_str("FLINT exception") -- fmpq_poly_set_coeff_mpz(self._poly, n, ( value).value) -+ fmpz_init_set_readonly(tmpfz, ( value).value) -+ fmpq_poly_set_coeff_fmpz(self._poly, n, tmpfz) -+ fmpz_clear_readonly(tmpfz) - if do_sig: sig_off() - elif isinstance(value, Rational): - if do_sig: sig_str("FLINT exception") -@@ -492,7 +492,7 @@ cdef class Polynomial_rational_flint(Polynomial): - cdef Polynomial_rational_flint f - cdef Rational r - cdef fmpz_t tmpfz -- cdef fmpq_t tmpfq -+ cdef fmpq_t tmpfq, tmpfq1 - cdef RealBall arb_a, arb_z - cdef ComplexBall acb_a, acb_z - -@@ -508,13 +508,23 @@ cdef class Polynomial_rational_flint(Polynomial): - elif isinstance(a, Rational): - r = Rational.__new__(Rational) - sig_str("FLINT exception") -- fmpq_poly_evaluate_mpq(r.value, self._poly, ( a).value) -+ fmpq_init_set_readonly(tmpfq, ( a).value) -+ fmpq_init(tmpfq1) -+ fmpq_poly_evaluate_fmpq(tmpfq1, self._poly, tmpfq) -+ fmpq_get_mpq(r.value, tmpfq1) -+ fmpq_clear(tmpfq1) -+ fmpq_clear_readonly(tmpfq) - sig_off() - return r - elif isinstance(a, Integer): - r = Rational.__new__(Rational) - sig_str("FLINT exception") -- fmpq_poly_evaluate_mpz(r.value, self._poly, ( a).value) -+ fmpz_init_set_readonly(tmpfz, ( a).value) -+ fmpq_init(tmpfq) -+ fmpq_poly_evaluate_fmpz(tmpfq, self._poly, tmpfz) -+ fmpq_get_mpq(r.value, tmpfq) -+ fmpq_clear(tmpfq) -+ fmpz_clear_readonly(tmpfz) - sig_off() - return r - elif isinstance(a, int): -@@ -1321,6 +1331,7 @@ cdef class Polynomial_rational_flint(Polynomial): - """ - cdef Polynomial_rational_flint res - cdef bint do_sig -+ cdef fmpq_t tmpfq - - if right == 0: - raise ZeroDivisionError("division by zero polynomial") -@@ -1331,8 +1342,9 @@ cdef class Polynomial_rational_flint(Polynomial): - do_sig = _do_sig(self._poly) - - if do_sig: sig_str("FLINT exception") -- fmpq_poly_scalar_div_mpq(res._poly, self._poly, -- ( QQ(right)).value) -+ fmpq_init_set_readonly(tmpfq, ( QQ(right)).value) -+ fmpq_poly_scalar_div_fmpq(res._poly, self._poly, tmpfq) -+ fmpq_clear_readonly(tmpfq) - if do_sig: sig_off() - return res - -diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx -index 6e7f7498329..3a66198d568 100644 ---- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx -+++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx -@@ -658,6 +658,11 @@ cdef class Polynomial_zmod_flint(Polynomial_template): - ... - NotImplementedError: square free factorization of polynomials over rings with composite characteristic is not implemented - -+ :trac:`20003`:: -+ -+ sage: P. = GF(7)[] -+ sage: (6*x+3).squarefree_decomposition() -+ (6) * (x + 4) - """ - if not self.base_ring().is_field(): - raise NotImplementedError("square free factorization of polynomials over rings with composite characteristic is not implemented") -diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx -index 17961ac36b2..8509b19cc66 100644 ---- a/src/sage/rings/real_arb.pyx -+++ b/src/sage/rings/real_arb.pyx -@@ -898,7 +898,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): - sage: RBF.gamma(5) - 24.00000000000000 - sage: RBF.gamma(10**20) -- [+/- ...e+1956570552410610660600] -+ [1.932849514310098...+1956570551809674817225 +/- ...] - sage: RBF.gamma(1/3) - [2.678938534707747 +/- ...e-16] - sage: RBF.gamma(-5) -@@ -1102,7 +1102,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): - 15.00000000000000, - 48.00000000000000] - sage: RBF.double_factorial(2**20) -- [1.4483729903e+2928836 +/- ...e+2928825] -+ [1.448372990...e+2928836 +/- ...] - sage: RBF.double_factorial(2**1000) - Traceback (most recent call last): - ... -diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py -index 05d24e78a85..581102b5c5b 100644 ---- a/src/sage/schemes/plane_conics/con_rational_function_field.py -+++ b/src/sage/schemes/plane_conics/con_rational_function_field.py -@@ -198,38 +198,6 @@ def has_rational_point(self, point=False, algorithm='default', - Fraction Field of Univariate Polynomial Ring in u over Rational - Field with modulus v^2 - u^3 - 1 - -- ``has_rational_point`` fails for some conics over function fields -- over finite fields, due to :trac:`20003`:: -- -- sage: K. = PolynomialRing(GF(7)) -- sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2, -- ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) -- sage: C.has_rational_point() # needs sage.libs.singular -- Traceback (most recent call last): -- ... -- TypeError: self (=Scheme morphism: -- From: Projective Conic Curve over Fraction Field of Univariate -- Polynomial Ring in t over Finite Field of size 7 defined by -- (-2*t^2 - 3)*x^2 + (-t^3 + 3*t^2 - 2*t - 2)/(t + 3)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z^2 -- To: Projective Conic Curve over Fraction Field of Univariate -- Polynomial Ring in t over Finite Field of size 7 defined by -- (-2*t^2 - 3)*x^2 + (t^2 + 3*t + 3)*x*y + (-2*t^2 - 2)*y^2 + (-t^2 + 3*t + 2)*x*z + (-3*t + 3)*y*z + (-3*t^2 + t - 2)*z^2 -- Defn: Defined on coordinates by sending (x : y : z) to -- (x + (2*t - 2)/(t + 3)*y + (3*t^4 + 2*t^3 - 2*t^2 - 2*t + 3)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z -- : y + (-t^3 - t^2 + 3*t - 1)/(t^3 - 3*t^2 + 2*t + 2)*z : z)) -- domain must equal right (=Scheme morphism: -- From: Projective Conic Curve over Fraction Field of Univariate -- Polynomial Ring in t over Finite Field of size 7 defined by -- (-2*t^3 - t^2 + 3*t + 3)*x^2 + (t - 3)*y^2 + (-t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 - t - 1)*z^2 -- To: Projective Conic Curve over Fraction Field of Univariate -- Polynomial Ring in t over Finite Field of size 7 defined by -- -2/(t^3 - 3*t^2 + 2*t + 2)*x^2 + 1/(t^3 + 3*t^2 - 2*t + 1)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^9 - 2*t^8 + t^7 - t^6 + 3*t^5 - 3*t^3 + t^2 - 2*t + 3)*z^2 -- Defn: Defined on coordinates by sending (x : y : z) to -- ((t^3 - 3*t^2 + 2*t + 2)*x : (t^2 - 2)*y : (t^5 - 3*t^4 + t^2 + 3*t + 3)*z)) -- codomain -- -- -- - TESTS:: - - sage: K. = FractionField(PolynomialRing(QQ, 't')) -@@ -250,6 +218,16 @@ def has_rational_point(self, point=False, algorithm='default', - sage: C.has_rational_point(point=True) # long time (4 seconds) # needs sage.libs.singular - (True, - ((-2/117*t^8 + 304/1053*t^7 + 40/117*t^6 - 1/27*t^5 - 110/351*t^4 - 2/195*t^3 + 11/351*t^2 + 1/117)/(t^4 + 2/39*t^3 + 4/117*t^2 + 2/39*t + 14/39) : -5/3*t^4 + 19*t^3 : 1)) -+ -+ ``has_rational_point`` used to fail for some conics over function fields -+ over finite fields, due to :trac:`20003`:: -+ -+ sage: K. = PolynomialRing(GF(7)) -+ sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2, -+ ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) -+ sage: C.has_rational_point() -+ True -+ - """ - from .constructor import Conic - -diff --git a/src/sage/symbolic/ginac/inifcns_orthopoly.cpp b/src/sage/symbolic/ginac/inifcns_orthopoly.cpp -index a591cb4cd7c..a90f2050c59 100644 ---- a/src/sage/symbolic/ginac/inifcns_orthopoly.cpp -+++ b/src/sage/symbolic/ginac/inifcns_orthopoly.cpp -@@ -20,6 +20,7 @@ - #include "utils.h" - - #include "gmp.h" -+#include "flint/fmpz_poly.h" - #include "flint/fmpq_poly.h" - #include "flint/fmpq.h" - -@@ -63,7 +64,7 @@ static ex chebyt_eval(const ex& n_, const ex& x) - for (int i = 0; i= 7 - -+ def jmolpath(self): -+ """ -+ Return the path to the jar file. -+ -+ EXAMPLES:: -+ -+ sage: from sage.interfaces.jmoldata import JmolData -+ sage: JData = JmolData() -+ sage: JData.jmolpath() -+ '.../JmolData.jar' -+ -+ """ -+ jmolpath = os.path.join(JMOL_DIR, "JmolData.jar") -+ -+ if sys.platform == 'cygwin': -+ import cygwin -+ jmolpath = cygwin.cygpath(jmolpath, 'w') -+ -+ return jmolpath -+ -+ def is_jmol_available(self): -+ """ -+ Returns True if jmol is available and False if not. -+ -+ EXAMPLES: -+ -+ Check that it returns a boolean:: -+ -+ sage: from sage.interfaces.jmoldata import JmolData -+ sage: JData = JmolData() -+ sage: type(JData.is_jmol_available()) -+ <... 'bool'> -+ """ -+ if not os.path.isfile(self.jmolpath()): -+ return False -+ -+ if not self.is_jvm_available(): -+ return False -+ -+ return True -+ - def export_image(self, - targetfile, - datafile, #name (path) of data file Jmol can read or script file telling it what to read or load -@@ -154,12 +195,11 @@ def export_image(self, - sage: archive.close() - """ - # Set up paths, file names and scripts -- jmolpath = os.path.join(JMOL_DIR, "JmolData.jar") -+ jmolpath = self.jmolpath() - target_native = targetfile - - if sys.platform == 'cygwin': - import cygwin -- jmolpath = cygwin.cygpath(jmolpath, 'w') - target_native = cygwin.cygpath(target_native, 'w') - if datafile_cmd != 'script': - datafile = cygwin.cygpath(datafile, 'w') -diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx -index 253f152130c..7588cde2e27 100644 ---- a/src/sage/plot/plot3d/base.pyx -+++ b/src/sage/plot/plot3d/base.pyx -@@ -278,7 +278,7 @@ cdef class Graphics3d(SageObject): - T.export_jmol(scene_zip, **opts) - from sage.interfaces.jmoldata import JmolData - jdata = JmolData() -- if not jdata.is_jvm_available(): -+ if not jdata.is_jmol_available(): - # We can only use JMol to generate preview if a jvm is installed - from sage.repl.rich_output.output_graphics import OutputImagePng - tachyon = self._rich_repr_tachyon(OutputImagePng, **opts) -diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py -index 69e63b76d60..10ccdc0c2c8 100644 ---- a/src/sage/repl/rich_output/backend_ipython.py -+++ b/src/sage/repl/rich_output/backend_ipython.py -@@ -369,7 +369,7 @@ def launch_jmol(self, output_jmol, plain_text): - from sage.doctest import DOCTEST_MODE - from sage.interfaces.jmoldata import JmolData - jdata = JmolData() -- if not jdata.is_jvm_available() and not DOCTEST_MODE: -+ if not jdata.is_jmol_available() and not DOCTEST_MODE: - raise RuntimeError('jmol cannot run, no suitable java version found') - launch_script = output_jmol.launch_script_filename() - jmol_cmd = 'jmol' diff --git a/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch b/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch deleted file mode 100644 index 8eb2c20a34c52..0000000000000 --- a/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py -index dfaafb4353f..8d62ade24c8 100644 ---- a/src/sage/calculus/calculus.py -+++ b/src/sage/calculus/calculus.py -@@ -568,8 +568,8 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): - - An example of this summation with Giac:: - -- sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac') -- (pi*e^(2*pi) - pi*e^(-2*pi))/(e^(2*pi) + e^(-2*pi) - 2) -+ sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac').factor() -+ pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) - - The same summation is solved by SymPy:: - diff --git a/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch b/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch new file mode 100644 index 0000000000000..a00fb76688fe2 --- /dev/null +++ b/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch @@ -0,0 +1,1509 @@ +diff --git a/src/sage/combinat/designs/MOLS_handbook_data.py b/src/sage/combinat/designs/MOLS_handbook_data.py +new file mode 100644 +index 00000000000..3891d20f81b +--- /dev/null ++++ b/src/sage/combinat/designs/MOLS_handbook_data.py +@@ -0,0 +1,571 @@ ++r""" ++Known lower bounds on the number of Mutually Orthogonal Latin ++Squares (MOLS) of a given size. ++ ++This module consists (almost) entirely of an internal, constant tuple ++of python integers corresponding to Table 3.87 in the Handbook of ++Combinatorial Designs, 2nd edition, by Colbourn and Dinitz. One public ++function, :func:`lower_bound`, is provided to access it. ++ ++Make sure we have all of the entries:: ++ ++ sage: from sage.combinat.designs import MOLS_handbook_data ++ sage: len(MOLS_handbook_data._LOWER_BOUNDS) ++ 10000 ++ ++Jeff Dinitz's website (at UVM) provides the following two updates to ++the table as printed in the second edition:: ++ ++ sage: from sage.combinat.designs import MOLS_handbook_data ++ sage: MOLS_handbook_data.lower_bound(60) ++ 5 ++ sage: MOLS_handbook_data.lower_bound(7968) ++ 31 ++ ++""" ++ ++_LOWER_BOUNDS: tuple[int, ...] ++_LOWER_BOUNDS = ( ++ 0,0,1,2,3,4,1,6,7,8,2,10,5,12,3,4,15,16,3,18, # 0 ++ 4,5,3,22,7,24,4,26,5,28,4,30,31,5,4,5,8,36,4,5, # 20 ++ 7,40,5,42,5,6,4,46,8,48,6,5,5,52,5,6,7,7,5,58, # 40 ++ 5,60,5,6,63,7,5,66,5,6,6,70,7,72,5,7,6,6,6,78, # 60 ++ 9,80,8,82,6,6,6,6,7,88,6,7,6,6,6,6,7,96,6,8, # 80 ++ 8,100,6,102,7,7,6,106,6,108,6,6,13,112,6,7,6,8,6,6, # 100 ++ 7,120,6,6,6,124,6,126,127,7,6,130,6,7,6,7,7,136,6,138, # 120 ++ 6,7,6,10,10,7,6,7,6,148,6,150,7,8,8,7,6,156,7,6, # 140 ++ 9,7,6,162,6,7,6,166,7,168,6,8,6,172,6,6,14,9,6,178, # 160 ++ 6,180,6,6,7,9,6,10,6,8,6,190,7,192,6,7,6,196,6,198, # 180 ++ 7,8,6,7,6,8,6,8,14,11,10,210,6,7,6,7,7,8,6,10, # 200 ++ 6,12,6,222,13,8,6,226,6,228,6,7,7,232,6,7,6,7,6,238, # 220 ++ 7,240,6,242,6,7,6,12,7,7,6,250,6,12,9,7,255,256,6,12, # 240 ++ 6,8,8,262,7,8,7,10,7,268,7,270,15,16,6,13,10,276,6,9, # 260 ++ 7,280,6,282,6,12,6,7,15,288,6,6,6,292,6,6,7,10,10,12, # 280 ++ 7,7,7,7,15,15,6,306,7,7,7,310,7,312,7,10,7,316,7,10, # 300 ++ 15,15,6,16,8,12,6,7,7,9,6,330,7,8,7,6,8,336,6,7, # 320 ++ 6,10,10,342,7,7,6,346,6,348,8,12,18,352,6,9,7,9,6,358, # 340 ++ 8,360,6,7,7,10,6,366,15,15,7,15,7,372,7,15,7,13,7,378, # 360 ++ 7,12,7,382,15,15,7,15,7,388,7,16,7,8,7,7,8,396,7,7, # 380 ++ 15,400,7,15,11,8,7,15,8,408,7,13,8,12,10,9,18,15,7,418, # 400 ++ 7,420,7,15,7,16,6,7,7,10,6,430,15,432,6,15,6,18,7,438, # 420 ++ 7,15,7,442,7,13,7,11,15,448,7,15,7,7,7,15,7,456,7,16, # 440 ++ 7,460,7,462,15,15,7,466,8,8,7,15,7,15,10,18,7,15,6,478, # 460 ++ 15,15,6,15,8,7,6,486,7,15,6,490,6,16,6,7,15,15,6,498, # 480 ++ 7,12,9,502,7,15,6,15,7,508,6,15,511,18,7,15,8,12,8,15, # 500 ++ 8,520,10,522,12,15,8,16,15,528,7,15,8,12,7,15,8,15,10,15, # 520 ++ 12,540,7,15,18,7,7,546,7,8,7,18,7,7,7,7,7,556,7,12, # 540 ++ 15,7,7,562,7,7,6,7,7,568,6,570,7,7,15,22,8,576,7,7, # 560 ++ 7,8,7,10,7,8,7,586,7,18,17,7,15,592,8,15,7,7,8,598, # 580 ++ 14,600,12,15,7,15,16,606,18,15,7,15,8,612,8,15,7,616,7,618, # 600 ++ 8,22,8,15,15,624,7,8,8,16,7,630,7,8,7,8,7,12,7,8, # 620 ++ 9,640,7,642,7,7,7,646,8,10,7,7,7,652,7,7,15,15,7,658, # 640 ++ 7,660,7,15,7,15,7,22,7,15,7,15,15,672,7,24,8,676,7,15, # 660 ++ 7,15,7,682,8,15,7,15,15,15,7,690,8,15,7,15,7,16,7,15, # 680 ++ 8,700,7,18,15,15,7,15,8,708,7,15,7,22,21,15,7,15,8,718, # 700 ++ 15,9,8,12,10,24,12,726,7,728,16,16,18,732,7,7,22,10,8,738, # 720 ++ 7,7,7,742,7,15,7,8,7,10,7,750,15,15,8,15,8,756,8,15, # 740 ++ 7,760,8,15,8,15,8,15,15,768,8,15,8,772,8,24,23,15,8,18, # 760 ++ 8,18,7,26,15,15,10,786,12,15,7,15,20,15,18,15,8,796,22,16, # 780 ++ 24,15,8,15,8,15,8,15,8,808,8,810,8,15,8,15,15,18,8,8, # 800 ++ 8,820,8,822,8,15,8,826,8,828,8,15,12,16,7,8,7,26,25,838, # 820 ++ 8,840,8,20,8,10,8,16,15,15,12,22,7,852,16,15,22,856,7,858, # 840 ++ 22,15,24,862,26,15,7,15,8,15,9,15,7,15,7,15,7,876,8,15, # 860 ++ 15,880,8,882,8,15,7,886,7,15,8,15,10,18,8,15,13,15,8,28, # 880 ++ 27,16,8,8,8,22,8,906,8,18,10,910,15,14,8,15,16,10,18,918, # 900 ++ 24,8,22,12,24,24,26,8,28,928,7,18,7,7,7,14,7,936,7,15, # 920 ++ 7,940,7,22,15,15,7,946,7,12,12,15,7,952,7,15,7,15,8,15, # 940 ++ 15,960,29,15,8,15,8,966,8,15,8,970,10,18,12,15,15,976,16,18, # 960 ++ 18,15,7,982,27,15,24,15,26,22,28,990,31,31,7,15,8,996,25,26, # 980 ++ 7,15,21,16,19,15,7,18,15,1008,13,18,8,1012,9,22,7,28,7,1018, # 1000 ++ 7,1020,7,30,1023,24,7,15,9,15,9,1030,7,1032,7,15,8,16,9,1038, # 1020 ++ 15,15,8,15,8,15,8,15,8,1048,8,1050,8,15,8,15,15,16,8,8, # 1040 ++ 8,1060,8,1062,8,15,8,15,10,1068,7,15,15,28,7,24,7,15,8,15, # 1060 ++ 12,22,8,15,8,15,8,1086,16,15,8,1090,8,1092,8,15,8,1096,8,15, # 1080 ++ 8,15,8,1102,15,15,8,26,8,1108,8,18,8,15,8,15,8,1116,7,15, # 1100 ++ 16,18,7,1122,7,15,7,22,8,1128,7,15,8,15,10,9,15,15,7,16, # 1120 ++ 7,8,7,15,7,15,7,30,30,15,7,1150,15,1152,7,15,8,26,12,24, # 1140 ++ 12,26,7,1162,16,18,18,15,15,15,22,1170,24,15,26,24,28,15,30,30, # 1160 ++ 8,1180,8,15,31,15,8,1186,8,28,8,15,8,1192,8,15,8,15,8,15, # 1180 ++ 15,1200,8,15,8,15,8,16,8,15,8,15,8,1212,8,15,18,1216,7,22, # 1200 ++ 7,15,8,1222,7,24,7,15,7,1228,7,1230,15,9,8,15,7,1236,7,15, # 1220 ++ 7,16,8,10,8,7,8,28,8,1248,8,8,7,7,7,8,8,8,7,1258, # 1240 ++ 7,12,23,7,15,15,9,15,9,26,9,30,30,23,8,15,9,1276,9,1278, # 1260 ++ 15,30,10,1282,12,15,9,24,16,1288,18,1290,8,18,22,15,24,1296,26,15, # 1280 ++ 28,1300,30,1302,8,15,8,1306,30,15,8,15,31,15,12,15,8,15,8,1318, # 1300 ++ 8,1320,8,26,8,24,7,1326,15,15,8,1330,8,30,30,15,8,15,9,30, # 1320 ++ 12,15,8,30,15,30,12,15,9,26,16,24,18,15,9,20,22,22,24,15, # 1340 ++ 26,1360,28,28,30,30,9,1366,28,1368,30,15,9,1372,30,15,31,16,8,15, # 1360 ++ 8,1380,8,15,8,15,8,18,8,15,8,15,15,15,8,15,8,10,9,1398, # 1380 ++ 10,15,8,22,8,8,8,15,10,1408,8,16,7,9,9,22,9,12,7,8, # 1400 ++ 9,28,7,1422,15,24,9,1426,9,1428,7,26,7,1432,9,15,7,15,7,1438, # 1420 ++ 15,15,7,15,9,15,9,1446,7,15,7,1450,7,1452,9,15,15,30,30,1458, # 1440 ++ 8,15,8,30,8,15,8,30,10,30,12,1470,22,30,16,28,18,15,8,24, # 1460 ++ 22,1480,24,1482,26,18,28,1486,30,1488,13,15,8,1492,30,15,8,15,30,1498, # 1480 ++ 30,18,9,15,31,15,9,15,9,14,9,1510,9,24,9,9,9,36,9,30, # 1500 ++ 30,9,9,1522,9,30,9,9,9,30,10,1530,12,9,9,30,16,30,18,18, # 1520 ++ 8,26,22,1542,24,8,26,20,28,1548,30,30,15,1552,8,15,30,8,8,1558, # 1540 ++ 30,15,30,15,8,15,30,1566,31,15,8,1570,8,15,12,15,8,18,8,1578, # 1560 ++ 8,15,8,1582,15,24,8,8,8,15,8,36,7,26,8,15,8,1596,8,15, # 1580 ++ 24,1600,8,15,8,15,8,1606,8,1608,8,15,8,1612,7,15,15,15,8,1618, # 1600 ++ 8,1620,7,15,7,15,7,1626,7,15,7,15,24,22,8,15,8,1636,7,15, # 1620 ++ 7,15,7,30,30,15,7,26,15,30,7,15,11,30,10,30,12,1656,7,30, # 1640 ++ 16,30,18,1662,15,30,22,1666,24,1668,26,24,28,22,30,30,19,15,7,22, # 1660 ++ 30,1680,9,15,30,15,30,15,9,15,30,18,30,1692,9,15,31,1696,9,1698, # 1680 ++ 9,15,8,15,8,15,8,15,8,1708,21,28,15,15,8,15,10,16,7,15, # 1700 ++ 8,1720,9,1722,9,15,7,15,26,21,8,15,8,1732,7,15,7,15,7,36, # 1720 ++ 9,1740,8,15,15,15,8,1746,8,15,8,16,9,1752,9,15,9,15,8,1758, # 1740 ++ 26,15,8,40,9,15,8,15,8,28,8,27,8,15,8,24,15,1776,9,15, # 1760 ++ 8,15,8,1782,8,15,8,1786,8,1788,8,15,15,15,9,15,8,15,8,15, # 1780 ++ 8,1800,8,15,9,15,8,30,15,26,8,1810,8,36,7,15,9,22,9,16, # 1800 ++ 9,15,9,1822,26,24,9,15,9,30,30,1830,9,15,9,30,9,15,9,30, # 1820 ++ 15,30,12,18,9,30,16,1846,18,1848,9,30,22,16,24,15,28,30,28,28, # 1840 ++ 30,1860,25,22,8,22,30,1866,8,18,30,1870,30,1872,8,15,30,1876,30,1878, # 1860 ++ 8,15,30,8,8,8,8,15,31,1888,8,30,30,15,8,15,8,30,8,15, # 1880 ++ 8,1900,10,30,15,15,8,1906,16,30,18,15,8,1912,22,15,24,26,26,30, # 1900 ++ 28,30,30,30,27,9,7,40,30,9,8,1930,30,1932,30,8,15,15,30,15, # 1920 ++ 30,10,8,28,30,15,8,15,8,1948,30,1950,31,15,8,15,8,18,8,15, # 1940 ++ 8,36,8,15,8,15,8,15,15,15,8,26,8,1972,8,24,9,15,9,1978, # 1960 ++ 9,15,9,15,30,30,9,1986,9,15,30,15,10,1992,30,15,30,1996,9,1998, # 1980 ++ 30,16,30,2002,9,9,30,22,9,40,9,2010,30,28,30,30,31,2016,8,15, # 2000 ++ 27,42,8,15,23,30,21,2026,8,2028,8,30,15,30,13,15,11,30,8,2038, # 2020 ++ 8,15,8,30,8,30,8,22,2047,15,8,15,8,2052,8,15,8,16,10,28, # 2040 ++ 8,15,9,2062,15,15,8,15,8,2068,8,18,8,15,9,24,8,30,30,15, # 2060 ++ 30,2080,8,2082,8,15,8,2086,10,2088,12,15,8,30,16,30,18,15,8,2098, # 2080 ++ 22,36,24,15,26,30,28,42,30,30,30,2110,15,2112,30,15,9,28,30,24, # 2100 ++ 30,15,10,15,30,18,30,16,15,2128,30,2130,8,26,9,15,30,2136,30,15, # 2120 ++ 9,2140,9,2142,31,15,9,18,9,15,9,15,9,2152,10,15,12,15,9,16, # 2140 ++ 15,2160,9,15,9,14,9,15,9,15,10,14,12,40,9,15,16,15,9,2178, # 2160 ++ 8,15,9,36,9,15,9,2186,9,15,9,23,15,15,8,15,9,2196,12,15, # 2180 ++ 9,30,30,2202,8,15,9,2206,15,2208,8,30,10,2212,12,15,8,30,16,30, # 2200 ++ 18,2220,8,30,22,24,24,16,26,30,28,30,30,30,30,15,10,2236,30,2238, # 2220 ++ 16,30,30,2242,30,15,8,15,30,22,30,2250,8,18,30,15,15,36,8,15, # 2240 ++ 30,15,30,30,30,30,9,2266,30,2268,8,15,31,2272,10,30,12,15,8,42, # 2260 ++ 16,2280,18,15,8,30,22,2286,24,15,26,30,28,2292,30,30,30,2296,9,30, # 2280 ++ 30,15,9,46,30,30,30,15,9,2308,30,2310,30,22,9,20,30,15,9,15, # 2300 ++ 15,15,30,22,30,15,9,30,28,16,30,15,9,2332,30,15,31,15,9,2338, # 2320 ++ 8,2340,8,10,9,15,8,2346,8,28,8,2350,15,12,8,15,9,2356,9,10, # 2340 ++ 8,15,8,16,8,9,8,10,36,22,10,2370,8,10,8,18,26,2376,8,10, # 2360 ++ 8,2380,8,2382,15,15,8,15,8,2388,8,15,8,2392,8,42,10,15,13,2398, # 2380 ++ 15,2400,8,26,8,15,9,28,7,15,7,2410,8,18,17,15,15,2416,7,40, # 2400 ++ 8,15,8,2422,14,24,12,15,8,15,16,15,18,15,8,15,9,2436,9,15, # 2420 ++ 9,2440,10,15,10,15,10,2446,15,30,30,15,9,27,9,30,9,15,9,2458, # 2440 ++ 10,30,12,15,15,30,16,2466,18,15,9,30,22,2472,24,15,26,2476,28,36, # 2460 ++ 30,30,30,15,12,30,30,15,9,30,30,46,30,15,9,15,30,30,30,28, # 2480 ++ 8,40,30,2502,8,15,9,22,30,15,30,30,30,30,9,15,30,30,8,15, # 2500 ++ 30,2520,30,30,12,24,9,30,31,30,18,2530,9,30,22,15,24,42,26,2538, # 2520 ++ 28,30,30,2542,30,15,9,30,30,2548,9,2550,30,30,30,15,9,2556,30,30, # 2540 ++ 30,30,9,28,30,15,10,16,9,23,30,15,30,30,30,30,15,15,30,2578, # 2560 ++ 9,28,30,30,30,30,12,12,12,30,30,2590,31,2592,8,30,22,48,24,22, # 2580 ++ 26,30,28,30,30,30,30,9,15,2608,30,15,9,30,30,30,30,2616,8,26, # 2600 ++ 30,2620,30,42,40,30,30,36,8,15,8,24,30,2632,30,15,8,30,8,16, # 2620 ++ 30,18,8,15,30,15,30,2646,28,15,8,15,30,15,30,15,31,2656,10,2658, # 2640 ++ 8,15,9,2662,9,15,9,15,7,16,9,2670,15,15,8,24,8,2676,8,15, # 2660 ++ 9,15,8,2682,9,15,8,2686,15,2688,8,15,10,2692,8,15,8,15,9,2698, # 2680 ++ 9,36,8,15,15,15,10,2706,8,15,10,2710,9,2712,8,15,10,15,10,2718, # 2700 ++ 31,15,9,15,9,24,10,26,10,2728,10,2730,9,15,10,15,15,15,8,15, # 2720 ++ 8,2740,8,15,9,15,8,40,9,2748,8,15,42,2752,9,15,8,15,9,30, # 2740 ++ 30,15,8,15,9,30,7,2766,15,30,10,30,12,46,8,30,16,2776,18,15, # 2760 ++ 9,30,22,22,24,15,26,30,28,2788,30,2790,30,15,9,30,30,2796,9,30, # 2780 ++ 30,2800,30,2802,9,15,30,30,30,2808,8,30,30,28,9,15,15,30,30,2818, # 2800 ++ 30,15,8,30,9,24,30,15,8,18,30,18,30,2832,9,15,9,2836,30,23, # 2820 ++ 30,15,30,2842,8,15,8,15,31,15,10,2850,8,15,9,15,8,2856,8,15, # 2840 ++ 8,2860,29,13,29,15,9,46,29,18,29,15,8,16,29,22,8,15,8,2878, # 2860 ++ 29,42,29,15,9,29,9,2886,29,26,8,48,29,15,29,15,15,2896,9,15, # 2880 ++ 29,15,30,2902,8,15,8,15,8,2908,10,40,31,15,9,15,8,2916,9,15, # 2900 ++ 8,22,21,36,9,18,9,2926,15,28,9,15,10,15,12,15,9,15,16,2938, # 2920 ++ 18,16,9,26,22,15,9,15,9,15,9,15,9,2952,9,15,9,2956,9,15, # 2940 ++ 15,15,9,2962,9,15,9,15,9,2968,9,2970,9,15,10,15,15,15,12,15, # 2960 ++ 9,15,10,18,9,15,9,28,9,48,8,15,15,40,9,15,9,36,9,2998, # 2980 ++ 9,3000,9,15,10,15,9,30,46,15,9,3010,9,30,8,15,10,30,10,3018, # 3000 ++ 12,15,9,3022,16,30,18,15,9,30,22,15,24,15,26,30,28,3036,30,30, # 3020 ++ 31,3040,9,30,30,15,9,30,30,3048,30,26,9,42,30,30,30,30,9,30, # 3040 ++ 30,3060,9,15,9,30,30,3066,30,15,9,36,15,30,30,15,8,26,30,3078, # 3060 ++ 30,15,9,3082,9,18,30,15,30,3088,30,15,9,15,10,15,30,18,9,15, # 3080 ++ 9,15,9,28,31,15,9,25,9,3108,8,15,9,15,8,15,8,15,9,3118, # 3100 ++ 15,3120,8,15,9,3124,8,52,8,15,9,30,30,15,8,15,48,3136,9,42, # 3120 ++ 8,30,10,30,12,15,9,30,16,46,18,22,15,30,22,15,24,15,26,30, # 3140 ++ 28,30,30,3162,30,15,9,3166,30,3168,9,30,30,30,30,24,23,15,30,30, # 3160 ++ 30,3180,10,30,30,15,10,3186,12,30,30,3190,30,30,30,30,8,30,30,30, # 3180 ++ 24,30,30,3202,30,30,12,24,9,3208,30,30,30,18,30,30,22,3216,24,15, # 3200 ++ 30,3220,28,30,30,30,30,15,30,3228,30,15,31,52,30,30,30,15,9,40, # 3220 ++ 30,30,30,30,9,30,30,16,15,15,10,3250,30,3252,30,15,9,3256,9,3258, # 3240 ++ 30,15,10,30,30,30,30,26,10,26,9,3270,30,15,30,24,30,28,10,15, # 3260 ++ 15,16,30,48,9,15,10,18,28,15,30,15,9,36,30,15,31,15,9,3298, # 3280 ++ 10,3300,10,15,10,15,10,3306,10,15,9,15,15,3312,9,15,9,30,30,3318, # 3300 ++ 9,40,9,3322,9,23,9,30,14,3328,12,3330,10,30,16,30,18,46,9,30, # 3320 ++ 22,15,24,3342,26,30,28,3346,30,30,30,15,10,30,30,13,10,30,30,3358, # 3340 ++ 30,3360,10,15,30,30,30,30,12,30,30,3370,10,3372,10,30,30,15,30,30, # 3360 ++ 30,30,9,30,30,30,9,30,30,3388,30,3390,52,30,10,30,30,42,30,24, # 3380 ++ 30,39,22,40,24,23,30,3406,28,30,30,30,30,3412,30,30,30,15,30,30, # 3400 ++ 30,30,30,15,31,24,30,30,30,30,25,46,30,3432,9,15,10,30,30,18, # 3420 ++ 30,15,13,30,10,30,30,15,22,3448,30,30,30,13,24,30,26,3456,30,15, # 3440 ++ 30,3460,30,3462,9,15,9,3466,30,3468,9,10,15,22,10,24,30,18,9,48, # 3460 ++ 30,3480,30,42,10,15,30,39,31,15,9,3490,9,11,10,13,10,15,12,3498, # 3480 ++ 9,15,10,30,30,11,10,15,9,30,10,3510,9,30,10,30,12,3516,9,30, # 3500 ++ 26,30,18,15,12,30,22,3526,24,3528,26,30,28,3532,30,30,30,26,10,3538, # 3520 ++ 30,3540,11,30,30,30,30,3546,11,15,30,52,30,30,10,30,30,3556,10,3558, # 3540 ++ 11,30,30,12,30,12,11,30,15,42,30,3570,11,30,30,30,30,48,10,30, # 3560 ++ 10,3580,30,3582,30,30,30,16,10,36,10,15,30,3592,11,15,11,18,10,58, # 3580 ++ 30,15,10,13,30,15,30,3606,9,15,30,22,30,3612,9,15,31,3616,9,15, # 3600 ++ 10,15,9,3622,10,28,11,15,9,25,11,3630,15,15,10,15,10,3636,9,15, # 3620 ++ 9,15,8,3642,11,15,9,15,26,40,10,15,9,15,12,15,9,25,9,3658, # 3640 ++ 11,15,11,15,15,15,10,18,9,15,9,3670,10,3672,10,15,9,3676,8,21, # 3660 ++ 15,15,10,28,27,15,10,24,9,15,10,3690,10,18,10,16,15,3696,10,26, # 3680 ++ 16,3700,18,15,24,15,22,15,24,3708,26,15,28,46,10,15,10,15,9,3718, # 3700 ++ 10,3720,10,15,11,24,9,3726,15,15,9,15,10,3732,10,15,9,36,9,3738, # 3720 ++ 9,15,10,18,15,39,10,15,9,22,10,30,30,26,9,15,10,30,12,15, # 3740 ++ 15,3760,10,52,12,15,10,3766,16,3768,18,15,9,30,22,24,58,15,26,3778, # 3760 ++ 28,30,30,30,30,15,10,30,30,15,10,30,30,3792,30,15,10,3796,30,30, # 3780 ++ 30,30,10,3802,30,15,9,46,31,30,30,36,30,15,9,30,9,30,30,15, # 3800 ++ 10,3820,30,3822,30,15,10,42,10,30,30,15,30,3832,30,15,10,15,10,15, # 3820 ++ 30,30,10,15,10,26,10,3846,30,15,9,3850,30,3852,30,15,15,15,30,16, # 3840 ++ 30,15,10,3862,30,15,9,15,9,52,9,48,31,15,10,30,30,3876,10,15, # 3860 ++ 10,3880,9,15,10,30,10,30,15,3888,10,30,16,30,18,15,9,30,22,15, # 3880 ++ 24,48,26,30,60,30,30,3906,30,15,9,3910,30,15,11,30,30,3916,30,3918, # 3900 ++ 15,15,30,3922,30,30,9,30,30,3928,9,3930,9,30,30,15,30,30,30,30, # 3920 ++ 9,30,30,3942,9,30,30,3946,30,30,12,30,15,58,30,30,30,30,30,36, # 3940 ++ 26,40,24,15,30,30,28,3966,30,48,30,28,30,36,30,24,30,40,30,30, # 3960 ++ 30,18,30,16,30,30,30,30,30,3988,30,22,10,24,10,30,30,28,30,30, # 3980 ++ 31,4000,10,4002,30,30,10,4006,30,30,30,30,9,4012,9,30,30,30,30,4018, # 4000 ++ 30,4020,9,26,9,24,30,4026,9,30,9,30,30,36,30,30,9,26,30,30, # 4020 ++ 30,30,10,20,30,18,30,30,15,4048,30,4050,18,15,9,15,28,4056,30,15, # 4040 ++ 26,30,30,16,31,30,10,48,27,30,9,30,10,4072,21,30,19,30,16,4078, # 4060 ++ 18,30,10,30,22,15,24,60,26,30,28,4090,30,4092,30,30,4095,30,30,4098, # 4080 ++ 9,30,30,30,30,15,9,15,30,30,30,4110,15,30,30,15,10,22,10,30, # 4100 ++ 30,15,30,15,11,30,9,4126,30,4128,10,30,30,4132,30,15,11,30,10,4138, # 4120 ++ 30,40,30,30,30,15,10,15,10,15,30,30,9,4152,11,30,9,4156,30,4158, # 4140 ++ 15,30,30,22,30,15,29,24,30,22,30,42,29,15,30,24,29,4176,10,15, # 4160 ++ 10,36,30,46,29,15,30,52,30,58,29,15,31,15,29,15,29,15,10,15, # 4180 ++ 12,4200,29,15,29,15,29,15,15,15,10,4210,29,15,9,15,9,4216,10,4218, # 4200 ++ 29,15,9,40,29,24,29,15,10,4228,29,4230,29,15,10,15,29,18,13,26, # 4220 ++ 15,4240,10,4242,30,15,9,30,30,15,12,15,9,4252,13,15,31,30,10,4258, # 4240 ++ 12,4260,10,30,16,30,18,42,9,30,22,4270,24,4272,26,30,28,30,30,30, # 4260 ++ 30,15,10,4282,30,15,9,30,63,4288,30,15,10,52,30,30,30,4296,9,30, # 4280 ++ 30,15,10,15,15,30,30,58,30,30,30,30,9,30,30,30,9,30,30,30, # 4300 ++ 30,30,12,30,10,30,30,4326,30,30,30,60,22,15,24,15,30,4336,28,4338, # 4320 ++ 30,30,30,42,30,30,30,30,30,4348,30,30,30,30,30,28,30,4356,30,30, # 4340 ++ 30,48,30,4362,13,18,13,30,30,16,30,15,30,4372,30,30,30,15,30,30, # 4360 ++ 30,30,30,15,31,30,12,40,30,15,30,4390,30,22,13,15,13,4396,30,52, # 4380 ++ 15,26,12,30,13,30,30,15,13,4408,30,15,30,15,10,30,30,30,30,15, # 4400 ++ 12,4420,30,4422,13,15,13,20,12,42,30,15,15,15,30,15,30,30,12,22, # 4420 ++ 30,4440,11,15,13,15,30,4446,31,15,10,4450,12,60,13,15,12,4456,13,15, # 4440 ++ 13,15,13,4462,15,15,11,15,10,40,12,16,13,15,13,24,13,36,13,15, # 4460 ++ 16,4480,10,4482,10,15,12,15,13,4488,13,15,10,4492,13,15,15,15,10,25, # 4480 ++ 10,15,10,15,10,15,12,4506,13,26,13,15,15,4512,10,15,10,4516,10,4518, # 4500 ++ 10,15,12,4522,13,24,10,15,15,15,11,22,10,15,10,15,10,15,10,15, # 4520 ++ 12,18,13,15,63,15,10,4546,10,4548,10,15,10,28,10,15,12,15,12,46, # 4540 ++ 15,4560,11,26,11,15,10,4566,10,15,12,15,12,16,13,15,31,22,11,18, # 4560 ++ 10,15,10,4582,10,15,10,15,12,15,13,4590,15,15,10,15,10,4596,12,15, # 4580 ++ 10,42,10,4602,12,15,9,16,15,15,13,15,11,15,9,15,9,18,10,30, # 4600 ++ 30,4620,12,15,16,36,15,15,13,30,15,30,15,40,15,30,16,4636,18,4638, # 4620 ++ 31,30,22,4642,24,15,26,30,28,4648,30,4650,30,15,15,30,30,4656,12,30, # 4640 ++ 30,58,30,4662,14,15,30,30,30,30,14,30,63,4672,12,15,14,30,30,4678, # 4660 ++ 30,30,30,30,14,30,30,42,15,30,30,4690,30,30,14,30,15,30,30,36, # 4680 ++ 35,30,30,4702,22,15,24,15,30,30,28,30,30,30,30,30,30,52,30,30, # 4700 ++ 30,4720,30,4722,30,30,30,30,30,4728,30,31,30,4732,30,15,36,30,12,30, # 4720 ++ 30,15,30,15,30,30,30,46,30,15,30,4750,30,48,30,15,30,66,30,4758, # 4740 ++ 30,15,30,30,30,15,13,15,31,18,30,30,11,15,10,30,10,39,30,58, # 4760 ++ 15,30,30,4782,30,15,12,4786,30,4788,30,15,10,4792,30,15,14,15,15,4798, # 4780 ++ 15,4800,30,15,10,15,30,24,30,30,10,16,30,4812,14,15,15,4816,30,60, # 4800 ++ 30,15,10,22,28,24,12,15,12,15,30,4830,31,26,12,15,10,23,10,15, # 4820 ++ 10,46,11,28,12,15,15,36,15,15,11,15,10,22,10,15,11,15,10,42, # 4840 ++ 11,4860,14,15,18,17,12,30,30,15,10,4870,11,30,11,15,12,4876,11,30, # 4860 ++ 15,16,10,30,16,30,18,26,10,4888,22,66,24,15,26,30,28,58,30,30, # 4880 ++ 30,28,12,4902,30,15,10,30,30,4908,30,15,15,4912,30,30,30,30,10,4918, # 4900 ++ 30,15,11,15,10,30,30,15,30,15,12,4930,11,4932,30,15,11,4936,30,30, # 4920 ++ 30,60,10,4942,15,30,30,15,30,48,30,4950,10,15,10,15,30,4956,10,15, # 4940 ++ 15,40,11,30,30,15,12,4966,30,4968,30,15,10,4972,30,30,30,15,12,15, # 4960 ++ 30,16,10,15,11,30,10,4986,30,15,10,15,30,4992,30,30,10,18,30,4998, # 4980 ++ 11,15,10,5002,30,18,30,15,15,5008,10,5010,11,15,10,15,30,28,30,15, # 5000 ++ 10,5020,10,5022,31,15,10,15,10,46,10,15,9,15,10,15,10,15,10,5038, # 5020 ++ 15,5040,10,15,11,15,10,48,9,15,10,5050,10,30,30,15,63,15,10,5058, # 5040 ++ 11,15,10,60,10,30,12,15,10,36,16,30,18,15,10,30,22,5076,24,15, # 5060 ++ 26,5080,28,30,30,30,30,5086,31,30,30,15,12,30,30,30,30,15,10,5098, # 5080 ++ 30,5100,30,30,15,30,30,5106,11,15,10,30,30,5112,30,15,10,30,10,5118, # 5100 ++ 30,39,10,46,30,40,30,15,10,30,13,30,30,15,30,30,30,15,10,15, # 5120 ++ 11,52,30,36,11,15,13,5146,13,45,30,15,31,5152,30,15,30,26,10,30, # 5140 ++ 30,30,30,15,12,15,30,5166,15,15,15,5170,15,30,30,15,15,30,30,5178, # 5160 ++ 30,30,15,70,63,30,15,30,15,5188,30,28,30,30,16,30,18,5196,15,30, # 5180 ++ 22,15,30,42,30,30,28,40,39,5208,30,36,15,30,30,15,31,30,30,30, # 5200 ++ 30,22,15,15,30,30,30,5226,15,30,30,5230,24,5232,26,30,30,5236,30,31, # 5220 ++ 30,30,13,48,36,30,15,30,40,30,30,58,15,30,15,30,30,30,30,30, # 5240 ++ 30,5260,22,18,24,15,30,30,28,30,30,30,30,5272,30,30,30,30,30,5278, # 5260 ++ 31,5280,30,30,30,30,30,30,30,30,30,30,30,66,15,30,15,5296,30,16, # 5280 ++ 30,15,30,5302,30,30,30,15,30,5308,30,46,63,30,30,30,30,30,30,26, # 5300 ++ 30,30,30,5322,15,18,30,16,30,5328,12,16,10,5332,30,30,30,15,15,30, # 5320 ++ 30,48,30,15,31,30,30,5346,30,15,10,5350,30,52,11,15,15,30,15,30, # 5340 ++ 30,15,12,30,30,30,30,30,10,30,30,40,15,30,15,42,30,30,30,30, # 5360 ++ 16,5380,18,15,14,30,22,5386,30,18,30,30,28,5392,30,30,30,15,12,5398, # 5380 ++ 30,15,30,30,30,30,30,5406,31,15,30,30,30,5412,9,30,30,5416,12,5418, # 5400 ++ 11,30,30,15,30,15,13,66,12,60,30,5430,11,30,30,30,30,5436,15,30, # 5420 ++ 40,5440,30,5442,30,30,30,15,11,5448,11,15,30,30,15,15,15,30,10,52, # 5440 ++ 30,42,41,30,30,38,30,15,11,30,30,5470,30,30,12,16,30,5476,16,5478, # 5460 ++ 18,30,10,5482,30,18,24,15,30,30,30,30,30,31,30,30,38,22,36,30, # 5480 ++ 30,5500,40,5502,42,30,10,5506,14,15,12,24,30,36,30,15,10,15,10,5518, # 5500 ++ 30,5520,10,15,10,15,30,5526,10,15,30,5530,30,15,10,15,31,48,10,28, # 5520 ++ 10,15,9,25,9,15,10,15,12,30,30,15,15,15,11,30,10,5556,10,30, # 5540 ++ 10,66,12,5562,9,30,16,30,18,5568,10,30,22,5572,24,24,26,30,28,30, # 5560 ++ 30,5580,30,15,15,30,30,36,12,30,30,5590,30,15,13,15,30,30,30,30, # 5580 ++ 15,30,30,15,11,15,10,30,30,70,30,30,30,30,10,30,30,40,12,30, # 5600 ++ 30,30,30,5622,12,30,11,30,30,30,30,30,30,42,22,15,24,15,30,5638, # 5620 ++ 28,5640,30,30,30,30,30,5646,30,30,30,5650,30,5652,30,30,30,5656,30,5658, # 5640 ++ 30,30,30,30,30,15,10,30,10,5668,30,52,30,15,30,30,30,30,30,15, # 5660 ++ 30,30,30,5682,30,30,30,46,30,5688,30,30,30,5692,30,15,63,30,30,40, # 5680 ++ 30,5700,10,15,11,30,30,30,30,18,11,5710,30,28,30,15,30,5716,30,30, # 5700 ++ 30,15,30,58,30,24,10,15,31,30,10,30,30,15,11,15,30,5736,30,30, # 5720 ++ 11,5740,30,5742,15,15,10,30,30,5748,30,70,11,30,11,15,14,15,11,30, # 5740 ++ 30,30,30,15,11,15,11,72,30,15,11,28,11,22,30,15,16,52,30,5778, # 5760 ++ 30,15,11,5782,30,15,10,15,10,15,30,5790,31,15,10,15,11,15,10,15, # 5780 ++ 11,5800,11,15,9,15,11,5806,15,39,10,15,11,5812,12,15,10,15,10,15, # 5800 ++ 10,5820,13,15,63,24,10,5826,11,15,10,16,10,18,10,15,10,15,13,5838, # 5820 ++ 15,15,10,5842,10,15,10,15,11,5848,10,5850,10,15,12,15,15,5856,10,15, # 5840 ++ 10,5860,10,27,11,15,10,5866,10,5868,11,15,15,15,13,46,11,15,10,5878, # 5860 ++ 10,5880,10,15,10,15,12,15,22,21,13,42,13,70,11,15,13,5896,13,16, # 5880 ++ 13,15,13,5902,15,16,13,18,12,18,13,22,13,72,13,15,13,60,13,15, # 5900 ++ 15,30,30,5922,13,15,13,5926,13,48,13,30,13,30,13,15,15,30,16,5938, # 5920 ++ 18,15,10,30,22,16,24,18,26,30,28,30,30,5952,30,15,12,30,30,58, # 5940 ++ 13,30,30,66,30,15,13,15,30,46,45,30,11,42,30,24,13,42,11,36, # 5960 ++ 30,5980,30,30,30,30,16,5986,30,52,13,30,30,30,30,30,26,30,28,30, # 5980 ++ 30,31,30,30,30,30,36,6006,24,15,40,6010,42,30,30,30,46,30,30,30, # 6000 ++ 30,30,30,30,30,30,30,30,30,6028,30,45,30,30,30,30,30,6036,13,30, # 6020 ++ 13,30,30,6042,30,15,30,6046,30,30,30,15,30,6052,30,30,30,30,30,72, # 6040 ++ 30,30,30,30,30,30,30,6066,12,30,30,30,30,6072,12,24,12,58,30,6078, # 6060 ++ 46,30,10,30,30,15,30,24,30,6088,30,6090,30,15,30,15,30,15,13,15, # 6080 ++ 30,6100,30,30,30,15,12,30,30,40,30,30,31,6112,30,30,11,30,10,30, # 6100 ++ 30,6120,30,30,16,48,18,15,15,45,22,6130,30,6132,30,30,28,30,30,30, # 6120 ++ 30,15,12,6142,30,30,30,30,30,30,30,6150,30,15,30,30,30,46,11,30, # 6140 ++ 30,60,30,6162,30,30,30,15,30,30,30,30,11,6172,30,30,31,45,30,36, # 6160 ++ 30,30,12,30,11,30,30,30,30,30,30,40,22,15,24,15,30,6196,28,6198, # 6180 ++ 30,30,30,6202,30,30,30,30,63,30,30,6210,30,30,30,30,30,6216,30,30, # 6200 ++ 30,6220,30,48,47,30,11,44,30,6228,30,15,30,38,30,36,30,15,30,30, # 6220 ++ 30,6240,30,30,30,30,30,6246,30,30,30,30,30,36,30,31,30,6256,30,30, # 6240 ++ 36,15,15,6262,44,30,42,30,15,6268,46,6270,48,30,30,30,30,6276,30,16, # 6260 ++ 30,15,30,60,15,15,30,6286,30,30,30,26,15,15,30,30,30,30,30,6298, # 6280 ++ 30,6300,15,15,31,30,30,30,30,15,15,6310,15,58,15,15,15,6316,30,70, # 6300 ++ 30,15,15,6322,15,39,30,16,15,6328,15,30,30,15,15,30,30,6336,30,15, # 6320 ++ 15,16,30,6342,15,15,15,15,30,18,30,15,15,6352,15,18,15,15,15,6358, # 6340 ++ 30,6360,30,15,15,15,30,6366,31,15,15,22,15,6372,15,15,15,15,15,6378, # 6360 ++ 15,15,15,15,15,15,15,15,15,6388,15,70,15,15,15,15,15,6396,15,78, # 6380 ++ 24,36,15,18,11,15,15,42,15,48,15,15,15,52,15,15,15,16,15,48, # 6400 ++ 15,6420,15,22,15,24,15,6426,15,15,15,58,15,15,13,15,15,40,10,46, # 6420 ++ 15,15,15,16,15,15,15,15,15,6448,15,6450,11,26,13,16,15,15,15,15, # 6440 ++ 15,15,15,22,63,15,15,28,15,6468,12,15,15,6472,15,15,15,15,15,15, # 6460 ++ 15,6480,15,15,13,15,13,15,15,15,15,6490,15,42,15,15,31,72,13,66, # 6480 ++ 15,15,12,15,11,15,15,26,15,22,15,16,15,15,13,15,15,18,12,16, # 6500 ++ 11,6520,15,15,15,15,15,60,24,6528,13,15,15,46,11,17,12,15,15,15, # 6520 ++ 15,30,30,15,15,15,15,6546,11,15,14,6550,11,6552,12,15,15,78,16,30, # 6540 ++ 31,6560,15,6562,22,15,24,16,26,6568,28,6570,30,30,30,24,15,6576,30,15, # 6560 ++ 11,6580,30,30,30,15,11,15,30,30,30,30,63,30,30,15,11,15,11,6598, # 6580 ++ 30,15,30,15,11,30,10,6606,30,15,10,30,30,30,30,16,11,30,11,6618, # 6600 ++ 30,15,30,36,30,52,11,15,11,15,30,30,11,15,11,30,11,6636,30,15, # 6620 ++ 15,30,30,15,30,15,11,30,30,60,30,15,11,6652,30,15,15,15,11,6658, # 6640 ++ 11,6660,30,15,11,15,30,58,30,30,12,15,30,6672,12,15,11,30,30,6678, # 6660 ++ 30,15,12,40,12,15,14,15,18,6688,30,6690,30,15,11,15,12,36,30,15, # 6680 ++ 14,6700,12,6702,30,16,11,30,30,6708,30,15,11,48,30,15,11,15,14,6718, # 6700 ++ 30,30,30,80,11,24,12,23,11,15,11,52,51,6732,30,48,15,6736,30,22, # 6720 ++ 30,42,11,40,12,15,11,15,16,16,18,42,31,30,22,28,24,28,26,15, # 6740 ++ 28,6760,30,6762,12,15,10,66,36,17,11,15,40,15,42,24,15,26,46,6778, # 6760 ++ 48,6780,15,15,52,15,15,17,12,15,13,6790,15,6792,15,15,15,15,15,15, # 6780 ++ 15,15,15,6802,15,17,15,15,15,23,15,48,15,15,15,15,15,16,15,15, # 6800 ++ 15,18,15,6822,15,24,15,6826,15,6828,15,15,15,6832,15,15,15,15,15,15, # 6820 ++ 15,6840,15,15,15,15,15,40,63,21,15,15,15,15,15,15,15,6856,15,6858, # 6840 ++ 15,15,15,6862,15,15,15,15,15,6868,15,6870,15,16,15,15,15,15,15,15, # 6860 ++ 31,15,15,6882,15,15,15,70,15,6888,15,15,15,60,15,15,15,15,15,6898, # 6880 ++ 15,66,15,15,15,15,15,6906,15,15,15,6910,26,30,30,15,15,6916,15,30, # 6900 ++ 15,16,15,30,15,30,15,15,15,40,16,30,18,15,15,30,22,24,24,26, # 6920 ++ 26,30,28,52,31,30,30,6946,15,6948,30,15,15,30,30,30,30,15,15,6958, # 6940 ++ 30,6960,30,30,15,30,30,6966,15,16,15,6970,30,18,30,15,63,6976,15,30, # 6960 ++ 30,15,15,6982,30,30,30,15,15,30,15,6990,30,15,30,30,30,6996,15,15, # 6980 ++ 15,7000,30,46,15,15,15,30,15,42,30,15,15,7012,30,15,30,15,15,7018, # 7000 ++ 30,30,30,15,15,24,30,7026,15,15,15,78,15,30,30,15,15,30,30,7038, # 7020 ++ 30,30,15,7042,30,30,15,30,15,52,30,30,30,30,16,30,18,7056,15,30, # 7040 ++ 22,30,30,30,30,30,28,36,30,7068,30,15,16,30,30,30,30,30,30,7078, # 7060 ++ 30,72,30,15,30,30,30,30,15,30,30,15,30,40,30,30,30,46,30,39, # 7080 ++ 30,30,15,7102,30,30,30,30,30,7108,30,30,30,30,15,30,30,30,30,30, # 7100 ++ 30,7120,22,16,30,15,30,7126,28,7128,30,30,30,30,30,30,31,30,30,58, # 7120 ++ 30,36,30,30,30,30,30,30,30,30,30,7150,30,22,13,30,15,30,30,7158, # 7140 ++ 30,16,30,30,30,30,30,15,30,66,30,70,30,30,30,30,30,7176,30,30, # 7160 ++ 30,42,30,15,15,30,30,7186,30,30,13,15,13,7192,30,30,30,30,15,30, # 7180 ++ 30,18,30,30,30,30,30,7206,30,80,30,7210,30,7212,15,15,30,30,30,7218, # 7200 ++ 30,15,10,30,30,30,30,30,30,7228,30,30,63,30,30,30,30,7236,30,30, # 7220 ++ 16,30,18,7242,14,30,22,7246,30,30,30,30,28,7252,30,30,30,15,13,30, # 7240 ++ 30,52,30,30,31,30,30,42,30,15,30,30,30,30,13,30,30,18,30,30, # 7260 ++ 30,30,30,7282,30,15,11,30,12,36,30,30,30,30,30,30,30,7296,30,30, # 7280 ++ 15,48,30,66,30,30,30,7306,15,7308,30,16,30,70,13,15,13,30,15,30, # 7300 ++ 30,7320,30,30,30,24,30,16,31,30,30,7330,30,7332,15,15,30,15,15,40, # 7320 ++ 15,30,15,30,30,15,15,15,30,7348,30,7350,15,15,30,30,15,15,15,30, # 7340 ++ 30,30,30,36,15,30,15,52,15,7368,15,30,30,72,30,58,15,15,15,46, # 7360 ++ 30,60,15,30,15,30,30,82,15,30,30,30,30,7392,15,15,30,16,15,48, # 7380 ++ 24,15,30,30,30,15,15,15,15,30,30,7410,15,15,30,30,30,7416,15,30, # 7400 ++ 30,40,30,15,28,30,16,30,18,16,15,30,22,7432,30,20,26,30,28,42, # 7420 ++ 30,30,30,18,15,30,30,22,15,30,30,7450,30,28,15,15,31,7456,30,7458, # 7440 ++ 15,30,30,16,15,15,15,30,30,15,30,30,30,30,15,30,30,7476,15,30, # 7460 ++ 30,7480,30,30,15,30,15,7486,30,7488,30,30,30,58,57,15,24,54,30,7498, # 7480 ++ 28,30,30,48,30,46,30,7506,30,30,30,30,30,30,30,36,30,7516,30,72, # 7500 ++ 30,30,30,7522,30,31,15,30,15,7528,36,16,30,30,40,30,42,7536,30,30, # 7520 ++ 46,7540,48,30,30,30,52,7546,30,7548,30,30,58,30,30,30,22,30,30,7558, # 7540 ++ 30,7560,28,30,30,30,30,30,30,30,30,66,30,7572,30,30,30,7576,30,30, # 7560 ++ 30,30,30,7582,30,30,30,26,30,7588,30,7590,30,15,30,16,30,70,30,30, # 7580 ++ 30,30,30,7602,30,30,30,7606,30,30,30,30,30,30,30,39,58,30,13,30, # 7600 ++ 30,7620,30,30,15,60,15,30,30,30,30,30,30,30,30,15,30,30,30,7638, # 7620 ++ 30,30,30,7642,30,15,30,15,31,7648,30,30,30,30,30,15,15,15,30,30, # 7640 ++ 30,46,30,78,30,30,15,30,30,7668,30,30,30,7672,14,30,15,15,15,30, # 7660 ++ 15,7680,30,30,30,15,15,7686,15,15,30,7690,15,48,30,30,30,42,30,7698, # 7680 ++ 30,30,30,7702,30,15,30,15,15,15,30,17,31,30,30,15,15,7716,15,15, # 7700 ++ 14,15,14,7722,30,30,30,7726,15,58,30,30,30,15,15,30,15,15,14,70, # 7720 ++ 13,7740,15,30,63,30,15,60,59,15,15,56,15,7752,14,15,30,7756,17,7758, # 7740 ++ 30,15,30,16,16,17,30,15,28,38,22,36,30,15,30,24,31,30,30,31, # 7760 ++ 14,30,30,42,36,15,14,30,40,7788,42,30,15,7792,46,15,48,30,16,30, # 7780 ++ 56,28,15,30,22,15,58,36,60,30,28,72,30,30,30,15,15,7816,30,16, # 7800 ++ 15,30,30,7822,30,24,14,15,30,7828,30,40,15,30,30,16,15,16,13,30, # 7820 ++ 30,7840,30,15,14,30,15,30,30,46,15,30,30,7852,30,15,15,80,13,30, # 7840 ++ 30,23,30,30,30,15,15,7866,15,15,30,30,15,7872,13,30,15,7876,30,7878, # 7860 ++ 15,30,30,7882,30,15,15,30,30,30,30,15,15,15,30,15,15,52,15,30, # 7880 ++ 15,7900,30,15,18,15,30,7906,30,30,15,26,30,40,15,16,15,30,30,7918, # 7900 ++ 30,7920,15,30,15,24,15,7926,15,30,30,30,30,7932,15,15,30,7936,30,16, # 7920 ++ 15,30,30,46,30,15,30,30,30,7948,30,7950,30,16,30,18,15,72,30,22, # 7940 ++ 30,30,30,7962,30,28,30,30,31,30,15,15,30,30,30,15,30,30,30,78, # 7960 ++ 30,22,15,30,30,30,30,48,30,30,22,60,30,7992,30,30,28,30,30,30, # 7980 ++ 63,30,30,52,30,15,30,30,30,8008,30,8010,30,18,30,30,30,8016,30,30, # 8000 ++ 30,15,30,70,30,30,30,22,30,15,30,30,31,30,30,15,30,30,30,8038, # 8020 ++ 30,15,30,30,30,30,30,15,30,30,30,82,15,8052,30,15,30,30,15,8058, # 8040 ++ 15,30,30,30,30,15,15,30,30,8068,30,15,30,30,30,30,30,40,30,15, # 8060 ++ 30,8080,15,58,30,30,30,8086,30,8088,15,15,30,8092,30,30,31,18,30,30, # 8080 ++ 15,8100,30,30,30,30,30,66,15,30,15,8110,15,25,15,30,30,8116,30,22, # 8100 ++ 15,15,15,8122,30,15,15,30,63,62,30,46,59,30,30,30,30,78,53,15, # 8120 ++ 51,17,15,16,30,27,30,8146,30,28,41,22,39,30,30,26,30,28,33,40, # 8140 ++ 31,8160,29,30,30,36,30,8166,23,40,21,8170,18,15,17,46,22,48,30,8178, # 8160 ++ 26,80,28,48,30,30,30,58,26,60,30,8190,8191,30,30,30,30,15,15,24, # 8180 ++ 30,58,30,30,15,30,30,28,30,8208,30,30,30,42,30,22,15,30,30,8218, # 8200 ++ 30,8220,15,30,31,30,30,18,15,30,15,8230,30,8232,30,30,30,8236,15,57, # 8220 ++ 15,15,30,8242,15,15,15,30,15,72,30,36,15,30,30,15,62,22,15,30, # 8240 ++ 30,30,30,8262,15,15,30,18,15,8268,15,30,15,8272,30,24,15,15,30,30, # 8260 ++ 30,48,14,15,30,30,15,8286,15,30,30,8290,30,8292,15,30,15,8296,15,42, # 8280 ++ 15,30,30,30,30,16,15,15,15,15,30,8310,15,30,15,30,30,8316,15,30, # 8300 ++ 30,52,30,15,15,17,30,25,15,8328,15,15,30,30,30,15,15,15,14,30, # 8320 ++ 30,18,15,80,30,30,30,16,15,30,30,30,30,8352,14,30,16,60,18,15, # 8340 ++ 14,57,22,8362,30,30,26,30,28,8368,30,30,30,30,15,66,30,8376,30,30, # 8360 ++ 30,30,30,82,63,30,30,8386,30,8388,15,30,30,22,30,16,30,30,30,36, # 8380 ++ 30,30,30,30,30,30,30,30,15,30,30,30,30,46,15,30,31,30,30,8418, # 8400 ++ 30,30,30,8422,22,24,24,15,30,8428,28,8430,30,30,30,30,30,30,30,30, # 8420 ++ 30,30,30,8442,30,30,30,8446,30,30,30,30,30,78,30,15,15,30,15,30, # 8440 ++ 30,8460,30,30,30,30,30,8466,30,16,30,42,30,36,30,30,30,48,30,60, # 8460 ++ 30,30,30,30,30,15,22,30,30,30,30,30,28,15,29,30,30,30,30,30, # 8480 ++ 29,8500,30,15,30,30,30,46,30,66,65,16,30,8512,30,15,29,15,30,56, # 8500 ++ 30,8520,30,15,29,15,30,8526,30,30,30,44,30,42,29,30,30,8536,30,8538, # 8520 ++ 30,31,29,8542,29,30,36,30,15,82,40,30,42,15,15,20,46,42,48,30, # 8540 ++ 29,30,52,8562,30,30,30,30,58,30,60,30,30,8572,30,24,66,30,30,28, # 8560 ++ 30,8580,30,15,29,22,15,30,30,18,30,70,30,30,30,30,30,8596,30,8598, # 8580 ++ 30,15,30,30,16,30,18,15,31,8608,22,78,30,30,29,30,28,30,30,30, # 8600 ++ 30,36,15,8622,30,16,30,8626,30,8628,30,15,29,88,30,30,30,30,15,52, # 8620 ++ 30,8640,30,16,30,30,30,8646,30,15,15,40,30,30,30,16,29,30,30,30, # 8640 ++ 30,15,29,8662,30,30,30,80,30,8668,30,30,31,15,15,24,30,8676,15,15, # 8660 ++ 15,8680,15,30,30,15,15,30,30,8688,30,15,15,8692,30,30,30,15,15,8698, # 8680 ++ 30,18,15,16,16,30,15,8706,30,15,15,30,30,8712,30,30,15,30,30,8718, # 8700 ++ 15,30,15,30,30,30,30,30,16,30,18,8730,15,30,22,30,30,8736,30,30, # 8720 ++ 28,8740,30,30,30,15,15,8746,30,30,30,30,30,8752,30,30,30,15,30,30, # 8740 ++ 30,8760,15,30,30,15,30,30,63,30,30,48,30,30,30,30,15,66,30,8778, # 8760 ++ 30,30,30,8782,30,30,30,30,15,30,30,58,30,30,30,30,22,30,30,30, # 8780 ++ 31,30,28,8802,30,30,30,8806,30,30,30,30,30,30,30,30,30,30,30,8818, # 8800 ++ 30,8820,30,30,30,30,30,30,30,80,30,8830,30,72,30,15,30,8836,30,8838, # 8820 ++ 30,15,30,36,30,30,30,30,30,8848,30,52,30,30,30,30,30,16,30,30, # 8840 ++ 30,8860,30,8862,31,15,15,8866,30,48,30,30,15,30,30,70,30,30,30,30, # 8860 ++ 30,82,30,15,30,28,30,8886,15,15,30,30,30,8892,30,16,63,15,30,30, # 8880 ++ 30,30,30,30,30,30,15,30,30,58,30,30,30,30,15,30,15,36,15,30, # 8900 ++ 15,30,30,8922,30,15,15,78,15,8928,30,30,15,8932,30,30,30,30,30,30, # 8920 ++ 30,8940,30,30,30,40,30,22,15,30,30,8950,30,30,30,15,15,52,15,30, # 8940 ++ 30,30,30,8962,30,30,30,30,30,8968,30,8970,30,18,30,30,16,46,18,15, # 8960 ++ 30,30,30,30,30,30,26,30,30,88,30,36,31,30,15,30,30,15,30,8998, # 8980 ++ 30,9000,30,15,15,30,30,9006,30,30,15,9010,30,9012,30,16,30,70,69,30, # 9000 ++ 30,66,15,30,30,30,30,60,15,9028,30,30,30,15,16,30,30,30,30,48, # 9020 ++ 30,9040,30,9042,30,15,28,82,30,9048,30,15,15,34,36,30,31,30,40,9058, # 9040 ++ 42,16,30,24,46,30,48,9066,30,18,52,46,30,42,15,15,58,30,60,30, # 9060 ++ 30,63,15,30,66,30,30,30,70,60,30,9090,15,30,15,30,30,30,30,30, # 9080 ++ 16,30,18,9102,15,30,22,30,30,9108,30,30,28,30,30,30,30,15,15,30, # 9100 ++ 30,30,30,30,30,72,30,9126,30,16,30,30,30,9132,15,30,30,9136,30,30, # 9120 ++ 30,30,30,40,30,15,15,30,15,30,30,9150,63,80,30,30,30,9156,30,30, # 9140 ++ 15,9160,30,16,30,30,30,88,15,52,30,30,30,9172,15,24,15,30,15,66, # 9160 ++ 30,9180,30,30,30,30,30,9186,30,30,30,30,30,28,15,15,30,30,30,9198, # 9180 ++ 30,30,30,9202,30,30,15,15,30,9208,30,60,15,15,30,30,30,30,15,30, # 9200 ++ 30,9220,30,22,15,30,15,9226,30,18,30,30,30,30,30,15,30,15,15,9238, # 9220 ++ 30,9240,30,30,15,30,30,16,31,30,30,30,30,18,15,15,30,9256,15,46, # 9240 ++ 15,26,30,58,30,16,15,15,15,15,15,72,71,15,30,68,30,9276,15,30, # 9260 ++ 63,9280,30,9282,15,30,15,36,16,15,18,30,15,9292,30,48,24,15,26,16, # 9280 ++ 28,70,30,31,15,17,30,40,36,30,30,9310,40,66,42,30,30,26,46,9318, # 9300 ++ 48,30,30,9322,52,24,30,15,15,30,58,17,60,30,30,63,68,9336,66,30, # 9320 ++ 30,9340,70,9342,72,30,30,15,15,9348,15,40,30,46,30,15,16,15,15,48, # 9340 ++ 30,15,15,15,30,15,30,16,15,26,15,9370,30,15,15,15,31,9376,15,82, # 9360 ++ 15,15,15,17,15,15,15,15,15,40,15,9390,15,15,15,15,15,9396,15,15, # 9380 ++ 15,15,15,9402,15,15,15,22,15,9408,15,15,15,9412,15,15,15,15,15,9418, # 9400 ++ 15,9420,15,26,15,15,15,15,15,15,15,9430,15,9432,15,15,15,9436,15,9438, # 9420 ++ 15,15,15,15,15,15,15,15,15,15,15,15,15,29,15,16,15,48,15,15, # 9440 ++ 15,9460,15,9462,15,15,15,9466,15,16,15,15,36,9472,15,24,15,18,15,9478, # 9460 ++ 15,18,15,15,15,23,15,52,15,16,15,9490,15,15,15,22,15,9496,15,26, # 9480 ++ 15,28,15,30,31,18,15,15,15,36,15,9510,15,17,15,15,15,30,30,15, # 9500 ++ 15,9520,15,88,15,15,15,30,15,30,15,26,15,9532,16,30,63,15,15,9538, # 9520 ++ 22,15,24,15,26,30,28,9546,30,30,30,9550,15,40,30,15,15,30,30,78, # 9540 ++ 30,15,15,72,30,30,30,30,31,30,30,17,15,15,15,30,30,60,30,15, # 9560 ++ 15,30,15,30,30,15,15,9586,30,42,30,15,15,52,15,30,30,15,30,30, # 9580 ++ 30,9600,15,15,15,15,30,30,15,15,15,30,15,9612,30,15,15,58,30,9618, # 9600 ++ 30,15,15,9622,30,30,30,15,15,9628,30,9630,31,15,15,30,15,30,30,15, # 9620 ++ 15,30,30,9642,30,30,15,30,30,9648,15,30,15,48,30,30,30,30,16,30, # 9640 ++ 18,9660,15,30,63,30,30,30,30,30,28,30,30,30,30,15,15,9676,30,9678, # 9660 ++ 30,30,30,30,30,30,30,15,30,9688,30,30,15,30,30,17,30,9696,30,30, # 9680 ++ 30,88,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,15,9718, # 9700 ++ 30,9720,30,30,30,30,22,70,30,30,30,36,28,9732,30,30,30,30,30,9738, # 9720 ++ 30,30,30,9742,30,30,30,30,30,9748,30,48,30,30,30,30,30,30,30,30, # 9740 ++ 30,42,30,30,30,16,30,9766,30,9768,30,16,30,30,30,30,30,30,30,30, # 9760 ++ 30,9780,30,30,30,30,30,9786,30,30,30,9790,30,30,30,16,15,96,30,40, # 9780 ++ 30,80,15,9802,30,15,30,30,30,30,30,9810,30,15,30,15,30,9816,15,15, # 9800 ++ 30,30,30,30,31,16,15,30,30,9828,30,30,30,9832,30,30,15,30,30,9838, # 9820 ++ 30,30,30,30,16,30,18,42,15,30,22,9850,30,58,30,30,28,9856,30,9858, # 9840 ++ 30,30,15,30,30,30,30,30,30,70,30,9870,30,30,30,78,30,30,17,30, # 9860 ++ 30,40,30,9882,30,30,30,9886,30,15,15,30,30,30,30,30,30,30,30,30, # 9880 ++ 30,9900,30,30,30,30,30,9906,30,30,30,30,30,30,30,30,30,46,30,15, # 9900 ++ 16,30,30,9922,30,24,30,30,30,9928,30,9930,30,30,30,30,30,39,15,15, # 9920 ++ 30,9940,30,60,30,30,30,30,30,9948,17,15,31,36,30,30,15,16,30,46, # 9940 ++ 30,30,15,40,30,30,30,9966,15,30,15,58,30,9972,30,30,30,30,30,30, # 9960 ++ 30,15,15,66,30,30,30,30,15,30,30,96,30,30,30,30,30,18,15,15 # 9980 ++) ++ ++ ++def lower_bound(order: int) -> int: ++ r""" ++ Return the best known lower bound on the number of MOLS of ++ the given ``order``. ++ ++ The source of this information is Table 3.87 in the Handbook of ++ Combinatorial Designs, 2nd edition, by Colbourn and Dinitz. A few ++ updates have subsequently been provided on Jeff Dinitz's website. ++ ++ Parameters ++ ---------- ++ ++ order : int ++ The order (also known as the side) for which you'd like a lower ++ bound on the number of MOLS instances. In the language of the ++ Handbook, this is ``n``, and it should be between 0 and 9999. ++ ++ Returns ++ ------- ++ ++ int ++ A lower bound on the number of MOLS. ++ ++ Raises ++ ------ ++ ++ IndexError ++ If you ask for an order that isn't contained in the table. ++ ++ Examples ++ -------- ++ ++ There are no MOLS of order zero:: ++ ++ sage: from sage.combinat.designs import MOLS_handbook_data ++ sage: MOLS_handbook_data.lower_bound(0) ++ 0 ++ ++ """ ++ return _LOWER_BOUNDS[order] +diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py +index 69b19540c22..27452495862 100644 +--- a/src/sage/combinat/designs/latin_squares.py ++++ b/src/sage/combinat/designs/latin_squares.py +@@ -75,7 +75,7 @@ + 0| + + + 20| + 40| +- 60| + ++ 60| + 80| + 100| + 120| +@@ -126,7 +126,6 @@ + from sage.rings.integer import Integer + from sage.categories.sets_cat import EmptySetError + from sage.misc.unknown import Unknown +-from sage.env import COMBINATORIAL_DESIGN_DATA_DIR + + + def are_mutually_orthogonal_latin_squares(l, verbose=False): +@@ -500,13 +499,13 @@ def MOLS_table(start,stop=None,compare=False,width=None): + 0| + + + 20| + 40| +- 60| + ++ 60| + 80| + sage: MOLS_table(50, 100, compare=True) + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + ________________________________________________________________________________ + 40| +- 60| + ++ 60| + 80| + """ + from .orthogonal_arrays import largest_available_k +@@ -520,11 +519,6 @@ def MOLS_table(start,stop=None,compare=False,width=None): + if stop <= start: + return + +- if compare: +- handbook_file = open("{}/MOLS_table.txt".format(COMBINATORIAL_DESIGN_DATA_DIR), 'r') +- hb = [int(_) for _ in handbook_file.readlines()[9].split(',')] +- handbook_file.close() +- + # choose an appropriate width (needs to be >= 3 because "+oo" should fit) + if width is None: + width = max(3, Integer(stop-1).ndigits(10)) +@@ -537,9 +531,11 @@ def MOLS_table(start,stop=None,compare=False,width=None): + print("\n{:>{width}}|".format(i, width=width), end="") + k = largest_available_k(i)-2 + if compare: +- if i < 2 or hb[i] == k: ++ from . import MOLS_handbook_data ++ lower_bound = MOLS_handbook_data.lower_bound(i) ++ if i < 2 or lower_bound == k: + c = "" +- elif hb[i] < k: ++ elif lower_bound < k: + c = "+" + else: + c = "-" +diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py +index aaab1397f0a..5f996662964 100644 +--- a/src/sage/databases/jones.py ++++ b/src/sage/databases/jones.py +@@ -79,8 +79,6 @@ + + from sage.features.databases import DatabaseJones + +-JONESDATA = os.path.join(SAGE_SHARE, 'jones') # should match the filename set in DatabaseJones +- + + def sortkey(K): + """ +@@ -160,8 +158,10 @@ def _init(self, path): + for Y in os.listdir(Z): + if Y[-3:] == ".gp": + self._load(Z, Y) +- os.makedirs(JONESDATA, exist_ok=True) +- save(self.root, JONESDATA + "/jones.sobj") ++ ++ data_dir = os.path.dirname(DatabaseJones().absolute_filename()) ++ os.makedirs(data_dir, exist_ok=True) ++ save(self.root, os.path.join(data_dir, "jones.sobj")) + + def unramified_outside(self, S, d=None, var='a'): + """ +diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py +index 469fe454afb..7e027673cc0 100644 +--- a/src/sage/databases/sql_db.py ++++ b/src/sage/databases/sql_db.py +@@ -250,7 +250,6 @@ def construct_skeleton(database): + skeleton = {} + cur = database.__connection__.cursor() + exe = cur.execute("SELECT name FROM sqlite_master WHERE TYPE='table'") +- from sage.env import GRAPHS_DATA_DIR + for table in exe.fetchall(): + skeleton[table[0]] = {} + exe1 = cur.execute("PRAGMA table_info(%s)" % table[0]) +@@ -264,8 +263,7 @@ def construct_skeleton(database): + exe2 = cur.execute("PRAGMA index_list(%s)" % table[0]) + for col in exe2.fetchall(): + if col[1].find('sqlite') == -1: +- if database.__dblocation__ == \ +- os.path.join(GRAPHS_DATA_DIR,'graphs.db'): ++ if os.path.basename(database.__dblocation__) == 'graphs.db': + name = col[1] + else: + name = col[1][len(table[0])+3:] +diff --git a/src/sage/env.py b/src/sage/env.py +index 39d09528788..cadcb820c5a 100644 +--- a/src/sage/env.py ++++ b/src/sage/env.py +@@ -195,18 +195,26 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st + SAGE_ARCHFLAGS = var("SAGE_ARCHFLAGS", "unset") + SAGE_PKG_CONFIG_PATH = var("SAGE_PKG_CONFIG_PATH") + ++# colon-separated search path for databases. ++SAGE_DATA_PATH = var("SAGE_DATA_PATH", ++ os.pathsep.join(filter(None, [ ++ join(DOT_SAGE, "db"), ++ join(SAGE_SHARE, "sagemath"), ++ SAGE_SHARE, ++ ]))) ++ ++# database directories, the default is to search in SAGE_DATA_PATH ++CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR") ++CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR") ++ELLCURVE_DATA_DIR = var("ELLCURVE_DATA_DIR") ++GRAPHS_DATA_DIR = var("GRAPHS_DATA_DIR") ++POLYTOPE_DATA_DIR = var("POLYTOPE_DATA_DIR") ++ + # installation directories for various packages +-GRAPHS_DATA_DIR = var("GRAPHS_DATA_DIR", join(SAGE_SHARE, "graphs")) +-ELLCURVE_DATA_DIR = var("ELLCURVE_DATA_DIR", join(SAGE_SHARE, "ellcurves")) +-POLYTOPE_DATA_DIR = var("POLYTOPE_DATA_DIR", join(SAGE_SHARE, "reflexive_polytopes")) +- +-COMBINATORIAL_DESIGN_DATA_DIR = var("COMBINATORIAL_DESIGN_DATA_DIR", join(SAGE_SHARE, "combinatorial_designs")) +-CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR", join(SAGE_SHARE, "cremona")) +-CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR", join(SAGE_SHARE, "cremona")) +-JMOL_DIR = var("JMOL_DIR", join(SAGE_SHARE, "jmol")) ++JMOL_DIR = var("JMOL_DIR") + MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax")) + MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe")) +-THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage")) ++THREEJS_DIR = var("THREEJS_DIR") + PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy")) + MAXIMA = var("MAXIMA", "maxima") + MAXIMA_FAS = var("MAXIMA_FAS") +@@ -313,6 +321,7 @@ def sage_include_directories(use_sources=False): + + return dirs + ++ + def get_cblas_pc_module_name() -> str: + """ + Return the name of the BLAS libraries to be used. +@@ -420,7 +429,7 @@ def cython_aliases(required_modules=None, + aliases["ECL_INCDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-I'), ecl_cflags))) + aliases["ECL_LIBDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-L'), ecl_libs))) + aliases["ECL_LIBRARIES"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-l'), ecl_libs))) +- aliases["ECL_LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l','-L')), ecl_libs)) ++ aliases["ECL_LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l', '-L')), ecl_libs)) + continue + else: + try: +@@ -439,7 +448,7 @@ def cython_aliases(required_modules=None, + # include search order matters. + aliases[var + "INCDIR"] = pc['include_dirs'] + aliases[var + "LIBDIR"] = pc['library_dirs'] +- aliases[var + "LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l','-L')), libs.split())) ++ aliases[var + "LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l', '-L')), libs.split())) + aliases[var + "LIBRARIES"] = pc['libraries'] + + # uname-specific flags +diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py +index d5669c3c9ff..ea8fd6bdb05 100644 +--- a/src/sage/features/__init__.py ++++ b/src/sage/features/__init__.py +@@ -416,6 +416,7 @@ def unhide(self): + """ + self._hidden = False + ++ + class FeatureNotPresentError(RuntimeError): + r""" + A missing feature error. +@@ -791,7 +792,9 @@ class StaticFile(FileFeature): + EXAMPLES:: + + sage: from sage.features import StaticFile +- sage: StaticFile(name="no_such_file", filename="KaT1aihu", search_path=("/",), spkg="some_spkg", url="http://rand.om").require() # optional - sage_spkg ++ sage: StaticFile(name="no_such_file", filename="KaT1aihu", # optional - sage_spkg ++ ....: search_path="/", spkg="some_spkg", ++ ....: url="http://rand.om").require() + Traceback (most recent call last): + ... + FeatureNotPresentError: no_such_file is not available. +@@ -799,18 +802,27 @@ class StaticFile(FileFeature): + To install no_such_file...you can try to run...sage -i some_spkg... + Further installation instructions might be available at http://rand.om. + """ +- def __init__(self, name, filename, search_path=None, **kwds): ++ def __init__(self, name, filename, *, search_path=None, **kwds): + r""" + TESTS:: + + sage: from sage.features import StaticFile +- sage: StaticFile(name="null", filename="null", search_path=("/dev",)) ++ sage: StaticFile(name="null", filename="null", search_path="/dev") + Feature('null') ++ sage: sh = StaticFile(name="shell", filename="sh", ++ ....: search_path=("/dev", "/bin", "/usr")) ++ sage: sh ++ Feature('shell') ++ sage: sh.absolute_filename() ++ '/bin/sh' ++ + """ + Feature.__init__(self, name, **kwds) + self.filename = filename + if search_path is None: + self.search_path = [SAGE_SHARE] ++ elif isinstance(search_path, str): ++ self.search_path = [search_path] + else: + self.search_path = list(search_path) + +diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py +index bca8c094b30..1410dc1167d 100644 +--- a/src/sage/features/databases.py ++++ b/src/sage/features/databases.py +@@ -16,14 +16,27 @@ + # https://www.gnu.org/licenses/ + # ***************************************************************************** + ++import os + + from . import StaticFile, PythonModule +-from sage.env import ( +- CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR, +- POLYTOPE_DATA_DIR) ++from sage.env import SAGE_DATA_PATH + + +-CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR]) ++def sage_data_path(data_name): ++ r""" ++ Search path for database `data_name`. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.databases import sage_data_path ++ sage: sage_data_path("cremona") ++ ['.../cremona'] ++ """ ++ if not SAGE_DATA_PATH: ++ return [] ++ ++ return [os.path.join(p, data_name) ++ for p in SAGE_DATA_PATH.split(os.pathsep)] + + + class DatabaseCremona(StaticFile): +@@ -44,7 +57,7 @@ class DatabaseCremona(StaticFile): + sage: DatabaseCremona().is_present() # optional - database_cremona_ellcurve + FeatureTestResult('database_cremona_ellcurve', True) + """ +- def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): ++ def __init__(self, name="cremona"): + r""" + TESTS:: + +@@ -52,14 +65,86 @@ def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): + sage: isinstance(DatabaseCremona(), DatabaseCremona) + True + """ ++ from sage.env import CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR ++ CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR]) ++ CREMONA_DATA_DIRS.discard(None) ++ search_path = CREMONA_DATA_DIRS or sage_data_path("cremona") ++ ++ spkg = "database_cremona_ellcurve" ++ spkg_type = "optional" ++ if name == 'cremona_mini': ++ spkg = "elliptic_curves" ++ spkg_type = "standard" ++ + StaticFile.__init__(self, f"database_{name}_ellcurve", +- filename='{}.db'.format(name.replace(' ', '_')), +- search_path=CREMONA_DATA_DIRS, ++ filename=f"{name}.db", ++ search_path=search_path, + spkg=spkg, ++ type=spkg_type, + url="https://github.com/JohnCremona/ecdata", + description="Cremona's database of elliptic curves") + + ++class DatabaseEllcurves(StaticFile): ++ r""" ++ A :class:`~sage.features.Feature` which describes the presence of ++ William Stein's database of interesting curves. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.databases import DatabaseEllcurves ++ sage: bool(DatabaseEllcurves().is_present()) # optional - database_ellcurves ++ True ++ """ ++ def __init__(self): ++ r""" ++ TESTS:: ++ ++ sage: from sage.features.databases import DatabaseEllcurves ++ sage: isinstance(DatabaseEllcurves(), DatabaseEllcurves) ++ True ++ """ ++ from sage.env import ELLCURVE_DATA_DIR ++ search_path = ELLCURVE_DATA_DIR or sage_data_path("ellcurves") ++ ++ StaticFile.__init__(self, "database_ellcurves", ++ filename='rank0', ++ search_path=search_path, ++ spkg="elliptic_curves", ++ type="standard", ++ description="William Stein's database of interesting curve") ++ ++ ++class DatabaseGraphs(StaticFile): ++ r""" ++ A :class:`~sage.features.Feature` which describes the presence of ++ the graphs database. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.databases import DatabaseGraphs ++ sage: bool(DatabaseGraphs().is_present()) # optional - database_graphs ++ True ++ """ ++ def __init__(self): ++ r""" ++ TESTS:: ++ ++ sage: from sage.features.databases import DatabaseGraphs ++ sage: isinstance(DatabaseGraphs(), DatabaseGraphs) ++ True ++ """ ++ from sage.env import GRAPHS_DATA_DIR ++ search_path = GRAPHS_DATA_DIR or sage_data_path("graphs") ++ ++ StaticFile.__init__(self, "database_graphs", ++ filename='graphs.db', ++ search_path=search_path, ++ spkg="graphs", ++ type="standard", ++ description="A database of graphs") ++ ++ + class DatabaseJones(StaticFile): + r""" + A :class:`~sage.features.Feature` which describes the presence of +@@ -80,7 +165,8 @@ def __init__(self): + True + """ + StaticFile.__init__(self, "database_jones_numfield", +- filename='jones/jones.sobj', ++ filename='jones.sobj', ++ search_path=sage_data_path("jones"), + spkg="database_jones_numfield", + description="John Jones's tables of number fields") + +@@ -146,27 +232,43 @@ class DatabaseReflexivePolytopes(StaticFile): + EXAMPLES:: + + sage: from sage.features.databases import DatabaseReflexivePolytopes +- sage: bool(DatabaseReflexivePolytopes().is_present()) # optional - polytopes_db ++ sage: bool(DatabaseReflexivePolytopes().is_present()) # optional - polytopes_db + True +- sage: bool(DatabaseReflexivePolytopes('polytopes_db_4d', 'Hodge4d').is_present()) # optional - polytopes_db_4d ++ sage: bool(DatabaseReflexivePolytopes('polytopes_db_4d').is_present()) # optional - polytopes_db_4d + True + """ +- def __init__(self, name='polytopes_db', dirname='Full3D'): ++ def __init__(self, name='polytopes_db'): + """ + TESTS:: + + sage: from sage.features.databases import DatabaseReflexivePolytopes + sage: isinstance(DatabaseReflexivePolytopes(), DatabaseReflexivePolytopes) + True ++ sage: DatabaseReflexivePolytopes().filename ++ 'Full3d' ++ sage: DatabaseReflexivePolytopes('polytopes_db_4d').filename ++ 'Hodge4d' + """ +- StaticFile.__init__(self, name, dirname, +- search_path=[POLYTOPE_DATA_DIR]) ++ from sage.env import POLYTOPE_DATA_DIR ++ search_path = POLYTOPE_DATA_DIR or sage_data_path("reflexive_polytopes") ++ ++ dirname = "Full3d" ++ if name == "polytopes_db_4d": ++ dirname = "Hodge4d" ++ ++ StaticFile.__init__(self, name, ++ filename=dirname, ++ search_path=search_path) + + + def all_features(): +- return [DatabaseCremona(), DatabaseCremona('cremona_mini'), ++ return [PythonModule('conway_polynomials'), ++ DatabaseCremona(), ++ DatabaseCremona('cremona_mini'), ++ DatabaseEllcurves(), ++ DatabaseGraphs(), + DatabaseJones(), + DatabaseKnotInfo(), + DatabaseCubicHecke(), + DatabaseReflexivePolytopes(), +- DatabaseReflexivePolytopes('polytopes_db_4d', 'Hodge4d')] ++ DatabaseReflexivePolytopes('polytopes_db_4d')] +diff --git a/src/sage/features/jmol.py b/src/sage/features/jmol.py +new file mode 100644 +index 00000000000..47ea7426991 +--- /dev/null ++++ b/src/sage/features/jmol.py +@@ -0,0 +1,43 @@ ++import os ++ ++from . import StaticFile ++ ++ ++class JmolDataJar(StaticFile): ++ r""" ++ A :class:`~sage.features.Feature` which describes the presence of ++ JmolData.jar in a few standard locations. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.jmol import JmolDataJar ++ sage: bool(JmolDataJar().is_present()) # needs jmol ++ True ++ """ ++ ++ def __init__(self): ++ r""" ++ TESTS:: ++ ++ sage: from sage.features.jmol import JmolDataJar ++ sage: isinstance(JmolDataJar(), JmolDataJar) ++ True ++ """ ++ from sage.env import SAGE_SHARE, JMOL_DIR ++ ++ jmol_search_path = JMOL_DIR or ( ++ os.path.join(SAGE_SHARE, "sagemath", "jmol"), ++ os.path.join(SAGE_SHARE, "jmol") ++ ) ++ ++ StaticFile.__init__( ++ self, name="jmol", ++ filename="JmolData.jar", ++ search_path=jmol_search_path, ++ spkg="jmol", ++ type="standard", ++ description="Java viewer for chemical structures in 3D") ++ ++ ++def all_features(): ++ return [JmolDataJar()] +diff --git a/src/sage/features/threejs.py b/src/sage/features/threejs.py +new file mode 100644 +index 00000000000..4517523918d +--- /dev/null ++++ b/src/sage/features/threejs.py +@@ -0,0 +1,64 @@ ++import os ++ ++from . import StaticFile ++ ++ ++class Threejs(StaticFile): ++ r""" ++ A :class:`~sage.features.Feature` which describes the presence of ++ threejs-sage in a few standard locations. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.threejs import Threejs ++ sage: bool(Threejs().is_present()) # needs threejs ++ True ++ """ ++ ++ def __init__(self): ++ r""" ++ TESTS:: ++ ++ sage: from sage.features.threejs import Threejs ++ sage: isinstance(Threejs(), Threejs) ++ True ++ """ ++ from sage.env import SAGE_SHARE, THREEJS_DIR ++ ++ version = self.required_version() ++ ++ threejs_search_path = THREEJS_DIR or ( ++ os.path.join(SAGE_SHARE, "jupyter", "nbextensions", "threejs-sage"), ++ os.path.join(SAGE_SHARE, "sagemath", "threejs-sage"), ++ os.path.join(SAGE_SHARE, "sage", "threejs"), ++ os.path.join(SAGE_SHARE, "threejs-sage") ++ ) ++ ++ StaticFile.__init__( ++ self, name="threejs", ++ filename=os.path.join(version, "three.min.js"), ++ spkg="threejs", ++ type="standard", ++ search_path=threejs_search_path, ++ description="JavaScript library to display 3D graphics") ++ ++ def required_version(self): ++ """ ++ Return the version of threejs that Sage requires. ++ ++ EXAMPLES:: ++ ++ sage: from sage.features.threejs import Threejs ++ sage: Threejs().required_version() ++ 'r...' ++ """ ++ from sage.env import SAGE_EXTCODE ++ ++ filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt') ++ ++ with open(filename) as f: ++ return f.read().strip() ++ ++ ++def all_features(): ++ return [Threejs()] +diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py +index 449143c8999..db25b345f4a 100644 +--- a/src/sage/geometry/lattice_polytope.py ++++ b/src/sage/geometry/lattice_polytope.py +@@ -123,7 +123,7 @@ + + from sage.arith.misc import GCD as gcd + from sage.combinat.posets.posets import FinitePoset +-from sage.env import POLYTOPE_DATA_DIR ++from sage.features.databases import DatabaseReflexivePolytopes + from sage.geometry.cone import _ambient_space_point, integral_length + from sage.geometry.hasse_diagram import lattice_from_incidences + from sage.geometry.point_collection import (PointCollection, +@@ -451,8 +451,10 @@ def ReflexivePolytopes(dim): + if dim not in [2, 3]: + raise NotImplementedError("only 2- and 3-dimensional reflexive polytopes are available!") + if _rp[dim] is None: ++ db = DatabaseReflexivePolytopes() + rp = read_all_polytopes( +- os.path.join(POLYTOPE_DATA_DIR, "reflexive_polytopes_%dd" % dim)) ++ os.path.join(os.path.dirname(db.absolute_filename()), ++ f'reflexive_polytopes_{dim}d')) + for n, p in enumerate(rp): + # Data files have normal form of reflexive polytopes + p.normal_form.set_cache(p._vertices) +diff --git a/src/sage/geometry/polyhedron/palp_database.py b/src/sage/geometry/polyhedron/palp_database.py +index 29b729cec18..60846d8df23 100644 +--- a/src/sage/geometry/polyhedron/palp_database.py ++++ b/src/sage/geometry/polyhedron/palp_database.py +@@ -36,6 +36,7 @@ + from sage.structure.sage_object import SageObject + from sage.rings.integer_ring import ZZ + from sage.features.palp import PalpExecutable ++from sage.features.databases import DatabaseReflexivePolytopes + + from sage.interfaces.process import terminate + +@@ -108,9 +109,10 @@ def __init__(self, dim, data_basename=None, output='Polyhedron'): + if data_basename is not None: + self._data_basename = data_basename + else: +- from sage.env import POLYTOPE_DATA_DIR +- self._data_basename = os.path.join(POLYTOPE_DATA_DIR, +- 'Full{}d'.format(dim), 'zzdb') ++ db = DatabaseReflexivePolytopes() ++ self._data_basename = os.path.join( ++ os.path.dirname(db.absolute_filename()), ++ f'Full{dim}d', 'zzdb') + info = self._data_basename + '.info' + if not os.path.exists(info): + raise ValueError('Cannot find PALP database: {}'.format(info)) +@@ -431,9 +433,8 @@ def __init__(self, h11, h21, data_basename=None, **kwds): + """ + dim = 4 + if data_basename is None: +- from sage.env import POLYTOPE_DATA_DIR +- data_basename = os.path.join(POLYTOPE_DATA_DIR, +- 'Hodge4d', 'all') ++ db = DatabaseReflexivePolytopes('polytopes_db_4d') ++ data_basename = os.path.join(db.absolute_filename(), 'all') + info = data_basename + '.vinfo' + if not os.path.exists(info): + raise ValueError( +diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py +index 9dec951aa98..653201c3d10 100644 +--- a/src/sage/graphs/graph_database.py ++++ b/src/sage/graphs/graph_database.py +@@ -49,9 +49,9 @@ + import re + from sage.rings.integer import Integer + from sage.databases.sql_db import SQLDatabase, SQLQuery +-from sage.env import GRAPHS_DATA_DIR ++from sage.features.databases import DatabaseGraphs + from sage.graphs.graph import Graph +-dblocation = os.path.join(GRAPHS_DATA_DIR, 'graphs.db') ++dblocation = DatabaseGraphs().absolute_filename() + + + def degseq_to_data(degree_sequence): +diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py +index 7c2fae74ba7..440135956c3 100644 +--- a/src/sage/graphs/isgci.py ++++ b/src/sage/graphs/isgci.py +@@ -378,7 +378,7 @@ class is defined by the exclusion of subgraphs, one can write a generic + from sage.structure.sage_object import SageObject + from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation + from sage.misc.unknown import Unknown +-from sage.env import GRAPHS_DATA_DIR ++from sage.features.databases import DatabaseGraphs + from sage.misc.cachefunc import cached_method + + import os +@@ -796,6 +796,7 @@ def _download_db(self): + sage: graph_classes._download_db() # optional - internet + """ + import tempfile ++ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) + u = urlopen('https://www.graphclasses.org/data.zip', + context=default_context()) + with tempfile.NamedTemporaryFile(suffix=".zip") as f: +@@ -804,29 +805,24 @@ def _download_db(self): + + # Save a systemwide updated copy whenever possible + try: +- z.extract(_XML_FILE, GRAPHS_DATA_DIR) +- z.extract(_SMALLGRAPHS_FILE, GRAPHS_DATA_DIR) ++ z.extract(_XML_FILE, data_dir) ++ z.extract(_SMALLGRAPHS_FILE, data_dir) + except OSError: + pass + +- def _parse_db(self, directory): ++ def _parse_db(self): + r""" + Parse the ISGCI database and stores its content in ``self``. + +- INPUT: +- +- - ``directory`` -- the name of the directory containing the latest +- version of the database. +- + EXAMPLES:: + +- sage: from sage.env import GRAPHS_DATA_DIR +- sage: graph_classes._parse_db(GRAPHS_DATA_DIR) ++ sage: graph_classes._parse_db() + """ + import xml.etree.cElementTree as ET + from sage.graphs.graph import Graph + +- xml_file = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) ++ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) ++ xml_file = os.path.join(data_dir, _XML_FILE) + tree = ET.ElementTree(file=xml_file) + root = tree.getroot() + DB = _XML_to_dict(root) +@@ -838,7 +834,7 @@ def _parse_db(self, directory): + inclusions = DB['Inclusions']['incl'] + + # Parses the list of ISGCI small graphs +- smallgraph_file = open(os.path.join(GRAPHS_DATA_DIR, _SMALLGRAPHS_FILE), 'r') ++ smallgraph_file = open(os.path.join(data_dir, _SMALLGRAPHS_FILE), 'r') + smallgraphs = {} + + for line in smallgraph_file.readlines(): +@@ -901,24 +897,7 @@ def _get_ISGCI(self): + + sage: graph_classes._get_ISGCI() # long time (4s on sage.math, 2012) + """ +- from sage.misc.misc import SAGE_DB +- +- try: +- open(os.path.join(SAGE_DB, _XML_FILE)) +- +- # Which copy is the most recent on the disk ? +- if (os.path.getmtime(os.path.join(SAGE_DB, _XML_FILE)) > +- os.path.getmtime(os.path.join(GRAPHS_DATA_DIR, _XML_FILE))): +- +- directory = os.path.join(SAGE_DB, _XML_FILE) +- +- else: +- directory = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) +- +- except OSError: +- directory = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) +- +- self._parse_db(directory) ++ self._parse_db() + + def show_all(self): + r""" +diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx +index 632016b0703..453f711731c 100644 +--- a/src/sage/graphs/strongly_regular_db.pyx ++++ b/src/sage/graphs/strongly_regular_db.pyx +@@ -1233,7 +1233,7 @@ def SRG_from_RSHCD(v, k, l, mu, existence=False, check=True): + if (e**2 == 1 and + k == (n-1-a+e)/2 and + l == (n-2*a)/4 - (1-e) and +- mu== (n-2*a)/4 and ++ mu == (n-2*a)/4 and + regular_symmetric_hadamard_matrix_with_constant_diagonal(n, sgn(a)*e, existence=True) is True): + if existence: + return True +@@ -2415,7 +2415,7 @@ def SRG_416_100_36_20(): + """ + from sage.libs.gap.libgap import libgap + libgap.load_package("AtlasRep") +- g=libgap.AtlasGroup("G2(4)", libgap.NrMovedPoints, 416) ++ g = libgap.AtlasGroup("G2(4)", libgap.NrMovedPoints, 416) + h = Graph() + h.add_edges(g.Orbit([1, 5],libgap.OnSets)) + h.relabel() +@@ -2439,7 +2439,7 @@ def SRG_560_208_72_80(): + """ + from sage.libs.gap.libgap import libgap + libgap.load_package("AtlasRep") +- g=libgap.AtlasGroup("Sz8", libgap.NrMovedPoints, 560) ++ g = libgap.AtlasGroup("Sz8", libgap.NrMovedPoints, 560) + + h = Graph() + h.add_edges(g.Orbit([1, 2],libgap.OnSets)) +@@ -2503,7 +2503,7 @@ def strongly_regular_from_two_intersection_set(M): + for v in M: + # u is adjacent with all vertices on a uv line. + g.add_edges([[u, tuple([u[i] + qq*v[i] for i in range(k)])] +- for qq in K if not qq==K.zero()]) ++ for qq in K if not qq == K.zero()]) + g.relabel() + e = QQ((1,k)) + qq = g.num_verts()**e +@@ -3264,8 +3264,9 @@ cdef load_brouwer_database() noexcept: + if _brouwer_database is not None: + return + +- from sage.env import GRAPHS_DATA_DIR +- filename = os.path.join(GRAPHS_DATA_DIR, 'brouwer_srg_database.json') ++ from sage.features.databases import DatabaseGraphs ++ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) ++ filename = os.path.join(data_dir, 'brouwer_srg_database.json') + with open(filename) as fobj: + database = json.load(fobj) + +diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py +index e7354e05c70..add4b453b3d 100644 +--- a/src/sage/interfaces/jmoldata.py ++++ b/src/sage/interfaces/jmoldata.py +@@ -21,7 +21,7 @@ + + from sage.structure.sage_object import SageObject + +-from sage.env import JMOL_DIR ++from sage.features.jmol import JmolDataJar + from sage.misc.temporary_file import tmp_filename + from sage.cpython.string import bytes_to_str + +@@ -79,11 +79,11 @@ def jmolpath(self): + + sage: from sage.interfaces.jmoldata import JmolData + sage: JData = JmolData() +- sage: JData.jmolpath() ++ sage: JData.jmolpath() # needs jmol + '.../JmolData.jar' + + """ +- jmolpath = os.path.join(JMOL_DIR, "JmolData.jar") ++ jmolpath = JmolDataJar().absolute_filename() + + return jmolpath + +@@ -100,7 +100,7 @@ def is_jmol_available(self): + sage: type(JData.is_jmol_available()) + <... 'bool'> + """ +- if not os.path.isfile(self.jmolpath()): ++ if not JmolDataJar().is_present(): + return False + + if not self.is_jvm_available(): +diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py +index 0adeab04bcd..e62c0175331 100644 +--- a/src/sage/repl/ipython_kernel/install.py ++++ b/src/sage/repl/ipython_kernel/install.py +@@ -23,7 +23,6 @@ + SAGE_EXTCODE, + SAGE_VENV, + SAGE_VERSION, +- THREEJS_DIR, + ) + + +@@ -123,6 +122,7 @@ def use_local_threejs(self): + + EXAMPLES:: + ++ sage: # needs threejs + sage: from sage.repl.ipython_kernel.install import SageKernelSpec + sage: spec = SageKernelSpec(prefix=tmp_dir()) + sage: spec.use_local_threejs() +@@ -130,7 +130,10 @@ def use_local_threejs(self): + sage: os.path.isdir(threejs) + True + """ +- src = THREEJS_DIR ++ from sage.features.threejs import Threejs ++ if not Threejs().is_present(): ++ return ++ src = os.path.dirname(os.path.dirname(Threejs().absolute_filename())) + dst = os.path.join(self.nbextensions_dir, 'threejs-sage') + self.symlink(src, dst) + +diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py +index ba17b9244b4..7f39e37bf8f 100644 +--- a/src/sage/repl/rich_output/backend_ipython.py ++++ b/src/sage/repl/rich_output/backend_ipython.py +@@ -409,15 +409,18 @@ def threejs_offline_scripts(self): + + EXAMPLES:: + ++ sage: # needs threejs + sage: from sage.repl.rich_output.backend_ipython import BackendIPythonCommandline + sage: backend = BackendIPythonCommandline() +- sage: backend.threejs_offline_scripts() # needs sage.plot ++ sage: backend.threejs_offline_scripts() + '...'.format(script) + +@@ -596,7 +599,7 @@ def threejs_offline_scripts(self): + '... +- """.format(_required_threejs_version(), CDN_script) ++ """.format(Threejs().required_version(), CDN_script) +diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py +index f6bec0209e1..cfece92a810 100644 +--- a/src/sage/repl/rich_output/display_manager.py ++++ b/src/sage/repl/rich_output/display_manager.py +@@ -46,22 +46,6 @@ + from sage.repl.rich_output.preferences import DisplayPreferences + + +-def _required_threejs_version(): +- """ +- Return the version of threejs that Sage requires. +- +- EXAMPLES:: +- +- sage: from sage.repl.rich_output.display_manager import _required_threejs_version +- sage: _required_threejs_version() # needs sage.plot +- 'r...' +- """ +- import os +- import sage.env +- with open(os.path.join(sage.env.SAGE_EXTCODE, 'threejs', 'threejs-version.txt')) as f: +- return f.read().strip() +- +- + class DisplayException(Exception): + """ + Base exception for all rich output-related exceptions. +@@ -768,8 +752,9 @@ def threejs_scripts(self, online): + ValueError: current backend does not support + offline threejs graphics + """ ++ from sage.features.threejs import Threejs + if online: +- version = _required_threejs_version() ++ version = Threejs().required_version() + return """ + + """.format(version) +diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py +index f66ee2d1d31..34099d620bb 100644 +--- a/src/sage/schemes/elliptic_curves/ec_database.py ++++ b/src/sage/schemes/elliptic_curves/ec_database.py +@@ -132,8 +132,10 @@ def rank(self, rank, tors=0, n=10, labels=False): + sage: elliptic_curves.rank(6, n=3, labels=True) + [] + """ +- from sage.env import ELLCURVE_DATA_DIR +- data = os.path.join(ELLCURVE_DATA_DIR, 'rank%s' % rank) ++ from sage.features.databases import DatabaseEllcurves ++ db = DatabaseEllcurves() ++ data = os.path.join(os.path.dirname(db.absolute_filename()), ++ f'rank{rank}') + try: + f = open(data) + except OSError: diff --git a/srcpkgs/sagemath/patches/get_patches b/srcpkgs/sagemath/patches/get_patches index b7836e27910d5..34bb125a98876 100755 --- a/srcpkgs/sagemath/patches/get_patches +++ b/srcpkgs/sagemath/patches/get_patches @@ -21,10 +21,10 @@ get_pr() { cd $(dirname "$0") # all merged in 10.3.beta6 or before -get_pr 35848 "flintlib 3.0" -get_pr 36769 "fix jmol detect" -get_pr 36862 "giac 1.9.0-73" get_pr 37004 "fix save_session when cython changes" +get_pr 37024 "use features for simpler configuration" # positive review get_pr 37123 "scipy 1.12" + +# needs review diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index 7bc92e7c10735..28f0d3423fca4 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,7 +1,7 @@ # Template file for 'sagemath' pkgname=sagemath -version=10.2 -revision=2 +version=10.3.beta5 +revision=1 build_wrksrc=pkgs/sagemath-standard build_style=python3-module _bindir=/usr/lib/sagemath/$version/bin @@ -24,7 +24,7 @@ depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran meson gd-devel python3-memory_allocator python3-networkx python3-pip python3-pkgconfig python3-pplpy python3-primecountpy python3-requests python3-scipy python3-sympy python3-traitlets sage-data-combinatorial_designs - sage-data-conway_polynomials sage-data-elliptic_curves sage-data-graphs + python3-conway-polynomials sage-data-elliptic_curves sage-data-graphs sage-data-polytopes_db sympow tachyon threejs-sage" checkdepends="$depends pythran python3-Sphinx" short_desc="Open source mathematics software" @@ -33,16 +33,18 @@ license="GPL-2.0-or-later" homepage="https://www.sagemath.org/" changelog="https://github.com/sagemath/sage/releases" distfiles="https://github.com/sagemath/sage/archive/refs/tags/$version.tar.gz" -checksum=e7125f13495e1068edab73735aca7f9b2c655688096e9d109e628c023e76411f +checksum=4f4e608f8d2fe84dd6d79dd5429ca3528f79d56baa174a6bc2e97ffc855eced8 nocross="due to ntl (eclib, singular), fflas-ffpack, givaro, linbox, sympow, maxima" post_patch() { # git tree needs bootstrapping $wrksrc/bootstrap sagelib + + # we need sage_setup here + ln -s ../../src/sage_setup . } pre_build() { - export PYTHONPATH=../sage-setup export PYTHONDONTWRITEBYTECODE=yes export SAGE_NUM_THREADS="$XBPS_MAKEJOBS" } @@ -52,12 +54,11 @@ post_build() { _scripts=$(cd build/scripts* && pwd) # configuration files - cp ${FILESDIR}/sage_conf.py $_lib + #cp ${FILESDIR}/sage_conf.py $_lib cp ${FILESDIR}/sage-env-config $_scripts } pre_install() { - export PYTHONPATH=../sage-setup export PYTHONDONTWRITEBYTECODE=yes export SAGE_NUM_THREADS="$XBPS_MAKEJOBS" } @@ -77,7 +78,7 @@ post_install() { # we don't have docs here rm ${DESTDIR}/usr/share/jupyter/kernels/sagemath/doc # this symlink is shipped in threejs-sage pkg - rm ${DESTDIR}/usr/share/jupyter/nbextensions/threejs-sage + rm -f ${DESTDIR}/usr/share/jupyter/nbextensions/threejs-sage # symlink main binary vmkdir usr/bin diff --git a/srcpkgs/sagemath/update b/srcpkgs/sagemath/update index 1a4e4049af025..f34bbdf5ec69b 100644 --- a/srcpkgs/sagemath/update +++ b/srcpkgs/sagemath/update @@ -1,6 +1,6 @@ pkgname="sage" -site="https://mirrors.mit.edu/sage/src/" -if [[ "$version" == *[abr]* ]]; then - site+=" +site="https://mirrors.mit.edu/sage/src/ https://mirrors.mit.edu/sage/devel/" +if [[ "$version" != *[abr]* ]]; then + ignore="*[abr]*" fi From 761b95b84a4bbd67fa7d919286ae6e5d88e9962b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 23 Jan 2024 11:12:24 -0300 Subject: [PATCH 5/5] sagemath: update to 10.3.beta6. --- ...fix_save_session_when_cython_changes.patch | 182 -- ...e_features_for_simpler_configuration.patch | 1509 ----------------- srcpkgs/sagemath/patches/get_patches | 4 - srcpkgs/sagemath/template | 4 +- 4 files changed, 2 insertions(+), 1697 deletions(-) delete mode 100644 srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch delete mode 100644 srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch diff --git a/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch b/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch deleted file mode 100644 index c3e6c05502621..0000000000000 --- a/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch +++ /dev/null @@ -1,182 +0,0 @@ -diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py -index efd28d10abe..56a9fe5e8f6 100644 ---- a/src/sage/doctest/forker.py -+++ b/src/sage/doctest/forker.py -@@ -2477,19 +2477,6 @@ class DocTestTask(): - ['cputime', 'err', 'failures', 'optionals', 'tests', 'walltime', 'walltime_skips'] - """ - -- extra_globals = {} -- """ -- Extra objects to place in the global namespace in which tests are run. -- Normally this should be empty but there are special cases where it may -- be useful. -- -- For example, in Sage versions 9.1 and earlier, on Python 3 add -- ``long`` as an alias for ``int`` so that tests that use the -- ``long`` built-in (of which there are many) still pass. We did -- this so that the test suite could run on Python 3 while Python 2 -- was still the default. -- """ -- - def __init__(self, source): - """ - Initialization. -@@ -2614,10 +2601,6 @@ def _run(self, runner, options, results): - # Remove '__package__' item from the globals since it is not - # always in the globals in an actual Sage session. - dict_all.pop('__package__', None) -- -- # Add any other special globals for testing purposes only -- dict_all.update(self.extra_globals) -- - sage_namespace = RecordingDict(dict_all) - sage_namespace['__name__'] = '__main__' - doctests, extras = self.source.create_doctests(sage_namespace) -diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx -index 31454dac993..53b732309da 100644 ---- a/src/sage/misc/session.pyx -+++ b/src/sage/misc/session.pyx -@@ -27,7 +27,7 @@ This saves a dictionary with ``w`` as one of the keys:: - - sage: z = load(os.path.join(d.name, 'session')) - sage: list(z) -- ['d', 'w'] -+ ['w', 'd'] - sage: z['w'] - 2/3 - -@@ -68,11 +68,12 @@ AUTHOR: - import builtins - import types - --# We want the caller's locals, but locals() is emulated in Cython --cdef caller_locals = builtins.locals -- - # Sage imports - from sage.misc.persist import load, save, loads, dumps -+from sage.misc.lazy_import import LazyImport -+ -+# We want the caller's locals, but locals() is emulated in Cython -+cdef caller_locals = builtins.locals - - # This module-scope variables is used to save the - # global state of the sage environment at the moment -@@ -80,7 +81,6 @@ from sage.misc.persist import load, save, loads, dumps - - state_at_init = None - --CythonFunctionType = type(lambda: None) - - def init(state=None): - """ -@@ -163,9 +163,13 @@ def _is_new_var(x, v, hidden): - # definitely new. - if x not in state_at_init: - return True -+ # A lazy import that was there at init time is not new -+ if isinstance(v, LazyImport): -+ return False - # A variable could also be new even if it was there at init, say if - # its value changed. -- return x not in state_at_init or state_at_init[x] is not v -+ return state_at_init[x] is not v -+ - - def show_identifiers(hidden=False): - r""" -@@ -196,7 +200,7 @@ def show_identifiers(hidden=False): - sage: a = 10 - sage: factor = 20 - sage: show_identifiers() -- ['a', 'factor'] -+ ['factor', 'a'] - - To get the actual value of a variable from the list, use the - :func:`globals()` function.:: -@@ -210,7 +214,7 @@ def show_identifiers(hidden=False): - - sage: _hello = 10 - sage: show_identifiers() -- ['a', 'factor'] -+ ['factor', 'a'] - sage: '_hello' in show_identifiers(hidden=True) - True - -@@ -218,19 +222,13 @@ def show_identifiers(hidden=False): - least in command line mode.:: - - sage: show_identifiers(hidden=True) # random output -- ['__', '_i', '_6', '_4', '_3', '_1', '_ii', '__doc__', '__builtins__', '___', '_9', '__name__', '_', 'a', '_i12', '_i14', 'factor', '__file__', '_hello', '_i13', '_i11', '_i10', '_i15', '_i5', '_13', '_10', '_iii', '_i9', '_i8', '_i7', '_i6', '_i4', '_i3', '_i2', '_i1', '_init_cmdline', '_14'] -+ ['__builtin__', '_ih', '_oh', '_dh', 'exit', 'quit', '_', '__', '___', -+ '_i', '_ii', '_iii', '_i1', 'factor', '_i2', '_2', '_i3', 'a', '_i4', -+ '_i5', '_5', '_i6', '_6', '_i7', '_hello', '_i8', '_8', '_i9', '_9', -+ '_i10'] - """ -- from sage.doctest.forker import DocTestTask - state = caller_locals() -- # Ignore extra variables injected into the global namespace by the doctest -- # runner -- _none = object() -- -- def _in_extra_globals(name, val): -- return val == DocTestTask.extra_globals.get(name, _none) -- -- return sorted([x for x, v in state.items() if _is_new_var(x, v, hidden) -- and not _in_extra_globals(x, v)]) -+ return [x for x, v in state.items() if _is_new_var(x, v, hidden)] - - - def save_session(name='sage_session', verbose=False): -@@ -293,28 +291,44 @@ def save_session(name='sage_session', verbose=False): - sage: f = lambda x : x^2 - sage: save_session(tmp_f) - sage: save_session(tmp_f, verbose=True) -- Saving... -- Not saving f: f is a function, method, class or type - ... -+ Not saving f: f is a function or method - - Something similar happens for cython-defined functions:: - - sage: g = cython_lambda('double x', 'x*x + 1.5') - sage: save_session(tmp_f, verbose=True) -- Saving... -- Not saving g: g is a function, method, class or type - ... -+ Not saving g: g is a cython function or method -+ -+ And the same for a lazy import:: -+ -+ sage: from sage.misc.lazy_import import LazyImport -+ sage: lazy_ZZ = LazyImport('sage.rings.integer_ring', 'ZZ') -+ sage: save_session(tmp_f, verbose=True) -+ ... -+ Not saving lazy_ZZ: lazy_ZZ is a lazy import - """ - state = caller_locals() - # This dict D will contain the session -- as a dict -- that we will save to disk. - D = {} - # We iterate only over the new variables that were defined in this - # session, since those are the only ones we will save. -- for k in show_identifiers(hidden = True): -+ for k in show_identifiers(hidden=True): - try: - x = state[k] -- if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType, CythonFunctionType, type)): -- raise TypeError('{} is a function, method, class or type'.format(k)) -+ -+ if isinstance(x, type): -+ raise TypeError('{} is a class or type'.format(k)) -+ -+ if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType)): -+ raise TypeError('{} is a function or method'.format(k)) -+ -+ if getattr(type(x), '__name__', None) == 'cython_function_or_method': -+ raise TypeError('{} is a cython function or method'.format(k)) -+ -+ if isinstance(x, LazyImport): -+ raise TypeError('{} is a lazy import'.format(k)) - - # We attempt to pickle *and* unpickle every variable to - # make *certain* that we can pickled D at the end below. diff --git a/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch b/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch deleted file mode 100644 index a00fb76688fe2..0000000000000 --- a/srcpkgs/sagemath/patches/37024-use_features_for_simpler_configuration.patch +++ /dev/null @@ -1,1509 +0,0 @@ -diff --git a/src/sage/combinat/designs/MOLS_handbook_data.py b/src/sage/combinat/designs/MOLS_handbook_data.py -new file mode 100644 -index 00000000000..3891d20f81b ---- /dev/null -+++ b/src/sage/combinat/designs/MOLS_handbook_data.py -@@ -0,0 +1,571 @@ -+r""" -+Known lower bounds on the number of Mutually Orthogonal Latin -+Squares (MOLS) of a given size. -+ -+This module consists (almost) entirely of an internal, constant tuple -+of python integers corresponding to Table 3.87 in the Handbook of -+Combinatorial Designs, 2nd edition, by Colbourn and Dinitz. One public -+function, :func:`lower_bound`, is provided to access it. -+ -+Make sure we have all of the entries:: -+ -+ sage: from sage.combinat.designs import MOLS_handbook_data -+ sage: len(MOLS_handbook_data._LOWER_BOUNDS) -+ 10000 -+ -+Jeff Dinitz's website (at UVM) provides the following two updates to -+the table as printed in the second edition:: -+ -+ sage: from sage.combinat.designs import MOLS_handbook_data -+ sage: MOLS_handbook_data.lower_bound(60) -+ 5 -+ sage: MOLS_handbook_data.lower_bound(7968) -+ 31 -+ -+""" -+ -+_LOWER_BOUNDS: tuple[int, ...] -+_LOWER_BOUNDS = ( -+ 0,0,1,2,3,4,1,6,7,8,2,10,5,12,3,4,15,16,3,18, # 0 -+ 4,5,3,22,7,24,4,26,5,28,4,30,31,5,4,5,8,36,4,5, # 20 -+ 7,40,5,42,5,6,4,46,8,48,6,5,5,52,5,6,7,7,5,58, # 40 -+ 5,60,5,6,63,7,5,66,5,6,6,70,7,72,5,7,6,6,6,78, # 60 -+ 9,80,8,82,6,6,6,6,7,88,6,7,6,6,6,6,7,96,6,8, # 80 -+ 8,100,6,102,7,7,6,106,6,108,6,6,13,112,6,7,6,8,6,6, # 100 -+ 7,120,6,6,6,124,6,126,127,7,6,130,6,7,6,7,7,136,6,138, # 120 -+ 6,7,6,10,10,7,6,7,6,148,6,150,7,8,8,7,6,156,7,6, # 140 -+ 9,7,6,162,6,7,6,166,7,168,6,8,6,172,6,6,14,9,6,178, # 160 -+ 6,180,6,6,7,9,6,10,6,8,6,190,7,192,6,7,6,196,6,198, # 180 -+ 7,8,6,7,6,8,6,8,14,11,10,210,6,7,6,7,7,8,6,10, # 200 -+ 6,12,6,222,13,8,6,226,6,228,6,7,7,232,6,7,6,7,6,238, # 220 -+ 7,240,6,242,6,7,6,12,7,7,6,250,6,12,9,7,255,256,6,12, # 240 -+ 6,8,8,262,7,8,7,10,7,268,7,270,15,16,6,13,10,276,6,9, # 260 -+ 7,280,6,282,6,12,6,7,15,288,6,6,6,292,6,6,7,10,10,12, # 280 -+ 7,7,7,7,15,15,6,306,7,7,7,310,7,312,7,10,7,316,7,10, # 300 -+ 15,15,6,16,8,12,6,7,7,9,6,330,7,8,7,6,8,336,6,7, # 320 -+ 6,10,10,342,7,7,6,346,6,348,8,12,18,352,6,9,7,9,6,358, # 340 -+ 8,360,6,7,7,10,6,366,15,15,7,15,7,372,7,15,7,13,7,378, # 360 -+ 7,12,7,382,15,15,7,15,7,388,7,16,7,8,7,7,8,396,7,7, # 380 -+ 15,400,7,15,11,8,7,15,8,408,7,13,8,12,10,9,18,15,7,418, # 400 -+ 7,420,7,15,7,16,6,7,7,10,6,430,15,432,6,15,6,18,7,438, # 420 -+ 7,15,7,442,7,13,7,11,15,448,7,15,7,7,7,15,7,456,7,16, # 440 -+ 7,460,7,462,15,15,7,466,8,8,7,15,7,15,10,18,7,15,6,478, # 460 -+ 15,15,6,15,8,7,6,486,7,15,6,490,6,16,6,7,15,15,6,498, # 480 -+ 7,12,9,502,7,15,6,15,7,508,6,15,511,18,7,15,8,12,8,15, # 500 -+ 8,520,10,522,12,15,8,16,15,528,7,15,8,12,7,15,8,15,10,15, # 520 -+ 12,540,7,15,18,7,7,546,7,8,7,18,7,7,7,7,7,556,7,12, # 540 -+ 15,7,7,562,7,7,6,7,7,568,6,570,7,7,15,22,8,576,7,7, # 560 -+ 7,8,7,10,7,8,7,586,7,18,17,7,15,592,8,15,7,7,8,598, # 580 -+ 14,600,12,15,7,15,16,606,18,15,7,15,8,612,8,15,7,616,7,618, # 600 -+ 8,22,8,15,15,624,7,8,8,16,7,630,7,8,7,8,7,12,7,8, # 620 -+ 9,640,7,642,7,7,7,646,8,10,7,7,7,652,7,7,15,15,7,658, # 640 -+ 7,660,7,15,7,15,7,22,7,15,7,15,15,672,7,24,8,676,7,15, # 660 -+ 7,15,7,682,8,15,7,15,15,15,7,690,8,15,7,15,7,16,7,15, # 680 -+ 8,700,7,18,15,15,7,15,8,708,7,15,7,22,21,15,7,15,8,718, # 700 -+ 15,9,8,12,10,24,12,726,7,728,16,16,18,732,7,7,22,10,8,738, # 720 -+ 7,7,7,742,7,15,7,8,7,10,7,750,15,15,8,15,8,756,8,15, # 740 -+ 7,760,8,15,8,15,8,15,15,768,8,15,8,772,8,24,23,15,8,18, # 760 -+ 8,18,7,26,15,15,10,786,12,15,7,15,20,15,18,15,8,796,22,16, # 780 -+ 24,15,8,15,8,15,8,15,8,808,8,810,8,15,8,15,15,18,8,8, # 800 -+ 8,820,8,822,8,15,8,826,8,828,8,15,12,16,7,8,7,26,25,838, # 820 -+ 8,840,8,20,8,10,8,16,15,15,12,22,7,852,16,15,22,856,7,858, # 840 -+ 22,15,24,862,26,15,7,15,8,15,9,15,7,15,7,15,7,876,8,15, # 860 -+ 15,880,8,882,8,15,7,886,7,15,8,15,10,18,8,15,13,15,8,28, # 880 -+ 27,16,8,8,8,22,8,906,8,18,10,910,15,14,8,15,16,10,18,918, # 900 -+ 24,8,22,12,24,24,26,8,28,928,7,18,7,7,7,14,7,936,7,15, # 920 -+ 7,940,7,22,15,15,7,946,7,12,12,15,7,952,7,15,7,15,8,15, # 940 -+ 15,960,29,15,8,15,8,966,8,15,8,970,10,18,12,15,15,976,16,18, # 960 -+ 18,15,7,982,27,15,24,15,26,22,28,990,31,31,7,15,8,996,25,26, # 980 -+ 7,15,21,16,19,15,7,18,15,1008,13,18,8,1012,9,22,7,28,7,1018, # 1000 -+ 7,1020,7,30,1023,24,7,15,9,15,9,1030,7,1032,7,15,8,16,9,1038, # 1020 -+ 15,15,8,15,8,15,8,15,8,1048,8,1050,8,15,8,15,15,16,8,8, # 1040 -+ 8,1060,8,1062,8,15,8,15,10,1068,7,15,15,28,7,24,7,15,8,15, # 1060 -+ 12,22,8,15,8,15,8,1086,16,15,8,1090,8,1092,8,15,8,1096,8,15, # 1080 -+ 8,15,8,1102,15,15,8,26,8,1108,8,18,8,15,8,15,8,1116,7,15, # 1100 -+ 16,18,7,1122,7,15,7,22,8,1128,7,15,8,15,10,9,15,15,7,16, # 1120 -+ 7,8,7,15,7,15,7,30,30,15,7,1150,15,1152,7,15,8,26,12,24, # 1140 -+ 12,26,7,1162,16,18,18,15,15,15,22,1170,24,15,26,24,28,15,30,30, # 1160 -+ 8,1180,8,15,31,15,8,1186,8,28,8,15,8,1192,8,15,8,15,8,15, # 1180 -+ 15,1200,8,15,8,15,8,16,8,15,8,15,8,1212,8,15,18,1216,7,22, # 1200 -+ 7,15,8,1222,7,24,7,15,7,1228,7,1230,15,9,8,15,7,1236,7,15, # 1220 -+ 7,16,8,10,8,7,8,28,8,1248,8,8,7,7,7,8,8,8,7,1258, # 1240 -+ 7,12,23,7,15,15,9,15,9,26,9,30,30,23,8,15,9,1276,9,1278, # 1260 -+ 15,30,10,1282,12,15,9,24,16,1288,18,1290,8,18,22,15,24,1296,26,15, # 1280 -+ 28,1300,30,1302,8,15,8,1306,30,15,8,15,31,15,12,15,8,15,8,1318, # 1300 -+ 8,1320,8,26,8,24,7,1326,15,15,8,1330,8,30,30,15,8,15,9,30, # 1320 -+ 12,15,8,30,15,30,12,15,9,26,16,24,18,15,9,20,22,22,24,15, # 1340 -+ 26,1360,28,28,30,30,9,1366,28,1368,30,15,9,1372,30,15,31,16,8,15, # 1360 -+ 8,1380,8,15,8,15,8,18,8,15,8,15,15,15,8,15,8,10,9,1398, # 1380 -+ 10,15,8,22,8,8,8,15,10,1408,8,16,7,9,9,22,9,12,7,8, # 1400 -+ 9,28,7,1422,15,24,9,1426,9,1428,7,26,7,1432,9,15,7,15,7,1438, # 1420 -+ 15,15,7,15,9,15,9,1446,7,15,7,1450,7,1452,9,15,15,30,30,1458, # 1440 -+ 8,15,8,30,8,15,8,30,10,30,12,1470,22,30,16,28,18,15,8,24, # 1460 -+ 22,1480,24,1482,26,18,28,1486,30,1488,13,15,8,1492,30,15,8,15,30,1498, # 1480 -+ 30,18,9,15,31,15,9,15,9,14,9,1510,9,24,9,9,9,36,9,30, # 1500 -+ 30,9,9,1522,9,30,9,9,9,30,10,1530,12,9,9,30,16,30,18,18, # 1520 -+ 8,26,22,1542,24,8,26,20,28,1548,30,30,15,1552,8,15,30,8,8,1558, # 1540 -+ 30,15,30,15,8,15,30,1566,31,15,8,1570,8,15,12,15,8,18,8,1578, # 1560 -+ 8,15,8,1582,15,24,8,8,8,15,8,36,7,26,8,15,8,1596,8,15, # 1580 -+ 24,1600,8,15,8,15,8,1606,8,1608,8,15,8,1612,7,15,15,15,8,1618, # 1600 -+ 8,1620,7,15,7,15,7,1626,7,15,7,15,24,22,8,15,8,1636,7,15, # 1620 -+ 7,15,7,30,30,15,7,26,15,30,7,15,11,30,10,30,12,1656,7,30, # 1640 -+ 16,30,18,1662,15,30,22,1666,24,1668,26,24,28,22,30,30,19,15,7,22, # 1660 -+ 30,1680,9,15,30,15,30,15,9,15,30,18,30,1692,9,15,31,1696,9,1698, # 1680 -+ 9,15,8,15,8,15,8,15,8,1708,21,28,15,15,8,15,10,16,7,15, # 1700 -+ 8,1720,9,1722,9,15,7,15,26,21,8,15,8,1732,7,15,7,15,7,36, # 1720 -+ 9,1740,8,15,15,15,8,1746,8,15,8,16,9,1752,9,15,9,15,8,1758, # 1740 -+ 26,15,8,40,9,15,8,15,8,28,8,27,8,15,8,24,15,1776,9,15, # 1760 -+ 8,15,8,1782,8,15,8,1786,8,1788,8,15,15,15,9,15,8,15,8,15, # 1780 -+ 8,1800,8,15,9,15,8,30,15,26,8,1810,8,36,7,15,9,22,9,16, # 1800 -+ 9,15,9,1822,26,24,9,15,9,30,30,1830,9,15,9,30,9,15,9,30, # 1820 -+ 15,30,12,18,9,30,16,1846,18,1848,9,30,22,16,24,15,28,30,28,28, # 1840 -+ 30,1860,25,22,8,22,30,1866,8,18,30,1870,30,1872,8,15,30,1876,30,1878, # 1860 -+ 8,15,30,8,8,8,8,15,31,1888,8,30,30,15,8,15,8,30,8,15, # 1880 -+ 8,1900,10,30,15,15,8,1906,16,30,18,15,8,1912,22,15,24,26,26,30, # 1900 -+ 28,30,30,30,27,9,7,40,30,9,8,1930,30,1932,30,8,15,15,30,15, # 1920 -+ 30,10,8,28,30,15,8,15,8,1948,30,1950,31,15,8,15,8,18,8,15, # 1940 -+ 8,36,8,15,8,15,8,15,15,15,8,26,8,1972,8,24,9,15,9,1978, # 1960 -+ 9,15,9,15,30,30,9,1986,9,15,30,15,10,1992,30,15,30,1996,9,1998, # 1980 -+ 30,16,30,2002,9,9,30,22,9,40,9,2010,30,28,30,30,31,2016,8,15, # 2000 -+ 27,42,8,15,23,30,21,2026,8,2028,8,30,15,30,13,15,11,30,8,2038, # 2020 -+ 8,15,8,30,8,30,8,22,2047,15,8,15,8,2052,8,15,8,16,10,28, # 2040 -+ 8,15,9,2062,15,15,8,15,8,2068,8,18,8,15,9,24,8,30,30,15, # 2060 -+ 30,2080,8,2082,8,15,8,2086,10,2088,12,15,8,30,16,30,18,15,8,2098, # 2080 -+ 22,36,24,15,26,30,28,42,30,30,30,2110,15,2112,30,15,9,28,30,24, # 2100 -+ 30,15,10,15,30,18,30,16,15,2128,30,2130,8,26,9,15,30,2136,30,15, # 2120 -+ 9,2140,9,2142,31,15,9,18,9,15,9,15,9,2152,10,15,12,15,9,16, # 2140 -+ 15,2160,9,15,9,14,9,15,9,15,10,14,12,40,9,15,16,15,9,2178, # 2160 -+ 8,15,9,36,9,15,9,2186,9,15,9,23,15,15,8,15,9,2196,12,15, # 2180 -+ 9,30,30,2202,8,15,9,2206,15,2208,8,30,10,2212,12,15,8,30,16,30, # 2200 -+ 18,2220,8,30,22,24,24,16,26,30,28,30,30,30,30,15,10,2236,30,2238, # 2220 -+ 16,30,30,2242,30,15,8,15,30,22,30,2250,8,18,30,15,15,36,8,15, # 2240 -+ 30,15,30,30,30,30,9,2266,30,2268,8,15,31,2272,10,30,12,15,8,42, # 2260 -+ 16,2280,18,15,8,30,22,2286,24,15,26,30,28,2292,30,30,30,2296,9,30, # 2280 -+ 30,15,9,46,30,30,30,15,9,2308,30,2310,30,22,9,20,30,15,9,15, # 2300 -+ 15,15,30,22,30,15,9,30,28,16,30,15,9,2332,30,15,31,15,9,2338, # 2320 -+ 8,2340,8,10,9,15,8,2346,8,28,8,2350,15,12,8,15,9,2356,9,10, # 2340 -+ 8,15,8,16,8,9,8,10,36,22,10,2370,8,10,8,18,26,2376,8,10, # 2360 -+ 8,2380,8,2382,15,15,8,15,8,2388,8,15,8,2392,8,42,10,15,13,2398, # 2380 -+ 15,2400,8,26,8,15,9,28,7,15,7,2410,8,18,17,15,15,2416,7,40, # 2400 -+ 8,15,8,2422,14,24,12,15,8,15,16,15,18,15,8,15,9,2436,9,15, # 2420 -+ 9,2440,10,15,10,15,10,2446,15,30,30,15,9,27,9,30,9,15,9,2458, # 2440 -+ 10,30,12,15,15,30,16,2466,18,15,9,30,22,2472,24,15,26,2476,28,36, # 2460 -+ 30,30,30,15,12,30,30,15,9,30,30,46,30,15,9,15,30,30,30,28, # 2480 -+ 8,40,30,2502,8,15,9,22,30,15,30,30,30,30,9,15,30,30,8,15, # 2500 -+ 30,2520,30,30,12,24,9,30,31,30,18,2530,9,30,22,15,24,42,26,2538, # 2520 -+ 28,30,30,2542,30,15,9,30,30,2548,9,2550,30,30,30,15,9,2556,30,30, # 2540 -+ 30,30,9,28,30,15,10,16,9,23,30,15,30,30,30,30,15,15,30,2578, # 2560 -+ 9,28,30,30,30,30,12,12,12,30,30,2590,31,2592,8,30,22,48,24,22, # 2580 -+ 26,30,28,30,30,30,30,9,15,2608,30,15,9,30,30,30,30,2616,8,26, # 2600 -+ 30,2620,30,42,40,30,30,36,8,15,8,24,30,2632,30,15,8,30,8,16, # 2620 -+ 30,18,8,15,30,15,30,2646,28,15,8,15,30,15,30,15,31,2656,10,2658, # 2640 -+ 8,15,9,2662,9,15,9,15,7,16,9,2670,15,15,8,24,8,2676,8,15, # 2660 -+ 9,15,8,2682,9,15,8,2686,15,2688,8,15,10,2692,8,15,8,15,9,2698, # 2680 -+ 9,36,8,15,15,15,10,2706,8,15,10,2710,9,2712,8,15,10,15,10,2718, # 2700 -+ 31,15,9,15,9,24,10,26,10,2728,10,2730,9,15,10,15,15,15,8,15, # 2720 -+ 8,2740,8,15,9,15,8,40,9,2748,8,15,42,2752,9,15,8,15,9,30, # 2740 -+ 30,15,8,15,9,30,7,2766,15,30,10,30,12,46,8,30,16,2776,18,15, # 2760 -+ 9,30,22,22,24,15,26,30,28,2788,30,2790,30,15,9,30,30,2796,9,30, # 2780 -+ 30,2800,30,2802,9,15,30,30,30,2808,8,30,30,28,9,15,15,30,30,2818, # 2800 -+ 30,15,8,30,9,24,30,15,8,18,30,18,30,2832,9,15,9,2836,30,23, # 2820 -+ 30,15,30,2842,8,15,8,15,31,15,10,2850,8,15,9,15,8,2856,8,15, # 2840 -+ 8,2860,29,13,29,15,9,46,29,18,29,15,8,16,29,22,8,15,8,2878, # 2860 -+ 29,42,29,15,9,29,9,2886,29,26,8,48,29,15,29,15,15,2896,9,15, # 2880 -+ 29,15,30,2902,8,15,8,15,8,2908,10,40,31,15,9,15,8,2916,9,15, # 2900 -+ 8,22,21,36,9,18,9,2926,15,28,9,15,10,15,12,15,9,15,16,2938, # 2920 -+ 18,16,9,26,22,15,9,15,9,15,9,15,9,2952,9,15,9,2956,9,15, # 2940 -+ 15,15,9,2962,9,15,9,15,9,2968,9,2970,9,15,10,15,15,15,12,15, # 2960 -+ 9,15,10,18,9,15,9,28,9,48,8,15,15,40,9,15,9,36,9,2998, # 2980 -+ 9,3000,9,15,10,15,9,30,46,15,9,3010,9,30,8,15,10,30,10,3018, # 3000 -+ 12,15,9,3022,16,30,18,15,9,30,22,15,24,15,26,30,28,3036,30,30, # 3020 -+ 31,3040,9,30,30,15,9,30,30,3048,30,26,9,42,30,30,30,30,9,30, # 3040 -+ 30,3060,9,15,9,30,30,3066,30,15,9,36,15,30,30,15,8,26,30,3078, # 3060 -+ 30,15,9,3082,9,18,30,15,30,3088,30,15,9,15,10,15,30,18,9,15, # 3080 -+ 9,15,9,28,31,15,9,25,9,3108,8,15,9,15,8,15,8,15,9,3118, # 3100 -+ 15,3120,8,15,9,3124,8,52,8,15,9,30,30,15,8,15,48,3136,9,42, # 3120 -+ 8,30,10,30,12,15,9,30,16,46,18,22,15,30,22,15,24,15,26,30, # 3140 -+ 28,30,30,3162,30,15,9,3166,30,3168,9,30,30,30,30,24,23,15,30,30, # 3160 -+ 30,3180,10,30,30,15,10,3186,12,30,30,3190,30,30,30,30,8,30,30,30, # 3180 -+ 24,30,30,3202,30,30,12,24,9,3208,30,30,30,18,30,30,22,3216,24,15, # 3200 -+ 30,3220,28,30,30,30,30,15,30,3228,30,15,31,52,30,30,30,15,9,40, # 3220 -+ 30,30,30,30,9,30,30,16,15,15,10,3250,30,3252,30,15,9,3256,9,3258, # 3240 -+ 30,15,10,30,30,30,30,26,10,26,9,3270,30,15,30,24,30,28,10,15, # 3260 -+ 15,16,30,48,9,15,10,18,28,15,30,15,9,36,30,15,31,15,9,3298, # 3280 -+ 10,3300,10,15,10,15,10,3306,10,15,9,15,15,3312,9,15,9,30,30,3318, # 3300 -+ 9,40,9,3322,9,23,9,30,14,3328,12,3330,10,30,16,30,18,46,9,30, # 3320 -+ 22,15,24,3342,26,30,28,3346,30,30,30,15,10,30,30,13,10,30,30,3358, # 3340 -+ 30,3360,10,15,30,30,30,30,12,30,30,3370,10,3372,10,30,30,15,30,30, # 3360 -+ 30,30,9,30,30,30,9,30,30,3388,30,3390,52,30,10,30,30,42,30,24, # 3380 -+ 30,39,22,40,24,23,30,3406,28,30,30,30,30,3412,30,30,30,15,30,30, # 3400 -+ 30,30,30,15,31,24,30,30,30,30,25,46,30,3432,9,15,10,30,30,18, # 3420 -+ 30,15,13,30,10,30,30,15,22,3448,30,30,30,13,24,30,26,3456,30,15, # 3440 -+ 30,3460,30,3462,9,15,9,3466,30,3468,9,10,15,22,10,24,30,18,9,48, # 3460 -+ 30,3480,30,42,10,15,30,39,31,15,9,3490,9,11,10,13,10,15,12,3498, # 3480 -+ 9,15,10,30,30,11,10,15,9,30,10,3510,9,30,10,30,12,3516,9,30, # 3500 -+ 26,30,18,15,12,30,22,3526,24,3528,26,30,28,3532,30,30,30,26,10,3538, # 3520 -+ 30,3540,11,30,30,30,30,3546,11,15,30,52,30,30,10,30,30,3556,10,3558, # 3540 -+ 11,30,30,12,30,12,11,30,15,42,30,3570,11,30,30,30,30,48,10,30, # 3560 -+ 10,3580,30,3582,30,30,30,16,10,36,10,15,30,3592,11,15,11,18,10,58, # 3580 -+ 30,15,10,13,30,15,30,3606,9,15,30,22,30,3612,9,15,31,3616,9,15, # 3600 -+ 10,15,9,3622,10,28,11,15,9,25,11,3630,15,15,10,15,10,3636,9,15, # 3620 -+ 9,15,8,3642,11,15,9,15,26,40,10,15,9,15,12,15,9,25,9,3658, # 3640 -+ 11,15,11,15,15,15,10,18,9,15,9,3670,10,3672,10,15,9,3676,8,21, # 3660 -+ 15,15,10,28,27,15,10,24,9,15,10,3690,10,18,10,16,15,3696,10,26, # 3680 -+ 16,3700,18,15,24,15,22,15,24,3708,26,15,28,46,10,15,10,15,9,3718, # 3700 -+ 10,3720,10,15,11,24,9,3726,15,15,9,15,10,3732,10,15,9,36,9,3738, # 3720 -+ 9,15,10,18,15,39,10,15,9,22,10,30,30,26,9,15,10,30,12,15, # 3740 -+ 15,3760,10,52,12,15,10,3766,16,3768,18,15,9,30,22,24,58,15,26,3778, # 3760 -+ 28,30,30,30,30,15,10,30,30,15,10,30,30,3792,30,15,10,3796,30,30, # 3780 -+ 30,30,10,3802,30,15,9,46,31,30,30,36,30,15,9,30,9,30,30,15, # 3800 -+ 10,3820,30,3822,30,15,10,42,10,30,30,15,30,3832,30,15,10,15,10,15, # 3820 -+ 30,30,10,15,10,26,10,3846,30,15,9,3850,30,3852,30,15,15,15,30,16, # 3840 -+ 30,15,10,3862,30,15,9,15,9,52,9,48,31,15,10,30,30,3876,10,15, # 3860 -+ 10,3880,9,15,10,30,10,30,15,3888,10,30,16,30,18,15,9,30,22,15, # 3880 -+ 24,48,26,30,60,30,30,3906,30,15,9,3910,30,15,11,30,30,3916,30,3918, # 3900 -+ 15,15,30,3922,30,30,9,30,30,3928,9,3930,9,30,30,15,30,30,30,30, # 3920 -+ 9,30,30,3942,9,30,30,3946,30,30,12,30,15,58,30,30,30,30,30,36, # 3940 -+ 26,40,24,15,30,30,28,3966,30,48,30,28,30,36,30,24,30,40,30,30, # 3960 -+ 30,18,30,16,30,30,30,30,30,3988,30,22,10,24,10,30,30,28,30,30, # 3980 -+ 31,4000,10,4002,30,30,10,4006,30,30,30,30,9,4012,9,30,30,30,30,4018, # 4000 -+ 30,4020,9,26,9,24,30,4026,9,30,9,30,30,36,30,30,9,26,30,30, # 4020 -+ 30,30,10,20,30,18,30,30,15,4048,30,4050,18,15,9,15,28,4056,30,15, # 4040 -+ 26,30,30,16,31,30,10,48,27,30,9,30,10,4072,21,30,19,30,16,4078, # 4060 -+ 18,30,10,30,22,15,24,60,26,30,28,4090,30,4092,30,30,4095,30,30,4098, # 4080 -+ 9,30,30,30,30,15,9,15,30,30,30,4110,15,30,30,15,10,22,10,30, # 4100 -+ 30,15,30,15,11,30,9,4126,30,4128,10,30,30,4132,30,15,11,30,10,4138, # 4120 -+ 30,40,30,30,30,15,10,15,10,15,30,30,9,4152,11,30,9,4156,30,4158, # 4140 -+ 15,30,30,22,30,15,29,24,30,22,30,42,29,15,30,24,29,4176,10,15, # 4160 -+ 10,36,30,46,29,15,30,52,30,58,29,15,31,15,29,15,29,15,10,15, # 4180 -+ 12,4200,29,15,29,15,29,15,15,15,10,4210,29,15,9,15,9,4216,10,4218, # 4200 -+ 29,15,9,40,29,24,29,15,10,4228,29,4230,29,15,10,15,29,18,13,26, # 4220 -+ 15,4240,10,4242,30,15,9,30,30,15,12,15,9,4252,13,15,31,30,10,4258, # 4240 -+ 12,4260,10,30,16,30,18,42,9,30,22,4270,24,4272,26,30,28,30,30,30, # 4260 -+ 30,15,10,4282,30,15,9,30,63,4288,30,15,10,52,30,30,30,4296,9,30, # 4280 -+ 30,15,10,15,15,30,30,58,30,30,30,30,9,30,30,30,9,30,30,30, # 4300 -+ 30,30,12,30,10,30,30,4326,30,30,30,60,22,15,24,15,30,4336,28,4338, # 4320 -+ 30,30,30,42,30,30,30,30,30,4348,30,30,30,30,30,28,30,4356,30,30, # 4340 -+ 30,48,30,4362,13,18,13,30,30,16,30,15,30,4372,30,30,30,15,30,30, # 4360 -+ 30,30,30,15,31,30,12,40,30,15,30,4390,30,22,13,15,13,4396,30,52, # 4380 -+ 15,26,12,30,13,30,30,15,13,4408,30,15,30,15,10,30,30,30,30,15, # 4400 -+ 12,4420,30,4422,13,15,13,20,12,42,30,15,15,15,30,15,30,30,12,22, # 4420 -+ 30,4440,11,15,13,15,30,4446,31,15,10,4450,12,60,13,15,12,4456,13,15, # 4440 -+ 13,15,13,4462,15,15,11,15,10,40,12,16,13,15,13,24,13,36,13,15, # 4460 -+ 16,4480,10,4482,10,15,12,15,13,4488,13,15,10,4492,13,15,15,15,10,25, # 4480 -+ 10,15,10,15,10,15,12,4506,13,26,13,15,15,4512,10,15,10,4516,10,4518, # 4500 -+ 10,15,12,4522,13,24,10,15,15,15,11,22,10,15,10,15,10,15,10,15, # 4520 -+ 12,18,13,15,63,15,10,4546,10,4548,10,15,10,28,10,15,12,15,12,46, # 4540 -+ 15,4560,11,26,11,15,10,4566,10,15,12,15,12,16,13,15,31,22,11,18, # 4560 -+ 10,15,10,4582,10,15,10,15,12,15,13,4590,15,15,10,15,10,4596,12,15, # 4580 -+ 10,42,10,4602,12,15,9,16,15,15,13,15,11,15,9,15,9,18,10,30, # 4600 -+ 30,4620,12,15,16,36,15,15,13,30,15,30,15,40,15,30,16,4636,18,4638, # 4620 -+ 31,30,22,4642,24,15,26,30,28,4648,30,4650,30,15,15,30,30,4656,12,30, # 4640 -+ 30,58,30,4662,14,15,30,30,30,30,14,30,63,4672,12,15,14,30,30,4678, # 4660 -+ 30,30,30,30,14,30,30,42,15,30,30,4690,30,30,14,30,15,30,30,36, # 4680 -+ 35,30,30,4702,22,15,24,15,30,30,28,30,30,30,30,30,30,52,30,30, # 4700 -+ 30,4720,30,4722,30,30,30,30,30,4728,30,31,30,4732,30,15,36,30,12,30, # 4720 -+ 30,15,30,15,30,30,30,46,30,15,30,4750,30,48,30,15,30,66,30,4758, # 4740 -+ 30,15,30,30,30,15,13,15,31,18,30,30,11,15,10,30,10,39,30,58, # 4760 -+ 15,30,30,4782,30,15,12,4786,30,4788,30,15,10,4792,30,15,14,15,15,4798, # 4780 -+ 15,4800,30,15,10,15,30,24,30,30,10,16,30,4812,14,15,15,4816,30,60, # 4800 -+ 30,15,10,22,28,24,12,15,12,15,30,4830,31,26,12,15,10,23,10,15, # 4820 -+ 10,46,11,28,12,15,15,36,15,15,11,15,10,22,10,15,11,15,10,42, # 4840 -+ 11,4860,14,15,18,17,12,30,30,15,10,4870,11,30,11,15,12,4876,11,30, # 4860 -+ 15,16,10,30,16,30,18,26,10,4888,22,66,24,15,26,30,28,58,30,30, # 4880 -+ 30,28,12,4902,30,15,10,30,30,4908,30,15,15,4912,30,30,30,30,10,4918, # 4900 -+ 30,15,11,15,10,30,30,15,30,15,12,4930,11,4932,30,15,11,4936,30,30, # 4920 -+ 30,60,10,4942,15,30,30,15,30,48,30,4950,10,15,10,15,30,4956,10,15, # 4940 -+ 15,40,11,30,30,15,12,4966,30,4968,30,15,10,4972,30,30,30,15,12,15, # 4960 -+ 30,16,10,15,11,30,10,4986,30,15,10,15,30,4992,30,30,10,18,30,4998, # 4980 -+ 11,15,10,5002,30,18,30,15,15,5008,10,5010,11,15,10,15,30,28,30,15, # 5000 -+ 10,5020,10,5022,31,15,10,15,10,46,10,15,9,15,10,15,10,15,10,5038, # 5020 -+ 15,5040,10,15,11,15,10,48,9,15,10,5050,10,30,30,15,63,15,10,5058, # 5040 -+ 11,15,10,60,10,30,12,15,10,36,16,30,18,15,10,30,22,5076,24,15, # 5060 -+ 26,5080,28,30,30,30,30,5086,31,30,30,15,12,30,30,30,30,15,10,5098, # 5080 -+ 30,5100,30,30,15,30,30,5106,11,15,10,30,30,5112,30,15,10,30,10,5118, # 5100 -+ 30,39,10,46,30,40,30,15,10,30,13,30,30,15,30,30,30,15,10,15, # 5120 -+ 11,52,30,36,11,15,13,5146,13,45,30,15,31,5152,30,15,30,26,10,30, # 5140 -+ 30,30,30,15,12,15,30,5166,15,15,15,5170,15,30,30,15,15,30,30,5178, # 5160 -+ 30,30,15,70,63,30,15,30,15,5188,30,28,30,30,16,30,18,5196,15,30, # 5180 -+ 22,15,30,42,30,30,28,40,39,5208,30,36,15,30,30,15,31,30,30,30, # 5200 -+ 30,22,15,15,30,30,30,5226,15,30,30,5230,24,5232,26,30,30,5236,30,31, # 5220 -+ 30,30,13,48,36,30,15,30,40,30,30,58,15,30,15,30,30,30,30,30, # 5240 -+ 30,5260,22,18,24,15,30,30,28,30,30,30,30,5272,30,30,30,30,30,5278, # 5260 -+ 31,5280,30,30,30,30,30,30,30,30,30,30,30,66,15,30,15,5296,30,16, # 5280 -+ 30,15,30,5302,30,30,30,15,30,5308,30,46,63,30,30,30,30,30,30,26, # 5300 -+ 30,30,30,5322,15,18,30,16,30,5328,12,16,10,5332,30,30,30,15,15,30, # 5320 -+ 30,48,30,15,31,30,30,5346,30,15,10,5350,30,52,11,15,15,30,15,30, # 5340 -+ 30,15,12,30,30,30,30,30,10,30,30,40,15,30,15,42,30,30,30,30, # 5360 -+ 16,5380,18,15,14,30,22,5386,30,18,30,30,28,5392,30,30,30,15,12,5398, # 5380 -+ 30,15,30,30,30,30,30,5406,31,15,30,30,30,5412,9,30,30,5416,12,5418, # 5400 -+ 11,30,30,15,30,15,13,66,12,60,30,5430,11,30,30,30,30,5436,15,30, # 5420 -+ 40,5440,30,5442,30,30,30,15,11,5448,11,15,30,30,15,15,15,30,10,52, # 5440 -+ 30,42,41,30,30,38,30,15,11,30,30,5470,30,30,12,16,30,5476,16,5478, # 5460 -+ 18,30,10,5482,30,18,24,15,30,30,30,30,30,31,30,30,38,22,36,30, # 5480 -+ 30,5500,40,5502,42,30,10,5506,14,15,12,24,30,36,30,15,10,15,10,5518, # 5500 -+ 30,5520,10,15,10,15,30,5526,10,15,30,5530,30,15,10,15,31,48,10,28, # 5520 -+ 10,15,9,25,9,15,10,15,12,30,30,15,15,15,11,30,10,5556,10,30, # 5540 -+ 10,66,12,5562,9,30,16,30,18,5568,10,30,22,5572,24,24,26,30,28,30, # 5560 -+ 30,5580,30,15,15,30,30,36,12,30,30,5590,30,15,13,15,30,30,30,30, # 5580 -+ 15,30,30,15,11,15,10,30,30,70,30,30,30,30,10,30,30,40,12,30, # 5600 -+ 30,30,30,5622,12,30,11,30,30,30,30,30,30,42,22,15,24,15,30,5638, # 5620 -+ 28,5640,30,30,30,30,30,5646,30,30,30,5650,30,5652,30,30,30,5656,30,5658, # 5640 -+ 30,30,30,30,30,15,10,30,10,5668,30,52,30,15,30,30,30,30,30,15, # 5660 -+ 30,30,30,5682,30,30,30,46,30,5688,30,30,30,5692,30,15,63,30,30,40, # 5680 -+ 30,5700,10,15,11,30,30,30,30,18,11,5710,30,28,30,15,30,5716,30,30, # 5700 -+ 30,15,30,58,30,24,10,15,31,30,10,30,30,15,11,15,30,5736,30,30, # 5720 -+ 11,5740,30,5742,15,15,10,30,30,5748,30,70,11,30,11,15,14,15,11,30, # 5740 -+ 30,30,30,15,11,15,11,72,30,15,11,28,11,22,30,15,16,52,30,5778, # 5760 -+ 30,15,11,5782,30,15,10,15,10,15,30,5790,31,15,10,15,11,15,10,15, # 5780 -+ 11,5800,11,15,9,15,11,5806,15,39,10,15,11,5812,12,15,10,15,10,15, # 5800 -+ 10,5820,13,15,63,24,10,5826,11,15,10,16,10,18,10,15,10,15,13,5838, # 5820 -+ 15,15,10,5842,10,15,10,15,11,5848,10,5850,10,15,12,15,15,5856,10,15, # 5840 -+ 10,5860,10,27,11,15,10,5866,10,5868,11,15,15,15,13,46,11,15,10,5878, # 5860 -+ 10,5880,10,15,10,15,12,15,22,21,13,42,13,70,11,15,13,5896,13,16, # 5880 -+ 13,15,13,5902,15,16,13,18,12,18,13,22,13,72,13,15,13,60,13,15, # 5900 -+ 15,30,30,5922,13,15,13,5926,13,48,13,30,13,30,13,15,15,30,16,5938, # 5920 -+ 18,15,10,30,22,16,24,18,26,30,28,30,30,5952,30,15,12,30,30,58, # 5940 -+ 13,30,30,66,30,15,13,15,30,46,45,30,11,42,30,24,13,42,11,36, # 5960 -+ 30,5980,30,30,30,30,16,5986,30,52,13,30,30,30,30,30,26,30,28,30, # 5980 -+ 30,31,30,30,30,30,36,6006,24,15,40,6010,42,30,30,30,46,30,30,30, # 6000 -+ 30,30,30,30,30,30,30,30,30,6028,30,45,30,30,30,30,30,6036,13,30, # 6020 -+ 13,30,30,6042,30,15,30,6046,30,30,30,15,30,6052,30,30,30,30,30,72, # 6040 -+ 30,30,30,30,30,30,30,6066,12,30,30,30,30,6072,12,24,12,58,30,6078, # 6060 -+ 46,30,10,30,30,15,30,24,30,6088,30,6090,30,15,30,15,30,15,13,15, # 6080 -+ 30,6100,30,30,30,15,12,30,30,40,30,30,31,6112,30,30,11,30,10,30, # 6100 -+ 30,6120,30,30,16,48,18,15,15,45,22,6130,30,6132,30,30,28,30,30,30, # 6120 -+ 30,15,12,6142,30,30,30,30,30,30,30,6150,30,15,30,30,30,46,11,30, # 6140 -+ 30,60,30,6162,30,30,30,15,30,30,30,30,11,6172,30,30,31,45,30,36, # 6160 -+ 30,30,12,30,11,30,30,30,30,30,30,40,22,15,24,15,30,6196,28,6198, # 6180 -+ 30,30,30,6202,30,30,30,30,63,30,30,6210,30,30,30,30,30,6216,30,30, # 6200 -+ 30,6220,30,48,47,30,11,44,30,6228,30,15,30,38,30,36,30,15,30,30, # 6220 -+ 30,6240,30,30,30,30,30,6246,30,30,30,30,30,36,30,31,30,6256,30,30, # 6240 -+ 36,15,15,6262,44,30,42,30,15,6268,46,6270,48,30,30,30,30,6276,30,16, # 6260 -+ 30,15,30,60,15,15,30,6286,30,30,30,26,15,15,30,30,30,30,30,6298, # 6280 -+ 30,6300,15,15,31,30,30,30,30,15,15,6310,15,58,15,15,15,6316,30,70, # 6300 -+ 30,15,15,6322,15,39,30,16,15,6328,15,30,30,15,15,30,30,6336,30,15, # 6320 -+ 15,16,30,6342,15,15,15,15,30,18,30,15,15,6352,15,18,15,15,15,6358, # 6340 -+ 30,6360,30,15,15,15,30,6366,31,15,15,22,15,6372,15,15,15,15,15,6378, # 6360 -+ 15,15,15,15,15,15,15,15,15,6388,15,70,15,15,15,15,15,6396,15,78, # 6380 -+ 24,36,15,18,11,15,15,42,15,48,15,15,15,52,15,15,15,16,15,48, # 6400 -+ 15,6420,15,22,15,24,15,6426,15,15,15,58,15,15,13,15,15,40,10,46, # 6420 -+ 15,15,15,16,15,15,15,15,15,6448,15,6450,11,26,13,16,15,15,15,15, # 6440 -+ 15,15,15,22,63,15,15,28,15,6468,12,15,15,6472,15,15,15,15,15,15, # 6460 -+ 15,6480,15,15,13,15,13,15,15,15,15,6490,15,42,15,15,31,72,13,66, # 6480 -+ 15,15,12,15,11,15,15,26,15,22,15,16,15,15,13,15,15,18,12,16, # 6500 -+ 11,6520,15,15,15,15,15,60,24,6528,13,15,15,46,11,17,12,15,15,15, # 6520 -+ 15,30,30,15,15,15,15,6546,11,15,14,6550,11,6552,12,15,15,78,16,30, # 6540 -+ 31,6560,15,6562,22,15,24,16,26,6568,28,6570,30,30,30,24,15,6576,30,15, # 6560 -+ 11,6580,30,30,30,15,11,15,30,30,30,30,63,30,30,15,11,15,11,6598, # 6580 -+ 30,15,30,15,11,30,10,6606,30,15,10,30,30,30,30,16,11,30,11,6618, # 6600 -+ 30,15,30,36,30,52,11,15,11,15,30,30,11,15,11,30,11,6636,30,15, # 6620 -+ 15,30,30,15,30,15,11,30,30,60,30,15,11,6652,30,15,15,15,11,6658, # 6640 -+ 11,6660,30,15,11,15,30,58,30,30,12,15,30,6672,12,15,11,30,30,6678, # 6660 -+ 30,15,12,40,12,15,14,15,18,6688,30,6690,30,15,11,15,12,36,30,15, # 6680 -+ 14,6700,12,6702,30,16,11,30,30,6708,30,15,11,48,30,15,11,15,14,6718, # 6700 -+ 30,30,30,80,11,24,12,23,11,15,11,52,51,6732,30,48,15,6736,30,22, # 6720 -+ 30,42,11,40,12,15,11,15,16,16,18,42,31,30,22,28,24,28,26,15, # 6740 -+ 28,6760,30,6762,12,15,10,66,36,17,11,15,40,15,42,24,15,26,46,6778, # 6760 -+ 48,6780,15,15,52,15,15,17,12,15,13,6790,15,6792,15,15,15,15,15,15, # 6780 -+ 15,15,15,6802,15,17,15,15,15,23,15,48,15,15,15,15,15,16,15,15, # 6800 -+ 15,18,15,6822,15,24,15,6826,15,6828,15,15,15,6832,15,15,15,15,15,15, # 6820 -+ 15,6840,15,15,15,15,15,40,63,21,15,15,15,15,15,15,15,6856,15,6858, # 6840 -+ 15,15,15,6862,15,15,15,15,15,6868,15,6870,15,16,15,15,15,15,15,15, # 6860 -+ 31,15,15,6882,15,15,15,70,15,6888,15,15,15,60,15,15,15,15,15,6898, # 6880 -+ 15,66,15,15,15,15,15,6906,15,15,15,6910,26,30,30,15,15,6916,15,30, # 6900 -+ 15,16,15,30,15,30,15,15,15,40,16,30,18,15,15,30,22,24,24,26, # 6920 -+ 26,30,28,52,31,30,30,6946,15,6948,30,15,15,30,30,30,30,15,15,6958, # 6940 -+ 30,6960,30,30,15,30,30,6966,15,16,15,6970,30,18,30,15,63,6976,15,30, # 6960 -+ 30,15,15,6982,30,30,30,15,15,30,15,6990,30,15,30,30,30,6996,15,15, # 6980 -+ 15,7000,30,46,15,15,15,30,15,42,30,15,15,7012,30,15,30,15,15,7018, # 7000 -+ 30,30,30,15,15,24,30,7026,15,15,15,78,15,30,30,15,15,30,30,7038, # 7020 -+ 30,30,15,7042,30,30,15,30,15,52,30,30,30,30,16,30,18,7056,15,30, # 7040 -+ 22,30,30,30,30,30,28,36,30,7068,30,15,16,30,30,30,30,30,30,7078, # 7060 -+ 30,72,30,15,30,30,30,30,15,30,30,15,30,40,30,30,30,46,30,39, # 7080 -+ 30,30,15,7102,30,30,30,30,30,7108,30,30,30,30,15,30,30,30,30,30, # 7100 -+ 30,7120,22,16,30,15,30,7126,28,7128,30,30,30,30,30,30,31,30,30,58, # 7120 -+ 30,36,30,30,30,30,30,30,30,30,30,7150,30,22,13,30,15,30,30,7158, # 7140 -+ 30,16,30,30,30,30,30,15,30,66,30,70,30,30,30,30,30,7176,30,30, # 7160 -+ 30,42,30,15,15,30,30,7186,30,30,13,15,13,7192,30,30,30,30,15,30, # 7180 -+ 30,18,30,30,30,30,30,7206,30,80,30,7210,30,7212,15,15,30,30,30,7218, # 7200 -+ 30,15,10,30,30,30,30,30,30,7228,30,30,63,30,30,30,30,7236,30,30, # 7220 -+ 16,30,18,7242,14,30,22,7246,30,30,30,30,28,7252,30,30,30,15,13,30, # 7240 -+ 30,52,30,30,31,30,30,42,30,15,30,30,30,30,13,30,30,18,30,30, # 7260 -+ 30,30,30,7282,30,15,11,30,12,36,30,30,30,30,30,30,30,7296,30,30, # 7280 -+ 15,48,30,66,30,30,30,7306,15,7308,30,16,30,70,13,15,13,30,15,30, # 7300 -+ 30,7320,30,30,30,24,30,16,31,30,30,7330,30,7332,15,15,30,15,15,40, # 7320 -+ 15,30,15,30,30,15,15,15,30,7348,30,7350,15,15,30,30,15,15,15,30, # 7340 -+ 30,30,30,36,15,30,15,52,15,7368,15,30,30,72,30,58,15,15,15,46, # 7360 -+ 30,60,15,30,15,30,30,82,15,30,30,30,30,7392,15,15,30,16,15,48, # 7380 -+ 24,15,30,30,30,15,15,15,15,30,30,7410,15,15,30,30,30,7416,15,30, # 7400 -+ 30,40,30,15,28,30,16,30,18,16,15,30,22,7432,30,20,26,30,28,42, # 7420 -+ 30,30,30,18,15,30,30,22,15,30,30,7450,30,28,15,15,31,7456,30,7458, # 7440 -+ 15,30,30,16,15,15,15,30,30,15,30,30,30,30,15,30,30,7476,15,30, # 7460 -+ 30,7480,30,30,15,30,15,7486,30,7488,30,30,30,58,57,15,24,54,30,7498, # 7480 -+ 28,30,30,48,30,46,30,7506,30,30,30,30,30,30,30,36,30,7516,30,72, # 7500 -+ 30,30,30,7522,30,31,15,30,15,7528,36,16,30,30,40,30,42,7536,30,30, # 7520 -+ 46,7540,48,30,30,30,52,7546,30,7548,30,30,58,30,30,30,22,30,30,7558, # 7540 -+ 30,7560,28,30,30,30,30,30,30,30,30,66,30,7572,30,30,30,7576,30,30, # 7560 -+ 30,30,30,7582,30,30,30,26,30,7588,30,7590,30,15,30,16,30,70,30,30, # 7580 -+ 30,30,30,7602,30,30,30,7606,30,30,30,30,30,30,30,39,58,30,13,30, # 7600 -+ 30,7620,30,30,15,60,15,30,30,30,30,30,30,30,30,15,30,30,30,7638, # 7620 -+ 30,30,30,7642,30,15,30,15,31,7648,30,30,30,30,30,15,15,15,30,30, # 7640 -+ 30,46,30,78,30,30,15,30,30,7668,30,30,30,7672,14,30,15,15,15,30, # 7660 -+ 15,7680,30,30,30,15,15,7686,15,15,30,7690,15,48,30,30,30,42,30,7698, # 7680 -+ 30,30,30,7702,30,15,30,15,15,15,30,17,31,30,30,15,15,7716,15,15, # 7700 -+ 14,15,14,7722,30,30,30,7726,15,58,30,30,30,15,15,30,15,15,14,70, # 7720 -+ 13,7740,15,30,63,30,15,60,59,15,15,56,15,7752,14,15,30,7756,17,7758, # 7740 -+ 30,15,30,16,16,17,30,15,28,38,22,36,30,15,30,24,31,30,30,31, # 7760 -+ 14,30,30,42,36,15,14,30,40,7788,42,30,15,7792,46,15,48,30,16,30, # 7780 -+ 56,28,15,30,22,15,58,36,60,30,28,72,30,30,30,15,15,7816,30,16, # 7800 -+ 15,30,30,7822,30,24,14,15,30,7828,30,40,15,30,30,16,15,16,13,30, # 7820 -+ 30,7840,30,15,14,30,15,30,30,46,15,30,30,7852,30,15,15,80,13,30, # 7840 -+ 30,23,30,30,30,15,15,7866,15,15,30,30,15,7872,13,30,15,7876,30,7878, # 7860 -+ 15,30,30,7882,30,15,15,30,30,30,30,15,15,15,30,15,15,52,15,30, # 7880 -+ 15,7900,30,15,18,15,30,7906,30,30,15,26,30,40,15,16,15,30,30,7918, # 7900 -+ 30,7920,15,30,15,24,15,7926,15,30,30,30,30,7932,15,15,30,7936,30,16, # 7920 -+ 15,30,30,46,30,15,30,30,30,7948,30,7950,30,16,30,18,15,72,30,22, # 7940 -+ 30,30,30,7962,30,28,30,30,31,30,15,15,30,30,30,15,30,30,30,78, # 7960 -+ 30,22,15,30,30,30,30,48,30,30,22,60,30,7992,30,30,28,30,30,30, # 7980 -+ 63,30,30,52,30,15,30,30,30,8008,30,8010,30,18,30,30,30,8016,30,30, # 8000 -+ 30,15,30,70,30,30,30,22,30,15,30,30,31,30,30,15,30,30,30,8038, # 8020 -+ 30,15,30,30,30,30,30,15,30,30,30,82,15,8052,30,15,30,30,15,8058, # 8040 -+ 15,30,30,30,30,15,15,30,30,8068,30,15,30,30,30,30,30,40,30,15, # 8060 -+ 30,8080,15,58,30,30,30,8086,30,8088,15,15,30,8092,30,30,31,18,30,30, # 8080 -+ 15,8100,30,30,30,30,30,66,15,30,15,8110,15,25,15,30,30,8116,30,22, # 8100 -+ 15,15,15,8122,30,15,15,30,63,62,30,46,59,30,30,30,30,78,53,15, # 8120 -+ 51,17,15,16,30,27,30,8146,30,28,41,22,39,30,30,26,30,28,33,40, # 8140 -+ 31,8160,29,30,30,36,30,8166,23,40,21,8170,18,15,17,46,22,48,30,8178, # 8160 -+ 26,80,28,48,30,30,30,58,26,60,30,8190,8191,30,30,30,30,15,15,24, # 8180 -+ 30,58,30,30,15,30,30,28,30,8208,30,30,30,42,30,22,15,30,30,8218, # 8200 -+ 30,8220,15,30,31,30,30,18,15,30,15,8230,30,8232,30,30,30,8236,15,57, # 8220 -+ 15,15,30,8242,15,15,15,30,15,72,30,36,15,30,30,15,62,22,15,30, # 8240 -+ 30,30,30,8262,15,15,30,18,15,8268,15,30,15,8272,30,24,15,15,30,30, # 8260 -+ 30,48,14,15,30,30,15,8286,15,30,30,8290,30,8292,15,30,15,8296,15,42, # 8280 -+ 15,30,30,30,30,16,15,15,15,15,30,8310,15,30,15,30,30,8316,15,30, # 8300 -+ 30,52,30,15,15,17,30,25,15,8328,15,15,30,30,30,15,15,15,14,30, # 8320 -+ 30,18,15,80,30,30,30,16,15,30,30,30,30,8352,14,30,16,60,18,15, # 8340 -+ 14,57,22,8362,30,30,26,30,28,8368,30,30,30,30,15,66,30,8376,30,30, # 8360 -+ 30,30,30,82,63,30,30,8386,30,8388,15,30,30,22,30,16,30,30,30,36, # 8380 -+ 30,30,30,30,30,30,30,30,15,30,30,30,30,46,15,30,31,30,30,8418, # 8400 -+ 30,30,30,8422,22,24,24,15,30,8428,28,8430,30,30,30,30,30,30,30,30, # 8420 -+ 30,30,30,8442,30,30,30,8446,30,30,30,30,30,78,30,15,15,30,15,30, # 8440 -+ 30,8460,30,30,30,30,30,8466,30,16,30,42,30,36,30,30,30,48,30,60, # 8460 -+ 30,30,30,30,30,15,22,30,30,30,30,30,28,15,29,30,30,30,30,30, # 8480 -+ 29,8500,30,15,30,30,30,46,30,66,65,16,30,8512,30,15,29,15,30,56, # 8500 -+ 30,8520,30,15,29,15,30,8526,30,30,30,44,30,42,29,30,30,8536,30,8538, # 8520 -+ 30,31,29,8542,29,30,36,30,15,82,40,30,42,15,15,20,46,42,48,30, # 8540 -+ 29,30,52,8562,30,30,30,30,58,30,60,30,30,8572,30,24,66,30,30,28, # 8560 -+ 30,8580,30,15,29,22,15,30,30,18,30,70,30,30,30,30,30,8596,30,8598, # 8580 -+ 30,15,30,30,16,30,18,15,31,8608,22,78,30,30,29,30,28,30,30,30, # 8600 -+ 30,36,15,8622,30,16,30,8626,30,8628,30,15,29,88,30,30,30,30,15,52, # 8620 -+ 30,8640,30,16,30,30,30,8646,30,15,15,40,30,30,30,16,29,30,30,30, # 8640 -+ 30,15,29,8662,30,30,30,80,30,8668,30,30,31,15,15,24,30,8676,15,15, # 8660 -+ 15,8680,15,30,30,15,15,30,30,8688,30,15,15,8692,30,30,30,15,15,8698, # 8680 -+ 30,18,15,16,16,30,15,8706,30,15,15,30,30,8712,30,30,15,30,30,8718, # 8700 -+ 15,30,15,30,30,30,30,30,16,30,18,8730,15,30,22,30,30,8736,30,30, # 8720 -+ 28,8740,30,30,30,15,15,8746,30,30,30,30,30,8752,30,30,30,15,30,30, # 8740 -+ 30,8760,15,30,30,15,30,30,63,30,30,48,30,30,30,30,15,66,30,8778, # 8760 -+ 30,30,30,8782,30,30,30,30,15,30,30,58,30,30,30,30,22,30,30,30, # 8780 -+ 31,30,28,8802,30,30,30,8806,30,30,30,30,30,30,30,30,30,30,30,8818, # 8800 -+ 30,8820,30,30,30,30,30,30,30,80,30,8830,30,72,30,15,30,8836,30,8838, # 8820 -+ 30,15,30,36,30,30,30,30,30,8848,30,52,30,30,30,30,30,16,30,30, # 8840 -+ 30,8860,30,8862,31,15,15,8866,30,48,30,30,15,30,30,70,30,30,30,30, # 8860 -+ 30,82,30,15,30,28,30,8886,15,15,30,30,30,8892,30,16,63,15,30,30, # 8880 -+ 30,30,30,30,30,30,15,30,30,58,30,30,30,30,15,30,15,36,15,30, # 8900 -+ 15,30,30,8922,30,15,15,78,15,8928,30,30,15,8932,30,30,30,30,30,30, # 8920 -+ 30,8940,30,30,30,40,30,22,15,30,30,8950,30,30,30,15,15,52,15,30, # 8940 -+ 30,30,30,8962,30,30,30,30,30,8968,30,8970,30,18,30,30,16,46,18,15, # 8960 -+ 30,30,30,30,30,30,26,30,30,88,30,36,31,30,15,30,30,15,30,8998, # 8980 -+ 30,9000,30,15,15,30,30,9006,30,30,15,9010,30,9012,30,16,30,70,69,30, # 9000 -+ 30,66,15,30,30,30,30,60,15,9028,30,30,30,15,16,30,30,30,30,48, # 9020 -+ 30,9040,30,9042,30,15,28,82,30,9048,30,15,15,34,36,30,31,30,40,9058, # 9040 -+ 42,16,30,24,46,30,48,9066,30,18,52,46,30,42,15,15,58,30,60,30, # 9060 -+ 30,63,15,30,66,30,30,30,70,60,30,9090,15,30,15,30,30,30,30,30, # 9080 -+ 16,30,18,9102,15,30,22,30,30,9108,30,30,28,30,30,30,30,15,15,30, # 9100 -+ 30,30,30,30,30,72,30,9126,30,16,30,30,30,9132,15,30,30,9136,30,30, # 9120 -+ 30,30,30,40,30,15,15,30,15,30,30,9150,63,80,30,30,30,9156,30,30, # 9140 -+ 15,9160,30,16,30,30,30,88,15,52,30,30,30,9172,15,24,15,30,15,66, # 9160 -+ 30,9180,30,30,30,30,30,9186,30,30,30,30,30,28,15,15,30,30,30,9198, # 9180 -+ 30,30,30,9202,30,30,15,15,30,9208,30,60,15,15,30,30,30,30,15,30, # 9200 -+ 30,9220,30,22,15,30,15,9226,30,18,30,30,30,30,30,15,30,15,15,9238, # 9220 -+ 30,9240,30,30,15,30,30,16,31,30,30,30,30,18,15,15,30,9256,15,46, # 9240 -+ 15,26,30,58,30,16,15,15,15,15,15,72,71,15,30,68,30,9276,15,30, # 9260 -+ 63,9280,30,9282,15,30,15,36,16,15,18,30,15,9292,30,48,24,15,26,16, # 9280 -+ 28,70,30,31,15,17,30,40,36,30,30,9310,40,66,42,30,30,26,46,9318, # 9300 -+ 48,30,30,9322,52,24,30,15,15,30,58,17,60,30,30,63,68,9336,66,30, # 9320 -+ 30,9340,70,9342,72,30,30,15,15,9348,15,40,30,46,30,15,16,15,15,48, # 9340 -+ 30,15,15,15,30,15,30,16,15,26,15,9370,30,15,15,15,31,9376,15,82, # 9360 -+ 15,15,15,17,15,15,15,15,15,40,15,9390,15,15,15,15,15,9396,15,15, # 9380 -+ 15,15,15,9402,15,15,15,22,15,9408,15,15,15,9412,15,15,15,15,15,9418, # 9400 -+ 15,9420,15,26,15,15,15,15,15,15,15,9430,15,9432,15,15,15,9436,15,9438, # 9420 -+ 15,15,15,15,15,15,15,15,15,15,15,15,15,29,15,16,15,48,15,15, # 9440 -+ 15,9460,15,9462,15,15,15,9466,15,16,15,15,36,9472,15,24,15,18,15,9478, # 9460 -+ 15,18,15,15,15,23,15,52,15,16,15,9490,15,15,15,22,15,9496,15,26, # 9480 -+ 15,28,15,30,31,18,15,15,15,36,15,9510,15,17,15,15,15,30,30,15, # 9500 -+ 15,9520,15,88,15,15,15,30,15,30,15,26,15,9532,16,30,63,15,15,9538, # 9520 -+ 22,15,24,15,26,30,28,9546,30,30,30,9550,15,40,30,15,15,30,30,78, # 9540 -+ 30,15,15,72,30,30,30,30,31,30,30,17,15,15,15,30,30,60,30,15, # 9560 -+ 15,30,15,30,30,15,15,9586,30,42,30,15,15,52,15,30,30,15,30,30, # 9580 -+ 30,9600,15,15,15,15,30,30,15,15,15,30,15,9612,30,15,15,58,30,9618, # 9600 -+ 30,15,15,9622,30,30,30,15,15,9628,30,9630,31,15,15,30,15,30,30,15, # 9620 -+ 15,30,30,9642,30,30,15,30,30,9648,15,30,15,48,30,30,30,30,16,30, # 9640 -+ 18,9660,15,30,63,30,30,30,30,30,28,30,30,30,30,15,15,9676,30,9678, # 9660 -+ 30,30,30,30,30,30,30,15,30,9688,30,30,15,30,30,17,30,9696,30,30, # 9680 -+ 30,88,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,15,9718, # 9700 -+ 30,9720,30,30,30,30,22,70,30,30,30,36,28,9732,30,30,30,30,30,9738, # 9720 -+ 30,30,30,9742,30,30,30,30,30,9748,30,48,30,30,30,30,30,30,30,30, # 9740 -+ 30,42,30,30,30,16,30,9766,30,9768,30,16,30,30,30,30,30,30,30,30, # 9760 -+ 30,9780,30,30,30,30,30,9786,30,30,30,9790,30,30,30,16,15,96,30,40, # 9780 -+ 30,80,15,9802,30,15,30,30,30,30,30,9810,30,15,30,15,30,9816,15,15, # 9800 -+ 30,30,30,30,31,16,15,30,30,9828,30,30,30,9832,30,30,15,30,30,9838, # 9820 -+ 30,30,30,30,16,30,18,42,15,30,22,9850,30,58,30,30,28,9856,30,9858, # 9840 -+ 30,30,15,30,30,30,30,30,30,70,30,9870,30,30,30,78,30,30,17,30, # 9860 -+ 30,40,30,9882,30,30,30,9886,30,15,15,30,30,30,30,30,30,30,30,30, # 9880 -+ 30,9900,30,30,30,30,30,9906,30,30,30,30,30,30,30,30,30,46,30,15, # 9900 -+ 16,30,30,9922,30,24,30,30,30,9928,30,9930,30,30,30,30,30,39,15,15, # 9920 -+ 30,9940,30,60,30,30,30,30,30,9948,17,15,31,36,30,30,15,16,30,46, # 9940 -+ 30,30,15,40,30,30,30,9966,15,30,15,58,30,9972,30,30,30,30,30,30, # 9960 -+ 30,15,15,66,30,30,30,30,15,30,30,96,30,30,30,30,30,18,15,15 # 9980 -+) -+ -+ -+def lower_bound(order: int) -> int: -+ r""" -+ Return the best known lower bound on the number of MOLS of -+ the given ``order``. -+ -+ The source of this information is Table 3.87 in the Handbook of -+ Combinatorial Designs, 2nd edition, by Colbourn and Dinitz. A few -+ updates have subsequently been provided on Jeff Dinitz's website. -+ -+ Parameters -+ ---------- -+ -+ order : int -+ The order (also known as the side) for which you'd like a lower -+ bound on the number of MOLS instances. In the language of the -+ Handbook, this is ``n``, and it should be between 0 and 9999. -+ -+ Returns -+ ------- -+ -+ int -+ A lower bound on the number of MOLS. -+ -+ Raises -+ ------ -+ -+ IndexError -+ If you ask for an order that isn't contained in the table. -+ -+ Examples -+ -------- -+ -+ There are no MOLS of order zero:: -+ -+ sage: from sage.combinat.designs import MOLS_handbook_data -+ sage: MOLS_handbook_data.lower_bound(0) -+ 0 -+ -+ """ -+ return _LOWER_BOUNDS[order] -diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py -index 69b19540c22..27452495862 100644 ---- a/src/sage/combinat/designs/latin_squares.py -+++ b/src/sage/combinat/designs/latin_squares.py -@@ -75,7 +75,7 @@ - 0| + + - 20| - 40| -- 60| + -+ 60| - 80| - 100| - 120| -@@ -126,7 +126,6 @@ - from sage.rings.integer import Integer - from sage.categories.sets_cat import EmptySetError - from sage.misc.unknown import Unknown --from sage.env import COMBINATORIAL_DESIGN_DATA_DIR - - - def are_mutually_orthogonal_latin_squares(l, verbose=False): -@@ -500,13 +499,13 @@ def MOLS_table(start,stop=None,compare=False,width=None): - 0| + + - 20| - 40| -- 60| + -+ 60| - 80| - sage: MOLS_table(50, 100, compare=True) - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - ________________________________________________________________________________ - 40| -- 60| + -+ 60| - 80| - """ - from .orthogonal_arrays import largest_available_k -@@ -520,11 +519,6 @@ def MOLS_table(start,stop=None,compare=False,width=None): - if stop <= start: - return - -- if compare: -- handbook_file = open("{}/MOLS_table.txt".format(COMBINATORIAL_DESIGN_DATA_DIR), 'r') -- hb = [int(_) for _ in handbook_file.readlines()[9].split(',')] -- handbook_file.close() -- - # choose an appropriate width (needs to be >= 3 because "+oo" should fit) - if width is None: - width = max(3, Integer(stop-1).ndigits(10)) -@@ -537,9 +531,11 @@ def MOLS_table(start,stop=None,compare=False,width=None): - print("\n{:>{width}}|".format(i, width=width), end="") - k = largest_available_k(i)-2 - if compare: -- if i < 2 or hb[i] == k: -+ from . import MOLS_handbook_data -+ lower_bound = MOLS_handbook_data.lower_bound(i) -+ if i < 2 or lower_bound == k: - c = "" -- elif hb[i] < k: -+ elif lower_bound < k: - c = "+" - else: - c = "-" -diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py -index aaab1397f0a..5f996662964 100644 ---- a/src/sage/databases/jones.py -+++ b/src/sage/databases/jones.py -@@ -79,8 +79,6 @@ - - from sage.features.databases import DatabaseJones - --JONESDATA = os.path.join(SAGE_SHARE, 'jones') # should match the filename set in DatabaseJones -- - - def sortkey(K): - """ -@@ -160,8 +158,10 @@ def _init(self, path): - for Y in os.listdir(Z): - if Y[-3:] == ".gp": - self._load(Z, Y) -- os.makedirs(JONESDATA, exist_ok=True) -- save(self.root, JONESDATA + "/jones.sobj") -+ -+ data_dir = os.path.dirname(DatabaseJones().absolute_filename()) -+ os.makedirs(data_dir, exist_ok=True) -+ save(self.root, os.path.join(data_dir, "jones.sobj")) - - def unramified_outside(self, S, d=None, var='a'): - """ -diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py -index 469fe454afb..7e027673cc0 100644 ---- a/src/sage/databases/sql_db.py -+++ b/src/sage/databases/sql_db.py -@@ -250,7 +250,6 @@ def construct_skeleton(database): - skeleton = {} - cur = database.__connection__.cursor() - exe = cur.execute("SELECT name FROM sqlite_master WHERE TYPE='table'") -- from sage.env import GRAPHS_DATA_DIR - for table in exe.fetchall(): - skeleton[table[0]] = {} - exe1 = cur.execute("PRAGMA table_info(%s)" % table[0]) -@@ -264,8 +263,7 @@ def construct_skeleton(database): - exe2 = cur.execute("PRAGMA index_list(%s)" % table[0]) - for col in exe2.fetchall(): - if col[1].find('sqlite') == -1: -- if database.__dblocation__ == \ -- os.path.join(GRAPHS_DATA_DIR,'graphs.db'): -+ if os.path.basename(database.__dblocation__) == 'graphs.db': - name = col[1] - else: - name = col[1][len(table[0])+3:] -diff --git a/src/sage/env.py b/src/sage/env.py -index 39d09528788..cadcb820c5a 100644 ---- a/src/sage/env.py -+++ b/src/sage/env.py -@@ -195,18 +195,26 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st - SAGE_ARCHFLAGS = var("SAGE_ARCHFLAGS", "unset") - SAGE_PKG_CONFIG_PATH = var("SAGE_PKG_CONFIG_PATH") - -+# colon-separated search path for databases. -+SAGE_DATA_PATH = var("SAGE_DATA_PATH", -+ os.pathsep.join(filter(None, [ -+ join(DOT_SAGE, "db"), -+ join(SAGE_SHARE, "sagemath"), -+ SAGE_SHARE, -+ ]))) -+ -+# database directories, the default is to search in SAGE_DATA_PATH -+CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR") -+CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR") -+ELLCURVE_DATA_DIR = var("ELLCURVE_DATA_DIR") -+GRAPHS_DATA_DIR = var("GRAPHS_DATA_DIR") -+POLYTOPE_DATA_DIR = var("POLYTOPE_DATA_DIR") -+ - # installation directories for various packages --GRAPHS_DATA_DIR = var("GRAPHS_DATA_DIR", join(SAGE_SHARE, "graphs")) --ELLCURVE_DATA_DIR = var("ELLCURVE_DATA_DIR", join(SAGE_SHARE, "ellcurves")) --POLYTOPE_DATA_DIR = var("POLYTOPE_DATA_DIR", join(SAGE_SHARE, "reflexive_polytopes")) -- --COMBINATORIAL_DESIGN_DATA_DIR = var("COMBINATORIAL_DESIGN_DATA_DIR", join(SAGE_SHARE, "combinatorial_designs")) --CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR", join(SAGE_SHARE, "cremona")) --CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR", join(SAGE_SHARE, "cremona")) --JMOL_DIR = var("JMOL_DIR", join(SAGE_SHARE, "jmol")) -+JMOL_DIR = var("JMOL_DIR") - MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax")) - MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe")) --THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage")) -+THREEJS_DIR = var("THREEJS_DIR") - PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy")) - MAXIMA = var("MAXIMA", "maxima") - MAXIMA_FAS = var("MAXIMA_FAS") -@@ -313,6 +321,7 @@ def sage_include_directories(use_sources=False): - - return dirs - -+ - def get_cblas_pc_module_name() -> str: - """ - Return the name of the BLAS libraries to be used. -@@ -420,7 +429,7 @@ def cython_aliases(required_modules=None, - aliases["ECL_INCDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-I'), ecl_cflags))) - aliases["ECL_LIBDIR"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-L'), ecl_libs))) - aliases["ECL_LIBRARIES"] = list(map(lambda s: s[2:], filter(lambda s: s.startswith('-l'), ecl_libs))) -- aliases["ECL_LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l','-L')), ecl_libs)) -+ aliases["ECL_LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l', '-L')), ecl_libs)) - continue - else: - try: -@@ -439,7 +448,7 @@ def cython_aliases(required_modules=None, - # include search order matters. - aliases[var + "INCDIR"] = pc['include_dirs'] - aliases[var + "LIBDIR"] = pc['library_dirs'] -- aliases[var + "LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l','-L')), libs.split())) -+ aliases[var + "LIBEXTRA"] = list(filter(lambda s: not s.startswith(('-l', '-L')), libs.split())) - aliases[var + "LIBRARIES"] = pc['libraries'] - - # uname-specific flags -diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py -index d5669c3c9ff..ea8fd6bdb05 100644 ---- a/src/sage/features/__init__.py -+++ b/src/sage/features/__init__.py -@@ -416,6 +416,7 @@ def unhide(self): - """ - self._hidden = False - -+ - class FeatureNotPresentError(RuntimeError): - r""" - A missing feature error. -@@ -791,7 +792,9 @@ class StaticFile(FileFeature): - EXAMPLES:: - - sage: from sage.features import StaticFile -- sage: StaticFile(name="no_such_file", filename="KaT1aihu", search_path=("/",), spkg="some_spkg", url="http://rand.om").require() # optional - sage_spkg -+ sage: StaticFile(name="no_such_file", filename="KaT1aihu", # optional - sage_spkg -+ ....: search_path="/", spkg="some_spkg", -+ ....: url="http://rand.om").require() - Traceback (most recent call last): - ... - FeatureNotPresentError: no_such_file is not available. -@@ -799,18 +802,27 @@ class StaticFile(FileFeature): - To install no_such_file...you can try to run...sage -i some_spkg... - Further installation instructions might be available at http://rand.om. - """ -- def __init__(self, name, filename, search_path=None, **kwds): -+ def __init__(self, name, filename, *, search_path=None, **kwds): - r""" - TESTS:: - - sage: from sage.features import StaticFile -- sage: StaticFile(name="null", filename="null", search_path=("/dev",)) -+ sage: StaticFile(name="null", filename="null", search_path="/dev") - Feature('null') -+ sage: sh = StaticFile(name="shell", filename="sh", -+ ....: search_path=("/dev", "/bin", "/usr")) -+ sage: sh -+ Feature('shell') -+ sage: sh.absolute_filename() -+ '/bin/sh' -+ - """ - Feature.__init__(self, name, **kwds) - self.filename = filename - if search_path is None: - self.search_path = [SAGE_SHARE] -+ elif isinstance(search_path, str): -+ self.search_path = [search_path] - else: - self.search_path = list(search_path) - -diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py -index bca8c094b30..1410dc1167d 100644 ---- a/src/sage/features/databases.py -+++ b/src/sage/features/databases.py -@@ -16,14 +16,27 @@ - # https://www.gnu.org/licenses/ - # ***************************************************************************** - -+import os - - from . import StaticFile, PythonModule --from sage.env import ( -- CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR, -- POLYTOPE_DATA_DIR) -+from sage.env import SAGE_DATA_PATH - - --CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR]) -+def sage_data_path(data_name): -+ r""" -+ Search path for database `data_name`. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.databases import sage_data_path -+ sage: sage_data_path("cremona") -+ ['.../cremona'] -+ """ -+ if not SAGE_DATA_PATH: -+ return [] -+ -+ return [os.path.join(p, data_name) -+ for p in SAGE_DATA_PATH.split(os.pathsep)] - - - class DatabaseCremona(StaticFile): -@@ -44,7 +57,7 @@ class DatabaseCremona(StaticFile): - sage: DatabaseCremona().is_present() # optional - database_cremona_ellcurve - FeatureTestResult('database_cremona_ellcurve', True) - """ -- def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): -+ def __init__(self, name="cremona"): - r""" - TESTS:: - -@@ -52,14 +65,86 @@ def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): - sage: isinstance(DatabaseCremona(), DatabaseCremona) - True - """ -+ from sage.env import CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR -+ CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR]) -+ CREMONA_DATA_DIRS.discard(None) -+ search_path = CREMONA_DATA_DIRS or sage_data_path("cremona") -+ -+ spkg = "database_cremona_ellcurve" -+ spkg_type = "optional" -+ if name == 'cremona_mini': -+ spkg = "elliptic_curves" -+ spkg_type = "standard" -+ - StaticFile.__init__(self, f"database_{name}_ellcurve", -- filename='{}.db'.format(name.replace(' ', '_')), -- search_path=CREMONA_DATA_DIRS, -+ filename=f"{name}.db", -+ search_path=search_path, - spkg=spkg, -+ type=spkg_type, - url="https://github.com/JohnCremona/ecdata", - description="Cremona's database of elliptic curves") - - -+class DatabaseEllcurves(StaticFile): -+ r""" -+ A :class:`~sage.features.Feature` which describes the presence of -+ William Stein's database of interesting curves. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.databases import DatabaseEllcurves -+ sage: bool(DatabaseEllcurves().is_present()) # optional - database_ellcurves -+ True -+ """ -+ def __init__(self): -+ r""" -+ TESTS:: -+ -+ sage: from sage.features.databases import DatabaseEllcurves -+ sage: isinstance(DatabaseEllcurves(), DatabaseEllcurves) -+ True -+ """ -+ from sage.env import ELLCURVE_DATA_DIR -+ search_path = ELLCURVE_DATA_DIR or sage_data_path("ellcurves") -+ -+ StaticFile.__init__(self, "database_ellcurves", -+ filename='rank0', -+ search_path=search_path, -+ spkg="elliptic_curves", -+ type="standard", -+ description="William Stein's database of interesting curve") -+ -+ -+class DatabaseGraphs(StaticFile): -+ r""" -+ A :class:`~sage.features.Feature` which describes the presence of -+ the graphs database. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.databases import DatabaseGraphs -+ sage: bool(DatabaseGraphs().is_present()) # optional - database_graphs -+ True -+ """ -+ def __init__(self): -+ r""" -+ TESTS:: -+ -+ sage: from sage.features.databases import DatabaseGraphs -+ sage: isinstance(DatabaseGraphs(), DatabaseGraphs) -+ True -+ """ -+ from sage.env import GRAPHS_DATA_DIR -+ search_path = GRAPHS_DATA_DIR or sage_data_path("graphs") -+ -+ StaticFile.__init__(self, "database_graphs", -+ filename='graphs.db', -+ search_path=search_path, -+ spkg="graphs", -+ type="standard", -+ description="A database of graphs") -+ -+ - class DatabaseJones(StaticFile): - r""" - A :class:`~sage.features.Feature` which describes the presence of -@@ -80,7 +165,8 @@ def __init__(self): - True - """ - StaticFile.__init__(self, "database_jones_numfield", -- filename='jones/jones.sobj', -+ filename='jones.sobj', -+ search_path=sage_data_path("jones"), - spkg="database_jones_numfield", - description="John Jones's tables of number fields") - -@@ -146,27 +232,43 @@ class DatabaseReflexivePolytopes(StaticFile): - EXAMPLES:: - - sage: from sage.features.databases import DatabaseReflexivePolytopes -- sage: bool(DatabaseReflexivePolytopes().is_present()) # optional - polytopes_db -+ sage: bool(DatabaseReflexivePolytopes().is_present()) # optional - polytopes_db - True -- sage: bool(DatabaseReflexivePolytopes('polytopes_db_4d', 'Hodge4d').is_present()) # optional - polytopes_db_4d -+ sage: bool(DatabaseReflexivePolytopes('polytopes_db_4d').is_present()) # optional - polytopes_db_4d - True - """ -- def __init__(self, name='polytopes_db', dirname='Full3D'): -+ def __init__(self, name='polytopes_db'): - """ - TESTS:: - - sage: from sage.features.databases import DatabaseReflexivePolytopes - sage: isinstance(DatabaseReflexivePolytopes(), DatabaseReflexivePolytopes) - True -+ sage: DatabaseReflexivePolytopes().filename -+ 'Full3d' -+ sage: DatabaseReflexivePolytopes('polytopes_db_4d').filename -+ 'Hodge4d' - """ -- StaticFile.__init__(self, name, dirname, -- search_path=[POLYTOPE_DATA_DIR]) -+ from sage.env import POLYTOPE_DATA_DIR -+ search_path = POLYTOPE_DATA_DIR or sage_data_path("reflexive_polytopes") -+ -+ dirname = "Full3d" -+ if name == "polytopes_db_4d": -+ dirname = "Hodge4d" -+ -+ StaticFile.__init__(self, name, -+ filename=dirname, -+ search_path=search_path) - - - def all_features(): -- return [DatabaseCremona(), DatabaseCremona('cremona_mini'), -+ return [PythonModule('conway_polynomials'), -+ DatabaseCremona(), -+ DatabaseCremona('cremona_mini'), -+ DatabaseEllcurves(), -+ DatabaseGraphs(), - DatabaseJones(), - DatabaseKnotInfo(), - DatabaseCubicHecke(), - DatabaseReflexivePolytopes(), -- DatabaseReflexivePolytopes('polytopes_db_4d', 'Hodge4d')] -+ DatabaseReflexivePolytopes('polytopes_db_4d')] -diff --git a/src/sage/features/jmol.py b/src/sage/features/jmol.py -new file mode 100644 -index 00000000000..47ea7426991 ---- /dev/null -+++ b/src/sage/features/jmol.py -@@ -0,0 +1,43 @@ -+import os -+ -+from . import StaticFile -+ -+ -+class JmolDataJar(StaticFile): -+ r""" -+ A :class:`~sage.features.Feature` which describes the presence of -+ JmolData.jar in a few standard locations. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.jmol import JmolDataJar -+ sage: bool(JmolDataJar().is_present()) # needs jmol -+ True -+ """ -+ -+ def __init__(self): -+ r""" -+ TESTS:: -+ -+ sage: from sage.features.jmol import JmolDataJar -+ sage: isinstance(JmolDataJar(), JmolDataJar) -+ True -+ """ -+ from sage.env import SAGE_SHARE, JMOL_DIR -+ -+ jmol_search_path = JMOL_DIR or ( -+ os.path.join(SAGE_SHARE, "sagemath", "jmol"), -+ os.path.join(SAGE_SHARE, "jmol") -+ ) -+ -+ StaticFile.__init__( -+ self, name="jmol", -+ filename="JmolData.jar", -+ search_path=jmol_search_path, -+ spkg="jmol", -+ type="standard", -+ description="Java viewer for chemical structures in 3D") -+ -+ -+def all_features(): -+ return [JmolDataJar()] -diff --git a/src/sage/features/threejs.py b/src/sage/features/threejs.py -new file mode 100644 -index 00000000000..4517523918d ---- /dev/null -+++ b/src/sage/features/threejs.py -@@ -0,0 +1,64 @@ -+import os -+ -+from . import StaticFile -+ -+ -+class Threejs(StaticFile): -+ r""" -+ A :class:`~sage.features.Feature` which describes the presence of -+ threejs-sage in a few standard locations. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.threejs import Threejs -+ sage: bool(Threejs().is_present()) # needs threejs -+ True -+ """ -+ -+ def __init__(self): -+ r""" -+ TESTS:: -+ -+ sage: from sage.features.threejs import Threejs -+ sage: isinstance(Threejs(), Threejs) -+ True -+ """ -+ from sage.env import SAGE_SHARE, THREEJS_DIR -+ -+ version = self.required_version() -+ -+ threejs_search_path = THREEJS_DIR or ( -+ os.path.join(SAGE_SHARE, "jupyter", "nbextensions", "threejs-sage"), -+ os.path.join(SAGE_SHARE, "sagemath", "threejs-sage"), -+ os.path.join(SAGE_SHARE, "sage", "threejs"), -+ os.path.join(SAGE_SHARE, "threejs-sage") -+ ) -+ -+ StaticFile.__init__( -+ self, name="threejs", -+ filename=os.path.join(version, "three.min.js"), -+ spkg="threejs", -+ type="standard", -+ search_path=threejs_search_path, -+ description="JavaScript library to display 3D graphics") -+ -+ def required_version(self): -+ """ -+ Return the version of threejs that Sage requires. -+ -+ EXAMPLES:: -+ -+ sage: from sage.features.threejs import Threejs -+ sage: Threejs().required_version() -+ 'r...' -+ """ -+ from sage.env import SAGE_EXTCODE -+ -+ filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt') -+ -+ with open(filename) as f: -+ return f.read().strip() -+ -+ -+def all_features(): -+ return [Threejs()] -diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py -index 449143c8999..db25b345f4a 100644 ---- a/src/sage/geometry/lattice_polytope.py -+++ b/src/sage/geometry/lattice_polytope.py -@@ -123,7 +123,7 @@ - - from sage.arith.misc import GCD as gcd - from sage.combinat.posets.posets import FinitePoset --from sage.env import POLYTOPE_DATA_DIR -+from sage.features.databases import DatabaseReflexivePolytopes - from sage.geometry.cone import _ambient_space_point, integral_length - from sage.geometry.hasse_diagram import lattice_from_incidences - from sage.geometry.point_collection import (PointCollection, -@@ -451,8 +451,10 @@ def ReflexivePolytopes(dim): - if dim not in [2, 3]: - raise NotImplementedError("only 2- and 3-dimensional reflexive polytopes are available!") - if _rp[dim] is None: -+ db = DatabaseReflexivePolytopes() - rp = read_all_polytopes( -- os.path.join(POLYTOPE_DATA_DIR, "reflexive_polytopes_%dd" % dim)) -+ os.path.join(os.path.dirname(db.absolute_filename()), -+ f'reflexive_polytopes_{dim}d')) - for n, p in enumerate(rp): - # Data files have normal form of reflexive polytopes - p.normal_form.set_cache(p._vertices) -diff --git a/src/sage/geometry/polyhedron/palp_database.py b/src/sage/geometry/polyhedron/palp_database.py -index 29b729cec18..60846d8df23 100644 ---- a/src/sage/geometry/polyhedron/palp_database.py -+++ b/src/sage/geometry/polyhedron/palp_database.py -@@ -36,6 +36,7 @@ - from sage.structure.sage_object import SageObject - from sage.rings.integer_ring import ZZ - from sage.features.palp import PalpExecutable -+from sage.features.databases import DatabaseReflexivePolytopes - - from sage.interfaces.process import terminate - -@@ -108,9 +109,10 @@ def __init__(self, dim, data_basename=None, output='Polyhedron'): - if data_basename is not None: - self._data_basename = data_basename - else: -- from sage.env import POLYTOPE_DATA_DIR -- self._data_basename = os.path.join(POLYTOPE_DATA_DIR, -- 'Full{}d'.format(dim), 'zzdb') -+ db = DatabaseReflexivePolytopes() -+ self._data_basename = os.path.join( -+ os.path.dirname(db.absolute_filename()), -+ f'Full{dim}d', 'zzdb') - info = self._data_basename + '.info' - if not os.path.exists(info): - raise ValueError('Cannot find PALP database: {}'.format(info)) -@@ -431,9 +433,8 @@ def __init__(self, h11, h21, data_basename=None, **kwds): - """ - dim = 4 - if data_basename is None: -- from sage.env import POLYTOPE_DATA_DIR -- data_basename = os.path.join(POLYTOPE_DATA_DIR, -- 'Hodge4d', 'all') -+ db = DatabaseReflexivePolytopes('polytopes_db_4d') -+ data_basename = os.path.join(db.absolute_filename(), 'all') - info = data_basename + '.vinfo' - if not os.path.exists(info): - raise ValueError( -diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py -index 9dec951aa98..653201c3d10 100644 ---- a/src/sage/graphs/graph_database.py -+++ b/src/sage/graphs/graph_database.py -@@ -49,9 +49,9 @@ - import re - from sage.rings.integer import Integer - from sage.databases.sql_db import SQLDatabase, SQLQuery --from sage.env import GRAPHS_DATA_DIR -+from sage.features.databases import DatabaseGraphs - from sage.graphs.graph import Graph --dblocation = os.path.join(GRAPHS_DATA_DIR, 'graphs.db') -+dblocation = DatabaseGraphs().absolute_filename() - - - def degseq_to_data(degree_sequence): -diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py -index 7c2fae74ba7..440135956c3 100644 ---- a/src/sage/graphs/isgci.py -+++ b/src/sage/graphs/isgci.py -@@ -378,7 +378,7 @@ class is defined by the exclusion of subgraphs, one can write a generic - from sage.structure.sage_object import SageObject - from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation - from sage.misc.unknown import Unknown --from sage.env import GRAPHS_DATA_DIR -+from sage.features.databases import DatabaseGraphs - from sage.misc.cachefunc import cached_method - - import os -@@ -796,6 +796,7 @@ def _download_db(self): - sage: graph_classes._download_db() # optional - internet - """ - import tempfile -+ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) - u = urlopen('https://www.graphclasses.org/data.zip', - context=default_context()) - with tempfile.NamedTemporaryFile(suffix=".zip") as f: -@@ -804,29 +805,24 @@ def _download_db(self): - - # Save a systemwide updated copy whenever possible - try: -- z.extract(_XML_FILE, GRAPHS_DATA_DIR) -- z.extract(_SMALLGRAPHS_FILE, GRAPHS_DATA_DIR) -+ z.extract(_XML_FILE, data_dir) -+ z.extract(_SMALLGRAPHS_FILE, data_dir) - except OSError: - pass - -- def _parse_db(self, directory): -+ def _parse_db(self): - r""" - Parse the ISGCI database and stores its content in ``self``. - -- INPUT: -- -- - ``directory`` -- the name of the directory containing the latest -- version of the database. -- - EXAMPLES:: - -- sage: from sage.env import GRAPHS_DATA_DIR -- sage: graph_classes._parse_db(GRAPHS_DATA_DIR) -+ sage: graph_classes._parse_db() - """ - import xml.etree.cElementTree as ET - from sage.graphs.graph import Graph - -- xml_file = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) -+ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) -+ xml_file = os.path.join(data_dir, _XML_FILE) - tree = ET.ElementTree(file=xml_file) - root = tree.getroot() - DB = _XML_to_dict(root) -@@ -838,7 +834,7 @@ def _parse_db(self, directory): - inclusions = DB['Inclusions']['incl'] - - # Parses the list of ISGCI small graphs -- smallgraph_file = open(os.path.join(GRAPHS_DATA_DIR, _SMALLGRAPHS_FILE), 'r') -+ smallgraph_file = open(os.path.join(data_dir, _SMALLGRAPHS_FILE), 'r') - smallgraphs = {} - - for line in smallgraph_file.readlines(): -@@ -901,24 +897,7 @@ def _get_ISGCI(self): - - sage: graph_classes._get_ISGCI() # long time (4s on sage.math, 2012) - """ -- from sage.misc.misc import SAGE_DB -- -- try: -- open(os.path.join(SAGE_DB, _XML_FILE)) -- -- # Which copy is the most recent on the disk ? -- if (os.path.getmtime(os.path.join(SAGE_DB, _XML_FILE)) > -- os.path.getmtime(os.path.join(GRAPHS_DATA_DIR, _XML_FILE))): -- -- directory = os.path.join(SAGE_DB, _XML_FILE) -- -- else: -- directory = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) -- -- except OSError: -- directory = os.path.join(GRAPHS_DATA_DIR, _XML_FILE) -- -- self._parse_db(directory) -+ self._parse_db() - - def show_all(self): - r""" -diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx -index 632016b0703..453f711731c 100644 ---- a/src/sage/graphs/strongly_regular_db.pyx -+++ b/src/sage/graphs/strongly_regular_db.pyx -@@ -1233,7 +1233,7 @@ def SRG_from_RSHCD(v, k, l, mu, existence=False, check=True): - if (e**2 == 1 and - k == (n-1-a+e)/2 and - l == (n-2*a)/4 - (1-e) and -- mu== (n-2*a)/4 and -+ mu == (n-2*a)/4 and - regular_symmetric_hadamard_matrix_with_constant_diagonal(n, sgn(a)*e, existence=True) is True): - if existence: - return True -@@ -2415,7 +2415,7 @@ def SRG_416_100_36_20(): - """ - from sage.libs.gap.libgap import libgap - libgap.load_package("AtlasRep") -- g=libgap.AtlasGroup("G2(4)", libgap.NrMovedPoints, 416) -+ g = libgap.AtlasGroup("G2(4)", libgap.NrMovedPoints, 416) - h = Graph() - h.add_edges(g.Orbit([1, 5],libgap.OnSets)) - h.relabel() -@@ -2439,7 +2439,7 @@ def SRG_560_208_72_80(): - """ - from sage.libs.gap.libgap import libgap - libgap.load_package("AtlasRep") -- g=libgap.AtlasGroup("Sz8", libgap.NrMovedPoints, 560) -+ g = libgap.AtlasGroup("Sz8", libgap.NrMovedPoints, 560) - - h = Graph() - h.add_edges(g.Orbit([1, 2],libgap.OnSets)) -@@ -2503,7 +2503,7 @@ def strongly_regular_from_two_intersection_set(M): - for v in M: - # u is adjacent with all vertices on a uv line. - g.add_edges([[u, tuple([u[i] + qq*v[i] for i in range(k)])] -- for qq in K if not qq==K.zero()]) -+ for qq in K if not qq == K.zero()]) - g.relabel() - e = QQ((1,k)) - qq = g.num_verts()**e -@@ -3264,8 +3264,9 @@ cdef load_brouwer_database() noexcept: - if _brouwer_database is not None: - return - -- from sage.env import GRAPHS_DATA_DIR -- filename = os.path.join(GRAPHS_DATA_DIR, 'brouwer_srg_database.json') -+ from sage.features.databases import DatabaseGraphs -+ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename()) -+ filename = os.path.join(data_dir, 'brouwer_srg_database.json') - with open(filename) as fobj: - database = json.load(fobj) - -diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py -index e7354e05c70..add4b453b3d 100644 ---- a/src/sage/interfaces/jmoldata.py -+++ b/src/sage/interfaces/jmoldata.py -@@ -21,7 +21,7 @@ - - from sage.structure.sage_object import SageObject - --from sage.env import JMOL_DIR -+from sage.features.jmol import JmolDataJar - from sage.misc.temporary_file import tmp_filename - from sage.cpython.string import bytes_to_str - -@@ -79,11 +79,11 @@ def jmolpath(self): - - sage: from sage.interfaces.jmoldata import JmolData - sage: JData = JmolData() -- sage: JData.jmolpath() -+ sage: JData.jmolpath() # needs jmol - '.../JmolData.jar' - - """ -- jmolpath = os.path.join(JMOL_DIR, "JmolData.jar") -+ jmolpath = JmolDataJar().absolute_filename() - - return jmolpath - -@@ -100,7 +100,7 @@ def is_jmol_available(self): - sage: type(JData.is_jmol_available()) - <... 'bool'> - """ -- if not os.path.isfile(self.jmolpath()): -+ if not JmolDataJar().is_present(): - return False - - if not self.is_jvm_available(): -diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py -index 0adeab04bcd..e62c0175331 100644 ---- a/src/sage/repl/ipython_kernel/install.py -+++ b/src/sage/repl/ipython_kernel/install.py -@@ -23,7 +23,6 @@ - SAGE_EXTCODE, - SAGE_VENV, - SAGE_VERSION, -- THREEJS_DIR, - ) - - -@@ -123,6 +122,7 @@ def use_local_threejs(self): - - EXAMPLES:: - -+ sage: # needs threejs - sage: from sage.repl.ipython_kernel.install import SageKernelSpec - sage: spec = SageKernelSpec(prefix=tmp_dir()) - sage: spec.use_local_threejs() -@@ -130,7 +130,10 @@ def use_local_threejs(self): - sage: os.path.isdir(threejs) - True - """ -- src = THREEJS_DIR -+ from sage.features.threejs import Threejs -+ if not Threejs().is_present(): -+ return -+ src = os.path.dirname(os.path.dirname(Threejs().absolute_filename())) - dst = os.path.join(self.nbextensions_dir, 'threejs-sage') - self.symlink(src, dst) - -diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py -index ba17b9244b4..7f39e37bf8f 100644 ---- a/src/sage/repl/rich_output/backend_ipython.py -+++ b/src/sage/repl/rich_output/backend_ipython.py -@@ -409,15 +409,18 @@ def threejs_offline_scripts(self): - - EXAMPLES:: - -+ sage: # needs threejs - sage: from sage.repl.rich_output.backend_ipython import BackendIPythonCommandline - sage: backend = BackendIPythonCommandline() -- sage: backend.threejs_offline_scripts() # needs sage.plot -+ sage: backend.threejs_offline_scripts() - '...'.format(script) - -@@ -596,7 +599,7 @@ def threejs_offline_scripts(self): - '... -- """.format(_required_threejs_version(), CDN_script) -+ """.format(Threejs().required_version(), CDN_script) -diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py -index f6bec0209e1..cfece92a810 100644 ---- a/src/sage/repl/rich_output/display_manager.py -+++ b/src/sage/repl/rich_output/display_manager.py -@@ -46,22 +46,6 @@ - from sage.repl.rich_output.preferences import DisplayPreferences - - --def _required_threejs_version(): -- """ -- Return the version of threejs that Sage requires. -- -- EXAMPLES:: -- -- sage: from sage.repl.rich_output.display_manager import _required_threejs_version -- sage: _required_threejs_version() # needs sage.plot -- 'r...' -- """ -- import os -- import sage.env -- with open(os.path.join(sage.env.SAGE_EXTCODE, 'threejs', 'threejs-version.txt')) as f: -- return f.read().strip() -- -- - class DisplayException(Exception): - """ - Base exception for all rich output-related exceptions. -@@ -768,8 +752,9 @@ def threejs_scripts(self, online): - ValueError: current backend does not support - offline threejs graphics - """ -+ from sage.features.threejs import Threejs - if online: -- version = _required_threejs_version() -+ version = Threejs().required_version() - return """ - - """.format(version) -diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py -index f66ee2d1d31..34099d620bb 100644 ---- a/src/sage/schemes/elliptic_curves/ec_database.py -+++ b/src/sage/schemes/elliptic_curves/ec_database.py -@@ -132,8 +132,10 @@ def rank(self, rank, tors=0, n=10, labels=False): - sage: elliptic_curves.rank(6, n=3, labels=True) - [] - """ -- from sage.env import ELLCURVE_DATA_DIR -- data = os.path.join(ELLCURVE_DATA_DIR, 'rank%s' % rank) -+ from sage.features.databases import DatabaseEllcurves -+ db = DatabaseEllcurves() -+ data = os.path.join(os.path.dirname(db.absolute_filename()), -+ f'rank{rank}') - try: - f = open(data) - except OSError: diff --git a/srcpkgs/sagemath/patches/get_patches b/srcpkgs/sagemath/patches/get_patches index 34bb125a98876..b5daac7ddb82e 100755 --- a/srcpkgs/sagemath/patches/get_patches +++ b/srcpkgs/sagemath/patches/get_patches @@ -20,10 +20,6 @@ get_pr() { # run from patches dir cd $(dirname "$0") -# all merged in 10.3.beta6 or before -get_pr 37004 "fix save_session when cython changes" -get_pr 37024 "use features for simpler configuration" - # positive review get_pr 37123 "scipy 1.12" diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index 28f0d3423fca4..2b08099e47638 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,6 +1,6 @@ # Template file for 'sagemath' pkgname=sagemath -version=10.3.beta5 +version=10.3.beta6 revision=1 build_wrksrc=pkgs/sagemath-standard build_style=python3-module @@ -33,7 +33,7 @@ license="GPL-2.0-or-later" homepage="https://www.sagemath.org/" changelog="https://github.com/sagemath/sage/releases" distfiles="https://github.com/sagemath/sage/archive/refs/tags/$version.tar.gz" -checksum=4f4e608f8d2fe84dd6d79dd5429ca3528f79d56baa174a6bc2e97ffc855eced8 +checksum=6c87a4c44deb8f58ae4b1288d5c2711282d67d601735cae37908ec7d6fe2d02f nocross="due to ntl (eclib, singular), fflas-ffpack, givaro, linbox, sympow, maxima" post_patch() {