Skip to content
Permalink
Browse files

Merge pull request #38464 from rldhont/trust-layer-metadata-propagation

Trust layer metadata propagation
  • Loading branch information
elpaso committed Sep 11, 2020
2 parents c76a32a + 02cff9f commit 63d8ee7fab107a5138748d7ea345bc42ec26b223
Showing with 419 additions and 181 deletions.
  1. +3 −1 python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in
  2. +16 −2 python/core/auto_generated/qgsdataprovider.sip.in
  3. +1 −0 python/core/auto_generated/qgsmaplayer.sip.in
  4. +7 −1 python/core/auto_generated/qgsprovidermetadata.sip.in
  5. +3 −1 python/core/auto_generated/qgsproviderregistry.sip.in
  6. +4 −2 python/core/auto_generated/qgsvectordataprovider.sip.in
  7. +4 −2 python/core/auto_generated/raster/qgsrasterdataprovider.sip.in
  8. +2 −1 python/core/auto_generated/raster/qgsrasterlayer.sip.in
  9. +3 −2 src/core/mesh/qgsmeshdataprovider.cpp
  10. +3 −1 src/core/mesh/qgsmeshdataprovider.h
  11. +14 −4 src/core/mesh/qgsmeshlayer.cpp
  12. +2 −1 src/core/mesh/qgsmeshlayer.h
  13. +2 −2 src/core/providers/gdal/qgsgdalprovider.cpp
  14. +1 −1 src/core/providers/gdal/qgsgdalprovider.h
  15. +6 −4 src/core/providers/memory/qgsmemoryprovider.cpp
  16. +4 −2 src/core/providers/memory/qgsmemoryprovider.h
  17. +8 −4 src/core/providers/meshmemory/qgsmeshmemorydataprovider.cpp
  18. +5 −2 src/core/providers/meshmemory/qgsmeshmemorydataprovider.h
  19. +5 −4 src/core/providers/ogr/qgsogrprovider.cpp
  20. +3 −2 src/core/providers/ogr/qgsogrprovider.h
  21. +3 −1 src/core/qgsdataprovider.cpp
  22. +25 −4 src/core/qgsdataprovider.h
  23. +1 −0 src/core/qgsmaplayer.h
  24. +5 −3 src/core/qgspluginlayer.cpp
  25. +3 −1 src/core/qgspluginlayer.h
  26. +3 −0 src/core/qgsproject.cpp
  27. +4 −2 src/core/qgsprovidermetadata.cpp
  28. +9 −2 src/core/qgsprovidermetadata.h
  29. +4 −2 src/core/qgsproviderregistry.cpp
  30. +3 −1 src/core/qgsproviderregistry.h
  31. +3 −2 src/core/qgsvectordataprovider.cpp
  32. +4 −2 src/core/qgsvectordataprovider.h
  33. +15 −4 src/core/qgsvectorlayer.cpp
  34. +2 −1 src/core/qgsvectorlayer.h
  35. +4 −3 src/core/raster/qgsrasterdataprovider.cpp
  36. +4 −2 src/core/raster/qgsrasterdataprovider.h
  37. +21 −5 src/core/raster/qgsrasterlayer.cpp
  38. +2 −1 src/core/raster/qgsrasterlayer.h
  39. +4 −4 src/providers/arcgisrest/qgsafsprovider.cpp
  40. +2 −2 src/providers/arcgisrest/qgsafsprovider.h
  41. +4 −4 src/providers/arcgisrest/qgsamsprovider.cpp
  42. +2 −2 src/providers/arcgisrest/qgsamsprovider.h
  43. +9 −4 src/providers/db2/qgsdb2provider.cpp
  44. +3 −2 src/providers/db2/qgsdb2provider.h
  45. +4 −4 src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
  46. +2 −2 src/providers/delimitedtext/qgsdelimitedtextprovider.h
  47. +4 −4 src/providers/gpx/qgsgpxprovider.cpp
  48. +2 −2 src/providers/gpx/qgsgpxprovider.h
  49. +2 −1 src/providers/grass/qgsgrassprovidermodule.cpp
  50. +2 −1 src/providers/grass/qgsgrassrasterprovidermodule.cpp
  51. +4 −4 src/providers/mdal/qgsmdalprovider.cpp
  52. +2 −2 src/providers/mdal/qgsmdalprovider.h
  53. +11 −5 src/providers/mssql/qgsmssqlprovider.cpp
  54. +3 −2 src/providers/mssql/qgsmssqlprovider.h
  55. +17 −4 src/providers/oracle/qgsoracleprovider.cpp
  56. +4 −2 src/providers/oracle/qgsoracleprovider.h
  57. +4 −4 src/providers/ows/qgsowsprovider.cpp
  58. +2 −2 src/providers/ows/qgsowsprovider.h
  59. +70 −7 src/providers/postgres/qgspostgresprovider.cpp
  60. +4 −2 src/providers/postgres/qgspostgresprovider.h
  61. +6 −6 src/providers/postgres/raster/qgspostgresrasterprovider.cpp
  62. +3 −3 src/providers/postgres/raster/qgspostgresrasterprovider.h
  63. +5 −4 src/providers/spatialite/qgsspatialiteprovider.cpp
  64. +2 −2 src/providers/spatialite/qgsspatialiteprovider.h
  65. +7 −4 src/providers/virtual/qgsvirtuallayerprovider.cpp
  66. +2 −2 src/providers/virtual/qgsvirtuallayerprovider.h
  67. +4 −4 src/providers/wcs/qgswcsprovider.cpp
  68. +2 −2 src/providers/wcs/qgswcsprovider.h
  69. +4 −4 src/providers/wfs/qgsoapifprovider.cpp
  70. +2 −2 src/providers/wfs/qgsoapifprovider.h
  71. +2 −1 src/providers/wfs/qgswfsprovider.cpp
  72. +1 −1 src/providers/wfs/qgswfsprovider.h
  73. +2 −1 src/providers/wms/qgswmsprovider.cpp
  74. +1 −1 src/providers/wms/qgswmsprovider.h
  75. +4 −3 tests/src/python/provider_python.py
@@ -393,7 +393,9 @@ Responsible for reading native mesh data
#include "qgsmeshdataprovider.h"
%End
public:
QgsMeshDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions );
QgsMeshDataProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
%Docstring
Ctor
%End
@@ -61,14 +61,25 @@ Abstract base class for spatial data provider implementations.

struct ProviderOptions
{

QgsCoordinateTransformContext transformContext;

};

enum ReadFlag
{
FlagTrustDataSource,
};
typedef QFlags<QgsDataProvider::ReadFlag> ReadFlags;


QgsDataProvider( const QString &uri = QString(), const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions() );
QgsDataProvider( const QString &uri = QString(),
const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions(),
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
%Docstring
Create a new dataprovider with the specified in the ``uri``.

Additional creation options are specified within the ``options`` value.
Additional creation options are specified within the ``options`` value and since QGIS 3.16 creation flags are specified within the ``flags`` value.
%End

virtual QgsCoordinateReferenceSystem crs() const = 0;
@@ -477,8 +488,11 @@ Add error message
Sets error message
%End


};

QFlags<QgsDataProvider::ReadFlag> operator|(QgsDataProvider::ReadFlag f1, QFlags<QgsDataProvider::ReadFlag> f2);


/************************************************************************
* This file has been generated automatically from *
@@ -537,6 +537,7 @@ or layer with temporary data (as temporary mesh layer dataset)
enum ReadFlag
{
FlagDontResolveLayers,
FlagTrustLayerMetadata,
};
typedef QFlags<QgsMapLayer::ReadFlag> ReadFlags;

@@ -180,10 +180,16 @@ Builds the list of available mesh drivers metadata
.. versionadded:: 3.12
%End

virtual QgsDataProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options ) /Factory/;
virtual QgsDataProvider *createProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &options,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) /Factory/;
%Docstring
Class factory to return a pointer to a newly created QgsDataProvider object

:param uri: the datasource uri
:param options: creation options
:param flags: creation flags, sing QGIS 3.16

.. versionadded:: 3.10
%End

@@ -78,13 +78,15 @@ Sets library directory where to search for plugins

QgsDataProvider *createProvider( const QString &providerKey,
const QString &dataSource,
const QgsDataProvider::ProviderOptions &options = QgsDataProvider::ProviderOptions() ) /Factory/;
const QgsDataProvider::ProviderOptions &options = QgsDataProvider::ProviderOptions(),
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) /Factory/;
%Docstring
Creates a new instance of a provider.

:param providerKey: identifier of the provider
:param dataSource: string containing data source for the provider
:param options: provider options
:param flags: provider flags since QGIS 3.16

:return: new instance of provider or ``None`` on error

@@ -68,13 +68,15 @@ of feature and attribute information from a spatial datasource.
UnknownCount,
};

QgsVectorDataProvider( const QString &uri = QString(), const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions() );
QgsVectorDataProvider( const QString &uri = QString(),
const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions(),
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
%Docstring
Constructor for a vector data provider.

The ``uri`` argument specifies the uniform resource locator (URI) for the associated dataset.

Additional creation options are specified within the ``options`` value.
Additional creation options are specified within the ``options`` value and since QGIS 3.16 creation flags are specified within the ``flags`` value.
%End

virtual QgsAbstractFeatureSource *featureSource() const = 0 /Factory/;
@@ -84,14 +84,16 @@ Base class for raster data providers.

QgsRasterDataProvider();

QgsRasterDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions() );
QgsRasterDataProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &providerOptions = QgsDataProvider::ProviderOptions(),
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
%Docstring
Constructor for QgsRasterDataProvider.

The ``uri`` argument gives a provider-specific uri indicating the underlying data
source and it's parameters.

The ``options`` argument specifies generic provider options.
The ``options`` argument specifies generic provider options and since QGIS 3.16 creation flags are specified within the ``flags`` value.
%End

virtual QgsRasterInterface *clone() const = 0;
@@ -141,12 +141,13 @@ Set the data provider.
Use the version with ProviderOptions instead.
%End

void setDataProvider( const QString &provider, const QgsDataProvider::ProviderOptions &options );
void setDataProvider( const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
%Docstring
Set the data provider.

:param provider: provider key string, must match a valid QgsRasterDataProvider key. E.g. "gdal", "wms", etc.
:param options: provider options
:param flags: provider flags since QGIS 3.16

.. versionadded:: 3.2
%End
@@ -20,8 +20,9 @@
#include "qgsmeshdataprovidertemporalcapabilities.h"
#include "qgsrectangle.h"

QgsMeshDataProvider::QgsMeshDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options )
: QgsDataProvider( uri, options )
QgsMeshDataProvider::QgsMeshDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
: QgsDataProvider( uri, options, flags )
{
}

@@ -399,7 +399,9 @@ class CORE_EXPORT QgsMeshDataProvider: public QgsDataProvider, public QgsMeshDat
Q_OBJECT
public:
//! Ctor
QgsMeshDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions );
QgsMeshDataProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

QgsMeshDataProviderTemporalCapabilities *temporalCapabilities() override;
const QgsMeshDataProviderTemporalCapabilities *temporalCapabilities() const override SIP_SKIP;
@@ -54,7 +54,12 @@ QgsMeshLayer::QgsMeshLayer( const QString &meshLayerPath,
if ( !meshLayerPath.isEmpty() && !providerKey.isEmpty() )
{
QgsDataProvider::ProviderOptions providerOptions { options.transformContext };
ok = setDataProvider( providerKey, providerOptions );
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
ok = setDataProvider( providerKey, providerOptions, flags );
}

if ( ok )
@@ -1111,7 +1116,12 @@ bool QgsMeshLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &con
}

QgsDataProvider::ProviderOptions providerOptions;
if ( !setDataProvider( mProviderKey, providerOptions ) )
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
if ( !setDataProvider( mProviderKey, providerOptions, flags ) )
{
return false;
}
@@ -1242,14 +1252,14 @@ QStringList QgsMeshLayer::subLayers() const
}


bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options )
bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
delete mDataProvider;

mProviderKey = provider;
QString dataSource = mDataSource;

mDataProvider = qobject_cast<QgsMeshDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, dataSource, options ) );
mDataProvider = qobject_cast<QgsMeshDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, dataSource, options, flags ) );
if ( !mDataProvider )
{
QgsDebugMsgLevel( QStringLiteral( "Unable to get mesh data provider" ), 2 );
@@ -721,8 +721,9 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
* Binds layer to a specific data provider
* \param provider provider key string, must match a valid QgsMeshDataProvider key. E.g. "mesh_memory", etc.
* \param options generic provider options
* \param flags provider flags since QGIS 3.16
*/
bool setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options );
bool setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

#ifdef SIP_RUN
QgsMeshLayer( const QgsMeshLayer &rhs );
@@ -2351,9 +2351,9 @@ QString QgsGdalProviderMetadata::encodeUri( const QVariantMap &parts )
}


QgsGdalProvider *QgsGdalProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options )
QgsGdalProvider *QgsGdalProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
return new QgsGdalProvider( uri, options );
return new QgsGdalProvider( uri, options, flags );
}

/**
@@ -367,7 +367,7 @@ class QgsGdalProviderMetadata final: public QgsProviderMetadata
QgsGdalProviderMetadata();
QVariantMap decodeUri( const QString &uri ) override;
QString encodeUri( const QVariantMap &parts ) override;
QgsGdalProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options ) override;
QgsGdalProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
QgsGdalProvider *createRasterDataProvider(
const QString &uri,
const QString &format,
@@ -32,8 +32,8 @@
#define TEXT_PROVIDER_KEY QStringLiteral( "memory" )
#define TEXT_PROVIDER_DESCRIPTION QStringLiteral( "Memory provider" )

QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions &options )
: QgsVectorDataProvider( uri, options )
QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions &options, QgsDataProvider::ReadFlags flags )
: QgsVectorDataProvider( uri, options, flags )
{
// Initialize the geometry with the uri to support old style uri's
// (ie, just 'point', 'line', 'polygon')
@@ -227,9 +227,11 @@ QString QgsMemoryProvider::providerDescription()
return TEXT_PROVIDER_DESCRIPTION;
}

QgsMemoryProvider *QgsMemoryProvider::createProvider( const QString &uri, const ProviderOptions &options )
QgsMemoryProvider *QgsMemoryProvider::createProvider( const QString &uri,
const ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
{
return new QgsMemoryProvider( uri, options );
return new QgsMemoryProvider( uri, options, flags );
}

QgsAbstractFeatureSource *QgsMemoryProvider::featureSource() const
@@ -31,7 +31,8 @@ class QgsMemoryProvider final: public QgsVectorDataProvider
Q_OBJECT

public:
explicit QgsMemoryProvider( const QString &uri, const QgsVectorDataProvider::ProviderOptions &coordinateTransformContext );
explicit QgsMemoryProvider( const QString &uri, const QgsVectorDataProvider::ProviderOptions &coordinateTransformContext,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

~QgsMemoryProvider() override;

@@ -44,7 +45,8 @@ class QgsMemoryProvider final: public QgsVectorDataProvider
* Creates a new memory provider, with provider properties embedded within the given \a uri and \a options
* argument.
*/
static QgsMemoryProvider *createProvider( const QString &uri, const QgsVectorDataProvider::ProviderOptions &coordinateTransformContext );
static QgsMemoryProvider *createProvider( const QString &uri, const QgsVectorDataProvider::ProviderOptions &coordinateTransformContext,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

/* Implementation of functions from QgsVectorDataProvider */

@@ -45,8 +45,10 @@ QgsCoordinateReferenceSystem QgsMeshMemoryDataProvider::crs() const
return QgsCoordinateReferenceSystem();
}

QgsMeshMemoryDataProvider::QgsMeshMemoryDataProvider( const QString &uri, const ProviderOptions &options )
: QgsMeshDataProvider( uri, options )
QgsMeshMemoryDataProvider::QgsMeshMemoryDataProvider( const QString &uri,
const ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
: QgsMeshDataProvider( uri, options, flags )
{
QString data( uri );
// see QgsMeshLayer::setDataProvider how mDataSource is created for memory layers
@@ -69,9 +71,11 @@ QString QgsMeshMemoryDataProvider::providerDescription()
return TEXT_PROVIDER_DESCRIPTION;
}

QgsMeshMemoryDataProvider *QgsMeshMemoryDataProvider::createProvider( const QString &uri, const ProviderOptions &options )
QgsMeshMemoryDataProvider *QgsMeshMemoryDataProvider::createProvider( const QString &uri,
const ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
{
return new QgsMeshMemoryDataProvider( uri, options );
return new QgsMeshMemoryDataProvider( uri, options, flags );
}

bool QgsMeshMemoryDataProvider::splitMeshSections( const QString &uri )
@@ -83,7 +83,8 @@ class CORE_EXPORT QgsMeshMemoryDataProvider final: public QgsMeshDataProvider
* );
* \endcode
*/
QgsMeshMemoryDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions );
QgsMeshMemoryDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

bool isValid() const override;
QString name() const override;
@@ -157,7 +158,9 @@ class CORE_EXPORT QgsMeshMemoryDataProvider final: public QgsMeshDataProvider
//! Returns the memory provider description
static QString providerDescription();
//! Provider factory
static QgsMeshMemoryDataProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions );
static QgsMeshMemoryDataProvider *createProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

private:
QgsRectangle calculateExtent( ) const;
@@ -482,8 +482,8 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr
return QgsVectorLayerExporter::NoError;
}

QgsOgrProvider::QgsOgrProvider( QString const &uri, const ProviderOptions &options )
: QgsVectorDataProvider( uri, options )
QgsOgrProvider::QgsOgrProvider( QString const &uri, const ProviderOptions &options, QgsDataProvider::ReadFlags flags )
: QgsVectorDataProvider( uri, options, flags )
{
QgsApplication::registerOgrDrivers();

@@ -3564,9 +3564,10 @@ QStringList QgsOgrProviderUtils::wildcards()
* Class factory to return a pointer to a newly created
* QgsOgrProvider object
*/
QgsOgrProvider *QgsOgrProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options )
QgsOgrProvider *QgsOgrProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
{
return new QgsOgrProvider( uri, options );
return new QgsOgrProvider( uri, options, flags );
}

/**
@@ -86,7 +86,8 @@ class QgsOgrProvider final: public QgsVectorDataProvider
* \param options generic data provider options
*/
explicit QgsOgrProvider( QString const &uri,
const QgsDataProvider::ProviderOptions &providerOptions );
const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );

~QgsOgrProvider() override;

@@ -742,7 +743,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
void initProvider() override;
void cleanupProvider() override;
QList< QgsDataItemProvider * > dataItemProviders() const override;
QgsOgrProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options ) override;
QgsOgrProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
QVariantMap decodeUri( const QString &uri ) override;
QString encodeUri( const QVariantMap &parts ) override;
QString filters( FilterType type ) override;
@@ -19,10 +19,12 @@

#define SUBLAYER_SEPARATOR QStringLiteral( "!!::!!" )

QgsDataProvider::QgsDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions )
QgsDataProvider::QgsDataProvider( const QString &uri, const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags )
: mDataSourceURI( uri ),
mOptions( providerOptions )
{
mReadFlags = flags;
}

QgsDataProviderTemporalCapabilities *QgsDataProvider::temporalCapabilities()

0 comments on commit 63d8ee7

Please sign in to comment.
You can’t perform that action at this time.