diff --git a/.cirrus.yml b/.cirrus.yml
index ae90520..38facc4 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -7,11 +7,6 @@ task:
matrix:
- JULIA_VERSION: 1.6
- JULIA_VERSION: 1
- - name: musl Linux
- container:
- image: alpine:3.14
- env:
- - JULIA_VERSION: 1
- name: MacOS M1
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-base:latest
diff --git a/.github/actions/spelling/README.md b/.github/actions/spelling/README.md
new file mode 100644
index 0000000..1f699f3
--- /dev/null
+++ b/.github/actions/spelling/README.md
@@ -0,0 +1,17 @@
+# check-spelling/check-spelling configuration
+
+File | Purpose | Format | Info
+-|-|-|-
+[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary)
+[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
+[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
+[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
+[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)
+[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
+[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
+[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
+[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
+[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
+
+Note: you can replace any of these files with a directory by the same name (minus the suffix)
+and then include multiple files inside that directory (with that suffix) to merge multiple files together.
diff --git a/.github/actions/spelling/advice.md b/.github/actions/spelling/advice.md
new file mode 100644
index 0000000..1004eea
--- /dev/null
+++ b/.github/actions/spelling/advice.md
@@ -0,0 +1,25 @@
+
+If the flagged items are :exploding_head: false positives
+
+If items relate to a ...
+* binary file (or some other file you wouldn't want to check at all).
+
+ Please add a file path to the `excludes.txt` file matching the containing file.
+
+ File paths are Perl 5 Regular Expressions - you can [test](
+https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
+
+ `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
+../tree/HEAD/README.md) (on whichever branch you're using).
+
+* well-formed pattern.
+
+ If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
+ try adding it to the `patterns.txt` file.
+
+ Patterns are Perl 5 Regular Expressions - you can [test](
+https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
+
+ Note that patterns can't match multiline strings.
+
+
diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt
new file mode 100644
index 0000000..7ab0963
--- /dev/null
+++ b/.github/actions/spelling/allow.txt
@@ -0,0 +1,2183 @@
+ACCB
+ACOPP
+ACOPR
+ACTRED
+ADELT
+ADW
+AFDIR
+AFORT
+AKIVA
+ALPBD
+AMAD
+AMAX
+ANGBD
+ANGT
+ANGTEST
+ARGLALE
+ARGLBLE
+ARGLCLE
+ARGLINA
+ARGLINB
+ARGLINC
+ARGTRIGLS
+ARMDIR
+ARMLD
+ATMAT
+AVGASA
+AVGASB
+AVX
+Aineq
+Aub
+BDTEST
+BDTOL
+BENNETT
+BFDIR
+BIGLSQ
+BIGV
+BLEN
+BLOCKNAME
+BLOWEYA
+BLOWEYB
+BNE
+BOBTR
+BQP
+BQPGASIM
+BROWNAL
+Bindel
+Broyden
+CGRAD
+CHANDHEQ
+CHCKTST
+CHEBYQAD
+CHEBYQADNE
+CHNROSNB
+CHNRSBNE
+CHNRSNBM
+CHNRSNBMNE
+CLIST
+CODEOWNERS
+COMPILERCURRENT
+COMPILERYEAR
+CONSTSF
+COSV
+CRV
+CSAVE
+CURDIR
+CVMAXM
+CVSABA
+CVXQP
+Cholesky
+Comput
+Conx
+DAGGRESSIVE
+DALLASM
+DALLASS
+DAMTP
+DANWOODLS
+DDEBUGGING
+DDKNEW
+DEBUGF
+DECACT
+DECONVB
+DECONVBNE
+DECONVC
+DECONVNE
+DECONVU
+DEGENLPB
+DEGENQPC
+DETRAT
+DFF
+DFFALT
+DFLOAT
+DFORT
+DGD
+DIAMON
+DIFFA
+DIFFB
+DIFFC
+DINTEGER
+DISTEST
+DISTQ
+DMN
+DMOVE
+DNORMSAVE
+DQP
+DREAL
+DSQMIN
+DSTEP
+DTOC
+DUALC
+DXNEW
+DXSIGN
+Dble
+Demmel
+EDGMAX
+ELTA
+ERRBIG
+ERRINBAR
+ERRINROS
+ERRINRSM
+ERRINRSMNE
+ERRTOL
+ESTIM
+EXTRASIM
+Evals
+FBRAIN
+FCF
+FDEBUGFLAGS
+FEAS
+FEEDLOC
+FFF
+FFLAGSG
+FFLAGSO
+FFORT
+FINDLOC
+FINTRFH
+FMXAPIF
+FNAMELEN
+FNEW
+FOPTIMFLAGS
+FPEs
+FPTR
+FRACSQ
+FRESERVE
+FRHOSQ
+FSAVE
+FSTD
+Frobenius
+Funval
+GBEG
+GETACTF
+GFF
+GFORT
+GFVER
+GGBEG
+GISQ
+GNUC
+GOFFIN
+GQSQ
+Galann
+HAIFAM
+HALFRT
+HATFLDFL
+HATFLDG
+HDF
+HHMM
+HIELOW
+HIMMELBI
+HIMMELBJ
+HISTORYF
+HKT
+HLAG
+HMAX
+HOMEPATH
+HRED
+HUESTIS
+HYDC
+HYDCAR
+HYPOT
+Hennart
+Himmelblau
+IABS
+IBDSAV
+IBRNCH
+ICONT
+ICOUNT
+IDIAG
+IDXNEW
+IFEAS
+IFLAG
+IFULL
+IMPROVEX
+INTREAL
+IPTEM
+IPTEMP
+ISAVE
+ISDIRN
+ITCSAV
+ITERSW
+IVMC
+IVMD
+IZDOTA
+Idnani
+JCP
+JDIAG
+JDRO
+JPN
+JPT
+JSWITCH
+JVM
+KKT
+KOEBHELB
+KOLD
+KPP
+KSAVE
+KTEMP
+Kahan
+Kieee
+Ktrap
+LAGINT
+LAGMAX
+LCPP
+LCTRS
+LDDEBUGFLAGS
+LDOPTIMFLAGS
+LEVYMONE
+LFORT
+LFUNC
+LGPL
+LGPLv
+LHAIFAM
+LINALGF
+LINCONT
+LINGEO
+LINSPANH
+LINTR
+LINUPD
+LLVM
+LOADBAL
+LRA
+LRCOVTYPE
+LSNNODOC
+LSQFIT
+LUKSAN
+MAKELA
+MANCINO
+MANCINONE
+MAXCV
+MAXE
+MAXHISTMEM
+MAXLIKA
+MAXNHIST
+MAXRED
+MEMORYF
+MEXF
+MEXGATE
+MHM
+MIFFLIN
+MINMAXRB
+MINSURF
+MJDP
+MMA
+MODERRSAVE
+MPI
+MPtr
+MSGLEN
+MTEST
+Mbounds
+Mchkptr
+Mchkstk
+Minform
+Mnostack
+Mstack
+Mstandard
+NACTP
+NACTX
+NBEST
+NCALL
+NEAUOA
+NEWSTR
+NEWUOAM
+NEquality
+NFF
+NFM
+NFMM
+NFORT
+NFSAV
+NFTEST
+NFX
+NInbineq
+NOISEF
+NOPAUSE
+NPROCS
+NPTM
+NPTx
+NREM
+NRESC
+NSAV
+NTRITS
+NVALA
+NVALB
+NVCOMPILER
+OBJCON
+OET
+OLDSTR
+ONEMIN
+ONESHELL
+OSTYPE
+OUTPUTF
+OUTUNIT
+Ofast
+Omojokun
+PARETA
+PARMU
+PARSIG
+PGI
+PGIC
+PIVKSAV
+PNLEN
+POLAK
+PQOLD
+PREPROCF
+PRESAV
+PRODPL
+PSB
+Pennec
+Pillo
+Postconditions
+Powellful
+QING
+QINGNE
+QMSTEP
+QOPTSQ
+QPAVLB
+QPCBLEND
+QPCBOEI
+QPNBLEND
+QPNBOEI
+Qsave
+RANDNUM
+RCV
+RDNEXT
+RDPREV
+READONLY
+REDMAX
+REDNEW
+REDSAV
+RESMAX
+RFF
+RFORT
+ROWCOL
+Raphson
+Rdsave
+Rsave
+SBDI
+SCADEN
+SDK
+SEDI
+SEGFAULTs
+SFF
+SFORT
+SHFMAX
+SHFMIN
+SHORTD
+SIGABRT
+SIGI
+SIGSEG
+SINV
+SIPOW
+SIXTHM
+SNORM
+SNSQ
+SPABS
+SPANHYD
+SPLS
+SQSTP
+STDERR
+STDIN
+STDOUT
+STEPA
+STEPB
+STPFUL
+STPSAV
+STRINGF
+SUFFIXG
+SUFFIXO
+SUMA
+SUMABS
+SUMB
+SUMG
+SUMH
+SUMOLD
+SUMPQ
+SUMV
+SUMW
+SVAL
+SWOPF
+SYMTOL
+Scheinberg
+Szego
+TARGUS
+TAXR
+TDIAD
+TDMIN
+TEMPQ
+TENBARS
+TENV
+TFI
+TINYCV
+TINYNUM
+TMPF
+TODO
+TOINTGOR
+TOINTPSP
+TRESTING
+TRO
+TRURED
+TWOPI
+TWORSQ
+Terpolation
+Tmin
+Toint
+Tpng
+Trefethen
+Uninstalling
+VANDANIUMS
+VANDERM
+VBIG
+VESUVIO
+VESUVIOU
+VFF
+VFORT
+VGRAD
+VHW
+VLMXSQ
+VMAX
+VMNEW
+VMOLD
+VNEW
+VQALT
+VSAVE
+VSQ
+Vardi
+WFIXSQ
+WGD
+WHW
+WINC
+WMULT
+WMX
+WORKDIR
+WSIG
+WSQSAV
+WVEC
+Waliasing
+Wampersand
+Wcompare
+Wconversion
+Wdo
+Werror
+Weverything
+Wextra
+Wimplicit
+Wintrinsics
+Wline
+Wmaybe
+Wno
+Wpedantic
+Wprecision
+Wrealloc
+Wreturn
+Wsurprising
+Wunderflow
+Wuninitialized
+Wunset
+Wunused
+Wuse
+XAV
+XFF
+XFORT
+XIPT
+XJPT
+XOPTD
+XOPTS
+XPR
+XRESERVE
+XSUM
+Xcode
+Xiaojun
+YFITU
+YYY
+YYYY
+Yurakucho
+ZDOTV
+ZDOTW
+ZDVABS
+ZDWABS
+Zongaro
+aarch
+abig
+absoft
+absvars
+acos
+actrem
+addact
+addpath
+adec
+adjustl
+aflang
+afun
+agrid
+ainc
+alloc
+allprec
+allvar
+alphm
+alpht
+altmov
+amat
+amed
+anl
+anorm
+aocc
+apiref
+apsd
+args
+argwhere
+armflang
+armv
+arrayfun
+arxiv
+asin
+asml
+astamm
+asubd
+atan
+atest
+awvwgk
+backend
+backtr
+bak
+bakf
+ballcon
+barmu
+bashrc
+bcon
+befin
+beq
+berr
+betabd
+bfirst
+bifin
+bigden
+biglag
+bign
+bigprob
+bigstp
+bineq
+bisheng
+bln
+bmat
+bmatk
+bmatknew
+bobyqa
+bobyqb
+boundmax
+bsecond
+bstep
+bsum
+bvec
+bwvd
+bymat
+byterecl
+calbeta
+calcfc
+calfun
+callstack
+calquad
+calvlag
+cauchy
+cbfun
+cbig
+cdec
+cdecs
+cellfun
+ceq
+cerg
+cfile
+cfilt
+chckfunval
+chebquad
+chebyquad
+checkcode
+checkexit
+checktest
+chist
+chistx
+chk
+chkfunval
+chkglobal
+chmod
+chrosen
+chstr
+cineq
+classname
+cleanall
+cleanbin
+cleanmisc
+cleansrc
+clf
+clflag
+cmax
+cmdx
+cmin
+cmod
+cmpaths
+cmtools
+cobyla
+cobylal
+cobylan
+cobylb
+coindexing
+colsq
+compdf
+completenames
+config
+confilt
+conhist
+conmat
+consav
+constrmax
+constrv
+constrviolation
+constrviolations
+consts
+copyfile
+copyfiles
+cpen
+cpenalty
+cpenmsg
+cpp
+cpuinfo
+cpwd
+cqa
+crec
+cref
+cron
+crvmin
+cshift
+csnumerics
+cstr
+cstrv
+cstyle
+ctest
+cth
+ctol
+cureos
+curv
+cval
+cviol
+cvmaxn
+cvmaxp
+cvold
+cvsabs
+cvshift
+cvsn
+cvtol
+cweight
+dataprof
+datenum
+datestr
+datetime
+datmat
+dbg
+dbgstr
+dbstack
+dcauchy
+dden
+dderiv
+ddmove
+ddsav
+debian
+deblank
+debugflag
+decup
+delact
+delbar
+delsame
+delsav
+delsq
+dena
+denabs
+denb
+denex
+denmax
+denold
+denomc
+denomg
+denomold
+denorm
+denormal
+denrat
+densav
+dependabot
+devblogs
+dfo
+dftpath
+dgm
+dhd
+dhs
+dimrange
+dimstride
+dirname
+dirs
+discmn
+distsq
+divz
+divzero
+dlen
+dlin
+dmask
+dnew
+dnewton
+dnoise
+dnorm
+dnormsav
+dnrm
+dold
+dproj
+dred
+dredg
+dredsq
+dsq
+dstemp
+dtest
+dtg
+dth
+dtz
+dumpversion
+dvlag
+dxn
+dxpt
+dxref
+eastoutside
+ebound
+edu
+eference
+eid
+eig
+eigen
+eigmin
+eigs
+elif
+elseif
+eminlb
+eminub
+emsg
+enddo
+endif
+entrywise
+envvar
+envvars
+eps
+epsc
+epsfiles
+epsname
+epstopdf
+equipez
+eqv
+errbd
+erres
+errh
+erri
+errmsg
+errorid
+errormsg
+errquad
+errstop
+esac
+etamax
+evalc
+evalcb
+evalcon
+evalf
+evalfun
+evalobj
+evaluatef
+evaluatefc
+exe
+exitflag
+exitflags
+exmp
+expr
+falseloc
+fautomatic
+fbacktrace
+fbase
+fbeg
+fbounds
+fcheck
+fclose
+fcratio
+fdefault
+feval
+fexist
+ffast
+ffiles
+ffilt
+fflags
+ffmt
+ffp
+ffpe
+fhist
+fhistf
+fhistx
+fieldnames
+figname
+fileattrib
+filelist
+fileparts
+fileread
+filesep
+fimplicit
+findall
+findpole
+findstring
+finfo
+finit
+fintrf
+firstorderopt
+fixedx
+fixl
+fixu
+fletcheq
+flist
+flsrc
+fmax
+fmexapi
+fmin
+fmincon
+fminp
+fminsearch
+fminunc
+fmodule
+fmq
+fmsg
+fmx
+fmxapi
+fmxcl
+fnext
+fno
+fnonstd
+fontsize
+fopen
+fopt
+foreach
+forrtl
+fortd
+fortls
+fortranwiki
+fout
+fpe
+fpp
+fprev
+fprintf
+fprob
+fpscomp
+fqdiff
+fqdz
+frac
+fracmult
+freal
+frec
+freex
+freexhist
+fref
+fsolver
+fsource
+fsrc
+fstack
+fstat
+fstr
+ftarget
+ftest
+fthreshold
+ftrace
+ftrap
+ftrapuv
+ftrapv
+ftz
+fullfile
+fullpath
+fullx
+func
+funcmax
+funcon
+funname
+funx
+fval
+fwrite
+fvdsrc
+frdsrc
+gaussian
+gca
+gcc
+gcf
+gcrt
+gdb
+genmod
+geostep
+getact
+getenv
+getfintrf
+gethuge
+getmax
+getmodel
+getseed
+gfortran
+ggfree
+ggsav
+ghg
+ghostscript
+ghv
+github
+githuge
+gitmodules
+gitpersonal
+gitsubmodule
+gittest
+glag
+gline
+glnxa
+gmon
+gnew
+gnorm
+goldp
+google
+gopt
+gotcha
+gotchas
+gprof
+grdstp
+gredsq
+grep
+gsq
+gstp
+gtest
+gub
+hangt
+hcol
+hdiag
+hdir
+hdred
+hess
+hessenberg
+hessmul
+hfig
+hfiles
+hkpfs
+hmlb
+hmul
+hnorm
+homedir
+htm
+html
+htol
+http
+https
+huawei
+hugecon
+hugefun
+hugenum
+iac
+iact
+iamat
+ibd
+ibmat
+ibmxl
+icf
+ichar
+iclflag
+idbg
+idim
+idmatrix
+idz
+ieeeinf
+ieeenan
+ienvvar
+ifcore
+ifeq
+iff
+ifile
+ifmt
+ifneq
+ifort
+ifun
+ifv
+ifx
+ignoredir
+ignorefiles
+igo
+ihq
+iid
+iin
+ikind
+ilbd
+ilm
+imag
+imask
+imatrix
+imf
+img
+incb
+includenan
+incx
+ineq
+infnan
+initfilt
+inith
+initl
+initq
+initxf
+initxfc
+inout
+inprod
+inputdir
+inputfiles
+interform
+interpolants
+intmax
+intnum
+intovf
+intp
+intrinsics
+iostat
+iout
+ipo
+ipq
+ipqw
+iprc
+iprec
+iprint
+iprob
+ipt
+iqf
+irand
+irc
+irf
+irun
+isa
+isav
+isavailable
+isbanded
+isbd
+isbetter
+iscalar
+ischarstr
+ischstr
+iscs
+isd
+isdigit
+isdir
+isempty
+isenv
+isenvs
+iseq
+isequiv
+isf
+isfield
+isinf
+isintegerscalar
+isintnum
+isinv
+isleap
+islogical
+islogicalscalar
+ismac
+ismatrix
+ismember
+isminor
+isnan
+isnumeric
+isnumvec
+isol
+isolver
+isorth
+isp
+ispc
+isprofile
+isq
+isqs
+isrc
+isreal
+isrealcolumn
+isrealmatrix
+isrealrow
+isrealscalar
+isrealvector
+isrm
+isrr
+isrs
+isrv
+isrvlb
+isrvub
+isscalar
+isspace
+isstruct
+issymmetric
+istp
+istr
+istril
+istriu
+isu
+isub
+isubsub
+isunix
+isvector
+isverify
+itemp
+iterc
+itercg
+itermax
+itest
+itol
+itpset
+itype
+iubd
+ivar
+ivector
+ivl
+ixa
+ixb
+ixn
+ixo
+ixp
+ixs
+izmat
+izmiran
+jan
+jblevins
+jcobyla
+jdrop
+jopt
+jorge
+jrfonseca
+jsav
+jsl
+jsu
+jwd
+kbase
+khist
+kopt
+korig
+kprov
+kpt
+kref
+ksav
+ksq
+ksqs
+kunpeng
+kworst
+lagmax
+lapack
+lbfin
+lbx
+lcon
+ldout
+len
+lenb
+lenlb
+lenub
+lenx
+leq
+lfqint
+lfrac
+lfsrc
+lhs
+libflang
+libpgmath
+libprima
+libsprima
+libthread
+linalg
+lincoa
+lincob
+lineq
+linewidth
+linspace
+lintering
+linting
+linux
+logfile
+logfiles
+logicals
+loor
+lscalar
+lscpu
+lsec
+lsqminnorm
+lsqr
+ltest
+lvector
+lwidth
+macos
+macup
+makefiles
+matcutest
+matd
+matfile
+mathrm
+mathworks
+matlab
+matlabcentral
+matlabroot
+matlabs
+matmul
+matprod
+matv
+maxabs
+maxarg
+maxchist
+maxcon
+maxconhist
+maxdepth
+maxdi
+maxdim
+maxeval
+maxexponent
+maxfhist
+maxfilt
+maxfloat
+maxfun
+maxhist
+maxint
+maxip
+maxir
+maxit
+maxiter
+maxloc
+maxmemory
+maxminloc
+maxn
+maxnum
+maxsigma
+maxtime
+maxtr
+maxval
+maxxhist
+mcc
+mcon
+mcs
+mex
+mexcallmatlab
+mexdir
+mexename
+mexext
+mexfunction
+mexification
+mexified
+mexifies
+mexify
+mexifying
+mexname
+mexopt
+mexopts
+mfiledir
+mfilename
+mfilepath
+microsoft
+minalpha
+minchist
+mincon
+mincv
+mindim
+minexponent
+minf
+minfhist
+minip
+minir
+minloc
+minval
+mkdir
+mkfiles
+mlint
+mlist
+mlog
+mmin
+moderatec
+moderatef
+moderatex
+moderr
+moderrsav
+modscal
+monlens
+movefile
+mplementation
+mpp
+mrec
+mref
+mtools
+mtrace
+mul
+mulvdi
+mulvsi
+mxn
+mytype
+nact
+nactold
+nactsav
+nagfor
+nagsrc
+nargin
+nargout
+ncopies
+ncp
+ncpu
+ndftpath
+ndiag
+ndim
+negcrv
+neginf
+negvdi
+negvsi
+netlib
+newact
+newfile
+newn
+newuoa
+newuob
+nfail
+nfc
+nfilt
+nfvals
+ngetact
+nhist
+nimg
+nin
+nint
+nlc
+nlcehist
+nlcehistx
+nlceq
+nlceqx
+nlchist
+nlcihist
+nlcihistx
+nlcineq
+nlcineqx
+nlhs
+nlinceq
+nlopt
+nloptr
+nname
+nnpt
+nocompile
+nofreex
+noisimul
+noisyceval
+noisyfeval
+noisyfun
+nonlcon
+nonstd
+nonzeros
+noold
+nopass
+norecursion
+normd
+normg
+normx
+northoutside
+notbig
+nout
+nprec
+nprobs
+nprov
+npt
+nrand
+nrhs
+nrun
+nsave
+nswm
+ntest
+numel
+numericalalgorithmsgroup
+numpy
+numvec
+nvararg
+nvfortran
+nvidia
+nyear
+odernization
+olddir
+oldnewthing
+oldpath
+omask
+omitnan
+oneapi
+oop
+openturns
+optim
+optimoptions
+optimset
+optnew
+optold
+optool
+origdir
+outdir
+outprod
+outptuts
+outputdir
+outputfile
+outputfiles
+ovf
+owell
+parallelizable
+parfor
+parlest
+partmp
+paru
+paruest
+pathdef
+pathsep
+pbaspect
+pdf
+pdfname
+pdfo
+pdfwrite
+pdim
+pdstr
+pdv
+perfdata
+perfprof
+permprob
+pfmt
+pgalt
+pgfortran
+pglag
+pgopt
+pgstp
+phimax
+phimin
+phiu
+pinput
+pintrf
+pipefail
+piv
+pivksv
+pivnew
+planerot
+plhs
+plist
+plnew
+pname
+png
+poisedness
+polyu
+posdef
+posinf
+postprima
+postprocesses
+poutput
+powalg
+powell
+powidf
+powisf
+ppf
+pqalt
+pqinc
+pqlag
+pqw
+preconnected
+predsq
+prefdir
+prehist
+preprima
+preproc
+prerec
+preref
+prerem
+prhs
+primalib
+primapack
+printf
+probinfo
+probname
+probs
+probtype
+psd
+psdsav
+ptinsq
+ptr
+ptsaux
+ptsid
+ptype
+pwd
+pybobyqa
+qadd
+qalt
+qbeg
+qdiff
+qdz
+qfac
+qinc
+qint
+qlist
+qmin
+qmstep
+qnew
+qradd
+qred
+qrexc
+qsav
+quada
+quadb
+quadinc
+quadprog
+qval
+qxoptq
+ragonneau
+ralna
+randomizex
+randperm
+randseed
+rangehist
+rayleighq
+rdiag
+readme
+realloc
+realmax
+realmin
+realpath
+reciq
+recl
+redrat
+redrho
+reduc
+refa
+refactor
+refactored
+refactoring
+refactors
+refb
+refbook
+regexp
+regexprep
+repmat
+resact
+rescon
+resis
+resnew
+restmp
+restoredefaultpath
+retmsg
+retnf
+rfac
+rfmt
+rfull
+rgc
+rhobeg
+rhoend
+rhomsg
+rhosq
+rineq
+rlb
+rlbp
+rmatrix
+rmdir
+rmempty
+rmfield
+rmpath
+rnf
+rng
+rnumq
+rosenbrock
+rownorm
+rpi
+rpnf
+rsc
+rscalar
+rseed
+rshrink
+rsnszk
+rstat
+rtest
+rubp
+rvector
+safealloc
+saveas
+savefilt
+savehist
+savepath
+sbig
+sbound
+scalb
+scipy
+scl
+scoreinc
+sdec
+sdiff
+sdirn
+secup
+seedf
+seedsav
+seedx
+segfault
+selectx
+semilogx
+semismooth
+setdiff
+setdrop
+setenv
+setij
+setopt
+setpath
+setseed
+setsolvopt
+setvars
+severes
+sfixsq
+sfrac
+sgk
+shiftbase
+shortd
+showpath
+shs
+sigbar
+signif
+simd
+simi
+simid
+sinc
+sizeof
+slbd
+smallestreal
+smallx
+smat
+smatv
+snan
+soldir
+solname
+solvera
+solvern
+spaths
+spdiags
+speye
+sprintf
+sqdscr
+sqp
+sqrtd
+sqrtdn
+srand
+src
+sredg
+srname
+ssden
+ssh
+ssml
+ssq
+ssqsav
+sstemp
+stackexchange
+stackoverflow
+stackvar
+stb
+stdlib
+stefan
+steplength
+stepsq
+stest
+stevengj
+sth
+stplen
+stpm
+stpsiz
+strcat
+strcmp
+strcmpi
+strjoin
+strlen
+strlength
+strnew
+strrep
+strs
+strt
+strtmp
+strtrim
+sturlamolden
+subd
+subdiagonal
+subdir
+subi
+subinfo
+subsubdir
+subsubdirectories
+subsubsubdirectories
+subvdi
+subvsi
+succ
+sumin
+sumsq
+sumz
+sunf
+sunsrc
+superdiagonal
+svg
+sxpt
+symlink
+symmat
+symmetrizes
+sys
+sysctl
+szymansk
+tanbd
+taua
+taub
+taubeg
+taumax
+tauold
+tausq
+tbig
+tdel
+tdiag
+techdoc
+tempa
+tempb
+tempc
+tempd
+tempdir
+tempv
+testcu
+testdata
+testdim
+testfeature
+testperm
+testprima
+testsolv
+testsuite
+textread
+textscan
+thegeekstuff
+threadsafe
+timestwo
+timezone
+tlist
+tmp
+tnz
+toc
+todo
+tomragonneau
+tracebackqq
+trapuv
+trapv
+tridh
+tridiagonalized
+tridiagonalizes
+tridiagonalizing
+trigsabs
+trigssqs
+tril
+trimstr
+triu
+trrad
+trsapp
+trsbox
+trstep
+trstlp
+trsubp
+trtol
+trueloc
+trustregion
+tryqalt
+tsml
+tsource
+tsubdiag
+tuxfamily
+twod
+ubfin
+ubl
+ubln
+ubuntu
+ubx
+ufrac
+ugc
+umask
+uname
+uncmax
+undef
+unf
+uniformoutput
+uninitialised
+uninstall
+uninstalls
+unitang
+univar
+unsetenv
+uobyqa
+uobyqb
+updateh
+updatepole
+updateq
+updateres
+updatexf
+updatexfc
+url
+userdata
+userpath
+usr
+uwidth
+varargin
+varargout
+vardim
+vec
+vectorized
+verisize
+verisym
+vhd
+vhg
+vhv
+vimdiff
+violmx
+vlag
+vlagabs
+vlagbeta
+vlagsq
+vlam
+vlin
+vmu
+vmult
+vmultc
+vmultd
+vnorm
+vquad
+vsig
+vsigj
+vtest
+vxopt
+warnerror
+warningid
+warningmsg
+warnoff
+wassert
+wcheck
+wcos
+website
+weeknum
+whatday
+wholename
+wiki
+wikipedia
+wmsg
+wmv
+workflow
+workflows
+wsin
+wsq
+wunit
+wvlag
+wwsq
+www
+wzsav
+xalt
+xargs
+xbase
+xbdi
+xcache
+xcauchy
+xcheck
+xdiff
+xdist
+xdrop
+xdsq
+xfilt
+xfmt
+xfree
+xgrid
+xhist
+xiang
+ximproved
+xinbd
+xind
+xjchen
+xlabel
+xlabh
+xline
+xmax
+xmin
+xminloc
+xml
+xnew
+xnsq
+xopt
+xoptsq
+xor
+xosav
+xpq
+xpt
+xptemp
+xptknew
+xptxav
+xrefsq
+xsav
+xsize
+xsq
+xstar
+xstart
+xstop
+xstr
+xtemp
+xtest
+xunit
+xxpt
+xxxx
+xypron
+ylabel
+ymat
+ymax
+ymd
+ymin
+yml
+yqa
+ysq
+ystar
+yticklabels
+yticks
+yymmdd
+yyx
+yzmat
+zaikun
+zaikunzhang
+zdasav
+zdota
+zequipe
+zhang
+zhangzk
+zknew
+zmask
+zmat
+zsq
+ztemp
+ztest
+strsplit
+filemode
+gitee
+logallrefupdates
+mygit
+pushurl
+repositoryformatversion
+pushurls
+Aex
+constrvmax
+fixedxl
+fixedxu
+rbounds
+NInequality
+gitlab
+href
+DEGENLPA
+dev
+archiva
+norma
+fdlist
+idir
+worktree
+funit
+ndgt
+nexp
+sformat
+drawnow
+SMBANK
+FSAN
+MESSAGEF
+NVDIR
+NVBIN
+ghist
+jachist
+radhist
+rathist
+statehist
+Hanzomon
+Dantzig
+newunit
+SSEBLIN
+GFSTD
+Mrecursive
+frecursive
+bibtex
+howpublished
+REREF
+getcpen
+cpenmin
+postconditions
+trfail
+ceval
+CMN
+fprint
+mdash
+segfaults
+slen
+ehdr
+METHANL
+updatedb
+mlocate
+TOINTQOR
+doi
+zenodo
+hilb
+maxub
+minlb
+sprimalib
+COMPFLAGS
+daynum
+dfrv
+mineq
+BQPGABIM
+idmat
+ixl
+ixu
+mxl
+mxu
+lincon
+Aeqx
+Aineqx
+ieq
+iineq
+AINEQ
+cbnd
+lceq
+lcineq
+lconstr
+nlconstr
+dotnet
+jlumbroso
+NONLCON
+nonlcon
+sqr
+cvnd
+cvpd
+nlcon
+charityware
+AFINC
+AFLIB
+cmake
+endmacro
+evals
+primac
+primaf
+cintrf
+COBJ
+COBJCON
+cobjfun
+cobjfuncon
+constrc
+evalcobj
+evalcobjcon
+execstack
+FUNPTR
+PROCPOINTER
+cfun
+cobj
+NVHPC
+objcon
+cobjcon
+FEVL
+Qdiag
+phimeca
+schueller
+julia
+libclang
+dumpbin
+objdump
+rfun
+cfiles
+ifiles
+parcluster
+ERRINROSNE
+FLG
+gsrc
+ifd
+INCLUDEDIR
+nbut
+ncharacter
+nchist
+nconstrviolation
+nds
+nexitflag
+nfhist
+nfintrf
+nfrac
+ngredsq
+nif
+ninteger
+nmex
+nnf
+nrestmp
+nreturn
+nshs
+nsolver
+nwhich
+Olimit
+tfopt
+tfun
+tfx
+vlagc
+gcp
+whos
+fortlab
+LEVYMONT
+BEALE
+BOXBODLS
+GMNCASE
+ZECEVIC
+BROWNBS
+HALDMADS
+CANTILVR
+WATSONNE
+GBRAIN
+GOULDQP
+MEYER
+NYSTROM
+TRUSPYR
+WACHBIEG
+WAYSEA
+ZANGWIL
+CHWIRUT
+LOTSCHD
+HYDROELS
+JENSMP
+KSIP
+MARATOS
+MEXHAT
+OPTCNTRL
+OPTPRLOC
+OSCIPANE
+TWOBARS
+lang
+appveyor
+baut
+bprima
+buildpkg
+ccall
+Cdouble
+CEnum
+cfunction
+Cint
+cirrusjl
+cirruslabs
+codecov
+COMPATHELPER
+copyto
+Cvoid
+dfed
+eachindex
+eead
+eltype
+firstindex
+freebsd
+iex
+isdefined
+iseven
+jll
+lastindex
+lcov
+libprimac
+lookback
+Nonconvex
+ntuple
+objfun
+objfuncon
+println
+processcoverage
+ric
+rtol
+runtest
+runtests
+stask
+stp
+testset
+Thi
+thiebaut
+threadid
+typemax
+typemin
+typeof
+uplo
+webclient
diff --git a/.github/actions/spelling/candidate.patterns b/.github/actions/spelling/candidate.patterns
new file mode 100644
index 0000000..8023bbb
--- /dev/null
+++ b/.github/actions/spelling/candidate.patterns
@@ -0,0 +1,527 @@
+# marker to ignore all code on line
+^.*/\* #no-spell-check-line \*/.*$
+# marker to ignore all code on line
+^.*\bno-spell-check(?:-line|)(?:\s.*|)$
+
+# https://cspell.org/configuration/document-settings/
+# cspell inline
+^.*\b[Cc][Ss][Pp][Ee][Ll]{2}:\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\b
+
+# patch hunk comments
+^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
+# git index header
+index (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
+
+# cid urls
+(['"])cid:.*?\g{-1}
+
+# data url in parens
+\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
+# data url in quotes
+([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
+# data url
+data:[-a-zA-Z=;:/0-9+]*,\S*
+
+# https/http/file urls
+(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
+
+# mailto urls
+mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
+
+# magnet urls
+magnet:[?=:\w]+
+
+# magnet urls
+"magnet:[^"]+"
+
+# obs:
+"obs:[^"]*"
+
+# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
+# In this examples content, I'm using a number of different ways to match things to show various approaches
+# asciinema
+\basciinema\.org/a/[0-9a-zA-Z]+
+
+# apple
+\bdeveloper\.apple\.com/[-\w?=/]+
+# Apple music
+\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
+
+# appveyor api
+\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
+# appveyor project
+\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
+
+# Amazon
+
+# Amazon
+\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
+# AWS S3
+\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/%_?:=]*
+# AWS execute-api
+\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
+# AWS ELB
+\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
+# AWS SNS
+\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/%_?:=]*
+# AWS VPC
+vpc-\w+
+
+# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
+# YouTube url
+\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
+# YouTube music
+\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
+# YouTube tag
+<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
+# YouTube image
+\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
+# Google Accounts
+\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
+# Google Analytics
+\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
+# Google APIs
+\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
+# Google Storage
+\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
+# Google Calendar
+\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
+\w+\@group\.calendar\.google\.com\b
+# Google DataStudio
+\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
+# The leading `/` here is as opposed to the `\b` above
+# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
+# Google Docs
+/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
+# Google Drive
+\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
+# Google Groups
+\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
+# Google Maps
+\bmaps\.google\.com/maps\?[\w&;=]*
+# Google themes
+themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
+# Google CDN
+\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
+# Goo.gl
+/goo\.gl/[a-zA-Z0-9]+
+# Google Chrome Store
+\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
+# Google Books
+\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=.]*
+# Google Fonts
+\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
+# Google Forms
+\bforms\.gle/\w+
+# Google Scholar
+\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
+# Google Colab Research Drive
+\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
+
+# GitHub SHAs (api)
+\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
+# GitHub SHAs (markdown)
+(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
+# GitHub SHAs
+\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
+# GitHub wiki
+\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
+# githubusercontent
+/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
+# githubassets
+\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
+# gist github
+\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
+# git.io
+\bgit\.io/[0-9a-zA-Z]+
+# GitHub JSON
+"node_id": "[-a-zA-Z=;:/0-9+]*"
+# Contributor
+\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
+# GHSA
+GHSA(?:-[0-9a-z]{4}){3}
+
+# GitLab commit
+\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
+# GitLab merge requests
+\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
+# GitLab uploads
+\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
+# GitLab commits
+\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
+
+# binanace
+accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
+
+# bitbucket diff
+\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
+# bitbucket repositories commits
+\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
+# bitbucket commits
+\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
+
+# bit.ly
+\bbit\.ly/\w+
+
+# bitrise
+\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
+
+# bootstrapcdn.com
+\bbootstrapcdn\.com/[-./\w]+
+
+# cdn.cloudflare.com
+\bcdnjs\.cloudflare\.com/[./\w]+
+
+# circleci
+\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
+
+# gitter
+\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
+
+# gravatar
+\bgravatar\.com/avatar/[0-9a-f]+
+
+# ibm
+[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
+
+# imgur
+\bimgur\.com/[^.]+
+
+# Internet Archive
+\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
+
+# discord
+/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
+
+# Disqus
+\bdisqus\.com/[-\w/%.()!?&=_]*
+
+# medium link
+\blink\.medium\.com/[a-zA-Z0-9]+
+# medium
+\bmedium\.com/\@?[^/\s"]+/[-\w]+
+
+# microsoft
+\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
+# powerbi
+\bapp\.powerbi\.com/reportEmbed/[^"' ]*
+# vs devops
+\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
+# microsoft store
+\bmicrosoft\.com/store/apps/\w+
+
+# mvnrepository.com
+\bmvnrepository\.com/[-0-9a-z./]+
+
+# now.sh
+/[0-9a-z-.]+\.now\.sh\b
+
+# oracle
+\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
+
+# chromatic.com
+/\S+.chromatic.com\S*[")]
+
+# codacy
+\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
+
+# compai
+\bcompai\.pub/v1/png/[0-9a-f]+
+
+# mailgun api
+\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
+# mailgun
+\b[0-9a-z]+.mailgun.org
+
+# /message-id/
+/message-id/[-\w@./%]+
+
+# Reddit
+\breddit\.com/r/[/\w_]*
+
+# requestb.in
+\brequestb\.in/[0-9a-z]+
+
+# sched
+\b[a-z0-9]+\.sched\.com\b
+
+# Slack url
+slack://[a-zA-Z0-9?&=]+
+# Slack
+\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
+# Slack edge
+\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
+# Slack images
+\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
+
+# shields.io
+\bshields\.io/[-\w/%?=&.:+;,]*
+
+# stackexchange -- https://stackexchange.com/feeds/sites
+\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
+
+# Sentry
+[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
+
+# Twitter markdown
+\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
+# Twitter hashtag
+\btwitter\.com/hashtag/[\w?_=&]*
+# Twitter status
+\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
+# Twitter profile images
+\btwimg\.com/profile_images/[_\w./]*
+# Twitter media
+\btwimg\.com/media/[-_\w./?=]*
+# Twitter link shortened
+\bt\.co/\w+
+
+# facebook
+\bfburl\.com/[0-9a-z_]+
+# facebook CDN
+\bfbcdn\.net/[\w/.,]*
+# facebook watch
+\bfb\.watch/[0-9A-Za-z]+
+
+# dropbox
+\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
+
+# ipfs protocol
+ipfs://[0-9a-z]*
+# ipfs url
+/ipfs/[0-9a-z]*
+
+# w3
+\bw3\.org/[-0-9a-zA-Z/#.]+
+
+# loom
+\bloom\.com/embed/[0-9a-f]+
+
+# regex101
+\bregex101\.com/r/[^/\s"]+/\d+
+
+# figma
+\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
+
+# freecodecamp.org
+\bfreecodecamp\.org/[-\w/.]+
+
+# image.tmdb.org
+\bimage\.tmdb\.org/[/\w.]+
+
+# mermaid
+\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
+
+# Wikipedia
+\ben\.wikipedia\.org/wiki/[-\w%.#]+
+
+# gitweb
+[^"\s]+/gitweb/\S+;h=[0-9a-f]+
+
+# HyperKitty lists
+/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
+
+# lists
+/thread\.html/[^"\s]+
+
+# list-management
+\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
+
+# kubectl.kubernetes.io/last-applied-configuration
+"kubectl.kubernetes.io/last-applied-configuration": ".*"
+
+# pgp
+\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
+
+# Spotify
+\bopen\.spotify\.com/embed/playlist/\w+
+
+# Mastodon
+\bmastodon\.[-a-z.]*/(?:media/|\@)[?&=0-9a-zA-Z_]*
+
+# scastie
+\bscastie\.scala-lang\.org/[^/]+/\w+
+
+# images.unsplash.com
+\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
+
+# pastebin
+\bpastebin\.com/[\w/]+
+
+# heroku
+\b\w+\.heroku\.com/source/archive/\w+
+
+# quip
+\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
+
+# badgen.net
+\bbadgen\.net/badge/[^")\]'\s]+
+
+# statuspage.io
+\w+\.statuspage\.io\b
+
+# media.giphy.com
+\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
+
+# tinyurl
+\btinyurl\.com/\w+
+
+# getopts
+\bgetopts\s+(?:"[^"]+"|'[^']+')
+
+# ANSI color codes
+(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
+
+# URL escaped characters
+\%[0-9A-F][A-F]
+# IPv6
+\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
+# c99 hex digits (not the full format, just one I've seen)
+0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
+# Punycode
+\bxn--[-0-9a-z]+
+# sha
+sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
+# sha-... -- uses a fancy capture
+(['"]|")[0-9a-f]{40,}\g{-1}
+# hex runs
+\b[0-9a-fA-F]{16,}\b
+# hex in url queries
+=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
+# ssh
+(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
+
+# PGP
+\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
+# GPG keys
+\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
+# Well known gpg keys
+.well-known/openpgpkey/[\w./]+
+
+# uuid:
+\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
+# hex digits including css/html color classes:
+(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
+# integrity
+integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
+
+# https://www.gnu.org/software/groff/manual/groff.html
+# man troff content
+\\f[BCIPR]
+# '
+\\\(aq
+
+# .desktop mime types
+^MimeTypes?=.*$
+# .desktop localized entries
+^[A-Z][a-z]+\[[a-z]+\]=.*$
+# Localized .desktop content
+Name\[[^\]]+\]=.*
+
+# IServiceProvider
+\bI(?=(?:[A-Z][a-z]{2,})+\b)
+
+# crypt
+"\$2[ayb]\$.{56}"
+
+# scrypt / argon
+\$(?:scrypt|argon\d+[di]*)\$\S+
+
+# Input to GitHub JSON
+content: "[-a-zA-Z=;:/0-9+]*="
+
+# Python stringprefix / binaryprefix
+# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
+(?v#
+(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
+# Compiler flags (Scala)
+(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
+# Compiler flags
+(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
+# Compiler flags (linker)
+,-B
+# curl arguments
+\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
+# set arguments
+\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
+# tar arguments
+\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
+# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
+\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
+# macOS temp folders
+/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/
diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt
new file mode 100644
index 0000000..dc74921
--- /dev/null
+++ b/.github/actions/spelling/excludes.txt
@@ -0,0 +1,78 @@
+# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
+(?:^|/)(?i)COPYRIGHT
+(?:^|/)(?i)LICEN[CS]E
+(?:^|/)3rdparty/
+(?:^|/)go\.sum$
+(?:^|/)package(?:-lock|)\.json$
+(?:^|/)pyproject.toml
+(?:^|/)requirements(?:-dev|-doc|-test|)\.txt$
+(?:^|/)vendor/
+ignore$
+\.a$
+\.ai$
+\.avi$
+\.bmp$
+\.bz2$
+\.class$
+\.coveragerc$
+\.crt$
+\.dll$
+\.docx?$
+\.drawio$
+\.DS_Store$
+\.eot$
+\.exe$
+\.gif$
+\.git-blame-ignore-revs$
+\.gitattributes$
+\.graffle$
+\.gz$
+\.icns$
+\.ico$
+\.jar$
+\.jks$
+\.jpe?g$
+\.key$
+\.lib$
+\.lock$
+\.map$
+\.min\..
+\.mod$
+\.mp[34]$
+\.o$
+\.ocf$
+\.otf$
+\.pdf$
+\.pem$
+\.png$
+\.psd$
+\.pyc$
+\.pylintrc$
+\.s$
+\.svgz?$
+\.tar$
+\.tiff?$
+\.ttf$
+\.wav$
+\.webm$
+\.webp$
+\.woff2?$
+\.xlsx?$
+\.zip$
+^\.github/actions/spelling/
+^\Q.github/workflows/spelling.yml\E$
+
+#######################################
+# Added by Zaikun
+^\.github/CODEOWNERS
+^\.github/dependabot.yml
+\.eps$
+\.pdf$
+^\.development/archiva/
+^\.development/norma/
+rescue_idz/norma/
+fortran/original/
+^\Qbenchmark/rescue_idz/archiva/230305/fortran/.keep\E$
+^\Qbenchmark/rescue_idz/archiva/230305/norma/fortran/.keep\E$
+^\Qbenchmark/rescue_idz/archiva/230305/norma/matlab/.keep\E$
+^\Qbenchmark/rescue_idz/archiva/230305/matlab/.keep\E$
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
new file mode 100644
index 0000000..e69de29
diff --git a/.github/actions/spelling/line_forbidden.patterns b/.github/actions/spelling/line_forbidden.patterns
new file mode 100644
index 0000000..e04455e
--- /dev/null
+++ b/.github/actions/spelling/line_forbidden.patterns
@@ -0,0 +1,62 @@
+# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
+# \bm_data\b
+
+# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
+# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
+# to use this:
+#\bfit\(
+
+# s.b. GitHub
+\bGithub\b
+
+# s.b. GitLab
+\bGitlab\b
+
+# s.b. JavaScript
+\bJavascript\b
+
+# s.b. Microsoft
+\bMicroSoft\b
+
+# s.b. another
+\ban[- ]other\b
+
+# s.b. greater than
+\bgreater then\b
+
+# s.b. into
+\sin to\s
+
+# s.b. opt-in
+\sopt in\s
+
+# s.b. less than
+\bless then\b
+
+# s.b. otherwise
+\bother[- ]wise\b
+
+# s.b. nonexistent
+\bnon existing\b
+\b[Nn]o[nt][- ]existent\b
+
+# s.b. preexisting
+[Pp]re[- ]existing
+
+# s.b. preempt
+[Pp]re[- ]empt\b
+
+# s.b. preemptively
+[Pp]re[- ]emptively
+
+# s.b. reentrancy
+[Rr]e[- ]entrancy
+
+# s.b. reentrant
+[Rr]e[- ]entrant
+
+# s.b. workaround(s)
+\bwork[- ]arounds?\b
+
+# Reject duplicate words
+\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s
diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt
new file mode 100644
index 0000000..95eb9da
--- /dev/null
+++ b/.github/actions/spelling/patterns.txt
@@ -0,0 +1,62 @@
+# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
+
+# Questionably acceptable forms of `in to`
+# Personally, I prefer `log into`, but people object
+# https://www.tprteaching.com/log-into-log-in-to-login/
+\b[Ll]og in to\b
+
+# acceptable duplicates
+# ls directory listings
+[-bcdlpsw](?:[-r][-w][-Ssx]){3}\s+\d+\s+\S+\s+\S+\s+\d+\s+
+# C types and repeated CSS values
+\s(center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?: \g{-1})+\s
+# go templates
+\s(\w+)\s+\g{-1}\s+\`(?:graphql|json|yaml):
+# javadoc / .net
+(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
+
+# Commit message -- Signed-off-by and friends
+^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
+
+# Autogenerated revert commit message
+^This reverts commit [0-9a-f]{40}\.$
+
+# ignore long runs of a single character:
+\b([A-Za-z])\g{-1}{3,}\b
+
+
+####################################################################################################
+
+
+# Automatically suggested patterns
+
+# https/http/file urls
+(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
+
+# GitHub SHAs (markdown)
+(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
+
+# stackexchange -- https://stackexchange.com/feeds/sites
+\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
+
+# Compiler flags
+(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
+
+# hex digits including css/html color classes:
+(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
+
+# version suffix v#
+(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
+
+# stackexchange -- https://stackexchange.com/feeds/sites
+\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
+
+# Wikipedia
+\ben\.wikipedia\.org/wiki/[-\w%.#]+
+
+# uuid:
+\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
+
+# hit-count: 2 file-count: 1
+# Non-English
+[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
diff --git a/.github/actions/spelling/reject.txt b/.github/actions/spelling/reject.txt
new file mode 100644
index 0000000..b5a6d36
--- /dev/null
+++ b/.github/actions/spelling/reject.txt
@@ -0,0 +1,10 @@
+^attache$
+benefitting
+occurences?
+^dependan.*
+^oer$
+Sorce
+^[Ss]pae.*
+^untill$
+^untilling$
+^wether.*
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
new file mode 100644
index 0000000..1c9fceb
--- /dev/null
+++ b/.github/workflows/spelling.yml
@@ -0,0 +1,142 @@
+name: Check Spelling
+
+# Comment management is handled through a secondary job, for details see:
+# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
+#
+# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
+# (in odd cases, it might actually run just to collapse a comment, but that's fairly rare)
+# it needs `contents: write` in order to add a comment.
+#
+# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
+# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
+# it needs `pull-requests: write` in order to manipulate those comments.
+
+# Updating pull request branches is managed via comment handling.
+# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
+#
+# These elements work together to make it happen:
+#
+# `on.issue_comment`
+# This event listens to comments by users asking to update the metadata.
+#
+# `jobs.update`
+# This job runs in response to an issue_comment and will push a new commit
+# to update the spelling metadata.
+#
+# `with.experimental_apply_changes_via_bot`
+# Tells the action to support and generate messages that enable it
+# to make a commit to update the spelling metadata.
+#
+# `with.ssh_key`
+# In order to trigger workflows when the commit is made, you can provide a
+# secret (typically, a write-enabled github deploy key).
+#
+# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
+
+on:
+ push:
+ pull_request:
+ # Trigger the workflow manually
+ workflow_dispatch:
+
+jobs:
+ spelling:
+ name: Check Spelling
+ permissions:
+ contents: read
+ pull-requests: read
+ actions: read
+ security-events: write
+ outputs:
+ followup: ${{ steps.spelling.outputs.followup }}
+ runs-on: ubuntu-latest
+ if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
+ concurrency:
+ group: spelling-${{ github.event.pull_request.number || github.ref }}
+ # note: If you use only_check_changed_files, you do not want cancel-in-progress
+ cancel-in-progress: true
+ steps:
+ - name: check-spelling
+ id: spelling
+ uses: check-spelling/check-spelling@main
+ with:
+ suppress_push_for_open_pull_request: 1
+ checkout: true
+ check_file_names: 1
+ spell_check_this: check-spelling/spell-check-this@prerelease
+ post_comment: 0
+ use_magic_file: 1
+ experimental_apply_changes_via_bot: 1
+ use_sarif: 1
+ # Zaikun 20230426: add dictionaries
+ extra_dictionary_limit: 20
+ extra_dictionaries:
+ cspell:bash/src/bash-words.txt
+ cspell:python/src/common/extra.txt
+ cspell:python/src/python/python-lib.txt
+ cspell:python/src/python/python.txt
+ cspell:python/src/additional_words.txt
+ cspell:software-terms/src/software-terms.txt
+ cspell:software-terms/src/software-tools.txt
+ cspell:cpp/src/cpp.txt
+ cspell:latex/src/latex.txt
+ cspell:filetypes/filetypes.txt
+ cspell:html/src/html.txt
+ cspell:html-symbol-entities/entities.txt
+ cspell:css/src/css.txt
+
+ comment-push:
+ name: Report (Push)
+ # If your workflow isn't running on push, you can remove this job
+ runs-on: ubuntu-latest
+ needs: spelling
+ permissions:
+ contents: write
+ if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
+ steps:
+ - name: comment
+ uses: check-spelling/check-spelling@main
+ with:
+ checkout: true
+ spell_check_this: check-spelling/spell-check-this@prerelease
+ task: ${{ needs.spelling.outputs.followup }}
+
+ comment-pr:
+ name: Report (PR)
+ # If you workflow isn't running on pull_request*, you can remove this job
+ runs-on: ubuntu-latest
+ needs: spelling
+ permissions:
+ pull-requests: write
+ if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
+ steps:
+ - name: comment
+ uses: check-spelling/check-spelling@main
+ with:
+ checkout: true
+ spell_check_this: check-spelling/spell-check-this@prerelease
+ task: ${{ needs.spelling.outputs.followup }}
+ experimental_apply_changes_via_bot: 1
+
+ update:
+ name: Update PR
+ permissions:
+ contents: write
+ pull-requests: write
+ actions: read
+ runs-on: ubuntu-latest
+ if: ${{
+ github.event_name == 'issue_comment' &&
+ github.event.issue.pull_request &&
+ contains(github.event.comment.body, '@check-spelling-bot apply')
+ }}
+ concurrency:
+ group: spelling-update-${{ github.event.issue.number }}
+ cancel-in-progress: false
+ steps:
+ - name: apply spelling updates
+ uses: check-spelling/check-spelling@main
+ with:
+ experimental_apply_changes_via_bot: 1
+ checkout: true
+ ssh_key: "${{ secrets.CHECK_SPELLING }}"
diff --git a/src/PRIMA.jl b/src/PRIMA.jl
index c52efd1..cdb67a9 100644
--- a/src/PRIMA.jl
+++ b/src/PRIMA.jl
@@ -888,7 +888,7 @@ function _get_linear_constraints(Ab::LinearConstraints, n::Integer, scl::Abstrac
T = Cdouble
# FIXME: Like in FORTRAN, Julia matrices are in column-major storage order,
# but we must transpose the matrix A in linear constraints because we call
- # the FORTRAN code through a C interface which conisder that matrices are
+ # the FORTRAN code through a C interface which consider that matrices are
# in row-major storage. As a result, the matrix `A` will be transposed
# twice. This isn't a big issue for a small number of variables and
# constraints, but it's not completely satisfactory either.