mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2024-11-10 01:02:22 +01:00
chore: Merge branch dev
to main
(#264)
This commit is contained in:
commit
f8306ac43d
8 changed files with 93 additions and 27 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -1,3 +1,17 @@
|
||||||
|
# [19.2.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v19.1.1-dev.1...v19.2.0-dev.1) (2023-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `PatchExtensions#registerNewPatchOption` function to simplify instantiation and registration of patch options ([4a91845](https://github.com/ReVanced/revanced-patcher/commit/4a9184597be99cd458496cce0ee68994e6b8735c))
|
||||||
|
|
||||||
|
## [19.1.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v19.1.0...v19.1.1-dev.1) (2023-12-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Accept `PatchSet` in `PatchesConsumer#acceptPatches` ([716825f](https://github.com/ReVanced/revanced-patcher/commit/716825f232bf1aab3a97723968562aa6dbdb20b1))
|
||||||
|
|
||||||
# [19.1.0](https://github.com/ReVanced/revanced-patcher/compare/v19.0.0...v19.1.0) (2023-12-01)
|
# [19.1.0](https://github.com/ReVanced/revanced-patcher/compare/v19.0.0...v19.1.0) (2023-12-01)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ public final class app/revanced/patcher/Patcher : app/revanced/patcher/Integrati
|
||||||
public fun <init> (Lapp/revanced/patcher/PatcherOptions;)V
|
public fun <init> (Lapp/revanced/patcher/PatcherOptions;)V
|
||||||
public fun acceptIntegrations (Ljava/util/List;)V
|
public fun acceptIntegrations (Ljava/util/List;)V
|
||||||
public fun acceptPatches (Ljava/util/List;)V
|
public fun acceptPatches (Ljava/util/List;)V
|
||||||
|
public fun acceptPatches (Ljava/util/Set;)V
|
||||||
public synthetic fun apply (Ljava/lang/Object;)Ljava/lang/Object;
|
public synthetic fun apply (Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
public fun apply (Z)Lkotlinx/coroutines/flow/Flow;
|
public fun apply (Z)Lkotlinx/coroutines/flow/Flow;
|
||||||
public fun close ()V
|
public fun close ()V
|
||||||
|
@ -99,6 +100,11 @@ public final class app/revanced/patcher/PatcherResult$PatchedDexFile {
|
||||||
|
|
||||||
public abstract interface class app/revanced/patcher/PatchesConsumer {
|
public abstract interface class app/revanced/patcher/PatchesConsumer {
|
||||||
public abstract fun acceptPatches (Ljava/util/List;)V
|
public abstract fun acceptPatches (Ljava/util/List;)V
|
||||||
|
public abstract fun acceptPatches (Ljava/util/Set;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patcher/PatchesConsumer$DefaultImpls {
|
||||||
|
public static fun acceptPatches (Lapp/revanced/patcher/PatchesConsumer;Ljava/util/List;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/data/BytecodeContext : app/revanced/patcher/data/Context {
|
public final class app/revanced/patcher/data/BytecodeContext : app/revanced/patcher/data/Context {
|
||||||
|
@ -329,6 +335,8 @@ public final class app/revanced/patcher/patch/options/PatchOption$PatchExtension
|
||||||
public static synthetic fun longArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public static synthetic fun longArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
public final fun longPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public final fun longPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
public static synthetic fun longPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public static synthetic fun longPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
|
public final fun registerNewPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
|
public static synthetic fun registerNewPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
public final fun stringArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public final fun stringArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
public static synthetic fun stringArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public static synthetic fun stringArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
public final fun stringPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
public final fun stringPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 19.1.0
|
version = 19.2.0-dev.1
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
android = "4.1.1.4"
|
android = "4.1.1.4"
|
||||||
kotlin-reflect = "1.9.10"
|
kotlin-reflect = "1.9.10"
|
||||||
apktool-lib = "2.9.1"
|
apktool-lib = "2.9.1"
|
||||||
kotlin-test = "1.9.10"
|
kotlin-test = "1.9.20"
|
||||||
kotlinx-coroutines-core = "1.7.3"
|
kotlinx-coroutines-core = "1.7.3"
|
||||||
multidexlib2 = "3.0.3.r3"
|
multidexlib2 = "3.0.3.r3"
|
||||||
smali = "3.0.3"
|
smali = "3.0.3"
|
||||||
|
|
|
@ -2,6 +2,6 @@ rootProject.name = "revanced-patcher"
|
||||||
|
|
||||||
buildCache {
|
buildCache {
|
||||||
local {
|
local {
|
||||||
isEnabled = !System.getenv().containsKey("CI")
|
isEnabled = "CI" !in System.getenv()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Patcher(
|
||||||
* @param patches The [Patch]es to add.
|
* @param patches The [Patch]es to add.
|
||||||
*/
|
*/
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
override fun acceptPatches(patches: List<Patch<*>>) {
|
override fun acceptPatches(patches: PatchSet) {
|
||||||
/**
|
/**
|
||||||
* Add dependencies of a [Patch] recursively to [PatcherContext.allPatches].
|
* Add dependencies of a [Patch] recursively to [PatcherContext.allPatches].
|
||||||
* If a [Patch] is already in [PatcherContext.allPatches], it will not be added again.
|
* If a [Patch] is already in [PatcherContext.allPatches], it will not be added again.
|
||||||
|
|
|
@ -4,5 +4,7 @@ import app.revanced.patcher.patch.Patch
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface PatchesConsumer {
|
interface PatchesConsumer {
|
||||||
fun acceptPatches(patches: List<Patch<*>>)
|
@Deprecated("Use acceptPatches(PatchSet) instead.", ReplaceWith("acceptPatches(patches.toSet())"))
|
||||||
|
fun acceptPatches(patches: List<Patch<*>>) = acceptPatches(patches.toSet())
|
||||||
|
fun acceptPatches(patches: PatchSet)
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ open class PatchOption<T>(
|
||||||
if (!validator(value)) throw PatchOptionException.ValueValidationException(value, this)
|
if (!validator(value)) throw PatchOptionException.ValueValidationException(value, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun toString() = value.toString()
|
override fun toString() = value.toString()
|
||||||
|
|
||||||
operator fun getValue(
|
operator fun getValue(
|
||||||
|
@ -120,7 +121,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<String>.(String?) -> Boolean = { true },
|
validator: PatchOption<String>.(String?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -129,7 +130,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"String",
|
"String",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with an integer value and add it to the current [Patch].
|
* Create a new [PatchOption] with an integer value and add it to the current [Patch].
|
||||||
|
@ -154,7 +155,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Int?>.(Int?) -> Boolean = { true },
|
validator: PatchOption<Int?>.(Int?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -163,7 +164,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"Int",
|
"Int",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a boolean value and add it to the current [Patch].
|
* Create a new [PatchOption] with a boolean value and add it to the current [Patch].
|
||||||
|
@ -188,9 +189,16 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Boolean?>.(Boolean?) -> Boolean = { true },
|
validator: PatchOption<Boolean?>.(Boolean?) -> Boolean = { true },
|
||||||
) = PatchOption(key, default, values, title, description, required, "Boolean", validator).also {
|
) = registerNewPatchOption(
|
||||||
registerOption(it)
|
key,
|
||||||
}
|
default,
|
||||||
|
values,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
required,
|
||||||
|
"Boolean",
|
||||||
|
validator,
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a float value and add it to the current [Patch].
|
* Create a new [PatchOption] with a float value and add it to the current [Patch].
|
||||||
|
@ -215,7 +223,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Float?>.(Float?) -> Boolean = { true },
|
validator: PatchOption<Float?>.(Float?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -224,7 +232,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"Float",
|
"Float",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a long value and add it to the current [Patch].
|
* Create a new [PatchOption] with a long value and add it to the current [Patch].
|
||||||
|
@ -249,7 +257,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Long?>.(Long?) -> Boolean = { true },
|
validator: PatchOption<Long?>.(Long?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -258,7 +266,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"Long",
|
"Long",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a string array value and add it to the current [Patch].
|
* Create a new [PatchOption] with a string array value and add it to the current [Patch].
|
||||||
|
@ -283,7 +291,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Array<String>?>.(Array<String>?) -> Boolean = { true },
|
validator: PatchOption<Array<String>?>.(Array<String>?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -292,7 +300,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"StringArray",
|
"StringArray",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with an integer array value and add it to the current [Patch].
|
* Create a new [PatchOption] with an integer array value and add it to the current [Patch].
|
||||||
|
@ -317,7 +325,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Array<Int>?>.(Array<Int>?) -> Boolean = { true },
|
validator: PatchOption<Array<Int>?>.(Array<Int>?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -326,7 +334,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"IntArray",
|
"IntArray",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a boolean array value and add it to the current [Patch].
|
* Create a new [PatchOption] with a boolean array value and add it to the current [Patch].
|
||||||
|
@ -351,7 +359,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Array<Boolean>?>.(Array<Boolean>?) -> Boolean = { true },
|
validator: PatchOption<Array<Boolean>?>.(Array<Boolean>?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -360,7 +368,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"BooleanArray",
|
"BooleanArray",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a float array value and add it to the current [Patch].
|
* Create a new [PatchOption] with a float array value and add it to the current [Patch].
|
||||||
|
@ -385,7 +393,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Array<Float>?>.(Array<Float>?) -> Boolean = { true },
|
validator: PatchOption<Array<Float>?>.(Array<Float>?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -394,7 +402,7 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"FloatArray",
|
"FloatArray",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new [PatchOption] with a long array value and add it to the current [Patch].
|
* Create a new [PatchOption] with a long array value and add it to the current [Patch].
|
||||||
|
@ -419,7 +427,7 @@ open class PatchOption<T>(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
required: Boolean = false,
|
required: Boolean = false,
|
||||||
validator: PatchOption<Array<Long>?>.(Array<Long>?) -> Boolean = { true },
|
validator: PatchOption<Array<Long>?>.(Array<Long>?) -> Boolean = { true },
|
||||||
) = PatchOption(
|
) = registerNewPatchOption(
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
values,
|
values,
|
||||||
|
@ -428,8 +436,42 @@ open class PatchOption<T>(
|
||||||
required,
|
required,
|
||||||
"LongArray",
|
"LongArray",
|
||||||
validator,
|
validator,
|
||||||
).also { registerOption(it) }
|
)
|
||||||
|
|
||||||
private fun <P : Patch<*>> P.registerOption(option: PatchOption<*>) = option.also { options.register(it) }
|
/**
|
||||||
|
* Create a new [PatchOption] with a string set value and add it to the current [Patch].
|
||||||
|
*
|
||||||
|
* @param key The identifier.
|
||||||
|
* @param default The default value.
|
||||||
|
* @param values The set of guaranteed valid values identified by their string representation.
|
||||||
|
* @param title The title.
|
||||||
|
* @param description A description.
|
||||||
|
* @param required Whether the option is required.
|
||||||
|
* @param valueType The type of the option value (to handle type erasure).
|
||||||
|
* @param validator The function to validate the option value.
|
||||||
|
*
|
||||||
|
* @return The created [PatchOption].
|
||||||
|
*
|
||||||
|
* @see PatchOption
|
||||||
|
*/
|
||||||
|
fun <P : Patch<*>, T> P.registerNewPatchOption(
|
||||||
|
key: String,
|
||||||
|
default: T? = null,
|
||||||
|
values: Map<String, T?>? = null,
|
||||||
|
title: String? = null,
|
||||||
|
description: String? = null,
|
||||||
|
required: Boolean = false,
|
||||||
|
valueType: String,
|
||||||
|
validator: PatchOption<T>.(T?) -> Boolean = { true },
|
||||||
|
) = PatchOption(
|
||||||
|
key,
|
||||||
|
default,
|
||||||
|
values,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
required,
|
||||||
|
valueType,
|
||||||
|
validator,
|
||||||
|
).also(options::register)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue