Skip to content

Commit

Permalink
Merge branch 'develop' into fix-email-sendscript
Browse files Browse the repository at this point in the history
  • Loading branch information
eldy authored Mar 21, 2024
2 parents dd6dec3 + b5804ae commit 1ad4acc
Show file tree
Hide file tree
Showing 69 changed files with 476 additions and 327 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jobs:
ls -l ~/.cache/pre-commit/
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@2024.3.2
uses: mdeweerd/logToCheckStyle@v2024.3.4
if: ${{ failure() }}
with:
in: ${{ env.RAW_LOG }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
for /f "tokens=2 delims==" %%A in ('doskey /m:err') do EXIT /B %%A
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@2024.3.2
uses: mdeweerd/logToCheckStyle@v2024.3.4
if: ${{ failure() }}
with:
in: ${{ env.PHPUNIT_LOG }}
Expand Down
30 changes: 4 additions & 26 deletions dev/tools/phan/baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,44 @@
return [
// # Issue statistics:
// PhanParamSignatureMismatch : 25+ occurrences
// PhanTypeMismatchReturnNullable : 20+ occurrences
// PhanPluginSuspiciousParamPosition : 15+ occurrences
// PhanUndeclaredConstant : 15+ occurrences
// PhanPluginDuplicateExpressionBinaryOp : 10+ occurrences
// PhanTypeArraySuspiciousNull : 10+ occurrences
// PhanTypeMismatchReturn : 10+ occurrences
// PhanTypeMismatchReturn : 8 occurrences
// PhanRedefineFunctionInternal : 6 occurrences
// PhanTypeArraySuspiciousNull : 6 occurrences
// PhanParamTooMany : 4 occurrences
// PhanTypeMismatchPropertyProbablyReal : 2 occurrences
// PhanTypeMismatchReturnNullable : 3 occurrences
// PhanAccessMethodProtected : 1 occurrence
// PhanAccessPropertyStaticAsNonStatic : 1 occurrence
// PhanNoopStringLiteral : 1 occurrence
// PhanPluginAlwaysReturnFunction : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
'htdocs/adherents/class/adherent.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/adherents/class/adherentstats.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/adherents/stats/geo.php' => ['PhanTypeArraySuspiciousNull'],
'htdocs/adherents/type.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/admin/receiptprinter.php' => ['PhanRedefineFunctionInternal'],
'htdocs/api/class/api_documents.class.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/barcode/printsheet.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/categories/class/api_categories.class.php' => ['PhanAccessMethodProtected'],
'htdocs/categories/viewcat.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/collab/index.php' => ['PhanParamTooMany'],
'htdocs/comm/action/class/actioncomm.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/comm/action/index.php' => ['PhanTypeArraySuspiciousNull'],
'htdocs/comm/mailing/card.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/comm/propal/class/api_proposals.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/compta/cashcontrol/cashcontrol_card.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/compta/prelevement/class/bonprelevement.class.php' => ['PhanParamTooMany'],
'htdocs/compta/prelevement/create.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/core/class/commondocgenerator.class.php' => ['PhanTypeArraySuspiciousNull'],
'htdocs/core/class/commonobject.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/class/extrafields.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/class/html.form.class.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/core/class/html.formprojet.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/class/smtps.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/class/stats.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/db/mysqli.class.php' => ['PhanParamSignatureMismatch'],
'htdocs/core/db/pgsql.class.php' => ['PhanParamSignatureMismatch'],
'htdocs/core/db/sqlite3.class.php' => ['PhanParamSignatureMismatch', 'PhanTypeMismatchReturnNullable'],
'htdocs/core/get_info.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/core/lib/date.lib.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/lib/files.lib.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/core/lib/functions.lib.php' => ['PhanParamTooMany', 'PhanPluginAlwaysReturnFunction', 'PhanRedefineFunctionInternal'],
'htdocs/core/lib/functions2.lib.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/lib/pdf.lib.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/lib/functions.lib.php' => ['PhanParamTooMany', 'PhanRedefineFunctionInternal'],
'htdocs/core/lib/price.lib.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/core/lib/website.lib.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/modules/DolibarrModules.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/core/modules/movement/doc/pdf_standard.modules.php' => ['PhanPluginDuplicateExpressionBinaryOp'],
'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeArraySuspiciousNull'],
'htdocs/core/modules/societe/modules_societe.class.php' => ['PhanTypeMismatchReturn'],
'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanParamSignatureMismatch'],
'htdocs/core/modules/syslog/mod_syslog_syslog.php' => ['PhanParamSignatureMismatch'],
'htdocs/don/class/don.class.php' => ['PhanParamTooMany'],
Expand All @@ -76,17 +59,12 @@ return [
'htdocs/mrp/class/mo.class.php' => ['PhanParamSignatureMismatch'],
'htdocs/product/admin/product_tools.php' => ['PhanNoopStringLiteral'],
'htdocs/product/class/product.class.php' => ['PhanTypeMismatchReturn'],
'htdocs/projet/class/project.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/projet/class/projectstats.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/projet/class/task.class.php' => ['PhanTypeMismatchReturnNullable'],
'htdocs/projet/tasks/list.php' => ['PhanTypeArraySuspiciousNull'],
'htdocs/public/payment/paymentok.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/societe/class/companybankaccount.class.php' => ['PhanParamSignatureMismatch'],
'htdocs/stripe/admin/stripe.php' => ['PhanDeprecatedFunction'],
'htdocs/stripe/class/actions_stripe.class.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/takepos/invoice.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/variants/class/ProductCombination.class.php' => ['PhanPluginSuspiciousParamPosition'],
'htdocs/website/class/website.class.php' => ['PhanTypeMismatchReturnNullable'],
'internal' => ['PhanUndeclaredConstant'],
],
// 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed.
Expand Down
1 change: 1 addition & 0 deletions dev/translation/dynamic_translation_keys.lst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Reservation
ACCOUNTING_ACCOUNT_CUSTOMER
ACCOUNTING_ACCOUNT_CUSTOMER_Desc
ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY
ACCOUNTING_ACCOUNT_EXPENSEREPORT
ACCOUNTING_ACCOUNT_SUPPLIER
ACCOUNTING_ACCOUNT_SUPPLIER_Desc
ACCOUNTING_ACCOUNT_SUSPENSE
Expand Down
4 changes: 2 additions & 2 deletions htdocs/adherents/class/adherent.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,20 +560,20 @@ public function makeSubstitution($text)
* Return translated label by the nature of a adherent (physical or moral)
*
* @param string $morphy Nature of the adherent (physical or moral)
* @param int $addbadge Add badge (1=Full label, 2=First letters only)
* @param int<0,2> $addbadge Add badge (1=Full label, 2=First letters only)
* @return string Label
*/
public function getmorphylib($morphy = '', $addbadge = 0)
{
global $langs;
$s = '';

// Clean var
if (!$morphy) {
$morphy = $this->morphy;
}

if ($addbadge) {
$s = '';
$labeltoshowm = $langs->trans("Moral");
$labeltoshowp = $langs->trans("Physical");
if ($morphy == 'phy') {
Expand Down
19 changes: 10 additions & 9 deletions htdocs/adherents/class/adherentstats.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright (c) 2005-2011 Laurent Destailleur <[email protected]>
* Copyright (C) 2005-2009 Regis Houssin <[email protected]>
* Copyright (C) 2023 Waël Almoman <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -168,15 +169,15 @@ public function getAllByYear()
/**
* Return count of member by status group by adh type, total and average
*
* @param int $numberYears Number of years to scan (0 = all)
* @return array Array with total of draft, pending, uptodate, expired, resiliated for each member type
* @param int $numberYears Number of years to scan (0 = all)
* @return array<string,array{label:string,members_draft:int,members_pending:0,members_uptodate:int,members_expired:int,members_excluded:int,members_resiliated:int,all?:float|int,total_adhtag:float|int}> Array with total of draft, pending, uptodate, expired, resiliated for each member type
*/
public function countMembersByTypeAndStatus($numberYears = 0)
{
global $user;

$now = dol_now();
$endYear = date('Y');
$endYear = (int) date('Y');
$startYear = $endYear - $numberYears;

$sql = "SELECT t.rowid as fk_adherent_type, t.libelle as label";
Expand Down Expand Up @@ -224,7 +225,7 @@ public function countMembersByTypeAndStatus($numberYears = 0)
'members_resiliated' => (int) $objp->members_resiliated
);
$totalrow = 0;
foreach ($MembersCountArray[$objp->fk_adherent_type] as $key=>$nb) {
foreach ($MembersCountArray[$objp->fk_adherent_type] as $key => $nb) {
if ($key != 'label') {
$totalrow += $nb;
$totalstatus[$key] += $nb;
Expand All @@ -244,16 +245,17 @@ public function countMembersByTypeAndStatus($numberYears = 0)
/**
* Return count of member by status group by adh type, total and average
*
* @param int $numberYears Number of years to scan (0 = all)
* @return array Array with total of draft, pending, uptodate, expired, resiliated for each member tag
* @param int $numberYears Number of years to scan (0 = all)
* @return array<string,array{label:string,members_draft:int,members_pending:0,members_uptodate:int,members_expired:int,members_excluded:int,members_resiliated:int,all?:float|int,total_adhtag:float|int}> Array with total of draft, pending, uptodate, expired, resiliated for each member tag
*/
public function countMembersByTagAndStatus($numberYears = 0)
{
global $user;

$now = dol_now();
$endYear = date('Y');
$endYear = (int) date('Y');
$startYear = $endYear - $numberYears;
$MembersCountArray = [];

$sql = "SELECT c.rowid as fk_categorie, c.label as label";
$sql .= ", COUNT(".$this->db->ifsql("d.statut = ".Adherent::STATUS_DRAFT, "'members_draft'", 'NULL').") as members_draft";
Expand Down Expand Up @@ -282,7 +284,6 @@ public function countMembersByTagAndStatus($numberYears = 0)
if ($result) {
$num = $this->db->num_rows($result);
$i = 0;
$MembersCountArray = [];
$totalstatus = array(
'label' => 'Total',
'members_draft' => 0,
Expand All @@ -304,7 +305,7 @@ public function countMembersByTagAndStatus($numberYears = 0)
'members_resiliated' => (int) $objp->members_resiliated
);
$totalrow = 0;
foreach ($MembersCountArray[$objp->fk_categorie] as $key=>$nb) {
foreach ($MembersCountArray[$objp->fk_categorie] as $key => $nb) {
if ($key != 'label') {
$totalrow += $nb;
$totalstatus[$key] += $nb;
Expand Down
2 changes: 2 additions & 0 deletions htdocs/adherents/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright (C) 2014-2016 Juanjo Menent <[email protected]>
* Copyright (C) 2018 Alexandre Spangaro <[email protected]>
* Copyright (C) 2021-2023 Frédéric France <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -203,6 +204,7 @@
}
}
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
//var_dump($arrayfields);exit;

// Security check
Expand Down
4 changes: 2 additions & 2 deletions htdocs/comm/action/class/actioncomm.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ public function getActions($socid = 0, $fk_element = 0, $elementtype = '', $filt
*
* @param User $user Object user
* @param int $load_state_board Load indicator array this->nb
* @return WorkboardResponse|int Return integer <0 if KO, WorkboardResponse if OK
* @return WorkboardResponse|int<-1,1> Return integer <0 if KO, WorkboardResponse if OK
*/
public function load_board($user, $load_state_board = 0)
{
Expand Down Expand Up @@ -1462,7 +1462,7 @@ public function load_board($user, $load_state_board = 0)
}

$this->db->free($resql);
if (empty($load_state_board)) {
if (empty($load_state_board) && $response instanceof WorkboardResponse) {
return $response;
} else {
return 1;
Expand Down
1 change: 1 addition & 0 deletions htdocs/comm/action/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@

$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

$result = restrictedArea($user, 'agenda', 0, '', 'myactions');
if ($user->socid && $socid) {
Expand Down
2 changes: 2 additions & 0 deletions htdocs/comm/propal/class/api_proposals.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright (C) 2020 Thibault FOUCART <[email protected]>
* Copyright (C) 2022 ATM Consulting <[email protected]>
* Copyright (C) 2022 OpenDSI <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -410,6 +411,7 @@ public function postLines($id, $request_data = null)
}

$errors = [];
$updateRes = 0;
$this->db->begin();

foreach ($request_data as $TData) {
Expand Down
1 change: 1 addition & 0 deletions htdocs/commande/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@
$object->fields = dol_sort_array($object->fields, 'position');
//$arrayfields['anotherfield'] = array('type'=>'integer', 'label'=>'AnotherField', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan


// Security check
Expand Down
2 changes: 2 additions & 0 deletions htdocs/commande/list_det.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@

$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

if (!$user->hasRight('societe', 'client', 'voir')) {
$search_sale = $user->id;
Expand Down Expand Up @@ -1295,6 +1296,7 @@
// Détail commande
if (!empty($arrayfields['rowid']['checked'])) {
print_liste_field_titre($arrayfields['rowid']['label'], $_SERVER["PHP_SELF"], 'rowid', '', $param, '', $sortfield, $sortorder);
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
}
if (!empty($arrayfields['pr.ref']['checked'])) {
print_liste_field_titre($arrayfields['pr.ref']['label'], $_SERVER["PHP_SELF"], 'pr.ref', '', $param, '', $sortfield, $sortorder);
Expand Down
2 changes: 2 additions & 0 deletions htdocs/compta/bank/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (C) 2015 Jean-François Ferry <[email protected]>
* Copyright (C) 2018 Ferran Marcet <[email protected]>
* Copyright (C) 2020 Tobias Sekan <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -125,6 +126,7 @@

$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

$permissiontoadd = $user->hasRight('banque', 'modifier');
$permissiontodelete = $user->hasRight('banque', 'configurer');
Expand Down
2 changes: 2 additions & 0 deletions htdocs/compta/bank/various_payment/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright (C) 2017 Laurent Destailleur <[email protected]>
* Copyright (C) 2018 Frédéric France <[email protected]>
* Copyright (C) 2020 Tobias Sekan <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -172,6 +173,7 @@
);

$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

// Security check
$socid = GETPOSTINT("socid");
Expand Down
2 changes: 2 additions & 0 deletions htdocs/compta/facture/invoicetemplate_list.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Copyright (C) 2015-2021 Alexandre Spangaro <[email protected]>
* Copyright (C) 2016 Meziane Sof <[email protected]>
* Copyright (C) 2023 William Mead <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -161,6 +162,7 @@

$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

if ($socid > 0) {
$tmpthirdparty = new Societe($db);
Expand Down
1 change: 1 addition & 0 deletions htdocs/compta/facture/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@

$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

if (!$user->hasRight('societe', 'client', 'voir')) {
$search_sale = $user->id;
Expand Down
2 changes: 2 additions & 0 deletions htdocs/compta/paiement/cheque/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright (C) 2009-2012 Regis Houssin <[email protected]>
* Copyright (C) 2014 Alexandre Spangaro <[email protected]>
* Copyright (C) 2016 Juanjo Menent <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -99,6 +100,7 @@
'bc.statut' => array('label' => "Status", 'checked' => 1, 'position' => 70)
);
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('chequelist'));
Expand Down
2 changes: 2 additions & 0 deletions htdocs/compta/paiement/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Copyright (C) 2018-2021 Ferran Marcet <[email protected]>
* Copyright (C) 2018 Charlene Benke <[email protected]>
* Copyright (C) 2020 Tobias Sekan <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -110,6 +111,7 @@
'p.statut' => array('label' => "Status", 'checked' => 1, 'position' => 90, 'enabled' => (getDolGlobalString('BILL_ADD_PAYMENT_VALIDATION'))),
);
$arrayfields = dol_sort_array($arrayfields, 'position');
'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan

// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('paymentlist'));
Expand Down
Loading

0 comments on commit 1ad4acc

Please sign in to comment.