configuration added and updated

master
Marc Wäckerlin 7 years ago
parent 4f6fd7bad9
commit fdde529e91
  1. 2
      AUTHORS
  2. 1
      COPYING
  3. 18
      ChangeLog
  4. 1
      INSTALL
  5. 18
      README
  6. 37
      ax_init_standard_project.m4
  7. 27
      bootstrap.sh
  8. 5
      configure.ac
  9. 24
      etc/authentication.php
  10. 13
      etc/makefile.am
  11. 5
      etc/settings.php
  12. 6
      html/configuration.php.in
  13. 13
      html/index.php
  14. 11
      resolve-debbuilddeps.sh

@ -1 +1 @@
Marc Wäckerlin (http://marc.waeckerlin.org) <marc@waeckerlin.org> Marc Wäckerlin (https://marc.wäckerlin.ch) <marc@waeckerlin.org>

@ -0,0 +1 @@
/usr/share/automake-1.15/COPYING

@ -1,3 +1,21 @@
2017-02-17 11:04
* [r13] debian/control.in:
backup
2017-01-14 10:26
* [r12] debian/control.in:
build system updated
2017-01-12 13:22
* [r11] ChangeLog, autogen.sh, ax_init_standard_project.m4,
bootstrap.sh, build-in-docker.conf, build-in-docker.sh,
debian/changelog.in, debian/control.in, resolve-debbuilddeps.sh,
resolve-rpmbuilddeps.sh:
update build system
2016-09-30 21:55 2016-09-30 21:55
* [r10] ChangeLog[ADD], autogen.sh[ADD], * [r10] ChangeLog[ADD], autogen.sh[ADD],

@ -0,0 +1 @@
/usr/share/automake-1.15/INSTALL

@ -3,3 +3,21 @@ Browse Fotos in Internet and Share with Friends
Expose your personal foto folder to the internet, limit users by Apache or LDAP configuration and allow users to share fotos with friends. Expose your personal foto folder to the internet, limit users by Apache or LDAP configuration and allow users to share fotos with friends.
See: https://dev.marc.waeckerlin.org/redmine/projects/sharing-gallery/wiki See: https://dev.marc.waeckerlin.org/redmine/projects/sharing-gallery/wiki
Configuration:
/etc/gallery/password:
Contains only a server password that is used as part of any ancryption. Keep it secret. Only the web server process should be able to read this file.
You can generate it e.g. using: `pwgen 20 1` > /etc/gallery/password
/etc/gallery/settings.php
Provide path to images as `$path`, path to thumbnails as `$thumbs`. Set maximum of days a link is valid in `$max_validity_days`.
/etc/gallery/authentication.php
Check and verify the user, then provide `$username` if login is successful.
/etc/gallery/usersettings.php

@ -137,6 +137,8 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [
AX_SUBST(PREFIX) AX_SUBST(PREFIX)
SYSCONFDIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${sysconfdir}") SYSCONFDIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${sysconfdir}")
AX_SUBST(SYSCONFDIR) AX_SUBST(SYSCONFDIR)
PKGSYSCONFDIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${SYSCONFDIR}/${PACKAGE_NAME}")
AX_SUBST(PKGSYSCONFDIR)
DATADIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${datadir}") DATADIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${datadir}")
AX_SUBST(DATADIR) AX_SUBST(DATADIR)
PKGDATADIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${DATADIR}/${PACKAGE_NAME}") PKGDATADIR=$(test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${DATADIR}/${PACKAGE_NAME}")
@ -968,9 +970,40 @@ AC_DEFUN([AX_CHECK_VALID_LD_FLAG], [
# - parameter: # - parameter:
# $1 = package name # $1 = package name
AC_DEFUN([AX_DEB_DEPEND_IFEXISTS], [ AC_DEFUN([AX_DEB_DEPEND_IFEXISTS], [
pkg=$1 pkg="$1"
if test -n "$(apt-cache policy -q ${pkg} 2> /dev/null)"; then if test -n "$(apt-cache policy -q ${pkg} 2> /dev/null)"; then
DEB_DEPEND_IFEXISTS+=", ${pkg}" DEB_DEPEND_IFEXISTS="${DEB_DEPEND_IFEXISTS}, ${pkg}"
fi fi
])
# require package in debian/control.in append @DEB_BUILD_DEPEND@ to Build-Depends
# - parameter:
# $1 = package name
AC_DEFUN([AX_DEB_BUILD_DEPEND], [
pkg="$1"
DEB_BUILD_DEPEND="${DEB_BUILD_DEPEND}, ${pkg}"
])
# require package in debian/control.in append @DEB_DEPEND@ to Depends
# - parameter:
# $1 = package name
AC_DEFUN([AX_DEB_DEPEND], [
pkg="$1"
DEB_DEPEND="${DEB_DEPEND}, ${pkg}"
])
# require package in debian/control.in append @DEB_DEPEND@ to Depends
# - parameter:
# $1 = package name
AC_DEFUN([AX_DEB_SECTION], [
pkg="$1"
DEB_SECTION="${pkg}"
])
# call after setting debian dependencies
AC_DEFUN([AX_DEB_RESOLVE], [
AC_SUBST(DEB_BUILD_DEPEND)
AC_SUBST(DEB_DEPEND)
AC_SUBST(DEB_SECTION)
AC_SUBST(DEB_DEPEND_IFEXISTS) AC_SUBST(DEB_DEPEND_IFEXISTS)
]) ])

@ -147,6 +147,7 @@ GENERATED FILES
* src/makefile.am - if you enabled AX_USE_CXX * src/makefile.am - if you enabled AX_USE_CXX
* src/version.hxx - if you enabled AX_USE_CXX * src/version.hxx - if you enabled AX_USE_CXX
* src/version.cxx - if you enabled AX_USE_CXX * src/version.cxx - if you enabled AX_USE_CXX
* etc/makefile.am - if you enable AX_USE_ETC
* html/makefile.am - if you enabled AX_BUILD_HTML * html/makefile.am - if you enabled AX_BUILD_HTML
* scripts/makefile.am - if you enabled AX_USE_SCRIPTS * scripts/makefile.am - if you enabled AX_USE_SCRIPTS
* nodejs/makefile.am - if you add AX_USE_NODEJS * nodejs/makefile.am - if you add AX_USE_NODEJS
@ -256,6 +257,7 @@ FILES
number. In git, git rev-list --all --count is used. number. In git, git rev-list --all --count is used.
The following macros are supported in configure.ac: The following macros are supported in configure.ac:
* Enable C++: AX_USE_CXX * Enable C++: AX_USE_CXX
* Enable system config files in /etc: AX_USE_ETC
* Enable LibTool library creation: AX_USE_LIBTOOL * Enable LibTool library creation: AX_USE_LIBTOOL
* Enable Scripts: AX_USE_SCRIPTS * Enable Scripts: AX_USE_SCRIPTS
* Enable NodeJS project: AX_USE_NODEJS * Enable NodeJS project: AX_USE_NODEJS
@ -569,6 +571,7 @@ AX_INIT_STANDARD_PROJECT
# requirements, uncomment, what you need: # requirements, uncomment, what you need:
#AX_USE_CXX #AX_USE_CXX
#AX_USE_ETC
#AX_USE_LIBTOOL #AX_USE_LIBTOOL
#AX_USE_SCRIPTS #AX_USE_SCRIPTS
#AX_USE_NODEJS #AX_USE_NODEJS
@ -690,9 +693,13 @@ ${CHEADER}#include <${PACKAGE_NAME}.hxx>
#include <QApplication> #include <QApplication>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <iostream> #include <iostream>
#include <version.hxx>
int main(int argc, char *argv[]) try { int main(int argc, char *argv[]) try {
QApplication a(argc, argv); QApplication a(argc, argv);
a.setApplicationDisplayName(a.tr("${PACKAGE_NAME}"));
a.setApplicationName(${PACKAGE_NAME}::package_name().c_str());
a.setApplicationVersion(${PACKAGE_NAME}::version().c_str());
QCommandLineParser parser; QCommandLineParser parser;
parser.addHelpOption(); parser.addHelpOption();
parser.process(a); parser.process(a);
@ -725,6 +732,7 @@ class ${PackageName}: public QMainWindow, protected Ui::${PackageName} {
Q_OBJECT; Q_OBJECT;
public: public:
explicit ${PackageName}(QWidget *parent = 0): QMainWindow(parent) { explicit ${PackageName}(QWidget *parent = 0): QMainWindow(parent) {
setTitle(tr("${PACKAGE_NAME}[*]"));
setupUi(this); setupUi(this);
} }
virtual ~${PackageName}() {} virtual ~${PackageName}() {}
@ -854,6 +862,11 @@ namespace NAMESPACE {
const std::string IDENT("\$Id: " PACKAGE_STRING); const std::string IDENT("\$Id: " PACKAGE_STRING);
} }
EOF EOF
to --condition AX_USE_ETC etc/makefile.am <<EOF
${HEADER}pkgsysconfdir = \${sysconfdir}/@PACKAGE_NAME@
dist_pkgsysconf_DATA =
EOF
to --condition AX_USE_SCRIPTS scripts/makefile.am <<EOF to --condition AX_USE_SCRIPTS scripts/makefile.am <<EOF
${HEADER}dist_bin_SCRIPTS = ${HEADER}dist_bin_SCRIPTS =
@ -1465,17 +1478,18 @@ if testtag AX_USE_DEBIAN_PACKAGING; then
-- @PACKAGER@ @BUILD_DATE@ -- @PACKAGER@ @BUILD_DATE@
EOF EOF
RUN_DEPENDS="$(if testtag AX_USE_NODEJS; then echo -n ", nodejs, npm"; fi)"
BUILD_DEPENDS="debhelper, fakeroot, ${VCSDEPENDS_DEB} pkg-config, automake, libtool, autotools-dev, pandoc, lsb-release$(if testtag AX_USE_DOXYGEN; then echo -n ", doxygen, graphviz, mscgen, default-jre-headless|default-jre"; fi; if testtag AX_USE_PERLDOC; then echo -n ", libpod-tree-perl"; fi; if testtag AX_USE_CPPUNIT; then echo -n ", libcppunit-dev"; fi; if testtag AX_CXX_QT || testtag AX_CHECK_QT AX_REQUIRE_QT; then echo -n ", qt5-default | libqt4-core | libqtcore4, qt5-qmake | qt4-qmake, qtbase5-dev | libqt4-dev, qtbase5-dev-tools | qt4-dev-tools, qttools5-dev-tools | qt4-dev-tools, qttools5-dev-tools | qt4-dev-tools"; fi)" BUILD_DEPENDS="debhelper, fakeroot, ${VCSDEPENDS_DEB} pkg-config, automake, libtool, autotools-dev, pandoc, lsb-release$(if testtag AX_USE_DOXYGEN; then echo -n ", doxygen, graphviz, mscgen, default-jre-headless|default-jre"; fi; if testtag AX_USE_PERLDOC; then echo -n ", libpod-tree-perl"; fi; if testtag AX_USE_CPPUNIT; then echo -n ", libcppunit-dev"; fi; if testtag AX_CXX_QT || testtag AX_CHECK_QT AX_REQUIRE_QT; then echo -n ", qt5-default | libqt4-core | libqtcore4, qt5-qmake | qt4-qmake, qtbase5-dev | libqt4-dev, qtbase5-dev-tools | qt4-dev-tools, qttools5-dev-tools | qt4-dev-tools, qttools5-dev-tools | qt4-dev-tools"; fi)"
to debian/control.in <<EOF to debian/control.in <<EOF
Source: @PACKAGE_NAME@ Source: @PACKAGE_NAME@
Priority: extra Priority: extra
Maintainer: @PACKAGER@ Maintainer: @PACKAGER@
Build-Depends: ${BUILD_DEPENDS} Build-Depends: ${BUILD_DEPENDS}${RUN_DEPENDS} @DEB_BUILD_DEPEND@ @DEB_DEPEND_IFEXISTS@
Package: @PACKAGE_NAME@ Package: @PACKAGE_NAME@
Section: $(if testtag AX_USE_LIBTOOL; then echo "libs"; fi) Section: $(if testtag AX_USE_LIBTOOL; then echo "libs"; else echo "@DEB_SECTION@"; fi)
Architecture: any Architecture: any
Depends: \${shlibs:Depends}, \${misc:Depends} Depends: \${shlibs:Depends}, \${misc:Depends}${RUN_DEPENDS} @DEB_DEPEND@
Description: @DESCRIPTION@ Description: @DESCRIPTION@
@README_DEB@ @README_DEB@
$( if testtag AX_USE_LIBTOOL; then $( if testtag AX_USE_LIBTOOL; then
@ -1484,7 +1498,7 @@ $( if testtag AX_USE_LIBTOOL; then
Package: @PACKAGE_NAME@-dev Package: @PACKAGE_NAME@-dev
Section: libdevel Section: libdevel
Architecture: any Architecture: any
Depends: @PACKAGE_NAME@ (= \${binary:Version}), ${BUILD_DEPENDS} Depends: @PACKAGE_NAME@ (= \${binary:Version}), ${BUILD_DEPENDS}${RUN_DEPENDS} @DEB_DEPEND@ @DEB_BUILD_DEPEND@ @DEB_DEPEND_IFEXISTS@
Description: @DESCRIPTION@ - Development Package Description: @DESCRIPTION@ - Development Package
@README_DEB@ @README_DEB@
EOF2 EOF2
@ -1496,6 +1510,7 @@ README
EOF EOF
to --condition AX_USE_LIBTOOL debian/${PACKAGE_NAME}.install <<EOF to --condition AX_USE_LIBTOOL debian/${PACKAGE_NAME}.install <<EOF
usr/lib/lib*.so.* usr/lib/lib*.so.*
usr/share/${PACKAGE_NAME}
EOF EOF
to --condition AX_USE_LIBTOOL debian/${PACKAGE_NAME}-dev.install <<EOF to --condition AX_USE_LIBTOOL debian/${PACKAGE_NAME}-dev.install <<EOF
usr/include/* usr/include/*
@ -1503,7 +1518,6 @@ usr/lib/lib*.a
usr/lib/lib*.so usr/lib/lib*.so
usr/lib/pkgconfig/* usr/lib/pkgconfig/*
usr/lib/*.la usr/lib/*.la
usr/share/${PACKAGE_NAME}
usr/share/doc/${PACKAGE_NAME}/html usr/share/doc/${PACKAGE_NAME}/html
EOF EOF
to --mode "u=rwx,g=rwx,o=rx" debian/rules <<EOF to --mode "u=rwx,g=rwx,o=rx" debian/rules <<EOF
@ -1674,6 +1688,9 @@ SUBDIRS=""
if testtag AX_USE_CXX; then if testtag AX_USE_CXX; then
SUBDIRS="${SUBDIRS} src" SUBDIRS="${SUBDIRS} src"
fi fi
if testtag AX_USE_ETC; then
SUBDIRS="${SUBDIRS} etc"
fi
if testtag AX_BUILD_TEST AX_USE_CPPUNIT; then if testtag AX_BUILD_TEST AX_USE_CPPUNIT; then
SUBDIRS="${SUBDIRS} test" SUBDIRS="${SUBDIRS} test"
fi fi

@ -10,7 +10,7 @@
m4_define(x_package_name, sharing-gallery) # project's name m4_define(x_package_name, sharing-gallery) # project's name
m4_define(x_major, 0) # project's major version m4_define(x_major, 0) # project's major version
m4_define(x_minor, 0) # project's minor version m4_define(x_minor, 9) # project's minor version
m4_include(ax_init_standard_project.m4) m4_include(ax_init_standard_project.m4)
AC_INIT(x_package_name, x_version, x_bugreport, x_package_name) AC_INIT(x_package_name, x_version, x_bugreport, x_package_name)
AM_INIT_AUTOMAKE([1.9 tar-pax]) AM_INIT_AUTOMAKE([1.9 tar-pax])
@ -18,6 +18,7 @@ AX_INIT_STANDARD_PROJECT
# requirements, uncomment, what you need: # requirements, uncomment, what you need:
#AX_USE_CXX #AX_USE_CXX
AX_USE_ETC
#AX_USE_LIBTOOL #AX_USE_LIBTOOL
#AX_USE_SCRIPTS #AX_USE_SCRIPTS
AX_USE_DOXYGEN AX_USE_DOXYGEN
@ -33,5 +34,7 @@ AX_BUILD_HTML
#AX_REQUIRE_QT([QT], [QtCore QtGui QtNetwork], [QtWidgets]) #AX_REQUIRE_QT([QT], [QtCore QtGui QtNetwork], [QtWidgets])
#AX_QT_NO_KEYWORDS #AX_QT_NO_KEYWORDS
AC_CONFIG_FILES([html/configuration.php])
# create output # create output
AC_OUTPUT AC_OUTPUT

@ -0,0 +1,24 @@
<?php
$realm = "MY REALM HERE";
$ldaphost = "my.ldap.host";
$base = "dc=my,dc=server,dc=com";
$userbase = "ou=people,".$base;
$groupbase = "ou=group,".$base;
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="'.$REALM.'"');
header('HTTP/1.0 401 Unauthorized');
exit;
} else {
$tstusername = ereg_replace('/^[a-z]/', '-', $_SERVER['PHP_AUTH_USER']);
$password = $_SERVER['PHP_AUTH_PW'];
$ldapconn = ldap_connect($ldaphost, 389)
or error_die("connection to LDAP host failed");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3)
or error_die("failed to set LDAP protocol version 3");
ldap_start_tls($ldapconn)
or error_die($ldapconn, "cannot start LDAP TLS");
$ldapbind = @ldap_bind($ldapconn, 'uid='.$tstusername.','.$userbase, $password)
or error_die("login failed for $username", '403 Forbidden');
$username = $tstuserbname;
}
?>

@ -0,0 +1,13 @@
## @id $Id$
##
## This file has been added:
## - by bootstrap.sh
## - on Sun, 26 February 2017 11:29:20 +0100
## Feel free to change it or even remove and rebuild it, up to your needs
##
## 1 2 3 4 5 6 7 8
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
pkgsysconfdir = ${sysconfdir}/@PACKAGE_NAME@
dist_pkgsysconf_DATA = settings.php authentication.php

@ -0,0 +1,5 @@
<?php
$path='/path/to/your/files';
$thumbs='/var/tmp/sahring-gallery/thumbnails/';
$max_validity_days=30;
?>

@ -0,0 +1,6 @@
<?php
$server_password=file_get_contents('@PKGSYSCONFDIR@/password');
require('@PKGSYSCONFDIR@/settings.php');
if (!$server_password) error_die('no server password');
if (!isset($_REQUEST['secret'])) require('@PKGSYSCONFDIR@/authentication.php');
?>

@ -2,6 +2,7 @@
mb_internal_encoding("utf8"); mb_internal_encoding("utf8");
$subpath=""; $subpath="";
$file=""; $file="";
$username="";
function error_die($reason, $status='500 Internal Server Error') { function error_die($reason, $status='500 Internal Server Error') {
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT"); header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
@ -11,6 +12,7 @@
header('HTTP/1.0 '.$status); header('HTTP/1.0 '.$status);
die('<html><body><h1>Error: '.$status.'</h1><p>'.$reason.'</p>'); die('<html><body><h1>Error: '.$status.'</h1><p>'.$reason.'</p>');
} }
require('configuration.php');
function alt(&$p1 = NULL, &$p2 = NULL, &$p3 = NULL) { function alt(&$p1 = NULL, &$p2 = NULL, &$p3 = NULL) {
if (isset($p1)) return $p1; if (isset($p1)) return $p1;
if (isset($p2)) return $p2; if (isset($p2)) return $p2;
@ -57,9 +59,10 @@
} }
function checkPath($pathToCheck) { function checkPath($pathToCheck) {
global $path, $subpath; global $path, $subpath;
if (ereg('^[-_a-zA-Z0-9äöüÄÖÜ/]*$', $pathToCheck) && is_dir($path.'/'.$pathToCheck)) { $fullpath = $path.'/'.$pathToCheck
if ($fullpath==realpath($fullpath) && is_dir($fullpath)) {
$subpath=$pathToCheck; $subpath=$pathToCheck;
$path .= '/'.$pathToCheck; $path = $fullpath;
} else { } else {
error_die('path not allowed: '.htmlentities($pathToCheck)); error_die('path not allowed: '.htmlentities($pathToCheck));
} }
@ -153,13 +156,7 @@
makelink($link, $img, $filename); makelink($link, $img, $filename);
} }
} }
$server_password=file_get_contents('/etc/gallery/password');
require('/etc/gallery/settings.php');
if (!$server_password) $server_password=str_shuffle(sha1(rand().time()."ashu87as"));
$username="";
if (!isset($_REQUEST['secret'])) { if (!isset($_REQUEST['secret'])) {
require('/etc/gallery/authentication.php');
require('/etc/gallery/usersettings.php');
if ($username=="") error_die('not authorized', '403 Forbidden'); if ($username=="") error_die('not authorized', '403 Forbidden');
if (isset($_REQUEST['path'])) checkPath($_REQUEST['path']); if (isset($_REQUEST['path'])) checkPath($_REQUEST['path']);
if (isset($_REQUEST['folder']) && !ereg('/', $_REQUEST['folder'])) { if (isset($_REQUEST['folder']) && !ereg('/', $_REQUEST['folder'])) {

@ -32,21 +32,24 @@ function install() {
} }
TO_INSTALL= TO_INSTALL=
DEPS=
if test -e debian/control.in -a ! -e debian/control; then if test -e debian/control.in -a ! -e debian/control; then
for f in $(sed -n 's, *AX_DEB_DEPEND_IFEXISTS(\([^)]*\)).*,\1,p' configure.ac); do for f in $(sed -n 's, *AX_DEB_DEPEND_IFEXISTS(\([^)]*\)).*,\1,p' configure.ac); do
if test -n "$(${DO} apt-cache policy -q ${f})" && ((! $(${DO} apt-cache policy ${f} 2>&1 | grep -q 'N: Unable to locate package')) && (! ${DO} dpkg -l "${f}")); then if test -n "$(${DO} apt-cache policy -q ${f})" && ((! $(${DO} apt-cache policy ${f} 2>&1 | grep -q 'N: Unable to locate package')) && (! ${DO} dpkg -l "${f}")); then
TO_INSTALL+=" ${f}" DEPS+=" ${f}"
fi fi
done done
for f in $(sed -n 's, *AX_DEB_BUILD_DEPEND(\([^)]*\)).*,\1,p' configure.ac); do
DEPS+=" ${f}"
done
trap "rm debian/control" INT TERM EXIT trap "rm debian/control" INT TERM EXIT
sed 's,@DEB_DEPEND_IFEXISTS@,,g' debian/control.in | \ sed 's,@\(DEB_DEPEND_IFEXISTS\|DEB_BUILD_DEPEND\|DEB_DEPEND\)@,,g' debian/control.in | \
sed 's,@[^@]*@, dummytext,g' > debian/control sed 's,@[^@]*@, dummytext,g' > debian/control
fi fi
install dpkg-dev install dpkg-dev
DEPS=$(LANG= ${DO} dpkg-checkbuilddeps 2>&1 || true) DEPS+=" $(LANG= ${DO} dpkg-checkbuilddeps 2>&1 | sed -n '/Unmet build dependencies/ { s,.*Unmet build dependencies: ,,g; s, ([^)]*),,g; s, *| *,|,g; p}')"
DEPS=$(echo "$DEPS" | sed -n '/Unmet build dependencies/ { s,.*Unmet build dependencies: ,,g; s, ([^)]*),,g; s, *| *,|,g; p}')
for pa in ${DEPS}; do for pa in ${DEPS}; do
if test ${pa//|/} = ${pa}; then if test ${pa//|/} = ${pa}; then

Loading…
Cancel
Save