From 1d24cc0dc4899edf3acd1b29d339cac03e1b657e Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Mon, 17 Aug 2026 13:12:55 +0300 Subject: [PATCH 1/2] Upgrade to Gradle 9.7.0 and GradleUp Shadow, convert build to Kotlin DSL Upgrades the build to Gradle 9.7.0 (from 8.9) and migrates the Shadow plugin from the unmaintained `com.github.johnrengelman.shadow` 7.1.2 to `com.gradleup.shadow` 9.6.1, with the version moved into the version catalog. The build scripts are converted to Kotlin DSL, `buildSrc` is replaced by a `build-logic` included build, and the Gradle best practices are applied throughout. Plugin upgrades: - shadow: johnrengelman 7.1.2 -> com.gradleup.shadow 9.6.1 - rat: 0.8.0 -> 0.8.1 - test-logger: 3.2.0 -> 4.0.0 - versions: com.github.ben-manes 0.51.0 -> io.github.ben-manes 0.61.0 (the `com.github` plugin id is deprecated) - version-catalog-update: 0.8.5 -> 1.1.1 - licenser 0.6.1 -> replaced by Spotless 8.10.0 (see below) `org.cadixdev.licenser` had to be replaced: it fails with a StackOverflowError on Gradle 9 and has had no release since 2021. Spotless takes over the ASF license header check and apply, so CI now runs `spotlessCheck` instead of `licenseCheck` and `spotlessApply` replaces `updateLicenses`. `checkstyle/HEADER.txt` gains the comment markers because Spotless matches headers verbatim. Formatting of Java sources stays with spring-javaformat and Apache RAT remains the repository-wide backstop. Shadow 9 migration details: - `archiveClassifier.set(null)` -> `archiveClassifier = ""` - dropped the manual `dependsOn(jar)`, `manifest { inheritFrom ... }` and `build.dependsOn(shadowJar)`; Shadow 9 wires all three itself - `components.java.withVariantsFromConfiguration(...) { skip() }` -> `shadow { addShadowVariantIntoJavaComponent = false }` - the removed `dependency(Closure)` overload -> explicit `Spec` Best practices applied (docs.gradle.org/current/userguide/best_practices_index.html): - Kotlin DSL and a `build-logic` composite build instead of `buildSrc` - repositories declared in the settings files with `FAIL_ON_PROJECT_REPOS` and `exclusiveContent` filtering - configuration cache, build cache, parallel execution and UTF-8 encoding enabled in `gradle.properties` - `allprojects {}` cross-project configuration removed: `group` moves to `gradle.properties` and RAT becomes a single root task, which already covered every subproject directory - `afterEvaluate` in the POM replaced by a lazy `Property`, and `pluginManager.withPlugin` used instead of eager plugin checks - `buildDir` -> `layout.buildDirectory`, `tasks.register`/`configureEach` throughout, `isolated.rootProject` instead of `rootProject` - public task name constants instead of hardcoded strings, group and description on `sourceTar` - BOM constraints listed explicitly instead of iterating `rootProject.subprojects` - `distributionSha256Sum` added to the wrapper properties Verified that the shaded jar entries are identical to those produced by the previous build, and that the generated POMs match the released 0.7.0 POMs apart from genuine dependency version bumps. --- .github/workflows/ci.yml | 2 +- .../build.gradle.kts | 16 ++-- .../settings.gradle.kts | 34 +++---- ...-reactive.codestyle-conventions.gradle.kts | 61 ++++++++++++ ...nt-reactive.library-conventions.gradle.kts | 34 ++++--- ...nt-reactive.publish-conventions.gradle.kts | 86 +++++++++++++++++ ...lient-reactive.test-conventions.gradle.kts | 69 ++++++++++++++ build.gradle | 88 ------------------ build.gradle.kts | 80 ++++++++++++++++ ...client-reactive.publish-conventions.gradle | 77 --------------- ...ar-client-reactive.test-conventions.gradle | 64 ------------- checkstyle/HEADER.txt | 33 ++++--- gradle.properties | 9 ++ gradle/libs.versions.toml | 24 +++-- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 47505 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 18 ++-- gradlew.bat | 36 +++---- .../{build.gradle => build.gradle.kts} | 38 ++++---- .../{build.gradle => build.gradle.kts} | 26 +++--- .../build.gradle.kts | 31 +++--- .../{build.gradle => build.gradle.kts} | 18 ++-- .../build.gradle | 84 ----------------- .../build.gradle.kts | 86 +++++++++++++++++ .../{build.gradle => build.gradle.kts} | 19 ++-- settings.gradle | 26 ------ ...-conventions.gradle => settings.gradle.kts | 34 +++---- 27 files changed, 579 insertions(+), 519 deletions(-) rename buildSrc/settings.gradle => build-logic/build.gradle.kts (81%) rename pulsar-client-reactive-bom/build.gradle => build-logic/settings.gradle.kts (61%) create mode 100644 build-logic/src/main/kotlin/pulsar-client-reactive.codestyle-conventions.gradle.kts rename buildSrc/src/main/groovy/pulsar-client-reactive.library-conventions.gradle => build-logic/src/main/kotlin/pulsar-client-reactive.library-conventions.gradle.kts (58%) create mode 100644 build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts create mode 100644 build-logic/src/main/kotlin/pulsar-client-reactive.test-conventions.gradle.kts delete mode 100644 build.gradle create mode 100644 build.gradle.kts delete mode 100644 buildSrc/src/main/groovy/pulsar-client-reactive.publish-conventions.gradle delete mode 100644 buildSrc/src/main/groovy/pulsar-client-reactive.test-conventions.gradle rename pulsar-client-reactive-adapter/{build.gradle => build.gradle.kts} (50%) rename pulsar-client-reactive-api/{build.gradle => build.gradle.kts} (63%) rename buildSrc/build.gradle => pulsar-client-reactive-bom/build.gradle.kts (55%) rename pulsar-client-reactive-jackson/{build.gradle => build.gradle.kts} (70%) delete mode 100644 pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle create mode 100644 pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle.kts rename pulsar-client-reactive-producer-cache-caffeine/{build.gradle => build.gradle.kts} (73%) delete mode 100644 settings.gradle rename buildSrc/src/main/groovy/pulsar-client-reactive.codestyle-conventions.gradle => settings.gradle.kts (60%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a576d65..7ba8b169 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,4 +50,4 @@ jobs: uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 - name: Check with Gradle - run: ./gradlew rat licenseCheck javadoc check + run: ./gradlew rat spotlessCheck javadoc check diff --git a/buildSrc/settings.gradle b/build-logic/build.gradle.kts similarity index 81% rename from buildSrc/settings.gradle rename to build-logic/build.gradle.kts index 0e8e5cdd..90b5ea53 100644 --- a/buildSrc/settings.gradle +++ b/build-logic/build.gradle.kts @@ -17,10 +17,12 @@ * under the License. */ -dependencyResolutionManagement { - versionCatalogs { - libs { - from(files("../gradle/libs.versions.toml")) - } - } -} \ No newline at end of file +plugins { + `kotlin-dsl` +} + +dependencies { + implementation(libs.spotless.gradle.plugin) + implementation(libs.spring.javaformat.gradle.plugin) + implementation(libs.testlogger.gradle.plugin) +} diff --git a/pulsar-client-reactive-bom/build.gradle b/build-logic/settings.gradle.kts similarity index 61% rename from pulsar-client-reactive-bom/build.gradle rename to build-logic/settings.gradle.kts index 0442ff55..5ef9a46b 100644 --- a/pulsar-client-reactive-bom/build.gradle +++ b/build-logic/settings.gradle.kts @@ -17,28 +17,22 @@ * under the License. */ -plugins { - id 'java-platform' - id 'pulsar-client-reactive.publish-conventions' -} - -dependencies { - constraints { - project.rootProject.subprojects - .sort { "$it.name" } - .findAll { it.name != "pulsar-client-reactive-bom" } - .each { - api it - } +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + repositories { + mavenCentral() + // The test-logger plugin is published to the Gradle Plugin Portal only, so restrict + // the portal to that group instead of letting it answer for every dependency. + exclusiveContent { + forRepository { gradlePluginPortal() } + filter { includeGroup("com.adarshr") } + } } -} - -publishing { - publications { - mavenJava(MavenPublication) { - from components.javaPlatform + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) } } } -description = 'Reactive Java client for Apache Pulsar (Bill of Materials)' +rootProject.name = "build-logic" diff --git a/build-logic/src/main/kotlin/pulsar-client-reactive.codestyle-conventions.gradle.kts b/build-logic/src/main/kotlin/pulsar-client-reactive.codestyle-conventions.gradle.kts new file mode 100644 index 00000000..ca205a76 --- /dev/null +++ b/build-logic/src/main/kotlin/pulsar-client-reactive.codestyle-conventions.gradle.kts @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + checkstyle + id("io.spring.javaformat") + id("com.diffplug.spotless") +} + +// The version catalog has no type-safe accessors inside a precompiled script plugin, so it +// has to be looked up through the extension. +val libs = extensions.getByType().named("libs") + +// `isolated` keeps this compatible with configuration caching and project isolation. +val checkstyleConfigDir = isolated.rootProject.projectDirectory.dir("checkstyle") +val licenseHeader = checkstyleConfigDir.file("HEADER.txt") + +dependencies { + checkstyle(libs.findLibrary("spring-javaformat-checkstyle").get()) +} + +checkstyle { + toolVersion = libs.findVersion("checkstyle").get().requiredVersion + // `configFile` defaults to `checkstyle.xml` inside `configDirectory` + configDirectory = checkstyleConfigDir +} + +// Formatting of Java sources is owned by spring-javaformat; Spotless only enforces the ASF +// license header. Apache RAT is the repository-wide backstop for every other file type. +spotless { + kotlinGradle { + target("*.gradle.kts") + licenseHeaderFile(licenseHeader, "(plugins|import|rootProject|pluginManagement|dependencyResolutionManagement)") + } +} + +// `java` has no sources to point Spotless at until the `java` plugin is applied, which +// happens after this convention plugin. Reacting to the plugin avoids `afterEvaluate`. +pluginManager.withPlugin("java") { + spotless { + java { + licenseHeaderFile(licenseHeader) + } + } +} diff --git a/buildSrc/src/main/groovy/pulsar-client-reactive.library-conventions.gradle b/build-logic/src/main/kotlin/pulsar-client-reactive.library-conventions.gradle.kts similarity index 58% rename from buildSrc/src/main/groovy/pulsar-client-reactive.library-conventions.gradle rename to build-logic/src/main/kotlin/pulsar-client-reactive.library-conventions.gradle.kts index b1ca78dd..0f01fdf8 100644 --- a/buildSrc/src/main/groovy/pulsar-client-reactive.library-conventions.gradle +++ b/build-logic/src/main/kotlin/pulsar-client-reactive.library-conventions.gradle.kts @@ -18,43 +18,51 @@ */ plugins { - id 'java-library' - id 'pulsar-client-reactive.publish-conventions' + `java-library` + id("pulsar-client-reactive.publish-conventions") } -repositories { - mavenCentral() -} +val libs = extensions.getByType().named("libs") java { withJavadocJar() withSourcesJar() + // Pinning the toolchain decouples the build from whichever JDK happens to be on PATH + // and keeps the compiled output reproducible. toolchain { languageVersion = JavaLanguageVersion.of(17) } } -compileJava { +tasks.withType().configureEach { + options.encoding = "UTF-8" +} + +tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME) { options.release = 8 } +tasks.withType().configureEach { + options.encoding = "UTF-8" +} + dependencies { - testRuntimeOnly libs.junit.platform.launcher + testRuntimeOnly(libs.findLibrary("junit-platform-launcher").get()) } -tasks.withType(Test) { +tasks.withType().configureEach { useJUnitPlatform() } publishing { publications { - mavenJava(MavenPublication) { - from components.java + named("mavenJava") { + from(components["java"]) versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') + usage(Usage.JAVA_API) { + fromResolutionOf(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME) } - usage('java-runtime') { + usage(Usage.JAVA_RUNTIME) { fromResolutionResult() } } diff --git a/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts b/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts new file mode 100644 index 00000000..833010e5 --- /dev/null +++ b/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + `maven-publish` + signing +} + +val publishDebug = providers.gradleProperty("publishDebug") +val isSnapshot = provider { version.toString().endsWith("-SNAPSHOT") } + +// `project.description` is assigned at the bottom of each module's build script, so it has +// to be read lazily rather than when this convention plugin is applied. +val projectDescription = objects.property().value(provider { description }) + +publishing { + repositories { + maven { + if (publishDebug.isPresent) { + url = uri(publishDebug.get()) + } + else { + name = "asf" + url = uri( + if (isSnapshot.get()) "https://repository.apache.org/content/repositories/snapshots/" + else "https://repository.apache.org/service/local/staging/deploy/maven2" + ) + credentials(PasswordCredentials::class) + } + } + } + publications { + create("mavenJava") { + pom { + name = project.name + description = projectDescription + url = "https://github.com/apache/pulsar-client-reactive" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "repo" + } + } + developers { + developer { + id = "lhotari" + name = "Lari Hotari" + email = "lhotari@apache.org" + } + developer { + id = "cbornet" + name = "Christophe Bornet" + email = "cbornet@apache.org" + } + } + scm { + connection = "scm:git:https://github.com/apache/pulsar-client-reactive.git" + developerConnection = "scm:git:https://github.com/apache/pulsar-client-reactive.git" + url = "https://github.com/apache/pulsar-client-reactive" + } + } + } + } +} + +signing { + setRequired(!publishDebug.isPresent) + sign(publishing.publications["mavenJava"]) +} diff --git a/build-logic/src/main/kotlin/pulsar-client-reactive.test-conventions.gradle.kts b/build-logic/src/main/kotlin/pulsar-client-reactive.test-conventions.gradle.kts new file mode 100644 index 00000000..80118f84 --- /dev/null +++ b/build-logic/src/main/kotlin/pulsar-client-reactive.test-conventions.gradle.kts @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + `java-library` + id("com.adarshr.test-logger") +} + +val libs = extensions.getByType().named("libs") + +testlogger { + showStandardStreams = true +} + +val main: SourceSet = sourceSets[SourceSet.MAIN_SOURCE_SET_NAME] +val intTest: SourceSet = sourceSets.create("intTest") { + compileClasspath += main.output + runtimeClasspath += main.output +} + +configurations[intTest.implementationConfigurationName] + .extendsFrom(configurations[JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME]) +configurations[intTest.runtimeOnlyConfigurationName] + .extendsFrom(configurations[JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME]) + +// `isolated` keeps this compatible with configuration caching and project isolation. +val sharedTestResources = files(isolated.rootProject.projectDirectory.dir("shared-test-resources")) + +dependencies { + // add shared-test-resources directory to runtime classpath + intTest.runtimeOnlyConfigurationName(sharedTestResources) + JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME(sharedTestResources) + intTest.runtimeOnlyConfigurationName(libs.findLibrary("junit-platform-launcher").get()) +} + +val integrationTest = tasks.register("integrationTest") { + description = "Runs integration tests." + group = LifecycleBasePlugin.VERIFICATION_GROUP + + testClassesDirs = intTest.output.classesDirs + classpath = intTest.runtimeClasspath + shouldRunAfter(tasks.named(JavaPlugin.TEST_TASK_NAME)) +} + +tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) { + dependsOn(integrationTest) +} + +tasks.withType().configureEach { + // reduces CPU usage in tests when JIT compiler doesn't spend time compiling code + // this could help reduce flakiness in CI where there's less CPU resources available + jvmArgs("-XX:TieredStopAtLevel=1") +} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index e3896b81..00000000 --- a/build.gradle +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -plugins { - alias(libs.plugins.versions) - alias(libs.plugins.version.catalog.update) - id 'pulsar-client-reactive.codestyle-conventions' -} - -allprojects { - group = 'org.apache.pulsar' - apply plugin: 'io.spring.javaformat' - apply plugin: 'org.nosphere.apache.rat' - - repositories { - mavenCentral() - } - - tasks.named('rat') { - inputDir = projectDir - excludes = ['.asf.yaml', // ASF metadata for github integration excluded from src zip - '**/.gradle/**', '**/wrapper/**', 'gradlew*', // gradle wrapper files excluded from src zip - 'gradle.properties', // artifactory release plugin removes header when bumping version - '**/build/**', '**/target/**', 'licenses/**', 'notices/**', - '**/META-INF/services/*', - 'out/**', '*.ipr', '**/*.iml', '*.iws', '.idea/**', // Intellij files - '.classpath', '.project', '.settings/**', 'bin/**', // Eclipse files - ] - } -} - -task sourceTar(type: Tar) { - destinationDirectory = buildDir - archiveBaseName = "pulsar-client-reactive-${rootProject.version}" - archiveClassifier = "src" - archiveExtension = "tar.gz" - compression = Compression.GZIP - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - includeEmptyDirs = false - into(archiveBaseName) { - from(rootDir) { - excludes = [ - '.github/**', '.asf.yaml', - '**/build/**', '**/target/**', - 'out/**', '*.ipr', '**/*.iml', '*.iws', '.idea/**', // Intellij files - '.classpath', '.project', '.settings/**', 'bin/**', // Eclipse files - '**/.gradle/**', '**/wrapper/**', 'gradlew*', // gradle wrapper files excluded from src zip - ] - } - } -} - -license { - tasks { - rootProjectExtraFiles { - files.from('checkstyle', 'idea', 'shared-test-resources', 'buildSrc/src', 'buildSrc/build.gradle', '.github') - } - } -} - -tasks.named("dependencyUpdates").configure { - rejectVersionIf { - it.candidate.version.contains("alpha") || it.candidate.version.contains("beta") || it.candidate.version.contains("rc") - } -} - -versionCatalogUpdate { - keep { - keepUnusedLibraries = true - keepUnusedVersions = true - } -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..80dd9d4a --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + alias(libs.plugins.rat) + alias(libs.plugins.versions) + alias(libs.plugins.version.catalog.update) + id("pulsar-client-reactive.codestyle-conventions") +} + +// A single RAT run over the whole repository; it already covers every subproject directory. +tasks.rat { + inputDir = layout.projectDirectory + setExcludes( + listOf( + ".asf.yaml", // ASF metadata for github integration excluded from src zip + "**/.gradle/**", "**/wrapper/**", "gradlew*", // gradle wrapper files excluded from src zip + "gradle.properties", // artifactory release plugin removes header when bumping version + "**/build/**", "**/target/**", "licenses/**", "notices/**", + "**/META-INF/services/*", + "out/**", "*.ipr", "**/*.iml", "*.iws", ".idea/**", // Intellij files + ".classpath", ".project", ".settings/**", "bin/**", // Eclipse files + ) + ) +} + +tasks.register("sourceTar") { + description = "Assembles a source distribution archive of the whole repository." + group = BasePlugin.BUILD_GROUP + + destinationDirectory = layout.buildDirectory + archiveBaseName = "pulsar-client-reactive-$version" + archiveClassifier = "src" + archiveExtension = "tar.gz" + compression = Compression.GZIP + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + includeEmptyDirs = false + into(archiveBaseName) { + from(layout.projectDirectory) { + exclude( + ".github/**", ".asf.yaml", + "**/build/**", "**/target/**", + "out/**", "*.ipr", "**/*.iml", "*.iws", ".idea/**", // Intellij files + ".classpath", ".project", ".settings/**", "bin/**", // Eclipse files + "**/.gradle/**", "**/wrapper/**", "gradlew*", // gradle wrapper files excluded from src zip + ) + } + } +} + +tasks.dependencyUpdates { + rejectVersionIf { + listOf("alpha", "beta", "rc").any { candidate.version.contains(it) } + } +} + +// Note: `versionCatalogUpdate` reads `Task.project` at execution time, so it discards the +// configuration cache entry. It is a maintenance task outside the assemble/check flows. +versionCatalogUpdate { + keep { + // keep versions that no library or plugin entry references + keepUnusedVersions = true + } +} diff --git a/buildSrc/src/main/groovy/pulsar-client-reactive.publish-conventions.gradle b/buildSrc/src/main/groovy/pulsar-client-reactive.publish-conventions.gradle deleted file mode 100644 index 60151cb1..00000000 --- a/buildSrc/src/main/groovy/pulsar-client-reactive.publish-conventions.gradle +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -plugins { - id 'maven-publish' - id 'signing' -} - -publishing { - repositories { - maven { - if (project.hasProperty("publishDebug")) { - url = project.property("publishDebug") - } else { - name = 'asf' - url = version.endsWith('-SNAPSHOT') ? 'https://repository.apache.org/content/repositories/snapshots/' : 'https://repository.apache.org/service/local/staging/deploy/maven2' - credentials(PasswordCredentials) - } - } - } - publications { - mavenJava(MavenPublication) { publication -> - pom { - afterEvaluate { - name = project.name - description = project.description - } - url = 'https://github.com/apache/pulsar-client-reactive' - licenses { - license { - name = 'The Apache License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution = 'repo' - } - } - developers { - developer { - id = 'lhotari' - name = 'Lari Hotari' - email = 'lhotari@apache.org' - } - developer { - id = 'cbornet' - name = 'Christophe Bornet' - email = 'cbornet@apache.org' - } - } - scm { - connection = 'scm:git:https://github.com/apache/pulsar-client-reactive.git' - developerConnection = 'scm:git:https://github.com/apache/pulsar-client-reactive.git' - url = 'https://github.com/apache/pulsar-client-reactive' - } - } - } - } -} - -signing { - required !project.hasProperty("publishDebug") - sign publishing.publications.mavenJava -} diff --git a/buildSrc/src/main/groovy/pulsar-client-reactive.test-conventions.gradle b/buildSrc/src/main/groovy/pulsar-client-reactive.test-conventions.gradle deleted file mode 100644 index 6e137d49..00000000 --- a/buildSrc/src/main/groovy/pulsar-client-reactive.test-conventions.gradle +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -plugins { - id 'com.adarshr.test-logger' -} - -testlogger { - showStandardStreams true -} - -sourceSets { - intTest { - compileClasspath += sourceSets.main.output - runtimeClasspath += sourceSets.main.output - } -} - -configurations { - intTestImplementation.extendsFrom implementation - intTestRuntimeOnly.extendsFrom runtimeOnly -} - -dependencies { - // add shared-test-resources directory to runtime classpath - def sharedTestResourcesEntry = files(new File(rootDir, "shared-test-resources")) - intTestRuntimeOnly sharedTestResourcesEntry - testRuntimeOnly sharedTestResourcesEntry - intTestRuntimeOnly libs.junit.platform.launcher -} - -tasks.register('integrationTest', Test) { - description = 'Runs integration tests.' - group = 'verification' - - testClassesDirs = sourceSets.intTest.output.classesDirs - classpath = sourceSets.intTest.runtimeClasspath - shouldRunAfter test -} - -check.dependsOn integrationTest - - -tasks.withType(Test) { - // reduces CPU usage in tests when JIT compiler doesn't spend time compiling code - // this could help reduce flakiness in CI where there's less CPU resources available - jvmArgs '-XX:TieredStopAtLevel=1' -} \ No newline at end of file diff --git a/checkstyle/HEADER.txt b/checkstyle/HEADER.txt index 8ca94578..62084553 100644 --- a/checkstyle/HEADER.txt +++ b/checkstyle/HEADER.txt @@ -1,16 +1,19 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a107d410..c5c0ce07 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,4 +17,13 @@ # under the License. # +group=org.apache.pulsar version=0.7.1-SNAPSHOT + +# Pin the file encoding so the build behaves the same everywhere and does not miss build +# cache entries because of a platform-dependent default. +org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f5545c7a..8835c96d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,22 +20,24 @@ assertj = "3.27.7" # @pin caffeine = "2.9.3" +# @pin pinned by spring-javaformat-checkstyle, which depends on checkstyle 9.3 checkstyle = "9.3" # @pin jackson = "2.18.9" # @pin jctools = "3.3.0" junit-jupiter = "6.1.3" -licenser = "0.6.1" log4j = "2.24.3" mockito = "5.23.0" pulsar = "4.2.4" -rat-gradle = "0.8.0" +rat = "0.8.1" reactor = "3.7.19" +shadow = "9.6.1" slf4j = "2.0.18" +spotless = "8.10.0" spring-javaformat = "0.0.48" testcontainers = "1.21.4" -testlogger = "3.2.0" +testlogger = "4.0.0" [libraries] assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" } @@ -46,7 +48,6 @@ jctools-core = { module = "org.jctools:jctools-core", version.ref = "jctools" } junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-jupiter" } -licenser = { module = "gradle.plugin.org.cadixdev.gradle:licenser", version.ref = "licenser" } log4j-api = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j" } log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" } log4j-slf4j2-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" } @@ -54,14 +55,17 @@ mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } pulsar-client-all = { module = "org.apache.pulsar:pulsar-client-all", version.ref = "pulsar" } pulsar-client-api = { module = "org.apache.pulsar:pulsar-client-api", version.ref = "pulsar" } pulsar-client-shaded = { module = "org.apache.pulsar:pulsar-client", version.ref = "pulsar" } -rat-gradle = { module = "org.nosphere.apache:creadur-rat-gradle", version.ref = "rat-gradle" } reactor-core = { module = "io.projectreactor:reactor-core", version.ref = "reactor" } reactor-test = { module = "io.projectreactor:reactor-test", version.ref = "reactor" } slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } spring-javaformat-checkstyle = { module = "io.spring.javaformat:spring-javaformat-checkstyle", version.ref = "spring-javaformat" } -spring-javaformat-gradle-plugin = { module = "io.spring.javaformat:spring-javaformat-gradle-plugin", version.ref = "spring-javaformat" } testcontainers-pulsar = { module = "org.testcontainers:pulsar", version.ref = "testcontainers" } -testlogger = { module = "com.adarshr:gradle-test-logger-plugin", version.ref = "testlogger" } + +# Gradle plugin implementations, used on the `build-logic` compile classpath so that the +# convention plugins can apply them. Keep in sync with the matching `[plugins]` aliases. +spotless-gradle-plugin = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" } +spring-javaformat-gradle-plugin = { module = "io.spring.javaformat:spring-javaformat-gradle-plugin", version.ref = "spring-javaformat" } +testlogger-gradle-plugin = { module = "com.adarshr:gradle-test-logger-plugin", version.ref = "testlogger" } [bundles] log4j = [ @@ -72,5 +76,7 @@ log4j = [ ] [plugins] -version-catalog-update = "nl.littlerobots.version-catalog-update:0.8.5" -versions = "com.github.ben-manes.versions:0.51.0" +rat = { id = "org.nosphere.apache.rat", version.ref = "rat" } +shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } +version-catalog-update = "nl.littlerobots.version-catalog-update:1.1.1" +versions = "io.github.ben-manes.versions:0.61.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..eddabd2eef8d94a5437d6168ff9c87a78ff725b3 100644 GIT binary patch delta 39507 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 K03i5udGvqByx=AP delta 35571 zcmXV%V?br^_x8iogp+mhWZRxP+16y+P3}xO*|s@(GAC=YZ5tD(diwtU&zt>f?>G0l zu7%IKcl<5P)htY{Evn+J!k;mDIVR?56gejPi9eISR9WXZw)SuSFb&I$D~vP9FhV1p zK+ID1igf8(@Tf}mis*y!sBp21aIamiU7(?qMbJ@Xi1j`ViRWkL4Emdygko{LHcfnM8q+JU6H3>?@56Wus zusx)G{v__JYt^(LemOsfBLrvW0eWD)tkOsfFTb1BZpLUb@=9^eN=8NN(4$7Reut^g zD-yo!K$Ha90Ti$Utm#y`WpS!!DGK|Mxxv6_bPP>;V{frqhTE=&^)ya%EavUW z1uiF$NGL2iEZT`aC%JkG_x)G_ew^Xl&3Sz5%JbPW8*g4GmF7X;s?XuG?i8!>RN53N zYcO%32CJ-U`FBL(uhE!!UMoI9or|PW*)}LAoBthLqLH^Y88j4>6ZHQMPKlKyu@4;& ztgnP6iY){iQhbhtO&gfo;@?<2HX5q?`%&!Qm+}Q|n4U-Wb>b%2)pZLGIZny9&^Ktq z`LIt4QIl_|;81Um{HEa4Rt}E|p~H#vm($5+QmBL4KUe;amtM!wn!5)vPE7VP9L)^{ z7T(b%Zl1J4T8^G6c^xc7J+Pvw?j%PRVEr@!(VrMra^Kbv#Z_!qyn}e$@twm~b^5mxA&q+N8S{tKcy!)gzKN5Ljge*Cyl;pf=Mw( zX*a&BwSEqKy{yF6m7dY?9#!mY8W}3TkT3y#tG=m(s2=u(s;jsbWqG-x*Cyh>!K}J5 z&{fL(gQg^NKglU6)Gt=6AWnUaiwX&&Ndk-vsAw>OMNAlJT~S^@$u{(PR&NB+gr>{J z3_|uwj=RmoYQSZpQMFthV~`VH_rz4@Sj|tM7&ROmMUiI(1Dq+H8C!t~)ClFXQ;Kmd zMcajpTn{D4#Qt^}7UwWtafgT*TqZ5iF07}@=BdsrasC}i3$%TkL4j=rfMw?o$(dx$ z8S~(3^UgBVbVga6ZHXYXPr-UXa@k`>8Bn{XkIMZkCILNby{A%iu*NI2aB%UAXOa_u zvF(uk*hs;H^9O^lnGs@l;bvb{|6?^?)Wb^N4nuQ=G)w3@W&)2!(+ZmnEay+l`G#ml zZfHG3-nUb>0~nAuBOD+Z1sJC-Q1NR_#~MV$mLO-cps_v^FOS1UU7GH2FkkH6yx%5+ z*34*?NX0BYLq}lFE%5zK-bV1`vAcIJ21C2MMWE}{5hI6S@FSv334HaSg6Dq3c^HqI;zBUEMl;|(yTJJKQruT8{5}UzIY77+_cC$q0ob$ zWaQ;>Sqsvx2iBTA^z%FQ9R!kqPh@ZKB36M3Ry$}{Qus>E80aaCO(R0hhk}!QN|Qnl z54oh>P=ey|+q2WtV>h4scJ904V(M&`xJ-L$`|`G*1n0bip@8avQMu z#nTQf^92HpT`ZRPT!}XqmnAi8gDrvmiqM>I%05Qi{v42 zbX+;-{=mAKRDwPrFL{!q7bI%*FuHi(gJ*zU%0|8J&E^CUX6^Na3>?wS&(D2NkjaOJ?ZABqF|qkaj|O^WpFj*0*@B_pa4{UO|9 z!kFTv!l%yoby2I~t+Rs4DG7#z``>@IDlnlm=t_SqjB;GW7md3aV6t626uk7wd2rcy zdwe=Z{-LsF z$2j>cUR+~pG`OwD;YqqowzxGml3O6`p~<8O{GGPt&HG5MS<2r(o$M*|mdyKbd%4co z^T&GsTCw#0>Pz3Q)WjS+`Nho&&v!Yer?1B$-@|&)vhTLMPo-AmJ}a#xkTP&S1Mq4a z*H>zJRWq4(4nOzy@6xoZl(RDC#j^(c{3PfXXzg8xPk3l$p=@Apc*f~F6&cT)5N{p9 zcwSa$Gm5C)rZ8(e-DR zx_RulgS3dd86Q6)X->MojYwI31+}VIpVEz^-=oA*ILtaXisX*Hzo04J>4!16Ms0H} z(;JiD_z01B(YH^2bIZUyMavZlb=ye*bq4{oSYnPi1k4!gwFGLj+-Y9NPx;BtQcL$B z_L~t&Z8q`u2}<+IRJ2(0Gd!G8t?JZ))=Z6%kra);DC1fJW984_Ur@67`fI|itG=BuCg}uJbD;f9DB}$)$-2!`9@w{I&LDNqy!@FnMLgi zf-Z3ldh=LDhqq=FB`3$h*q#a7?stG?r@JNwrQsJPs+<(I5C#C#EGPKtI0}BRHA4gY zLf?QBPSVO>=5EC}Tfc|55UgPI@jT`7<`1)YhLJ6Z^No!$v%&G%B!6_vPxL1{h0~oD zd-xpAb%%Wbv+(9|)hn@ zOJ~d@SI)OTL__bbO&C(nZ!0NB74Gp@ArEWunE$Knv4l8%W^L%5`|O1uwoH~=l&YX< zL)%v(&Bcx21H=DZ6uHZW#|R4rrT_V(kq}L!B%lIkYg&6?o8$T$%;YC1hErA=#}{Bo z^RHX$%*B1l5Em~J5amx?`XN_*s!*EOR#8=<7>2~$GSPBb_KP-?V>eJf#hJIz|0c*# z==t;AAG9=A!6Bs`zn^W15C_1uoYr5z%g#&J-1d2%?th2KP?^^(5RVw*)x~=!D`f@J zgA!b@4O(%iSiJJe=z$x^-F+;|f+;$2?EqejSTVG(0!sny_Rg3l*In!!RIz;}O`95S zF|VhNC;Yh8RJF2&JJYxtaS!t9`x3xWDanI~!%>)-wc3_Wc8t(W+!ncKU-eCQwSa&W zk+=%l6oI;`Bm2PP2;Q<~xt^mgs>%jFwipF0v|w-ktD<~hWY%E*dyC&I$t(evk1I?I zi%eU^7}X~r_oR(pkArZKo!3qgLoIv%j@I!I&yi8urGOE_E2P{JwBmk@Zw!ZZiB#1e zCtpDfos#eV-HNIQ(Tt)Z{t&e<;gQT;JbGV$JSWOa+Lf@24`x2WceMECKsnD&y+V|2CEl(&KZL;W#di zAQUKe(6O88QEZ5@<8J9*e;3jyG5@}j?wgXy4AM%R%*)S6*A56gXe|MyM{^)5sK?rD zFLc!rQFV6h?KptkvrzGk8|Dh|F(6<#j?mYXY8fl4glAPBkI@!U+JV||FHJiZ&owp#$@13yok5|VE9X`lET)7jaK*$VqS&GnTLs*XRv8q; z><&FKUsU`UKx4^Fk#tL5l;g-m?gp6gXbNIHefNrL+sj!3CD?T8k{VJY%M0MJYG(!f zdb{E&Kb0U~2LD}p!bJhXZ??6GykyChvQHbDWSgJq(N(LdOz|$T(3v||0hAN+#?@D?>uz)e<(pH8VLV{+hHNt*BZBf(a{n)eVv#^ldhAqhH7Ot-i5~ zGc>*8FjL?Ww6r*eEV zetlC3^+;Jw7;{VB`~!p}lu}%@zyx)}?~KO55s?WawfQqnw0I-DfpuRbuhG;0Kz{MU zkmg5>EU)G7TuCVMEm7i4#BQrV-?P!biFvZ;px0XvS+-aV2G3CmQr%QoXG40XmehA@ zSJ?q#4Bu0%vMjIch;zV$uAI`uuVl=-N+#^gL${5*5gG&Wr#jE82UHN^@Q&>hPNdS) z6&1@4l$g<_BBoYF$-K!-mO?@IBUZIBzK&)=`O)T!p?0vCz}m zm*$r_(I8VSdz5ftr=Kb;O?;j6k@^=x)`>n!E4v$s_g$qjQN|dr{s(?QIZ9~mV71R^ znhM6paEwal>Am35t52HE@V#g7&`$17F$dbEGC;x1B4ArS1f| za|ahvWE!%+`tfopDpJ?^8DTbOxBsZdwys*ndSr1>8u-~e0uj)Ci*7H8d#vx(alDS| z;K(Z7g#UCD-I7O0rLLj}-CK_*fTWE{X?mw;7-3HLsv`sr@4|{>$rHiJ5j)Y-{+<54 zJxL5bhRUV=hhAj?*j7mF!PKzFJ!&HORHC@L__xld3gL|J*p$Tuh2C{Dex~lzZx6QKE;|4QKT3fiwtcqk|nRHzRq z0h_o$f%nl)QYBiEQUBi%GxVO?(-uu`8WE;s1$Ry|x<|&}V-;*=!rsFh6z}12u3z5J zEVmjDq#*5|+(K4xqwczbeaw$4E#|P2Mqep9yuSncAKtCGg5RFsV1JVXAZRZyECiPg z+&ms34GlQsXI5O}cb(O{H^bM(+fON9z+d!wK%%4`o>t&Af!;L~AA_J}WOo zKv4ev1B{xWvtEzW5ZYNAvC|li`>gxPY1g5%HCOmu*5`Z#i(Ecq>EUq)z30N;4ibWx zNDzFRp+PW78YlT!++QrDK9}32rJ&$YgrC^p&3MJTAKTUb1Yf-(jkUqL8>%Wlbbkc0 z;qdL<0(*Et)4PtVfkmPX=?i@2JeyZS1|F>qr&Y8U=QduMqSK@hbJMPjKAngctpcM2 zN|IPBB@m7pEshfj9&ph23D5rp;U5N~(qiR6q7;~}MgDeMF5$aA# z`O%%93$R<~Q+U`Yah1@l9{{)F8#2M%CoYKGK#=baU3gbHvx?0QBp1;2%6@`y%-7KR zOMdfJn9`S(;GhhbkZp9Ujy;Y=tdX2#)Jdr=$1nHH2*a;8O=h9Jcka|Z-5o4V;)`rm z=T2w8t*cxK6^=_%d7=nkE)SNjL8UiE^hZelAGrb1_!h{2j4i1jV~Z77{r}G_gh|n4 zQJFu=ltp=(*d0b&5Yj)PAfm#E2O19R_|S$lQIrykMg2nu2a(P>$#7nO{%>T#r%k1@ zP0X1+^xHV>%xZppJse_zDoitd^!4q?crC+i>7vmCWvl+R=c+o9u-vR~b;Qvhry~e- zqO0(H>(|@EbP!iZ zf5KjD&?76_&j=<#I96fo{RJ`w>5QX)J}LEPg&gVDQMzBR)Wh|Ot7PD-x%A=UuQ##Z zN(^mR*NMwA=y{9Xvs`}WI}~>E3a@-x!$ax?99K;62%dm}1b6S)@b1Sczv0$fs5!=! z4==S1-ksp?vz?%Q23?rIDccGK{GHy9d+opitFS!W2Vigb0905$9}?U(@B{-Ii%GeoTj?Te z*|D~g8lt*ov!0)-DAMJhyt+cR$G14vk+O9fx(<^zzd;Iz-+SvB$7;wn`r;0m8$`_L zGBw);U=fP2wem@qxc>2dEuB-)ZET2*bEKeaP;to)zBA}Y&`-j8M*c6gHY9y3T>KEb zEZqMvu^E?nOSk-gkP=Ev7+;O$_!AOVA%N4iPBZ9!JwcV<+d zq@OQne-p)I$^Rt1yf8~piILglW11Y6p}b1?f}5LHA561+no*1Z8HJTo7&(aH095wu zPvHl3{a+HudB7!}VQ4r} zXbF$v!C?VOcpU8l>!@d17R`QaHzIdvj}?eX;#lAxBBP$oOxJ~6iGMcuTqo0gCO1e$ zy8S<20pa_GW@i`2J=#X9u(ns9OB@>iwmHBV(CU+n{pRWTjT_9cjYNXjc6K#f%ijy; z4{tLla%^fP3~wXhhYW#0)C9f0&;8syv|3y&Pv_OAnCR{;bvZ?kF?S)#Gad-%h&a>V zf_WCX7cwAB-p~J)L4T1Wdby6IY9m&deNLhQdo4~zE$$}R$=$9_kgU%K%wxKQ$c(=@ z7i3Cg7$2lPc=qjg%`S1phTvGngN>z~_gRy^`x~OteFLN$eG%>9I39cC>ytGXbR;S# ziL)#A&fBK1-j5$}N8yuK+C{S9+zV9+C&T*;g74ES<}VMV>l@x4G%Pmcc1r|=n^f-{ zDGw4uo)C*QVmTR&*kZr6j4QuAyh&)aH7VhlRIOWQ38B4p0f)|uziGw6} zz7dcZ@x^JZ zEu)UU*WhO&mq4bS)2%|r)|^zS%r(77X3d-ODeM<2qJzn3V>?rgRulf_7{|{2C zjk)K*K-ffA*U6FAkxs`;mKvy9RAc}NDanMbN6cgpp?dzW^G^z;C!hEokVn+=lL=4J z=^T~GmEwkRmDch?dK6~Du`Jt1%mcw1rNpglj_tkPdEJfp&xA!>jWxI9F-b|%x@-Es zFmVt=tb!wGS0xganMM~ic{FVu!t@XQKLLZpKpyfxq{PUBD!AkE@JVFvVCXtviHGz; z++Fy0sYQSNLyS%;O$%iVn&G;1QF6iYDt+UEwzBMj>Q?+7{jQtR@Jz+0PUgPzV{p)DhFX!oF7_bs1@o8OT$bPx%jZAeV;1;U z6foF(x05Y_KJ~sMGrNA?@lM=jN_b4;MqQVpY$!G`)cHKDF7>=9976MF9w8=7u85_AE|l7YJBpOzh=Z*)*W}jzft-G)eF>jl z`hhXJ4Ui$bwP)2KWa8nRn00q8R*L^l`6_$o{{ zsdBf)^~RBYudX~mkcCjCoSdMuP){wo?2sE}vyicFj%{^t*CcGam^@2MRB)Cz@fqCq zi&0fc5$VfG7c`w+av%vMD1ZbqxYkJ%ua3dGdo2f!xlcTFn9evWA+`58ku zXPa$;fA{N;0!e#x?w3@Owg5sA6ZF=1d;u&yd0+n^vUH!6&8ewS2K=J<`8ZKWG*#eS z-gZ4ditUkPEPpin9Ur;>XrcM>oF7L2oIi87#0BdYS^Sy^wCnneA$c$}cv{q=_lK%Y zPFM&8G0L)RC%WXNVP)5~#ARD7F?%o#qR6DekdT`c1BArNEt)QJq!#ayGB{wfSf}-7 zldKKuLwZ~>XNJqc{Y~L{`u}v@wY0BQ{pCQ=v-ls2CG*ND0h1#wa?MkJjbW{h6U09= zv@>@ZSi=?iQ*=M?=fDjORP}UmCU>*V;>|K`G$W`u+?&+?Mn=!*paD=6FckQL%IU1- zT$Q{ol@fn0>u*0$ZQ6k|)?`xNi{apJ8$#p!lWEPJTksm~^#?Y?ot3fcuYmYN6xF%k zogPxG8=R~qPyh=xvA~u5iE#T`L|Ix<>3?wl6&$(Alss3M4-h%@Kb)_`$^nkn_~wD7 zf&GSxC{Iu@<;0hlY5%f!Y=7f36WPCUgL!Q7_{KOH(8A(_=jQH!JH z^fkqRV^EU!FTarOq2)=5419C1nk8jFJz)xZjB)Y^KMhgp1-XxsmWP&-ES~H2 zXEIiZQ%|)(MvFySplD;ZOWT>#I=1yV=ZsFf?tY4}e2!%6E|QdJ9C&+6UwG&P!jB&N z9#>BZ!o2`d_oaqD-?kp>S(q7lb8-j^v!QgN3`#$ zC2SdR=^3zxO#F7>AgZj_5(72RO?fMj z7oCE0bdbBYoNF$g7uRF9^c#YmiD<|XOuOBdN2e0f+W!4jKldMOIGO*Pc=~hhF5Aop z;gXGLHG~@Ol7lw-dp=AtW*;FLSIe>EX7Ub#;%*SDVm?zKIyl3O^;}#jNDp!wK9b#W zz5$B@34eIau=iT4T_dX-b~1BSj*dA>l`op28c|SFP$SEFQrhKoP@7U9KJs3>UPJ8r zX?NX-i~017KpN_ddKex>|6s*W1i2VrvI`M_bFN`#R5<%OBE5^QG7~8*BlC`$RTGG< zr`J6gy;aY61g7%sMc-_3nBtU3&%`g)t3etg)Se1fiV0)@B*9?8!a9k*9}qAn)+i?A$jZ+U2!xcUtwR){m!<&fYYl%za4e1>Vj z7&3P2_Im~ZQvju8L?<=lH;J+@MWu9W*5rG5t9KzyIKDE0Cd$OEmTF@p3U;XGPV5%@3xyj@hEj-v%#RlKdngn8+iF>%*U2VpeD6~{33f!n1eaT78 z84+^2XuOnoufP&Vn6u+k5kvBCfH$OKUhFV98qJ8uR@$%8Pa#@60uf zWNwYo4PQwr8AQPUBdyZ#<`m&rUtjX37XDVv9&@73>3VCw^~q(6ed|m5+uY!PW=Z;G zjO5eX|I!(8RQhqvCnzXWg#UF$N~~CkiuD+Yt6XRwX>Ij8mImQIjeZGR*gKHURw1KrK*Yn!Gf$O-F zsC=J*#!M`}Cx71**#xg_HhcKLoDSte%lDai-aKBf?`dskRh&D^p-qN1`tsr~oSBTU zYE0IGt30O{_y&j_T;})h_G3;48;PsWTlWhHb0&Y5jG1n$k{PJWIfLf5T3dC5ctF}T z%YPg1gskyezR)3w2U!1{zAPBHgBOZLS3>Js zCpT9!YN2vmcAk@>>%&R+i-eeaE&>&!J<0{0V|#dnot1jn03&heX26p)wO$$gJ_LF& zLS8p%C+~VdfeGfsFfW5LJN%~;1vuGtpUC?Y_MG6js7Uf%6adoNDge4~H|AtHCe5?J zeD7QIV_=|)9&Yv^Ffe;lF3l)Tnv2j)yz%^kA&i{+2f_}(|0k~Sa^<=hk%rV8TlWWYq8HBnVU}~u0JbE=TCF^&uR+9$Og4?c?QZM z0iL5MH~m|JYGkoZQ{^tkRT9IdyVWLRHu>fVGrq%wK~BecZiUgp^wo;_&*b6RZ>el524mvz~2fz#!8IXzwK2kbm^xHf1{ILp3N+`Ob0iCWyqMG z?O1E;pf2Jdg6&?XD_#!RYEF3g@i*~-IF+MCf^DBUq8S883EWNd?_V@x8x6%Ukhic1 z1RVt=l7Z=`?2kd<(!F`{hwHC{m`&w+eyEUv>cgvdY^jDvX`7-cX8PlbaF#qIg*{*| zlO4t_+`L^*-wG(2=aYh9^xQXa$e`qUU7WcOS@xkdlpp(#4s?&yV_UTG7yxQe^$vaK zd|JV5>d`|_EZKEO91kT)T!scgN=_(2;D!cK>7>x}<+srjsuu;$gmDKgr-F!WyNW=y zX;N0z0iEq!ig({gaDGH&FIpn_7=5?=2w9%pH6D8<*<5R5-(m5RloZv_u-8^7N&1#Q>R6X43&i zUb+@n*VczD$BFFp%iLHNC?9QePcQ#2RMJl9*ukWMjd(niPGXkP+3>gybgzR_FL_BV z%5YougD_hW0u{~$^NP+wveb<49blQAQs13O`XKnw&(}tqweP-X14*2_zme&X zvy)TR_m`=uuAH%Zx3qT?KC>xwmhuCGToY623tY*pP$5`X-ksb|An^XR977gYnM3w*Bk?XF1w^#p|lPdr3vK>4fT4Gf_8`xdV z)^%1ATZk}In#}XHv-H;ViTHy%WX>QvtF)IC%c-sF?X#Nn*trH#_h2 z51(ktU18cOt(>jQ0!FYL26FW$IIxf2d|(bjPK9Ve)&O&Ca+>S2G1K;|Zjx)*eQ&v< zPmYWEE6C3SedtpeNlo^!+6=2~NSq1*W*dD`fkE(Mr&o=^X_&^L2Ub-6%qToNI$ohR z>l{1&bN*ho_M=Kgh`iUC2i@N0UYm#1O;+eov|d&m{3t*m_e$epND$?f5PVKUJ_SFB zUlHLUVc?og)9>R}(we?7(^^)%{0_>k?HmHA1EZv?DE&Golrz%(v?Xv1HEM|sIaoLQ z6$!+wnHxU_J(9kSstlFnkae$lk_vA-lLX^GxAMMyM({cnUP<(jSJFjpZ@s4eUjfpv zDy+VtuY7$EMZ3-hFR=47;1XQFpS7E}N-A@=WqoANSGNrmaALBh<$nvpbuwtx3}od@ zca};)H4IFcuw0Py{3#yu1w7Rnt!>i+7_=b~Gc-5smvP3eI##Cyi`G?>+Kk+xlnUOE zS**07*#5F#7ERP9drV=o5|fl|v2yU;0gySChgXG^nXuoMEz_=~S$7MUzyBO!+>tpF zYzqlty1!Ambse*>dJ!aOy+9UkCMu2>zJ;@0`}wim&~U;{#UDlCR{#iPxOrBiB{ao( zcnaX|)7b?D{4+@d|B&J7(|CSKykhfqY@s*xDQ=Ad+_liD45wLuc?6Wb{2xbnqEy0u|G+?5 z{~O&h<^Qt>Y9fyqJ6KskY4t0*-#1KoF;!{nC+G_}@~D9!GC1{ev3+rkM(Mi_1Enmg zQ}+g2sl1ARac==ReEBY0!vUlk?sfs*MxKNwLH1;^`&B~Dp_a$Vb1lTEs*!bdwRk2jn4EKcvfnd2^YlbXy6=uu$Y9U&$ z=3Hu@O83IUH)nGItUq~Swyp_>eRx(Aexa*NjwPG$%El^*1l@QasT?}Y`mX|)2*n1n zfWBUH=L0hv+Jz=c%i{1M`GFE;wWbIW19~+tAx8pXT8RyCf~LhDOv5KlmOZ^e$@&{t z7tsnpEp4r55x9zZ6PeM@F6W^(SP>7p4JJs>fXdAdNy(62p|}-Odz05*-VK8%SRO#^ zkn`(Ng!i{xKvTsSiRQG zioWA4E4GluI(r*bP}S~>>2`5Y3G^UH8-oQTEe*=kfc-lyF!8&R30$kx5+`+cEa&Bz#7U?o_%p0*w0`9H$u|$^eY3XTQt~#$&5X z4u7Qu={ke)eWyBTrMt0a7TbVPrr<3>FIYVOb- zMpjnK3(c>y?ryG&(BUmh9S`to$G=#vh=jK|J0>k0V}?xS=Y}alH^(`2SA>CZ+HZJs%M*{IKiCuKQEs zA_Z<@ldLd!%mGUjy^<`JYw#-xWxz-EjOj2)cVa~xC6mqyjH~U3cDBB3THO6JQEf4J z@MAdi3PrEwM}Gj?Rv~&PDneX~ymiIT3Lo#T_s3_H-=H>1*vvhNf#wlRkM$%gJ@z&_Y*0m z+om1g-HfBq{Ut|g z8{^V<{7uSzoLT5+#a57BPGZyUSLRwD)~MR*TCP&6Vu)RQSK1#wWDIVcd#%dq8R}Wp zWwS^cu$Y|jZFm!Z7Ja3=PYu7-t|TD_ziJ-iE$?lb7A(^T-Moe85yJ;RLQ&)Xaa($wJ?Ld z6qHMnZ>!gu;F7lnxAE5geX1<`*7EwZgW-mYxTmc9*DL;KQZ1Oqf}$&||NNRIF_RJV z5i64a!?T(4%3u}8SxxLWX6us$S2i@4$dJVV zhBvwfNV4AEtl4VX)Y3@jyQ;@t)x>A3E82YME$9N<4W2`>6LtQ;wII<}~m|E_> z7QzfU`->2hg)_cl=F4QgWKhFIcHKAR;N;}y!_~S&l`m&kGaZ4CF{j96`kVPyhQo0! zv|K?|n5JnuFY;V1pZ>iDN4H?md2wYKO+Bwg4%lQy3@;-6 zePGjo^}=@ZjUn&bem~RcV^olm@TGrI_g5mZk>u`2tGi-SS(kI-6TMBL2{S`AC#K3G z2Pgcyky0+ju?g577UP(Gfk+Wg)4!i2ier}^ZBHEg!kSG$baJjRG zdceUEd2FaMTH@h!K#d_hFx+TZyTm9w)T-5b{27g{VC!>5aA)~&#-e|p6B|!w5I^!{ z*(6=oS1i0_gm9tApW*sFx+a8o8Y$cCI6|@~SlLy40Ri;Y0?B zJ;pbTbn6$tu4KBi?+m`ksB>uKtfmDe8qLUt?PcSHFvHW|ms1|7U2P-J_O2Yc?ggYZ zPckC4F)K-xNL$Faa$W8RrbQWbJvC)Lq;F12%JqLbgTX4egUB_S*A4RVt2tq|^Qr~C zKM@&@$dJ?$EsO(e**m`(RxWeHb+9W%!J(I$@rg-~(W$seNXNF&<|rys&LXN+S~>O_ z0Y*X1)F^C@%YkIaqpB5@t=5rq6?^j)apim-^L6?TF^n<~^DFY>EXYI6fQxqaU{px{ zp>Iej5qP^)*CiW(;W&OP5kg;{=!h7b@92zdc*`W(%!r$%M>S!catkvy6Tu-Pvf!;v0{dK1PCEH_Q%X5kB1<`S$S`If@2-)D z5DcgWU(qd)=e@6iswKgPDot9!7vza^7 zUw^m@+_nES>HN@IBCtu!|zG`yE!TPIGD=cdA#(4OP!@ zsefEh<<9`3$BUmGtjDIKwehzzd#m^Vso$fpiF*H|(qq8=U$w`ELP%Vpz)BoYV*zU+ z`Vwj2zjvGQ{91RAtG9=hvnB?Kxt^EcaVg|Y6=@BN4pW!QMY`9&)Tdi`SfrFN%^stBs6Tz8?Vca&{rE-Ubi5WLL(yIFPY`nc!qx%s#2 zVd)l47+@qc!A`{ISzCJjb>Igk@c~%3vY?!tUt7fxV?L3ND_^^!8ZOa03Tu4}u{tda zHx!!#NW3#`%#qE>kO7|@JaWpQdTpdC1E)b2gl4w^BwYIH6Fo@uZp0t|C6KS^(_%Q2 zuHHN^k2;g$9EL+$QRGo{K1%+eQBxVoRR1t|N#Kp_hfo8CcLL_IrHkrP7%$%w@cwTk{DhWq5U6gl3X#eUb) zqwovF#Z-+5VL)cv+Q{Z%?r(0=I z-(4tk06bL4RF^WrFAO>vtAiJZ88kg}ezctkA|B#q*xn4cW4jJx7;wkZ_9!v8ip{Ir zB7>aW6}r*J>Uty1X)U!4q?>{xfr5I!qOMtKV8<$MlQGJdLnG^EBB7X#wb^ZDdTn+z zm>g(R6q%WF2Ub&x6QS@~^rGFg0gomDogCcXIzKVwr_FHBZA83mcWf-Tcc|Bjn!M-mTatxR zPthm5(@>_U6^+H^6K6s^9mb!*lPBu&QtXCy#Bp+ZE!N5!gD1Plo zF-CxhjI`zZi6NLuGorp>d~PS&$${9M&wp?zS#%V3|1Me1un*Y zrNXsUk>}!X#|7FP?D+{VOjpsUO|X*&+A28T7P;gvb)d+rMK z5BBXGx|IIz4_|2zT@Ur(hr4HnZzgs@yP(c|jJD2@0BT~761A~xMEZ2Jz+RfRxIZl9 zR5w*;gI#iEWcT$uJJ;*a!Cv2?%(5?xbf(QTIJ}YwQi!szTWK@3xns>t5xtaqDaS;qaH-|rZ0uTpUY{GEtkb174Hdr_uQ%vbb@;WoFpYPidyEbg zo#5r`-$9dX*yq;qSK2AR;(QSei^9rQ!i41)dklPzpUyYH*DaxD z5aG!*1kF@Y0^B9>rRjbew-Lqcl4AS_)66VYsw*-KH?d_D1+q%zqWiQ7$ZMVY+()3P-{ubFLXfS0(cm6_ zP82Lq*cm?oa9B#{k;~M>7tdV72XH6PEzH*-wZL3_9if~vJ)Z@}JSH|KN(-4F>&QF8 z1_`QKfJ8KxYO^+^V5<9V2uEAyAR2erc*>sfkj+X_ff0`=BmHw&tH0mWTFS#d-Zo|V zRX0nUIoK1HC%=M>vBw`>0rfgO+rojl#uMIb=2X@|7t{{37Xrd3I_5`G(ucpiK*|ZQ4eWY;yjN@|PukN8bV-lSJ4Co@VsL+`B|KynRkdn8-S1@{yxIK1NrfHx#O zifFs`Jc-#)gYOu`8W9o&znWp>qsd+mN1#Q=Xa3ko&j#tzl<4VP*S>jV} zkpbtr%=HQ_?}vO3 z&B$k|e3c-h?uq}$)jI}f7OY*vnHUpJ?1}A6Y}>YN^NwvB6B`rTwr$<9jW_3+R<5RlW%2-70-HtnyKpGo&1K)OZ@qH(CAEV0GZkFh zfN}@H%d)?S)MZz(jQ1QsC+`UQHKC%y_<^4P{9gt*CV1^n69^a(5Gs`a)ou)h0Mwhl zdFl%C%El@bFzeBKLL!C%iaYs`^P0bMGk}*Du0UTC*XEG_$fV(n0!06hRB0Zy7f8?S zG@a#i)#`S%{xq%kV`Dg?r+t6lbw7G5btw!~YkQ%}zpGj+pP)5IdV_)CeTHlZ&4a{f zZ#+K=-b#FlLiR&_8&{kjQ0&6v_)||bB=a!uvmeS85ZGFNBgH4q6YK9z5$%OVYQNzp z-s<0flBPV-h-tULb_(BLT=%IOh(zJir>xO%=1EeEO*QPC)WE}}M~x*?IMFGw5-o8N z%G=mypCtNSyf#HVRL{uyiF=m^5LZ>~Y3S*bb#iN8_ncj~vb$;kWOUk=tX^Iaa9hDD zYjvY#lQ=z!^RL%)v)LyOgSM`%N%_BYOUNlM|C2zIM^4+yu%~8^b%bGVA(WS1)$|$J zV$pu@S2?DT9iiVz;9t!@XoYRfJrLI~a$Oo-(SJ!-Z86V-#x@G12+&s@?H zVU<2Ba=B2M8>8B903VZZokYc;_GWfNx-phCj%H4Q?tst?aVz&ycQ=lU`Wy%|HRYC= z7=kj^v3+QcrsNHZ-mQPMC^n&5ky~pYaJHD)k;VVz$93f&PBVOl>d5zBWL&@r17`Ib z!m0lsgyU(-1}M^i@y0n!2G}`Im{)42;1LN1*e8g_&}M><Yk1TA74SM;Q%Euw8O{@RW* z)@s6?+dfJ)7Ttc@dfW2xzMFVM z{^dhoW@049630})JEP>Owz9y>^wH!*0?reA&94f#QLPjV&U@OZ0PG0!AD|2aLbf_j z&&{7S{A8+VcAkv)9cT*Q8hR9eB%DW+y6~V$JsP^?=1A_-RMu2-RoI#kmS0u8)(TD( zx?-;?1BCT3BG07ZqLuA@>?9+H9$r5vtGe~%7Hil5w#~kcR&|BauEpu8=5GzJEh*B!QR)m?rTLo1d}+EOJZis{^)o~BY`BYx28){HdR zDxa2-qMEVBN_7+bAHr#iwvO{G$z$f6^Y6d<0b?wQ7T5@uA@wxj>9U#511of4sfl7m z8p^#aW>ggErp(Fy)+1qQLqUeH!ik>6T~=1mK}T_FMM@{iWKYj{>9R(S#!=N(Hi zGi2=iI)E{Ldt*aS&3xDEQ*+3b2-~f3VVOo0B*qH^Ft`Dkmy0G3UX#L0oZhkSMH)hm#o(*@O8_s;b4NYW@DVV& zEa{IQ<~xSDniQOF8akRqGtx-DVT!;t_G_4=+PoO~*_?C0348R|JtKu3AgT|Nb`#3M zqzyr1v);1JqQ?*|28Albdim91V;K0WPvX-B<+t_ty&Y1IGPJg341l|NQk2`4)Cs9I z+*TDR`szkj)6Eif_^-L#na4+Q;qMGd^&MfZB2e>{W&RcsHY8ZaGd8}yua$W{dpi~A zTKw?&i@hqi)01d`8J{*KyBb%>qj)CWA6*wptz2%Bd!3^6qalVPX_Pnj9vb~a!m;(0P>ZS8mC-sL7 z>Awdypu>+3T4P;e4U&tPM4BH26y+lJS-uYE&A>GI)kNv>PY>_(9MM1H|ES;pGD5&i z-{*qU4{Cdd=BNO%0IzhVFVj+L#}BLW&BFP|d2{Ma5F>zm3D$(@7nZ378#Eq^%W^o{Zq3Pe+ zBoj3i*D5J0tVpgG(-tEoPE;etxv0vHg){*t2X49<;qM?a)B|t-&Tz9|;Za zbZX^l)Yc3fR9=&aEDFP5M*al`NN7b&p};CWuDYs;Z<7qlabE?xUy2 zIoZ4Ci4gW4XDf4W2Dzb)__Z%NByAu!OgF#T@e?5=_#fHf=ImTU)HE_u8jdW18s{w1 zy`=*)U`Gp4_`ai2m1(k3{UIOe6=l_(3=-o>qe?8hPas(>+>eU~5sme}f!@Lxq)YC} zV)O?bY8?E@SP5=gdmPlCyeoLDp)Kp~2~6RmhK6dZb6A`8f4){mQl&0(YG!9kJUD-v zo7-BEtMFcKJ0|Yz$)jC8cq&967l_3q40FG7B9%q)T?YwPk$4=f~|sehMpG?n%=tmy8?H z1Nb)J&k$?OiaM})>ycy*k~T6iifNdgQi)+cOv5}~h35~Un-sx_v1T%?CYctIUhb#C zouru^rSMz!vZJ##luq2t(P>1KPn<{<8!2wv6+YTVk~#~KpxHV(@#&o!2F{x1fa*R8 zM2x1C-N^m6l7KT|uW$@tWTU-HO<1d+1)QR^*rePdKs&pCmXXG-Cjfs!Dy7rY=NQ4h z?eX#_9SS!CtqDZUQ(4wa6Vu6ci*A#n@-3fWuz39$C2i4f68M1F$u&E%dC1{I!hx&V zjhaKiUzdT;gaGNZLru&w-QBZzREBQTwaTus$=uoq@M3CF+ddZ3l1BVaYBZw^0N-Ha z1O+hj*)(7Or^-B&sF9hImR6U-j@G0V>JXucl^uuJu3Rrzq+S2ogR|z@qLyK28-+z^ zrLhS%DW&adifneJpTwW%E;VCrcRqhZJ+(V{2(c*-0@C*eqJO5dSd*gGO9)K+72 z;u=3YePKU>;st-*3R&S50EWwqP@7E?u?|KZCI_U_k}{&Lxh?-d$0s4g-aTZp*>;)x zXVeUfzXYxM^nvgOGdfRzEJtrz5a&#uq?qWj)}X(TQ+3m{A(EDn!pA31{_!fv1Wa`! zp}nRepa4u+sv42IpVbW>{o0!UW?;jNCmi`u7MQJZSvjbD*Hxmn`(Z1 zT`Q$C7ECbNp=a!iYVzr6uMI*C)q}~hu?>Kj{iy;Rc9*?l_%@rLt}H?Q%Xj|7DN&N!)viE2&@T$c|F~2A?7z0124lWI;+l`Xfm=*J`8J zky9NL4QJLs>79z^m4V6@IhmSO&GW%DT#$*L&YnkhmOid4iC>JE5~=uu|MQ38(^FeXF_(i=26)sh2HL`lVj z2mWet%7F_9H>8xg(6|f@J~3~0P&O}|QkSka*Ev+s15#*cV(GKH1|#Pp&ro5M5`S@^ zL->H!klrf=EcZ2#G>TW5;}^P6K)(2@Z){P|LEeMyU9!wIHD%BnVu%z#T3~eI5b4FZ!fY7xu4|yT@-b8>ymPouOJS&e6u`io z@L5tJ0R&wQRJ!bqiv$JMb;p4r3+qrY&Ot~wzMP)o;5<~qk}h!mdCVY2LFjXDEXHa@ zkW!G2E)%9Hdn4-Gd{yX?X1p7nXjYJV@l^b-f;0a0WHY8#w+w9=<@jOM4sO*BM{C+; zb%HBy+5l#xqPC{=ykRwW!XTY%H|w>8wQ9W325?Jk=u3`-VMgExu%_eP`3o5-l@(+C zS4+<37xxU-0pTi5O&Evbbu4N2$OFRGSXk2PVGQo%h=NJX(a}kiJ%w20c!iTPK-{;{ zG;PWwOqDqpvdsGpnl)(M%CW&UOw&?G$`ZDFd4GH8R^CG_rU^koErzb)Gep!}%ze2! z2Jm~$hEFhKAGsVR)aEc=)~j_Zy+GY#5}66MBGr(UR<#*JwO)OdUbXKK41}ip9a@J~ z8cOVB&3=Yga5)q#6c~cL$t2tiKbw#ID$RZZ?S3J2zZ!ZHDJ@X4{DQPO=^Pg8fw%W@ zCLQbVEI&27EA&oUqn-21aIO*=8?u@o4}it}NwY*SI%^a<0>^?i=FvxeH9D)r@v1w+ z=>Cp>&S!VI9R86G&*ACN3Q`Gv5=%298Tw&(cM*>Jp-y-KH76%clFMHo>+flDjJc8m zb#mN1j|=iO2kwfXxC-5gj{omQ?HO>cs9=}8=UE^k9Tq4 zyr_&5pe!<$Eh>^^#=-jtnJ1bLo}2RacI6Q7%=!gVF=}$hZ!ny^m!Y@e`ReJ_9N!-# zA-FgBoD50TWpT z)Osr1bpjOmkvJ!|F^fovgpdMdAy}6Uc(D=6AuQ=?h)D{S;Reu`J#|?3p?P$rDZWl| zi#*a|qpy{A<1i9DFB;{6ZjSF+>B0RMM6z@fp|OWkgGAT->D2+r))rz3hvY z2ZS|-KD(gFXU~7=xbI}c00unZ^ll8f1uqdE%U1uk#{ELCK{%Ae=0P$Sq{kmcWvFwn z_b!>h^V_lElcJ0)d#-*l8pE%qNU9YI7XmPY%o!|V*M}-_0k7DM!E2`@pG?UX3UB4}Q zYa1}h13d}JX$NgJ*p2VR&0IVS|J8M&P&28fI5YWHt>z?RUtxGMr?RbDf-H3yt83CL z{|WcFWY?Tw1Vrt}uSxHBmkFt_subRm`UfejdWCy$a!b-!yD}r_YIgi%t%s5#Te3069@w65@GA*I- zR{N3m;=S}4;m%2&<&+H-mL-)XHF*qcHsf9GP|cis2FS9R;^h{anmlsKyd%0>y*Ovi zRpUY&lX1s)-ZJjn-s_OzJ|t`1^tO%Xnlww@u;QhUuR)f(XXJUViTRV>IZ2gZ4!3F! zwJISt{fn3!KJTs-mS=kM#O0DCSzZ=MeNgOWj=d>059G)Ypr4UewLni*YQ1N@6-QJG zc21%y0t{O;+2Cgz-p%5!6Wy+r1C`euGpwwN=dHEObE;yG))SoDE(#9*>4=%F`0}eX zxtaTKio#tm(biArA+C;F)NRW7deN$^PZyIuqA45M6>7c(qt;#(b9x1xUO)k*-!Lr7 zeBx48uZsSi*UYRwx}D&@c{Sh?Kfw+QY678W)ToBjQJouREr(4xm*evwhj}&kG4t+l zbBh~eyvk-Z1Z1Yr7S21OHM5$PD(*})$!kg;Zs8jQd~?u^JnE}`m{BnjMM-tGNwo&8GPd*Wq^+b+rkngoXvoOm$O|?jQiXp@{d6=bjJS<^ znKBiwDecyNbLC_;qK-cNpttS(t z%G>W}$cXW)5tKvQD$Xi|R4bRGPGc+vKNzX4XWaY3u-j~AjAL!zgm^^F6SJdM7yWH{ zEO8zdJCOm>R}Yyq{U@59f-P3aRWdZAmshf)1uXhcC!Y`0T`A@L0R$k?0KB-V2x z`%(aGbXJ<1(CEp<)N&+H&GuyJpePm71*9}nQljYiAp98YXdjr)=4Ek~rU4tVSkYq| zd3izxhk`B*yQtF}@%>dDoanfM9%2Ta7&1KOHO%_Gd}AVmf$SmEwPH6BcnB(+jY_d& z;i@=%p6zoPE1Yer=5$r!J8~G*yNp^3E^5GJ5Whx>RGN-N%tD*+{Y-JoE=#r6ykMrJ zJC?=8AL7xVsM4N}CGHsKLJOx$#kDI3Pie0yZ%5wk;;5$%+jK0p>_gD-j9J&?{rV$3 znFGdk_A70ANqNm6!6dKz{IqT|uU#3yO9y7?%{%L2Buv_f-aNzxYe&sbW>$()6beAz zjM6*V;)E5RSI9v&+cFG<6ZnwGPqW4;sC3?{@YQGyxlVS3VXL%AZ2wVWqIJBf*7*ce z7HbmJ1unNB%ezF$&ZujN-Ek-fpETvI$K%4ob)npJxXTlClJn73KEmROQOvi3Wv< z24?MkS78aL8`AN=lXU?bedFE1T9kXhprpoHV`*6XO50&P?~`q^>#0d{`mX*(ed5cp zzn)}DsNSjan{}!UY|RbE0ykb!Qf~Wis0ydZ6PH!gRbB22bN!R)kiz;7ITcPc&o5x_ zaTjmMCQeMgb*t-RgJ0sS-Xn}_?gW>|(R{KP(Ja1~((CDe>mUJITbO7<10+8MS0}-d z7saa4Rx|eo12Ii05#yURs!B-P+oOY!b&XEyb$O(Zld`SCpU9Z)6S93tw9c3yk7*RH z)pG(9f)B{C@rQqb2A?fe-_k4G6!Kq;^xUB z$`zab66&p?xNO?8sgy!WnJmQu6EiaUMA2Qkwt6>}=9t!fEl9cBzMXu@_A{5iq2dsu zTUX`g7wt+J#AQ$-)DsY})QJ6{8#5Dp0J9^k#!`-8uyv+DbuhwW^`Qi#f=O?CFJ)V};c9T4we>Ynw zECz%ukX``vyhk5Ul$JWC+)hX3d7-^Y@j9p!wi5L`+4fG74>RpTXu&~R%=UO=MQ2dHoJ?${+MD+WzFL3+PIE7lN5ZT)MR1d9rZ!Bs|NEC z6#Gag#s4D4!5++MbrtBSSQsUwi!B9<54D-w1~>ql)|Vf5u(_oNGD>1-Oeom%c%j+3 z)!|t6xj9zT(G>w*+?$T7`WiVbnt*{U0@^edwa8TxtqB7NDbYiiLpB{N5nMTt91oqM z&>`1(ph5zx+=As_(FFype1x#qYU7%HG+$5MAaYEOY#qs>HUd$w z3z^fBR`d*)kfdh=q0`h0k+|Q}mC&ZWctXlnz}cwnRjd7l=EB8T7(=%ZRRuM9X&tdg*3b66o0lLN3v=iWw82i9_!tTbb>Dz-< z6{9JwK{C+F^RI&jgQX$=bU#%(0b=sgYc7>+}00IOBN_mmuul>hl9|2FwU-sa)AS#ybxO-Sms)XrJhQLJmn3MEYdJ zc6H4-1gqT>crTVfDCfR{bkW3pw&?2Ppx-PngX8DNfwR5qxS~a`1_2gJ_QH4U&+ahblfyyPmE4yJa5IOQDXn10 zE4go#KqmP%IP^q#bJw=>rag!QX?)_jvHPeg&*?utemB?OS(*XQ=JweTWy1XwX9`m= zTIqiNLE9t(Jv@Dk<*KLT?*>>XuJCY#6SCwWK*B!zNqun#b#KH13a<@-Vw4C?B?R>1 zsc;`AeImZ$O$G``_vd|Yy?HgY%qMieavlSi@|!UJcqsmD*_dDDr5Gv^rZka}lwO6* z+@BdzfTrNZ&QN_-CJ#Qx$`y3LM9E9?@WJW$Sx3lPdaFh5-N(&!2Nkqpi@G3-qnD6OfI3jf7< z@B#CSqhu0rRcj7=Yl4YNetC3tKbsO>RTG_Ylj)0-4O0pi4a*A2BUuxM zglpVYvWVzV)FeC`TU6)H1`#Ce(1j9sNggHI@63oWl^UefDnN56C&yc?xz$fGKumAKaRjZLqC%t@B zv;C)O*17u6z^hi?xbJ~{&KTcMHP%qDA%xA5+EBt*p>?Xa^8dQ zr|x$oL3eTT_UJ$tWAnn%D9GX-BA|!DF^Aeyi~_7^$=c}n!>NN5)xb@vr5Hy$ArCL% z4X(ON$t?5rX>tybWtC|(MwV3A_M1nBYZzig6^^5pAZ}hXt#>vKF z48`eA0)M1Z?LwVjGx>8QwMiKxu~9!+Uz$Ztv9P|_>sl8)Z@36hF{q8?^=~yF3u{bJ zUd*bjU~id1R=bc9NbtD@4819O?KGGDBL>!XFYw^jJe^6~f=kbB#U%ZOffcu=e#c zw#4gewr6X_h~_x;){*~cFUBD2l{8l>MpIla+FUMjHkXVympa=nKg5Aw-U(6GEYIc22JxixD}C0+Ry|WJWN3$U4ozySS*DB~A(pv|?oYq#?#r7MT5X(% zTc?x7hgdO1$DE?2ii_2? zl4)35iKUz8@eG40lv-X_2pfBT4`IzeXq(iA_BX_6vT91XF|txG1(+RizMX3$xPygk z5)P)FM!%=A<@E6u4~>OKC>`1BXQ5y>DsZVgrN#H#3kp?UoJ@FymIZPia<5bXi<9t& zXOo`^ZRX7Xwb+>R3~o{%Fl6jLDUhl1x?Q=AmBI zxlxvln3GFpBTUTIQZunonQu#+sS_-EHvCQYNwzKIzd2a>+P46=xYwNsgZ0s~THxb~ zHa~8aLw~Eb!J5pIRYN4czUCJX5rz1Nw3U%vggBZk81_XzYT`C40UN6MYkx!RW8@10 zVfitu-l`>Cl#$rom)bhsKsDs{DT>>_@1Ou!6duf()mc?`?v3SffUh64K%3oI3 z-7d~~$0S52_l|_m*RjTM3n}=dj@Dm4-g=?D5;B{t;gNA$Bdn&>5V&d zj>3KmFa`7kwxVfP{#;>OV*hs@y2hlBohWP0B1xXEs%!;Vwu?sN4r93Yj=N33Go{k& z%dCnQF-ku7Ys6ZYk9&U>goGZ5d4xsfp)x<1qZC#$psDbh;Rq}G^hI_H84^hx?#&rp ztwt`sN_^d!OVppH^7)OVQO+iPmFEU~^`zEN-R5A|J7H2p^`0ks3{C;h#__74sXX}n zJ8kM80m~F1>2X5f+_~oyx>Krvpx8}{QfzxCIs_dWuS8_l%0il&n~Xj%UH`?dDkSGas=9quHm&sl)!obI(06Nx7Y zD$}(*VDk=vHA$fWh7P|@EYQDm|#L`t-ozxi(>|`fo1z+ z>jnLQm~62mFWKH?n&a}W8X-FLO%%5`{)anCxY>Aq#N;SM}kNmMZpes0b;KkArIi=^4uDe-;bkU^ZszLv`gPb?w8M#f32vHG!YFHrf z3N0heq&N&w(@!8I0AcUP@2UGfD@Hb)8n)nBhXe1=W-#;X5FtpV>7~TIV{`>hrq%&} zC9iQEojt@)ivH449+GCM`{h(i$r=m z#r>81)y#N3(A{2AIrK!2`cUTOWTw<8cPSKn>kDB}KhseFejWg;{2BOJ(FVZ1tbslF z`oZTZ&P@SN&&;W(uMx8B@vPqsTPcDB0Pz^Vm9(2Fs%z57hQA#41E)vQ1}XH9VPui~ zjR4}^UY?*67I;Etdt(dd$fHm1&U2n7-8^h+!R&;26pXv1zAy4ma;>A&PDNs$)EbIS9wuHDiT16+Y*(@YP)yH+*}mkjYAl5K;Jk(#S<7OZ+6k$3MoPD zkvxQ~8;$CBEKzfrk)8uu{sYC1GIjf$mij4M4wER@?wD%;#l4FaG&fxk!DiB6+1^u> zka2>RA0lPB?}aH-dH%O;6-ge4U|uc9gWg zS*yY(aqc=~+?)E-iBEqbKFKC)Qf&F7!$v+$xLf^h`1xZ`7KC83yr+wWl`B2fba%Ab zK6dEIf&Ncg^}TD15~dK~1^$lCShDgQA?{sEGU!{J8pRH+>S2Jrl*N}i5fkRp9%axO zcSp4k_OEIG-FJ)F6*ukWDe|i-kMK%lvZ8^^9q10xY=?@$s(jpG7VB=rM=;|~(2bUE z-S)&@)vj=NRK+F8T{??%59&-L3=#Yc&6Hk{BN}?nP*T)XW6}TsgI{bFVCDPG3%QW2 z)pl8`=IFwLz9&}HSv8BRCU$RxGV2cia%-y<#w>lKCFH^xnPLf#Gm{w_k5VFJI3tQy zrGIORVsan@$jugE(oSHaHPZXdXUrZdjA|pS0^PUHYZ=%5wNoMR`C4F}hVBpfBXF<* zoZ}8$^sM&^N(T)fN03=KRM9}g!yqwvL)}2+5KMHTX1+)Yk?W}`VPD41H}lvm@Aw$$qbZsWY6C;= zRzG+4wAy4|NQ(mZo^%oMGz48LMr2v0ZJ{vz(q!7BpIasR0C~*q|CI0?Yi6Cn71#BO z;Y^tHpM-bbKS%8(-;AE*i+Q7qdQP>an0t%m=Pm~Dx*uqRAiOBHk8tE}sTIa%hf0P! z$J6z#P8S6jCf(QBcGL5o$o+&|gE~tHjON3;Nu{~>#(sQRJ(G+)tL0~|Dx_^$wM;V0 zw|U-VvZ)!|f$q`03hdM!bn9%`HgSG59E56Pt$t4ie}QnA=iKhB_|-CLd1K98=lKhl zOCIHu4aSr! zb@gkM!KYrln^8nhzUO7nLz5`=b(8pe9 z%D^e;L5!WUby#cO7$y|Th0^_U>fGBNa2yr6kTizP*D2u>9r{NI_7^_i#o-lT01=R< zTnM22M;6QWnQ8cO1x!9;kKD=SG`1U6-4+Nc{e=ONm(cp`=*3+n=s~DptOpdVqX?-c2BtLW~cR^BcW z0lk2QFc2PaMBsC&q%L&ZRT>^<@+H*!x*w+O(6)Nyd$@=PdMBc#Sxv|#lz=aB7xZis6sP(ayOZXCSH7STd8*tP1N zy%WT$)uepW1wo(wA$NQCQr8UECrBY5gY z2ai2Nyar*zCEt((6TX`|CE=Q=?@p7~j{kHn192>Al!xr{ek9e&N39OSGpQ;MU2GH$ z37TZ>mL%sCwU~pyZo^jcO2V;=@J{JZP)X4eZoB>X&)t@fx6G{cJ2+$w=fAi@MmpVh z4BdAKXUI14i6Et5D-1g7vX+**Y7b&E_OJPYph5*Bc+oDI=Fp2i-7#H;p%KJgwbI#) z=U#%HSf-qO5%IN<&GYli^e2w1^sIC~0N?|%7Dj33{@_3cn5dh&^!o+gN2~eqfprtM zBV~VV1;)D{4twAxPCEhl##l)-WRV1L#vs`tzP*)dD{SRC{)c;&2{$?LR1Tl*RI3tR z>iFGvuMIaWV{SzrW!u&J@63%&489U(9mcTKnbsL;fxz(Vu>!QeGp)E_q%J!h3=L$y z&04;7i?J`XNrg!Mx1>H(5WXK&3F=loqx#i53#R+`8Jz_H6AhC? z5;p>3Acz07Y@h3f*?;$4*Fa65LT_b~F!0R6JZ*w7`i3!zaGcpzA8z8X0>i_qPE$<7 zA=R?fC(7`aWrFb+$vN|~Kvs|UTaictZ+oi!bDOnv4-l zbBnP@6Ry8ls#O__iF!dn(6|5JSg>XHU@F8!MO+S%S|0UwJ7^}@YIe4N2#%VN4-Emu zc<9Enw~78y@RySh3aUzg%B5wnTYismGTY|(K!wt?>h8);jwKT2K6ypP#Ia#eH*?y~ z>`u3b_CAg{#`f2M@+DMpx1f&3gnm=Ss0(Z2;8hy0$SaO*b(6!Jc1wUHmySU`^@MBC zKHhGp+aNtIs`@eGpk1xF!BhJRRmcmZDd$R1UrNgQ$WwrjnZ7}-UUhV%ZWQ8=f-$!f zg8$4ZoySHyu5Z~s{{LAaBPQy4LnpGe-~v=)r@uY^kcP};z6LZ!a`{)4sAYtzLK`9o z1IPswPJI5Qe=A=97_e1A)gkU_xubCZ*WnMDhaK+j=HoF_+VOYh%OZ^l}Z{RJqn4fLV>+_YP!Auggo6Qm76yw#@eo5szqERfJy!V zA&R_2g1fjf`t#_Rx(cR68oYqhP|*abiivWTRa49kIW}b90F|WWXquM+GCS1JgjAP0 z`ezJmW=I)Y_|WxiM7=Q1Ryb9=Gs2yEfsIgL@26m;NNKP{|GK+>y`@m3z?n9diVg$& z`Q|&gGV+qv^k@5Ll>hSCblZ*)O9`0Gios0FU-};C4C6CHXYZBbE~!hu1!5cgZh@x< zHu*r>>#qN<%TvlkUXpLj$@0IL(+`G3d2e(iB@ZWO6B~I)JNs{sD+?2+M1&kHz<)ia zV`R7-P#PMN1W{prSlNDiOvBT<|A_o9JHX3B(YrHoNQB6m)=x=ms_WFh3U?) zOlaQjWFmIG;Jjlj`6#XxW2Bl^O-#Hz`dr!NZhw6qs)3}==&yL+8n?E@m)l#Zv@9+- zkChkQQjS|SS%*S39b?PXP(cGy`;a#`CWLi1f%n7u0%ZugS><+QdFg~$Tup0@x-Kt zmeyh36Y9godAb*Vmc`h^i!ZFV2-6AoMlYrp+FQmKF$W}9WZ>osFP zKc^FY40{YPY!^Pny;}~xztHk+eK79ygI$!Ne4kyGA#25{Gc`3Nk#i`y z%pbL*Y?r0Th2cdP#SRD%-?0e^+rOdeFXJiVeapGzVz1~U!Gfe6z7xTvR1pL{rrcGz zX`ul{E9@o*pB%WMBTL%#`Z@d<&SH%D*Oib2k$cqMG1mr&CX3)WG8`A&%iyS9o!^s( zyp29sKo}E=8NKVH{Wn4zwA6%4_f1rqmwq3t=;^l!lDjgg!+9Ry@{eSji1uv0LB{W+ zD@Q}7h>EwBe^u4~WR-6}QvJIPp&EFMfc?CS%6x-noV>j*AqlY_*w&kMX1c&C`S#d$Z7dpCTQ*by=0FJs!;(4N9JLZ98bTvJ>$=W2@AoQS7=$ zO;o)vDJd`Kt{NkVZTZB7y>?;qeZI9idN`^>F7Fy`Zh1s(_s1}CpONg4`y~$(w@fO| z%f7#7M&H`5*VB^Vn2o$lI!A=S0rH1}U1CW<2xs|Uo8Dxnn@;FDa3`yC3zktc%>HU#*`#o4rX;%i@J zv|CBA+zPz^?3x)E8o=-c;Y)I8aw{p~u}=Js>-n;Cbu)chz9QiJp^x7Lx z->VIUnuKu)1Fmjk>TT+6vrn35}V#y-aywVj-dsP{!Mmcbj$E#O}&|UV7rAS^y z67OIdpwW9TNdF_B0;ibn*h*WBuy$LyY(g5(^hq_|GTLs}A13JO%VaFwd-$S_ZGq+& zrfv3EGVpy*v0C-_jt{+BmGs8Hh9BBDiu3eaV`#;T(xAq%J>uC^j`11RC8V?Y)%y2A z{8t&3V@I6+m+J50e!npv12Js(RdtQo+#cPg0SHd*tN&7=YFvF7sQd_Q9|RDikWbts z2cOKIcd9`G&^qY(dv5We8T38=f(Sr6T;+opU>luq3KhgyHOwI?ULcgxLEFsWtUY&G#%HPimf*Q)`|GLUA9;vqHu)WKjQct){fb} zVHDK?&7m0eKqOJ!=0*&!5O@TvY-Bm>SOUwR`30G4u`IfNjQe~ja_2!MH`e=BfgIea z7<%kogj*>0(A|hK)GJNfO+VHVR?suI8&*6U1n#ekcirH`EG8spM1Ktrmy~Q9ka(B; zh`;WHjB>II@Jh@#ul=Ev11a1M`V~wF32@*Nz-+rloXJeH?P>Ux>tBe6n12X&PtqlD z5Q&!)oP>k#a6Mf8+!8q5y1$RWdlf;?{`{A#YiCEQ`Z*|&&taGxmwP`#j`O*mix;>< zU3(fJ=hM`0b=?3KtM7*EjrT|Ux-^h4P=;;8mS#)p-BsX!k=sYe;G>t{KM0`m|638S zg=~PA|DIzxIw*qb*kcIT1v7tSuwCK46NF|Y*|5=-f;eTq^IQ|t*_kcipf6z~-XsUn zAQY74(^RQ$1COr*0ZGGerU_&gN{Gh?2UA{GzHTp_-ySvdI zKU9J}OQKp@BsoYy|CW@gkqG0l3~X5|0F3M%r&^1#y(Vr_l)ZP{aA=hE8nm^PWJIr! zzcf`=3X_4x$_|(o8!66Dph0NiBo zQph5TO7WNeM%=b-@-oFtZK4^)6YwFVculfPNy*~V3-7KWFA%iDKyNXnB_cy<>_rC| znK8JG*IjZkp7wtrs`ks_Qe-4i z1RaZjz;PQN{tofrOhsvjF1CVl4$g1t$}ivtETE!oT@GSbqWN)x7PhPs1GQQ4d@+uG zc!+kG^UJf_8k^INtsaT1%2Zb*BusBS(jXd(>>cEW<#h^E(FK)_IGC}^0KyG)R*6u> zvLYo8O%M3(xCT*sIT15za}4}@rD&KI7E&!E+iV8N6oMy{^#6*tCQrrT#4^xGCTk+Y z=~|<)EE?kUYYQa)zq-yn9I7;q<8P%TmT|AyE`9skA`>e_Q`yEv*G%R zdJpqztMHhL0i}1~WTxg0s^?9<{T+MPniRw5u(fyRChs+gHXJQ4$A|JXtwFul6X#y4 z(lYjwavJPqN{T*|V)6?{)X|8Ej-;hGD@1HkXRP_!`C7|(RxVo-ujEA3A8Sn=ixVI_ zh|Kd66Px5479xW-MGDi~oq9Uf^J+)ahcZ4nI`IryVqlu8rrDmO{Uid;_Jed^Y8Hho za@xM$_Q$-wLhdPU-kmop1&irI<4?um6U@R_Pc9#?>p1+`BV_f*;k)x=yrNDphF*I6 zg~X*#1gw?Gco{)S+o6%1B-2bsbMuGVY8x7aD)nCnHhxr$;kYi$9~*o-bZ@yGe@Vnc z-F1h%9NI2Qs-8%Mxgw8M)tRw_CC+NsD~($o-`79UXn)(ktxtn-)h$f9IfA4sXJ&Cs zNpcsp{uZ|nt)Bj@@st9S(uhrMNmRyhAMU9<))`506fdFuqLd|E#H+0(FzUj(d(M71 zNTIZSHY#8Gl=PtGg~^0KC9TaPm-eYVSlWNhskZ-TWoqoa*t)YqcY2R3DxpPQzI+#r zX}!&y*g;|GFh3{9F+@^XNQOp0Q<}<1Y7udr*3PU0?ry^-Nn>)_CucsysC$Qm_Q@aZ zX{UVRQJu$Yj8oQo6>in$q#eIac~012eJRE1U^JwuA2`0>b6}N^sfoX04Pxg#G^2D> z_rCh@Q0nEU$pOg=xvyjaf~ql&htJFm1|dCgXxOaNn{b8w zHY`eV@195DDPJC+f1ba;_8dFTt}^cSdo#gG0^u^mfNp&} zu{1D%x%u{c=eU_={ATXs_83q4-u0~d;}I^E^gYqnvfM1gR?ntI#%pYijL-VQSMbwr zg?al3erug}^cc4{EhD8+`;}NqW6B*0Nj1R_*rhcT$fw7u zdpM;gy`?|zXo+EDg`h9HQ9qxneO+%Kf0ZFwTJoAvoE@-1xsU1pwD+0iI`L5CuC=xt zD`(kt!iAFGqjOG9B%U8v`?f1p58C+jCnP4dNd;CF1u1dFE0(WBoPizTXpu7nhwcs} zBipTL{j4OpQS> z0!k5sdutr1rip+?aIPj11+nyU032|jOdACaN^OYW=esV)K|A2>r9seCA}3M}FVbXy zibRl&(P~(lApm%x6eAQIDVqcDEi;F(^gICUa20P+CqWAc3s0MVk@7`TYMU=oAS|W} z04tnYfGG-=m@Y*7`#VDkiBLi=#1RK>rK6yQcnO3hlT4okUkd~>gwKjeL@ZrkI>dqp z#Ljw{BR&9TxJqx90(ge~Vzi$rU+{lTW3fG)U+xWIj?@4+;bb%&5rBwzh+BSB()-@F zcm)pBa00N6D|!C^`B=m0l_Usr(gnaA_i=X@SiMpk{(8w4nz9N-y2Ur+z(k=wi4q(o zSpj|Ts%V2#>vNw3mqDn>59;v)02v3-*GxilVc!Z8gjvJ@K*xd4{82E!!WzQ<=YY5d z;UHSzBs2$}Csl?Mr6dS@)CmAX9DI(0z7NF3QDl-V%=>cGYQ))c=4f?MW938ZW ue{P9=krfI*jMp+yd348U24Slh0E=)Hbh0Knswx?oGL0VqXg%?58T$)9BDhNc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0e..84c5a9c6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,10 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionSha256Sum=84fbba45c7f4c64abc77460e1c00f541e9f960e3c7ed2538f1ede19eacd873ae +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index f5feea6d..249efbb0 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ ############################################################################## # -# Gradle start up script for POSIX generated by Gradle. +# gradlew start up script for POSIX generated by Gradle. # # Important for running: # @@ -29,7 +29,7 @@ # bash, then to run this script, type that shell name before the whole # command line, like: # -# ksh Gradle +# ksh gradlew # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -173,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -206,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a218..a51ec4f5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -19,12 +19,12 @@ @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,30 +65,18 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/pulsar-client-reactive-adapter/build.gradle b/pulsar-client-reactive-adapter/build.gradle.kts similarity index 50% rename from pulsar-client-reactive-adapter/build.gradle rename to pulsar-client-reactive-adapter/build.gradle.kts index 37e67748..9e695cb1 100644 --- a/pulsar-client-reactive-adapter/build.gradle +++ b/pulsar-client-reactive-adapter/build.gradle.kts @@ -18,30 +18,30 @@ */ plugins { - id 'pulsar-client-reactive.codestyle-conventions' - id 'pulsar-client-reactive.library-conventions' - id 'pulsar-client-reactive.test-conventions' + id("pulsar-client-reactive.codestyle-conventions") + id("pulsar-client-reactive.library-conventions") + id("pulsar-client-reactive.test-conventions") } dependencies { - api project(':pulsar-client-reactive-api') - api libs.pulsar.client.shaded - api libs.reactor.core - api libs.slf4j.api + api(project(":pulsar-client-reactive-api")) + api(libs.pulsar.client.shaded) + api(libs.reactor.core) + api(libs.slf4j.api) - testImplementation libs.junit.jupiter - testImplementation libs.reactor.test - testImplementation libs.assertj.core - testImplementation libs.bundles.log4j - testImplementation libs.mockito.core + testImplementation(libs.junit.jupiter) + testImplementation(libs.reactor.test) + testImplementation(libs.assertj.core) + testImplementation(libs.bundles.log4j) + testImplementation(libs.mockito.core) - intTestImplementation libs.pulsar.client.all - intTestImplementation project(':pulsar-client-reactive-producer-cache-caffeine') - intTestImplementation project(path: ':pulsar-client-reactive-producer-cache-caffeine-shaded', configuration: 'shadow') - intTestImplementation libs.junit.jupiter - intTestImplementation libs.testcontainers.pulsar - intTestImplementation libs.assertj.core - intTestImplementation libs.bundles.log4j + "intTestImplementation"(libs.pulsar.client.all) + "intTestImplementation"(project(":pulsar-client-reactive-producer-cache-caffeine")) + "intTestImplementation"(project(":pulsar-client-reactive-producer-cache-caffeine-shaded", configuration = "shadow")) + "intTestImplementation"(libs.junit.jupiter) + "intTestImplementation"(libs.testcontainers.pulsar) + "intTestImplementation"(libs.assertj.core) + "intTestImplementation"(libs.bundles.log4j) } description = "Reactive Streams adapter for Apache Pulsar Java client" diff --git a/pulsar-client-reactive-api/build.gradle b/pulsar-client-reactive-api/build.gradle.kts similarity index 63% rename from pulsar-client-reactive-api/build.gradle rename to pulsar-client-reactive-api/build.gradle.kts index 47067e0b..8a0fc33c 100644 --- a/pulsar-client-reactive-api/build.gradle +++ b/pulsar-client-reactive-api/build.gradle.kts @@ -18,23 +18,23 @@ */ plugins { - id 'pulsar-client-reactive.codestyle-conventions' - id 'pulsar-client-reactive.library-conventions' - id 'pulsar-client-reactive.test-conventions' + id("pulsar-client-reactive.codestyle-conventions") + id("pulsar-client-reactive.library-conventions") + id("pulsar-client-reactive.test-conventions") } dependencies { - api libs.reactor.core - api libs.pulsar.client.api - api libs.slf4j.api - implementation libs.jctools.core + api(libs.reactor.core) + api(libs.pulsar.client.api) + api(libs.slf4j.api) + implementation(libs.jctools.core) - testImplementation libs.pulsar.client.shaded - testImplementation libs.junit.jupiter - testImplementation libs.junit.jupiter.params - testImplementation libs.reactor.test - testImplementation libs.assertj.core - testImplementation libs.bundles.log4j + testImplementation(libs.pulsar.client.shaded) + testImplementation(libs.junit.jupiter) + testImplementation(libs.junit.jupiter.params) + testImplementation(libs.reactor.test) + testImplementation(libs.assertj.core) + testImplementation(libs.bundles.log4j) } description = "Reactive Java client for Apache Pulsar" diff --git a/buildSrc/build.gradle b/pulsar-client-reactive-bom/build.gradle.kts similarity index 55% rename from buildSrc/build.gradle rename to pulsar-client-reactive-bom/build.gradle.kts index e53d3732..c66c3140 100644 --- a/buildSrc/build.gradle +++ b/pulsar-client-reactive-bom/build.gradle.kts @@ -18,19 +18,28 @@ */ plugins { - id 'groovy-gradle-plugin' + `java-platform` + id("pulsar-client-reactive.publish-conventions") } -repositories { - mavenCentral() - maven { - url "https://plugins.gradle.org/m2/" +// Listed explicitly rather than derived from `rootProject.subprojects`, which would be +// cross-project configuration. +dependencies { + constraints { + api(project(":pulsar-client-reactive-adapter")) + api(project(":pulsar-client-reactive-api")) + api(project(":pulsar-client-reactive-jackson")) + api(project(":pulsar-client-reactive-producer-cache-caffeine")) + api(project(":pulsar-client-reactive-producer-cache-caffeine-shaded")) } } -dependencies { - implementation libs.spring.javaformat.gradle.plugin - implementation libs.licenser - implementation libs.testlogger - implementation libs.rat.gradle -} \ No newline at end of file +publishing { + publications { + named("mavenJava") { + from(components["javaPlatform"]) + } + } +} + +description = "Reactive Java client for Apache Pulsar (Bill of Materials)" diff --git a/pulsar-client-reactive-jackson/build.gradle b/pulsar-client-reactive-jackson/build.gradle.kts similarity index 70% rename from pulsar-client-reactive-jackson/build.gradle rename to pulsar-client-reactive-jackson/build.gradle.kts index 3b8fbfc3..8bb0e334 100644 --- a/pulsar-client-reactive-jackson/build.gradle +++ b/pulsar-client-reactive-jackson/build.gradle.kts @@ -18,19 +18,19 @@ */ plugins { - id 'pulsar-client-reactive.codestyle-conventions' - id 'pulsar-client-reactive.library-conventions' - id 'pulsar-client-reactive.test-conventions' + id("pulsar-client-reactive.codestyle-conventions") + id("pulsar-client-reactive.library-conventions") + id("pulsar-client-reactive.test-conventions") } dependencies { - api project(':pulsar-client-reactive-api') - api libs.jackson.databind - api libs.jackson.datatype.jsr310 + api(project(":pulsar-client-reactive-api")) + api(libs.jackson.databind) + api(libs.jackson.datatype.jsr310) - testImplementation libs.pulsar.client.shaded - testImplementation libs.junit.jupiter - testImplementation libs.assertj.core + testImplementation(libs.pulsar.client.shaded) + testImplementation(libs.junit.jupiter) + testImplementation(libs.assertj.core) } description = "Jackson module for the reactive client configuration" diff --git a/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle b/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle deleted file mode 100644 index 20e32a8b..00000000 --- a/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -plugins { - id 'pulsar-client-reactive.codestyle-conventions' - id 'pulsar-client-reactive.library-conventions' - id 'com.github.johnrengelman.shadow' version '7.1.2' -} - -dependencies { - api project(':pulsar-client-reactive-adapter') - implementation libs.caffeine - shadow project(':pulsar-client-reactive-adapter') - testImplementation libs.junit.jupiter - testImplementation libs.assertj.core - testImplementation libs.reactor.test - testImplementation libs.mockito.core -} - -description = "Caffeine (shaded) implementation of producer cache" - -jar { - archiveClassifier.set('original') -} - -shadowJar { - archiveClassifier.set(null) - dependsOn(project.tasks.jar) - manifest { - inheritFrom project.tasks.jar.manifest - } - relocate 'com.github.benmanes.caffeine', 'org.apache.pulsar.reactive.shade.com.github.benmanes.caffeine' - relocate 'com.google', 'org.apache.pulsar.reactive.shade.com.google' - relocate 'org.checkerframework', 'org.apache.pulsar.reactive.shade.org.checkerframework' - dependencies { - exclude(dependency { - !['com.github.ben-manes.caffeine', 'org.checkerframework', 'com.google.errorprone'].contains(it.moduleGroup) - }) - } -} - -tasks.build.dependsOn tasks.shadowJar - -// disable module metadata - otherwise original jar will be used when published -tasks.withType(GenerateModuleMetadata) { - enabled = false -} - -// delay the maven publishing - instead add shadowJar to the publication -components.java.withVariantsFromConfiguration(configurations.shadowRuntimeElements) { - skip() -} - -publishing { - publications { - mavenJava { - artifact(shadowJar) - pom.withXml { - Node pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'caffeine' - }.each() { - it.parent().remove(it) - } - } - } - } -} diff --git a/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle.kts b/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle.kts new file mode 100644 index 00000000..bad7ea0a --- /dev/null +++ b/pulsar-client-reactive-producer-cache-caffeine-shaded/build.gradle.kts @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import groovy.util.Node +import groovy.util.NodeList +import org.gradle.api.artifacts.ResolvedDependency +import org.gradle.api.specs.Spec + +plugins { + id("pulsar-client-reactive.codestyle-conventions") + id("pulsar-client-reactive.library-conventions") + alias(libs.plugins.shadow) +} + +dependencies { + api(project(":pulsar-client-reactive-adapter")) + implementation(libs.caffeine) + shadow(project(":pulsar-client-reactive-adapter")) + + testImplementation(libs.junit.jupiter) + testImplementation(libs.assertj.core) + testImplementation(libs.reactor.test) + testImplementation(libs.mockito.core) +} + +description = "Caffeine (shaded) implementation of producer cache" + +// The shadowed jar is published as the main artifact, so the java component must not also +// expose a separate shadow variant. +shadow { + addShadowVariantIntoJavaComponent = false +} + +tasks.jar { + archiveClassifier = "original" +} + +val relocatedGroups = setOf("com.github.ben-manes.caffeine", "org.checkerframework", "com.google.errorprone") + +tasks.shadowJar { + archiveClassifier = "" + relocate("com.github.benmanes.caffeine", "org.apache.pulsar.reactive.shade.com.github.benmanes.caffeine") + relocate("com.google", "org.apache.pulsar.reactive.shade.com.google") + relocate("org.checkerframework", "org.apache.pulsar.reactive.shade.org.checkerframework") + dependencies { + include(Spec { it.moduleGroup in relocatedGroups }) + } +} + +// disable module metadata - otherwise original jar will be used when published +tasks.withType().configureEach { + enabled = false +} + +publishing { + publications { + named("mavenJava") { + artifact(tasks.shadowJar) + // the relocated dependencies are bundled into the shadowed jar, so they must not + // be declared as dependencies of the published module + pom.withXml { + (asNode()["dependencies"] as NodeList).filterIsInstance().forEach { dependencies -> + dependencies.children().removeIf { + it is Node && (it["artifactId"] as NodeList).text() == "caffeine" + } + } + } + } + } +} diff --git a/pulsar-client-reactive-producer-cache-caffeine/build.gradle b/pulsar-client-reactive-producer-cache-caffeine/build.gradle.kts similarity index 73% rename from pulsar-client-reactive-producer-cache-caffeine/build.gradle rename to pulsar-client-reactive-producer-cache-caffeine/build.gradle.kts index 12f80cb5..43fb345b 100644 --- a/pulsar-client-reactive-producer-cache-caffeine/build.gradle +++ b/pulsar-client-reactive-producer-cache-caffeine/build.gradle.kts @@ -18,19 +18,18 @@ */ plugins { - id 'pulsar-client-reactive.codestyle-conventions' - id 'pulsar-client-reactive.library-conventions' + id("pulsar-client-reactive.codestyle-conventions") + id("pulsar-client-reactive.library-conventions") } dependencies { - api project(':pulsar-client-reactive-adapter') - api libs.caffeine - testImplementation libs.junit.jupiter - testImplementation libs.assertj.core - testImplementation libs.reactor.test - testImplementation libs.mockito.core + api(project(":pulsar-client-reactive-adapter")) + api(libs.caffeine) + + testImplementation(libs.junit.jupiter) + testImplementation(libs.assertj.core) + testImplementation(libs.reactor.test) + testImplementation(libs.mockito.core) } description = "Caffeine implementation of producer cache" - - diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index a9f145de..00000000 --- a/settings.gradle +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -rootProject.name = 'pulsar-client-reactive' -include 'pulsar-client-reactive-api' -include 'pulsar-client-reactive-adapter' -include 'pulsar-client-reactive-bom' -include 'pulsar-client-reactive-producer-cache-caffeine' -include 'pulsar-client-reactive-producer-cache-caffeine-shaded' -include 'pulsar-client-reactive-jackson' diff --git a/buildSrc/src/main/groovy/pulsar-client-reactive.codestyle-conventions.gradle b/settings.gradle.kts similarity index 60% rename from buildSrc/src/main/groovy/pulsar-client-reactive.codestyle-conventions.gradle rename to settings.gradle.kts index bf7a05e3..85d31528 100644 --- a/buildSrc/src/main/groovy/pulsar-client-reactive.codestyle-conventions.gradle +++ b/settings.gradle.kts @@ -17,25 +17,25 @@ * under the License. */ -plugins { - id 'checkstyle' - id "org.cadixdev.licenser" +pluginManagement { + repositories { + gradlePluginPortal() + } + includeBuild("build-logic") } -dependencies { - checkstyle libs.spring.javaformat.checkstyle +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + repositories { + mavenCentral() + } } -checkstyle { - toolVersion libs.versions.checkstyle.get() - configFile project.rootProject.file('checkstyle/checkstyle.xml') -} +rootProject.name = "pulsar-client-reactive" -license { - header = rootProject.file('checkstyle/HEADER.txt') - tasks { - gradle { - files.from('build.gradle', 'settings.gradle', 'gradle.properties') - } - } -} +include("pulsar-client-reactive-api") +include("pulsar-client-reactive-adapter") +include("pulsar-client-reactive-bom") +include("pulsar-client-reactive-producer-cache-caffeine") +include("pulsar-client-reactive-producer-cache-caffeine-shaded") +include("pulsar-client-reactive-jackson") From 8cad32fca488a0d0f6d4a289154ac070647474ff Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Mon, 17 Aug 2026 13:17:04 +0300 Subject: [PATCH 2/2] Use the Apache Pulsar developers organization in the published POMs Replaces the two named developer entries with a single organization entry, matching how apache/pulsar declares developers in its own POM. --- ...lsar-client-reactive.publish-conventions.gradle.kts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts b/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts index 833010e5..eb11910e 100644 --- a/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/pulsar-client-reactive.publish-conventions.gradle.kts @@ -60,14 +60,8 @@ publishing { } developers { developer { - id = "lhotari" - name = "Lari Hotari" - email = "lhotari@apache.org" - } - developer { - id = "cbornet" - name = "Christophe Bornet" - email = "cbornet@apache.org" + organization = "Apache Pulsar developers" + organizationUrl = "https://pulsar.apache.org/" } } scm {