Support
Quality
Security
License
Reuse
kandi has reviewed ImmersionBar and discovered the below as its top functions. This is intended to give you an instant insight into ImmersionBar implemented functionality, and help decide if they suit your requirements.
android 4.4以上沉浸式状态栏和沉浸式导航栏管理,适配横竖屏切换、刘海屏、软键盘弹出等问题,可以修改状态栏字体颜色和导航栏图标颜色,以及不可修改字体颜色手机的适配,适用于Activity、Fragment、DialogFragment、Dialog,PopupWindow,一句代码轻松实现,以及对bar的其他设置,详见README。简书请参考:http://www.jianshu.com/p/2a884e211a62
使用
// 基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
// fragment快速实现(可选)
implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0'
// kotlin扩展(可选)
implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
关于使用AndroidX支持库
android.useAndroidX=true
android.enableJetifier=true
关于全面屏与刘海
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
Api详解
ImmersionBar.with(this).init();
在Activity中实现沉浸式
ImmersionBar.with(this).init();
在Dialog中实现沉浸式,具体实现参考demo
ImmersionBar.with(this).init();
在PopupWindow中实现沉浸式,具体实现参考demo
popupWindow.setClippingEnabled(false);
状态栏与布局顶部重叠解决方案,六种方案根据不同需求任选其一
<dimen name="status_bar_height">25dp</dimen>
解决EditText和软键盘的问题
ImmersionBar.with(this)
.keyboardEnable(true) //解决软键盘与底部输入框冲突问题
// .keyboardEnable(true, WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
// | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) //软键盘自动弹出
.init();
当白色背景状态栏遇到不能改变状态栏字体为深色的设备时,解决方案
ImmersionBar.with(this)
.statusBarDarkFont(true, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
.init();
混淆规则(proguard-rules.pro)
-keep class com.gyf.immersionbar.* {*;}
-dontwarn com.gyf.immersionbar.**
Execution failed for task ':app:minifyReleaseWithR8'.java.lang.NullPointerException (no error message)
org.gradle.jvmargs=-Xms1024m -Xmx4096m
QUESTION
Execution failed for task ':app:minifyReleaseWithR8'.java.lang.NullPointerException (no error message)
Asked 2020-May-17 at 10:35when id update android studio to 3.6 android gradle tools to 3.6.0 ,there is a problem.when I generate sign apk,I got an exception,it is like this
Execution failed for task ':app:minifyReleaseWithR8'.java.lang.NullPointerException (no error message)
* Exception is:
10:35:36.483 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:minifyReleaseWithR8'.
10:35:36.483 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:166)
10:35:36.483 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:163)
10:35:36.483 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:191)
10:35:36.483 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:156)
10:35:36.484 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
10:35:36.484 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
10:35:36.484 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
10:35:36.484 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
....
Caused by: java.lang.NullPointerException
10:35:36.486 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.A.a(:7)
10:35:36.486 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.A.c(:1)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.w.a(:71)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.w.a(:54)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.w.a(:61)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.w.a(:61)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.w.a(:29)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.naming.G.a(:25)
10:35:36.487 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.R8.a(:615)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.R8.c(:1)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.R8.b(:1)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.utils.O.a(:30)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.R8.runForTesting(:3)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.tools.r8.R8.run(:3)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.builder.dexing.R8Tool.runR8(r8Tool.kt:215)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.R8Task$Companion.shrink(R8Task.kt:387)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.R8Task.doTaskAction(R8Task.kt:268)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.NonIncrementalTask$taskAction$$inlined$recordTaskAction$1.invoke(AndroidVariantTask.kt:73)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.NonIncrementalTask$taskAction$$inlined$recordTaskAction$1.invoke(AndroidVariantTask.kt:34)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.Blocks.recordSpan(Blocks.java:91)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at com.android.build.gradle.internal.tasks.NonIncrementalTask.taskAction(NonIncrementalTask.kt:34)
10:35:36.488 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
....
this is my project build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.70'
apply from:'config.gradle'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
// classpath 'cn.jiguang.android:janalytics-gradle-plugin:3.0.0'
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
and this is my app build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'walle'
def dep = rootProject.ext.dependencies
def and = rootProject.ext.android
android {
compileSdkVersion and.compileSdkVersion
buildToolsVersion and.buildToolsVersion
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
defaultConfig {
applicationId and.appid
minSdkVersion and.minSdkVersion
targetSdkVersion and.targetSdkVersion
versionCode 215006
versionName "3.2"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "armeabi"//, "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "94ea05a225c0f9efc3f9e1db",
JPUSH_CHANNEL : "developer-default",
]
}
signingConfigs {
release {
keyAlias 'cordova-demo'
keyPassword ''
storeFile file('./release-key.keystore')
storePassword ''
v1SigningEnabled true
v2SigningEnabled true
}
debug {
keyAlias 'cordova-demo'
keyPassword ''
storeFile file('./release-key.keystore')
storePassword ''
}
}
buildTypes {
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.debug
buildConfigField("boolean", "ISRELEASE", "${IS_RELEASE}")
}
release {
debuggable false
minifyEnabled true
shrinkResources true /
zipAlignEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField("boolean", "ISRELEASE", "${IS_RELEASE}")
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
encoding = "UTF-8"
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation dep.eventbus
implementation dep.immersionbar
implementation dep.immersionbarfragment
implementation dep.SmartRefreshLayout
// implementation dep.networking
implementation project(':android-networking')
// implementation 'com.amitshekhar.android:jackson-android-networking:1.0.2'
//glide
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation dep.glide
implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0'
implementation 'androidx.annotation:annotation:1.1.0'
annotationProcessor 'androidx.annotation:annotation:1.1.0'
implementation dep.rxjava2
implementation dep.okhttp3
implementation dep.rxandroid
implementation dep.rxbinding2
implementation project(':qmui')
implementation project(':arch')
implementation project(':emoji')
implementation project(':reclib-qq')
implementation 'com.facebook.stetho:stetho:1.1.1'
//flowLayout
implementation(project(':flowlayout-lib')) {
transitive = true
exclude group: 'androidx.appcompat', module: 'appcompat'
}
implementation dep.multidex
implementation dep.banner
implementation dep.toast
implementation dep.brvah
implementation dep.gson
implementation dep.baseadapter
//webview
api dep.agentweb
api 'com.just.agentweb:filechooser:4.1.2'//
api 'com.download.library:Downloader:4.1.2'//
implementation dep.picker_view
implementation dep.picker_picture
// api dep.aliyun
implementation 'com.amap.api:3dmap:7.0.0'
implementation 'com.amap.api:location:4.7.2'
implementation 'com.amap.api:search:6.9.2'
/**kotlin*/
implementation "androidx.core:core-ktx:1.2.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//utils
implementation 'com.blankj:utilcode:1.25.9'
//tablayout//https://github.com/H07000223/FlycoTabLayout
implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
//butter knife
implementation "com.jakewharton:butterknife:$butterknifeVersion"
annotationProcessor "com.jakewharton:butterknife-compiler:$butterknifeVersion"
// api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.5.7'
api 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.3.1'
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
implementation 'com.kingja.loadsir:loadsir:1.3.6'
/*lottie*/
implementation('com.airbnb.android:lottie:3.2.0') { exclude group: 'com.androidx' }
implementation 'cn.jiguang.sdk:jmessage:2.9.0' //
implementation 'cn.jiguang.sdk:jcore:2.3.0' //
implementation project(':reclib-testemoticons')
implementation 'cn.jiguang.sdk:jpush:3.5.8' //
implementation 'cn.jiguang.sdk:janalytics:2.1.0' //
implementation 'com.github.chrisbanes.photoview:library:1.2.4'
implementation 'com.github.mtotschnig:StickyListHeaders:2.7.1'
implementation 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
implementation 'com.yanzhenjie:permission:2.0.3'
debugImplementation 'com.didichuxing.doraemonkit:doraemonkit:3.0_beta2'
releaseImplementation 'com.didichuxing.doraemonkit:doraemonkit-no-op:3.0_beta2'
// api project(path: ':LibEasyGlide')
implementation 'com.binioter:guideview:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
//bugly
implementation 'com.tencent.bugly:crashreport:3.1.7'
implementation 'com.tencent.bugly:nativecrashreport:3.7.1'
implementation 'com.meituan.android.walle:library:1.1.6'
implementation "com.google.android.material:material:$materialVersion"
api project(path: ':LibEasyGlide')
}
walle {
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}.apk';
//apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
channelFile = new File("${project.getProjectDir()}/channel")
}
I suspect it's the problem with proguard-rules.pro but don't know where it is
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dontshrink
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-keep class com.just.agentweb.** {
*;
}
-dontwarn com.just.agentweb.**
-keepclassmembers class com.yiguan.chuzhu.common.AndroidInterface{ *; }
#glide start
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#glide end
-keep class com.youth.banner.** {
*;
}
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.**{*;}
-keep class com.amap.api.trace.**{*;}
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
#utils
-keep class com.blankj.utilcode.** { *; }
-keepclassmembers class com.blankj.utilcode.** { *; }
-dontwarn com.blankj.utilcode.**
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.preference.Preference
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep public class * extends androidx.appcompat
-keep class androidx.**{*;}
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
public static *** e(...);
public static *** w(...);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep public class com.yiguan.chuzhu.R$*{
public static final int *;
}
-keep class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, jav.lang.String);
}
-keep class * extends com.yiguan.chuzhu.base.BaseModel {*;}
# Keep native methods
-keepclassmembers class * {
native <methods>;
}
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
# Gson
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
#-keep class com.example.bean.** { *; }
# ButterKnife
-keep public class * implements butterknife.Unbinder {
public <init>(**, android.view.View);
}
-keep class butterknife.*
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-dontnote rx.internal.util.PlatformDependent
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
#evebtbus
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
-keep class com.tencent.mm.opensdk.** {
*;
}
-keep class com.tencent.wxop.** {
*;
}
-keep class com.tencent.mm.sdk.** {
*;
}
#loadSir
-dontwarn com.kingja.loadsir.**
-keep class com.kingja.loadsir.** {*;}
-dontoptimize
-dontpreverify
-keepattributes EnclosingMethod,Signature
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
-dontwarn cn.jmessage.**
-keep class cn.jmessage.**{ *; }
-keepclassmembers class ** {
public void onEvent*(**);
}
#========================gson================================
#-dontwarn com.google.**
#-keep class com.google.gson.** {*;}
#========================protobuf================================
-keep class com.google.protobuf.** {*;}
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
#PictureSelector 2.0
-keep class com.luck.picture.lib.** { *; }
-dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }
# immersionbar
-keep class com.gyf.immersionbar.* {*;}
-dontwarn com.gyf.immersionbar.**
#activeandroid
-keep class com.activeandroid.** { *; }
-dontwarn com.ikoding.app.biz.dataobject.**
-dontwarn com.activeandroid.**
-keep public class com.ikoding.app.biz.dataobject.** { *;}
-keepattributes *Annotation*
-keep class cn.jiguang.** { *; }
-keep class android.support.** { *; }
-keep class androidx.** { *; }
-keep class com.google.android.** { *; }
# bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
It has bothered me for a while, I have been using 3.5.3 now
ANSWER
Answered 2020-Mar-30 at 06:39This looks like a known issue. Please see http://issuetracker.google.com/150325706#comment25 for how to use a version of R8 where this has been fixed.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
No vulnerabilities reported
Save this library and start creating your kit
Explore Related Topics
Save this library and start creating your kit