Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 4.29.4 #560

Merged
merged 35 commits into from
Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c50e67e
Add notice for move to help center
Sporiff Jun 30, 2021
c689f79
Create admob.md
Alzbeta-Knerova Jun 23, 2021
dceb08a
Create admob.md
Alzbeta-Knerova Jun 23, 2021
c582b5e
Create admob.md
Alzbeta-Knerova Jun 23, 2021
511c37b
Update README.md
Alzbeta-Knerova Jul 8, 2021
3d60854
Update README.md
Alzbeta-Knerova Jul 8, 2021
9ec7dc7
Update README.md
Alzbeta-Knerova Jul 8, 2021
98002ad
skip sending IDFA if zeroed
uerceg Jul 8, 2021
92bcd60
Small add idfa refac
nonelse Jul 8, 2021
ac6104e
fix(ADJUtil): iad-adgroup-name: AdGroupName, both capitalizations
buschtoens Mar 30, 2021
69a05e6
[fix] #550 Added ADJLinkResolution.h import in adjust.h
drlukas6 Jul 15, 2021
7251f1e
Create applovin-max.md
Alzbeta-Knerova Jul 19, 2021
d3b68e5
Create applovin-max.md
Alzbeta-Knerova Jul 19, 2021
20a1bfe
Create applovin-max.md
Alzbeta-Knerova Jul 19, 2021
bc48937
Create ironsource.md
Alzbeta-Knerova Jul 19, 2021
151700f
Create ironsource.md
Alzbeta-Knerova Jul 19, 2021
06a05c6
Create ironsource.md
Alzbeta-Knerova Jul 19, 2021
94c4cd6
Remove C style casts and use boolValue and intValue methods to avoid
sbehnke Jul 15, 2021
a758faa
improve timestamp date formatting
uerceg Jul 16, 2021
ed11ec3
use NSCalendarIdentifierGregorian by default
uerceg Jul 19, 2021
062fdc2
fix random strings deallocation before being processed by the plugin
uerceg Jul 16, 2021
0cbf45e
Update README.md
Alzbeta-Knerova Jul 26, 2021
a97ca70
Update README.md
Alzbeta-Knerova Jul 26, 2021
14addc2
Update README.md
Alzbeta-Knerova Jul 26, 2021
9b5b5be
update admob.md
uerceg Aug 5, 2021
df416dc
Annotate code referencing APIs annotated as unavailable for iOS exten…
cabeca Jul 15, 2021
b8e2513
cleanup
uerceg Aug 6, 2021
83f5f75
update version number to 4.29.4
uerceg Aug 6, 2021
8542f77
upate CHANGELOG
uerceg Aug 6, 2021
485e739
guard against performSelector: nil return values
uerceg Aug 6, 2021
96ded0e
fix return value in deleteFileInPath:
uerceg Aug 6, 2021
b05d75d
make Obj-C example app iOS 14.5+ friendly
uerceg Aug 9, 2021
3e8cfd3
remove commented out code
uerceg Aug 9, 2021
13e67c5
improve AdServices.framework integration logging a bit
uerceg Aug 9, 2021
f7a9fb6
update CHANGELOG
uerceg Aug 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Adjust.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = "Adjust"
s.version = "4.29.3"
s.version = "4.29.4"
s.summary = "This is the iOS SDK of adjust. You can read more about it at http://adjust.com."
s.homepage = "https://github.com/adjust/ios_sdk"
s.license = { :type => 'MIT', :file => 'MIT-LICENSE' }
s.author = { "Christian Wellenbrock" => "[email protected]" }
s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.29.3" }
s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.29.4" }
s.ios.deployment_target = '6.0'
s.tvos.deployment_target = '9.0'
s.framework = 'SystemConfiguration'
Expand Down
8 changes: 7 additions & 1 deletion Adjust/ADJActivityHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ @interface ADJActivityHandler()
@property (nonatomic, copy) NSString* gdprPath;
@property (nonatomic, copy) NSString* subscriptionPath;

- (void)prepareDeeplinkI:(ADJActivityHandler *_Nullable)selfI
responseData:(ADJAttributionResponseData *_Nullable)attributionResponseData NS_EXTENSION_UNAVAILABLE_IOS("");

@end

// copy from ADClientError
Expand Down Expand Up @@ -1764,6 +1767,9 @@ - (BOOL)shouldFetchAdServicesI:(ADJActivityHandler *)selfI {
}

// Fetch if no attribution OR not sent to backend yet
if ([ADJUserDefaults getAdServicesTracked]) {
[selfI.logger debug:@"AdServices attribution info already read"];
}
return (selfI.attribution == nil || ![ADJUserDefaults getAdServicesTracked]);
}

Expand Down Expand Up @@ -2736,7 +2742,7 @@ - (void)registerForSKAdNetworkAttribution {

Class skAdNetwork = NSClassFromString(@"SKAdNetwork");
if (skAdNetwork == nil) {
[logger warn:@"StoreKit framework not found in user's app (SKAdNetwork not found)"];
[logger warn:@"StoreKit framework not found in the app (SKAdNetwork not found)"];
return;
}

Expand Down
1 change: 0 additions & 1 deletion Adjust/ADJActivityState.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ - (BOOL)findTransactionId:(NSString *)transactionId {
#pragma mark - Private & helper methods

- (void)assignRandomToken:(NSString *)randomToken {
// self.secondaryDedupeToken = [[NSUUID UUID] UUIDString];
NSString *persistedDedupeToken = [ADJUtil getPersistedRandomToken];
if (persistedDedupeToken != nil) {
if ((bool)[[NSUUID alloc] initWithUUIDString:persistedDedupeToken]) {
Expand Down
105 changes: 54 additions & 51 deletions Adjust/ADJPackageBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright (c) 2013-2018 Adjust GmbH. All rights reserved.
//

#include <string.h>

#import "ADJUtil.h"
#import "ADJAttribution.h"
#import "ADJAdjustFactory.h"
Expand Down Expand Up @@ -295,28 +297,40 @@ - (void)signWithSigV2Plugin:(ADJActivityPackage *)activityPackage {
if (signerClass == nil) {
return;
}

SEL signSEL = NSSelectorFromString(@"sign:withActivityKind:withSdkVersion:");
if (![signerClass respondsToSelector:signSEL]) {
return;
}

NSMutableDictionary * parameters = activityPackage.parameters;
const char * activityKindChar = [[ADJActivityKindUtil activityKindToString:activityPackage.activityKind] UTF8String];
const char * sdkVersionChar = [activityPackage.clientSdk UTF8String];
NSMutableDictionary *parameters = activityPackage.parameters;
const char *activityKindChar = [[ADJActivityKindUtil activityKindToString:activityPackage.activityKind] UTF8String];
const char *sdkVersionChar = [activityPackage.clientSdk UTF8String];

// Stack allocated strings to ensure their lifetime stays until the next iteration
static char activityKind[51], sdkVersion[21];
strncpy(activityKind, activityKindChar, strlen(activityKindChar) + 1);
strncpy(sdkVersion, sdkVersionChar, strlen(sdkVersionChar) + 1);

// NSInvocation setArgument requires lvalue references with exact matching types to the executed function signature.
// With this usage we ensure that the lifetime of the object remains until the next iteration, as it points to the
// stack allocated string where we copied the buffer.
const char *lvalActivityKind = activityKind;
const char *lvalSdkVersion = sdkVersion;

/*
[ADJSigner sign:parameters
withActivityKind:activityKindChar
withSdkVersion:sdkVersionChar];
withActivityKind:activityKindChar
withSdkVersion:sdkVersionChar];
*/

NSMethodSignature *signMethodSignature = [signerClass methodSignatureForSelector:signSEL];
NSInvocation *signInvocation = [NSInvocation invocationWithMethodSignature:signMethodSignature];
[signInvocation setSelector: signSEL];
[signInvocation setSelector:signSEL];
[signInvocation setTarget:signerClass];

[signInvocation setArgument:&parameters atIndex: 2];
[signInvocation setArgument:&activityKindChar atIndex: 3];
[signInvocation setArgument:&sdkVersionChar atIndex: 4];
[signInvocation setArgument:&parameters atIndex:2];
[signInvocation setArgument:&lvalActivityKind atIndex:3];
[signInvocation setArgument:&lvalSdkVersion atIndex:4];

[signInvocation invoke];

Expand All @@ -325,17 +339,14 @@ - (void)signWithSigV2Plugin:(ADJActivityPackage *)activityPackage {
return;
}
/*
NSString *signerVersion = [ADJSigner getVersion];
NSString *signerVersion = [ADJSigner getVersion];
*/
IMP getVersionIMP = [signerClass methodForSelector:getVersionSEL];
if (!getVersionIMP) {
return;
}

id (*getVersionFunc)(id, SEL) = (void *)getVersionIMP;

id signerVersion = getVersionFunc(signerClass, getVersionSEL);

if (![signerVersion isKindOfClass:[NSString class]]) {
return;
}
Expand All @@ -344,7 +355,6 @@ - (void)signWithSigV2Plugin:(ADJActivityPackage *)activityPackage {
[ADJPackageBuilder parameters:parameters
setString:signerVersionString
forKey:@"native_version"];

}

- (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay {
Expand All @@ -364,9 +374,7 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay {
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -431,9 +439,7 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ
[ADJPackageBuilder parameters:parameters setString:event.eventToken forKey:@"event_token"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -518,9 +524,7 @@ - (NSMutableDictionary *)getInfoParameters:(NSString *)source {
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -589,9 +593,7 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -651,9 +653,7 @@ - (NSMutableDictionary *)getAdRevenueParameters:(ADJAdRevenue *)adRevenue isInDe
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -735,9 +735,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source {
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -804,9 +802,7 @@ - (NSMutableDictionary *)getAttributionParameters:(NSString *)initiatedBy {
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.environment forKey:@"environment"];
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setString:initiatedBy forKey:@"initiated_by"];
Expand Down Expand Up @@ -857,9 +853,7 @@ - (NSMutableDictionary *)getGdprParameters {
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.environment forKey:@"environment"];
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -915,9 +909,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters {
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -982,9 +974,7 @@ - (NSMutableDictionary *)getThirdPartySharingParameters:(nonnull ADJThirdPartySh
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -1055,9 +1045,7 @@ - (NSMutableDictionary *)getMeasurementConsentParameters:(BOOL)enabled {
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -1119,9 +1107,7 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti
[ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"];
[ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.fbAnonymousId forKey:@"fb_anon_id"];
if (self.adjustConfig.allowIdfaReading == YES) {
[ADJPackageBuilder parameters:parameters setString:[ADJUtil idfa] forKey:@"idfa"];
}
[self addIdfaIfPossibleToParameters:parameters];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.idfv forKey:@"idfv"];
[ADJPackageBuilder parameters:parameters setString:self.packageParams.installedAt forKey:@"installed_at"];
[ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"];
Expand Down Expand Up @@ -1181,6 +1167,23 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti
return parameters;
}

- (void)addIdfaIfPossibleToParameters:(NSMutableDictionary *)parameters {
if (! self.adjustConfig.allowIdfaReading) {
return;
}

NSString *idfa = [ADJUtil idfa];

if (idfa == nil
|| idfa.length == 0
|| [idfa isEqualToString:@"00000000-0000-0000-0000-000000000000"])
{
return;
}

[ADJPackageBuilder parameters:parameters setString:idfa forKey:@"idfa"];
}

- (ADJActivityPackage *)defaultActivityPackage {
ADJActivityPackage *activityPackage = [[ADJActivityPackage alloc] init];
activityPackage.clientSdk = self.packageParams.clientSdk;
Expand Down
4 changes: 2 additions & 2 deletions Adjust/ADJUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ typedef void (^isInactiveInjected)(BOOL);

+ (void)excludeFromBackup:(NSString *)filename;

+ (void)launchDeepLinkMain:(NSURL *)deepLinkUrl;
+ (void)launchDeepLinkMain:(NSURL *)deepLinkUrl NS_EXTENSION_UNAVAILABLE_IOS("");

+ (void)launchInMainThread:(dispatch_block_t)block;

+ (BOOL)isMainThread;

+ (BOOL)isInactive;
+ (BOOL)isInactive NS_EXTENSION_UNAVAILABLE_IOS("");

+ (void)launchInMainThreadWithInactive:(isInactiveInjected)isInactiveblock;

Expand Down
Loading