diff --git a/README.rst b/README.rst index 79b2904309..db8b8f9fa6 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,7 @@ +**WARNING: This old python-for-android toolchain is deprecated and +no longer supported. Please move to the current toolchain, see +https://github.com/kivy/python-for-android.** + Python for Android ================== diff --git a/distribute.sh b/distribute.sh index d873c3975e..05d3c63f1f 100755 --- a/distribute.sh +++ b/distribute.sh @@ -769,7 +769,7 @@ function run_pymodules_install() { done debug "Install pure-python modules via pip in venv" - try bash -c "source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPATH= pip install --target '$SITEPACKAGES_PATH' --download-cache '$PACKAGES_PATH' -r requirements.txt" + try bash -c "source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPATH= pip install --target '$SITEPACKAGES_PATH' -r requirements.txt" } diff --git a/recipes/android/src/android/activity.py b/recipes/android/src/android/activity.py index 94f02eb3bf..eaf7b07bdd 100644 --- a/recipes/android/src/android/activity.py +++ b/recipes/android/src/android/activity.py @@ -18,14 +18,6 @@ def __init__(self, callback, **kwargs): def onNewIntent(self, intent): self.callback(intent) - @java_method('(Ljava/lang/Object;)Z') - def equals(self, obj): - return obj.hashCode() == self.hashCode() - - @java_method('()I') - def hashCode(self): - return id(self) - class ActivityResultListener(PythonJavaClass): __javainterfaces__ = ['org/renpy/android/PythonActivity$ActivityResultListener'] @@ -39,14 +31,6 @@ def __init__(self, callback): def onActivityResult(self, requestCode, resultCode, intent): self.callback(requestCode, resultCode, intent) - @java_method('(Ljava/lang/Object;)Z') - def equals(self, obj): - return obj.hashCode() == self.hashCode() - - @java_method('()I') - def hashCode(self): - return id(self) - def bind(**kwargs): for event, callback in kwargs.items(): diff --git a/recipes/click/recipe.sh b/recipes/click/recipe.sh new file mode 100644 index 0000000000..0f3f8334db --- /dev/null +++ b/recipes/click/recipe.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +VERSION_click=${VERSION_click:-master} +DEPS_click=(python) +URL_click=https://github.com/mitsuhiko/click/archive/$VERSION_click.zip +MD5_click= +BUILD_click=$BUILD_PATH/click/$(get_directory $URL_click) +RECIPE_click=$RECIPES_PATH/click + +function prebuild_click() { + true +} + +function shouldbuild_click() { + if [ -d "$SITEPACKAGES_PATH/click" ]; then + DO_BUILD=0 + fi +} + +function build_click() { + cd $BUILD_click + + push_arm + sed -i "s/setuptools/distutils.core/g" `grep -rl "setuptools" ./setup.py` + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_click() { + true +} + diff --git a/recipes/ffmpeg2/recipe.sh b/recipes/ffmpeg2/recipe.sh index 6726e8c111..314f7e23cc 100644 --- a/recipes/ffmpeg2/recipe.sh +++ b/recipes/ffmpeg2/recipe.sh @@ -45,7 +45,7 @@ function build_ffmpeg2() { FLAGS="--disable-everything" FLAGS="$FLAGS --enable-parser=h264,aac" FLAGS="$FLAGS --enable-decoder=h263,h264,aac" - FLAGS="$FLAGS --enable-filter=aresample,resample,crop" + FLAGS="$FLAGS --enable-filter=aresample,resample,crop,adelay,volume" FLAGS="$FLAGS --enable-protocol=file,http,https,tls_openssl" FLAGS="$FLAGS --enable-demuxer=sdp --enable-pic" FLAGS="$FLAGS --enable-small" diff --git a/recipes/ffpyplayer_tito/recipe.sh b/recipes/ffpyplayer_tito/recipe.sh new file mode 100644 index 0000000000..287b00925e --- /dev/null +++ b/recipes/ffpyplayer_tito/recipe.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +VERSION_ffpyplayer_tito=${VERSION_ffpyplayer_tito:-master} +URL_ffpyplayer_tito=http://github.com/tito/ffpyplayer/archive/$VERSION_ffpyplayer_tito.zip +DEPS_ffpyplayer_tito=(python ffmpeg2) +MD5_ffpyplayer_tito= +BUILD_ffpyplayer_tito=$BUILD_PATH/ffpyplayer_tito/$(get_directory $URL_ffpyplayer_tito) +RECIPE_ffpyplayer_tito=$RECIPES_PATH/ffpyplayer_tito + +function prebuild_ffpyplayer_tito() { + true +} + +function shouldbuild_ffpyplayer_tito() { + if [ -d "$SITEPACKAGES_PATH/ffpyplayer" ]; then + DO_BUILD=0 + fi +} + +function build_ffpyplayer_tito() { + cd $BUILD_ffpyplayer_tito + + push_arm + + export FFMPEG_INCLUDE_DIR="$BUILD_ffmpeg2/build/ffmpeg/armeabi-v7a/include" + export FFMPEG_LIB_DIR="$BUILD_ffmpeg2/build/ffmpeg/armeabi-v7a/lib" + export SDL_INCLUDE_DIR="$SRC_PATH/jni/sdl/include" + export LDFLAGS="-L$LIBS_PATH" + + $HOSTPYTHON setup.py build_ext -v + try find . -iname '*.pyx' -exec $CYTHON {} \; + try $HOSTPYTHON setup.py build_ext -v + export PYTHONPATH=$BUILD_hostpython/Lib/site-packages + try $BUILD_hostpython/hostpython setup.py install -O2 --root=$BUILD_PATH/python-install --install-lib=lib/python2.7/site-packages + + pop_arm +} + +function postbuild_ffpyplayer_tito() { + true +} diff --git a/recipes/flask/recipe.sh b/recipes/flask/recipe.sh new file mode 100644 index 0000000000..65b782f8a6 --- /dev/null +++ b/recipes/flask/recipe.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +VERSION_flask=${VERSION_flask:-master} +DEPS_flask=(python werkzeug jinja2 itsdangerous click) +URL_flask=https://github.com/mitsuhiko/flask/archive/$VERSION_flask.zip +MD5_flask= +BUILD_flask=$BUILD_PATH/flask/$(get_directory $URL_flask) +RECIPE_flask=$RECIPES_PATH/flask + +function prebuild_flask() { + true +} + +function shouldbuild_flask() { + if [ -d "$SITEPACKAGES_PATH/flask" ]; then + DO_BUILD=0 + fi +} + +function build_flask() { + cd $BUILD_flask + + push_arm + sed -i "s/setuptools/distutils.core/g" `grep -rl "setuptools" ./setup.py` + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_flask() { + true +} + diff --git a/recipes/greenlet/recipe.sh b/recipes/greenlet/recipe.sh index 2e5059a82c..4f1cc40381 100644 --- a/recipes/greenlet/recipe.sh +++ b/recipes/greenlet/recipe.sh @@ -2,7 +2,6 @@ VERSION_greenlet=${VERSION_greenlet:-0.4.1} URL_greenlet=https://pypi.python.org/packages/source/g/greenlet/greenlet-$VERSION_greenlet.zip -https://github.com/downloads/greenlet/greenlet/greenlet-$VERSION_greenlet.tar.gz DEPS_greenlet=(python) MD5_greenlet=c2deda75bdda59c38cae12a77cc53adc BUILD_greenlet=$BUILD_PATH/greenlet/$(get_directory $URL_greenlet) diff --git a/recipes/itsdangerous/recipe.sh b/recipes/itsdangerous/recipe.sh new file mode 100644 index 0000000000..8ebe5b8e56 --- /dev/null +++ b/recipes/itsdangerous/recipe.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +VERSION_itsdangerous=${VERSION_itsdangerous:-master} +DEPS_itsdangerous=(python) +URL_itsdangerous=https://github.com/mitsuhiko/itsdangerous/archive/$VERSION_itsdangerous.zip +MD5_itsdangerous= +BUILD_itsdangerous=$BUILD_PATH/itsdangerous/$(get_directory $URL_itsdangerous) +RECIPE_itsdangerous=$RECIPES_PATH/itsdangerous + +function prebuild_itsdangerous() { + true +} + +function shouldbuild_itsdangerous() { + if [ -d "$SITEPACKAGES_PATH/itsdangerous" ]; then + DO_BUILD=0 + fi +} + +function build_itsdangerous() { + cd $BUILD_itsdangerous + + push_arm + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_itsdangerous() { + true +} + diff --git a/recipes/jinja2/recipe.sh b/recipes/jinja2/recipe.sh new file mode 100644 index 0000000000..0c4ca90a6a --- /dev/null +++ b/recipes/jinja2/recipe.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +VERSION_jinja2=${VERSION_jinja2:-master} +DEPS_jinja2=(python markupsafe) +URL_jinja2=https://github.com/mitsuhiko/jinja2/archive/$VERSION_jinja2.zip +MD5_jinja2= +BUILD_jinja2=$BUILD_PATH/jinja2/$(get_directory $URL_jinja2) +RECIPE_jinja2=$RECIPES_PATH/jinja2 + +function prebuild_jinja2() { + true +} + +function shouldbuild_jinja2() { + if [ -d "$SITEPACKAGES_PATH/jinja2" ]; then + DO_BUILD=0 + fi +} + +function build_jinja2() { + cd $BUILD_jinja2 + + push_arm + sed -i "s/setuptools/distutils.core/g" `grep -rl "setuptools" ./setup.py` + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_jinja2() { + true +} + diff --git a/recipes/markupsafe/recipe.sh b/recipes/markupsafe/recipe.sh new file mode 100644 index 0000000000..d3cefa0e8f --- /dev/null +++ b/recipes/markupsafe/recipe.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +VERSION_markupsafe=${VERSION_markupsafe:-master} +DEPS_markupsafe=(python) +URL_markupsafe=https://github.com/mitsuhiko/markupsafe/archive/$VERSION_markupsafe.zip +MD5_markupsafe= +BUILD_markupsafe=$BUILD_PATH/markupsafe/$(get_directory $URL_markupsafe) +RECIPE_markupsafe=$RECIPES_PATH/markupsafe + +function prebuild_markupsafe() { + true +} + +function shouldbuild_markupsafe() { + if [ -d "$SITEPACKAGES_PATH/markupsafe" ]; then + DO_BUILD=0 + fi +} + +function build_markupsafe() { + cd $BUILD_markupsafe + + push_arm + sed -i "s/setuptools/distutils.core/g" `grep -rl "setuptools" ./setup.py` + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_markupsafe() { + true +} + diff --git a/recipes/numpy/patches/ar.patch b/recipes/numpy/patches/ar.patch new file mode 100644 index 0000000000..c579d5e91a --- /dev/null +++ b/recipes/numpy/patches/ar.patch @@ -0,0 +1,11 @@ +--- a/numpy/distutils/unixccompiler.py 2015-02-01 17:38:21.000000000 +0100 ++++ b/numpy/distutils/unixccompiler.py 2015-07-08 17:21:05.742468485 +0200 +@@ -82,6 +82,8 @@ + pass + self.mkpath(os.path.dirname(output_filename)) + tmp_objects = objects + self.objects ++ from os import environ ++ self.archiver[0] = 'arm-linux-androideabi-ar' + while tmp_objects: + objects = tmp_objects[:50] + tmp_objects = tmp_objects[50:] diff --git a/recipes/numpy/patches/lib.patch b/recipes/numpy/patches/lib.patch new file mode 100644 index 0000000000..3087eb451d --- /dev/null +++ b/recipes/numpy/patches/lib.patch @@ -0,0 +1,44 @@ +--- a/numpy/linalg/setup.py 2015-07-09 14:15:59.850853336 +0200 ++++ b/numpy/linalg/setup.py 2015-07-09 14:21:59.403889000 +0200 +@@ -37,7 +37,8 @@ + config.add_extension('lapack_lite', + sources = [get_lapack_lite_sources], + depends = ['lapack_litemodule.c'] + lapack_lite_src, +- extra_info = lapack_info ++ extra_info = lapack_info, ++ libraries = ['m'], + ) + + # umath_linalg module +@@ -46,7 +47,7 @@ + sources = [get_lapack_lite_sources], + depends = ['umath_linalg.c.src'] + lapack_lite_src, + extra_info = lapack_info, +- libraries = ['npymath'], ++ libraries = ['npymath','m'], + ) + + return config +--- a/numpy/fft/setup.py 2015-07-09 14:35:22.299888028 +0200 ++++ b/numpy/fft/setup.py 2015-07-09 14:33:54.858392578 +0200 +@@ -9,7 +9,8 @@ + + # Configure fftpack_lite + config.add_extension('fftpack_lite', +- sources=['fftpack_litemodule.c', 'fftpack.c'] ++ sources=['fftpack_litemodule.c', 'fftpack.c'], ++ libraries = ['m'] + ) + + +--- a/numpy/random/setup.orig.py 2015-07-09 14:44:41.105174826 +0200 ++++ b/numpy/random/setup.py 2015-07-09 14:46:08.592679877 +0200 +@@ -38,7 +38,7 @@ + if needs_mingw_ftime_workaround(): + defs.append(("NPY_NEEDS_MINGW_TIME_WORKAROUND", None)) + +- libs = [] ++ libs = ['m'] + # Configure mtrand + config.add_extension('mtrand', + sources=[join('mtrand', x) for x in diff --git a/recipes/numpy/patches/prevent_libs_check.patch b/recipes/numpy/patches/prevent_libs_check.patch new file mode 100644 index 0000000000..73f2a9275c --- /dev/null +++ b/recipes/numpy/patches/prevent_libs_check.patch @@ -0,0 +1,12 @@ +diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py +index a050430..471e958 100644 +--- a/numpy/distutils/system_info.py ++++ b/numpy/distutils/system_info.py +@@ -610,6 +610,7 @@ class system_info: + return self.get_paths(self.section, key) + + def get_libs(self, key, default): ++ return [] + try: + libs = self.cp.get(self.section, key) + except NoOptionError: diff --git a/recipes/numpy/recipe.sh b/recipes/numpy/recipe.sh index 98ab200d79..c2e9c67a8d 100644 --- a/recipes/numpy/recipe.sh +++ b/recipes/numpy/recipe.sh @@ -15,6 +15,9 @@ function prebuild_numpy() { fi try patch -p1 < $RECIPE_numpy/patches/fix-numpy.patch + try patch -p1 < $RECIPE_numpy/patches/ar.patch + try patch -p1 < $RECIPE_numpy/patches/lib.patch + try patch -p1 < $RECIPE_numpy/patches/prevent_libs_check.patch touch .patched } @@ -29,9 +32,9 @@ function build_numpy() { cd $BUILD_numpy push_arm - try $HOSTPYTHON setup.py build_ext -v try find build/lib.* -name "*.o" -exec $STRIP {} \; + env try $HOSTPYTHON setup.py install -O2 pop_arm diff --git a/recipes/openssl/recipe.sh b/recipes/openssl/recipe.sh index 0aeb5e7455..198b5ba088 100644 --- a/recipes/openssl/recipe.sh +++ b/recipes/openssl/recipe.sh @@ -1,9 +1,9 @@ #!/bin/bash -VERSION_openssl=${VERSION_openssl:-1.0.2d} +VERSION_openssl=${VERSION_openssl:-1.0.2h} URL_openssl=https://www.openssl.org/source/openssl-$VERSION_openssl.tar.gz DEPS_openssl=() -MD5_openssl=38dd619b2e77cbac69b99f52a053d25a +MD5_openssl=9392e65072ce4b614c1392eefc1f23d0 BUILD_openssl=$BUILD_PATH/openssl/$(get_directory $URL_openssl) RECIPE_openssl=$RECIPES_PATH/openssl diff --git a/recipes/pyjnius/recipe.sh b/recipes/pyjnius/recipe.sh index 7616ffc155..49018241f8 100755 --- a/recipes/pyjnius/recipe.sh +++ b/recipes/pyjnius/recipe.sh @@ -2,7 +2,7 @@ VERSION_pyjnius=${VERSION_pyjnius:-master} URL_pyjnius=https://github.com/kivy/pyjnius/archive/$VERSION_pyjnius.zip -DEPS_pyjnius=(python sdl) +DEPS_pyjnius=(python sdl six) MD5_pyjnius= BUILD_pyjnius=$BUILD_PATH/pyjnius/$(get_directory $URL_pyjnius) RECIPE_pyjnius=$RECIPES_PATH/pyjnius diff --git a/recipes/pylibpd/patches/makefilefix.patch b/recipes/pylibpd/patches/makefilefix.patch new file mode 100644 index 0000000000..64ad4420dc --- /dev/null +++ b/recipes/pylibpd/patches/makefilefix.patch @@ -0,0 +1,11 @@ +--- Makefile 2015-08-19 10:42:49.160410592 +0200 ++++ Makefile-threadfix 2015-08-19 11:08:49.458350964 +0200 +@@ -150,7 +150,7 @@ + libpd: $(LIBPD) + + $(LIBPD): ${PD_FILES:.c=.o} ${UTIL_FILES:.c=.o} ${EXTRA_FILES:.c=.o} +- $(CC) -o $(LIBPD) $^ $(LDFLAGS) -lm -lpthread ++ $(CC) -o $(LIBPD) $^ $(LDFLAGS) -lm + + javalib: $(JNIH_FILE) $(PDJAVA_JAR) + diff --git a/recipes/pylibpd/patches/threadfix.patch b/recipes/pylibpd/patches/threadfix.patch index f299d01c7f..6d27bda282 100644 --- a/recipes/pylibpd/patches/threadfix.patch +++ b/recipes/pylibpd/patches/threadfix.patch @@ -1,10 +1,10 @@ ---- python/setup-threadfix.py 2013-05-29 13:10:16.000000000 -0400 -+++ python/setup.py 2013-06-07 11:53:34.447298388 -0400 -@@ -22,7 +22,6 @@ +--- python/setup.py 2015-08-18 11:15:35.546257493 +0200 ++++ python/setup-threadfix.py 2015-08-18 11:32:16.784394028 +0200 +@@ -24,7 +24,6 @@ libraries = [ 'm', 'dl', -- 'pthread', +- 'pthread' ], - sources=[ + sources = [ 'pylibpd.i', diff --git a/recipes/pylibpd/recipe.sh b/recipes/pylibpd/recipe.sh index 0e88d19981..4a6d7d5a1d 100644 --- a/recipes/pylibpd/recipe.sh +++ b/recipes/pylibpd/recipe.sh @@ -6,8 +6,12 @@ URL_pylibpd=https://github.com/libpd/libpd/archive/$VERSION_pylibpd.zip MD5_pylibpd= BUILD_pylibpd=$BUILD_PATH/pylibpd/$(get_directory $URL_pylibpd) RECIPE_pylibpd=$RECIPES_PATH/pylibpd +GIT_pylibpd=https://github.com/libpd/libpd function prebuild_pylibpd() { + # Clone recursively libpd repository + rm -rf $BUILD_pylibpd + git clone --recursive $GIT_pylibpd $BUILD_pylibpd # Apply thread removal patch cd $BUILD_pylibpd/python if [ -f .patched ]; then @@ -15,6 +19,13 @@ function prebuild_pylibpd() { fi try patch -p1 < $RECIPE_pylibpd/patches/threadfix.patch touch .patched + # Apply Makefile patch + cd $BUILD_pylibpd + if [ -f .patched ]; then + return + fi + try patch < $RECIPE_pylibpd/patches/makefilefix.patch + touch .patched } function shouldbuild_pylibpd() { @@ -24,8 +35,10 @@ function shouldbuild_pylibpd() { } function build_pylibpd() { - cd $BUILD_pylibpd/python push_arm + cd $BUILD_pylibpd + try make + cd python try $HOSTPYTHON setup.py build try $HOSTPYTHON setup.py install -O2 try $HOSTPYTHON setup.py clean diff --git a/recipes/werkzeug/recipe.sh b/recipes/werkzeug/recipe.sh new file mode 100644 index 0000000000..88730baf71 --- /dev/null +++ b/recipes/werkzeug/recipe.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +VERSION_werkzeug=${VERSION_werkzeug:-master} +DEPS_werkzeug=(python pyopenssl) +URL_werkzeug=https://github.com/mitsuhiko/werkzeug/archive/$VERSION_werkzeug.zip +MD5_werkzeug= +BUILD_werkzeug=$BUILD_PATH/werkzeug/$(get_directory $URL_werkzeug) +RECIPE_werkzeug=$RECIPES_PATH/werkzeug + +function prebuild_werkzeug() { + true +} + +function shouldbuild_werkzeug() { + if [ -d "$SITEPACKAGES_PATH/werkzeug" ]; then + DO_BUILD=0 + fi +} + +function build_werkzeug() { + cd $BUILD_werkzeug + + push_arm + sed -i "s/setuptools/distutils.core/g" `grep -rl "setuptools" ./setup.py` + try $HOSTPYTHON setup.py install + pop_arm +} + +function postbuild_werkzeug() { + true +} + diff --git a/src/src/org/renpy/android/SDLSurfaceView.java b/src/src/org/renpy/android/SDLSurfaceView.java index 853b0ba077..45ab161420 100644 --- a/src/src/org/renpy/android/SDLSurfaceView.java +++ b/src/src/org/renpy/android/SDLSurfaceView.java @@ -812,8 +812,37 @@ private void waitForStart() { GLES20.glViewport(0, 0, mWidth, mHeight); if (bitmap != null) { - float mx = ((float)mWidth / bitmap.getWidth()) / 2.0f; - float my = ((float)mHeight / bitmap.getHeight()) / 2.0f; + String fit = (String) ai.metaData.get("presplash-fit"); + + Log.i("python","presplash-fit is "+fit); + // WARNING: The presplash-fit api is unstable and may be changed + + int bitmapWidth = bitmap.getWidth(); + int bitmapHeight = bitmap.getHeight(); + + float mx; + float my; + + if (fit != null && fit.equals("fit")) { + float bitmapMultiplier = (float) Math.sqrt(2f * mWidth * mHeight / bitmapWidth / bitmapHeight); + mx = (float) mWidth / bitmapWidth / bitmapMultiplier; + my = (float) mHeight / bitmapHeight / bitmapMultiplier; + } else if (fit != null && fit.equals("width")) { + float bitmapMultiplier = ((float) mWidth) / bitmapWidth; + mx = (float) mWidth / bitmapWidth / 2.0f /bitmapMultiplier; + my = (float) mHeight / bitmapHeight / 2.0f /bitmapMultiplier; + } else if (fit != null && fit.equals("height")) { + float bitmapMultiplier = ((float) mHeight) / bitmapHeight; + mx = (float) mWidth / bitmapWidth / 2.0f / bitmapMultiplier; + my = (float) mHeight / bitmapHeight / 2.0f / bitmapMultiplier; + } else { + // default + mx = ((float) mWidth / bitmapWidth) / 2.0f; + my = ((float) mHeight / bitmapWidth) / 2.0f; + } + + Log.i("python", String.format("presplash (fit=%s) mx=%f,my=%f", fit,mx, my)); + Matrix.orthoM(mProjMatrix, 0, -mx, mx, my, -my, 0, 10); int value = bitmap.getPixel(0, 0); Color color = new Color(); @@ -1181,6 +1210,7 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) { public void onGlobalLayout() { Rect rctx = new Rect(); activityRootView.getWindowVisibleDisplayFrame(rctx); + rctx.top = 0; int heightDiff = default_display.getHeight() - (rctx.bottom - rctx.top); if (heightDiff != kHeight){ Log.i("Python:", String.format("Layout Triggered, Keyboard_height: %s", heightDiff)); diff --git a/src/tools/biglink b/src/tools/biglink index 1f82d18b48..6b86dbf841 100755 --- a/src/tools/biglink +++ b/src/tools/biglink @@ -38,7 +38,7 @@ while args: continue if a not in unique_args: unique_args.insert(0, a) - +unique_args = [x for x in unique_args if x] print('Biglink create %s library' % sys.argv[1]) print('Biglink arguments:') pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy