diff --git a/examples/README.md b/examples/README.md
index 55f75e587dc..85b7003168c 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,10 +1,10 @@
# Samples
-| Sample | Description | Platforms |
-| ------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------- |
-| [Imageviewer](imageviewer) | Image Viewer application | Android, iOS, Desktop |
-| [Codeviewer](codeviewer) | File browser and code viewer application | Android, iOS, Desktop |
-| [Chat](chat) | A simple chat | Android, iOS, Desktop |
-| [Graphics2D](graphics-2d) | 2D Games and graphics examples | Android, iOS, Desktop |
-| [Nav Cupcake](nav_cupcake) | Multiscreen app to demonstrate the use of Compose Navigation | Android, iOS, Desktop |
-| [Issues tracker](issues) | GitHub issue tracker with an adaptive UI and ktor-client | Android, Desktop |
-| [HTML based samples](html/README.md) | Examples written with Compose HTML Library |
+| Sample | Description | Platforms |
+| -------------------------------------- |:---------------------------------------------------------| -------------------------- |
+| [Imageviewer](imageviewer) | Image Viewer | Android, iOS, Desktop, Web |
+| [Codeviewer](codeviewer) | File browser and code viewer | Android, iOS, Desktop, Web |
+| [Chat](chat) | A simple chat | Android, iOS, Desktop, Web |
+| [Graphics2D](graphics-2d) | 2D Games and graphics examples | Android, iOS, Desktop, Web |
+| [Nav Cupcake](nav_cupcake) | Multiscreen app using Compose Navigation 2 | Android, iOS, Desktop, Web |
+| [Issues tracker](issues) | GitHub issue tracker with an adaptive UI and ktor-client | Android, Desktop |
+| [Compose HTML samples](html/README.md) | Examples written with Compose HTML Library | Web |
diff --git a/examples/buildWithKotlinToolchain.sh b/examples/buildWithKotlinToolchain.sh
new file mode 100755
index 00000000000..d1b34eae5b3
--- /dev/null
+++ b/examples/buildWithKotlinToolchain.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# Script to build an example with the Kotlin Toolchain, optionally with the given Compose and Kotlin versions.
+# The Kotlin Toolchain can't override versions from the command line, so in that case the example is copied
+# to a temporary directory, and every module there applies a template with the versions and the dev maven repo.
+
+set -euo pipefail
+
+if [ "$#" -lt 2 ] || [ "$#" -gt 4 ]; then
+ echo "Specify the example, the platform and optionally Compose and Kotlin versions. For example: ./buildWithKotlinToolchain.sh codeviewer jvm 1.13.0-alpha03 2.3.20"
+ exit 1
+fi
+
+example="$1"
+platform="$2"
+compose_version="${3:-}"
+kotlin_version="${4:-}"
+build_dir="$example"
+
+if [ -n "$compose_version" ]; then
+ temp_dir="$(mktemp -d)"
+ # Keep the copy if the build fails, so that its logs can be inspected
+ trap 'if [ "$?" -eq 0 ]; then rm -rf "$temp_dir"; else echo "Failed $example, its copy is kept in $temp_dir"; fi' EXIT
+
+ tar -C "$example" --exclude=./build -cf - . | tar -C "$temp_dir" -xf -
+ echo "Building a copy of $example in $temp_dir with Compose $compose_version${kotlin_version:+ and Kotlin $kotlin_version}"
+
+ template="validation-versions.module-template.yaml"
+ {
+ echo "repositories:"
+ echo " - https://packages.jetbrains.team/maven/p/cmp/dev"
+ echo
+ echo "settings:"
+ echo " compose:"
+ echo " version: $compose_version"
+ if [ -n "$kotlin_version" ]; then
+ echo " kotlin:"
+ echo " version: $kotlin_version"
+ fi
+ } > "$temp_dir/$template"
+
+ find "$temp_dir" -name module.yaml | while read -r module; do
+ { printf 'apply:\n - //%s\n\n' "$template"; cat "$module"; } > "$module.tmp"
+ mv "$module.tmp" "$module"
+ done
+
+ if [ -f "$temp_dir/libs.versions.toml" ]; then
+ sed -E "s/^(compose-multiplatform[[:space:]]*=[[:space:]]*).*/\1\"$compose_version\"/" "$temp_dir/libs.versions.toml" > "$temp_dir/libs.versions.toml.tmp"
+ mv "$temp_dir/libs.versions.toml.tmp" "$temp_dir/libs.versions.toml"
+ fi
+
+ build_dir="$temp_dir"
+fi
+
+cd "$build_dir"
+./kotlin build -p "$platform"
diff --git a/examples/codeviewer/.gitattributes b/examples/codeviewer/.gitattributes
new file mode 100644
index 00000000000..f539da4fa1d
--- /dev/null
+++ b/examples/codeviewer/.gitattributes
@@ -0,0 +1,4 @@
+*.bat text eol=crlf
+
+# Kotlin CLI wrapper without extension
+kotlin text eol=lf
diff --git a/examples/codeviewer/.gitignore b/examples/codeviewer/.gitignore
index 6e5f30477c5..7c1a2b3a43b 100644
--- a/examples/codeviewer/.gitignore
+++ b/examples/codeviewer/.gitignore
@@ -1,15 +1,11 @@
+build/
+.kotlin/
+.idea/
*.iml
-.gradle
-/local.properties
-/.idea
.DS_Store
-build/
-/captures
-.externalNativeBuild
-.cxx
-iosApp/Podfile.lock
-iosApp/Pods/*
-iosApp/iosApp.xcworkspace/*
-iosApp/iosApp.xcodeproj/*
-!iosApp/iosApp.xcodeproj/project.pbxproj
-shared/shared.podspec
+**/module.xcodeproj/*
+!**/module.xcodeproj/project.pbxproj
+!**/module.xcodeproj/xcshareddata/
+!**/module.xcodeproj/project.xcworkspace/
+**/xcshareddata/WorkspaceSettings.xcsettings
+xcuserdata
diff --git a/examples/codeviewer/.run/desktopApp.run.xml b/examples/codeviewer/.run/desktopApp.run.xml
deleted file mode 100644
index 2d56d7f072a..00000000000
--- a/examples/codeviewer/.run/desktopApp.run.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/examples/codeviewer/README.md b/examples/codeviewer/README.md
index 2c680764cfe..f58ff7f4444 100644
--- a/examples/codeviewer/README.md
+++ b/examples/codeviewer/README.md
@@ -1,24 +1,33 @@
# Code Viewer
-Code Viewer example for Desktop, Android and iOS written in Compose Multiplatform.
+Code Viewer example for Desktop, Android, iOS, and Web written in Compose Multiplatform.
+
+The project is built with the [Kotlin Toolchain](https://github.com/JetBrains/kotlin-toolchain).
## Setting up your development environment
-To setup the environment, please consult these [instructions](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-setup.html).
+To set up the environment, please consult these [instructions](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-setup.html).
+
+Open the project in IntelliJ IDEA with the Kotlin Toolchain plugin and use the run gutter icons or run configurations
+to launch the app on the target of your choice.
+
+## Run desktop app
+
+`./kotlin run -m desktopApp`
+
+## Run Android app
+
+`./kotlin run -m androidApp`
-## How to run
+## Run iOS app
-Choose a run configuration for an appropriate target in Android Studio and run it.
+`./kotlin run -m iosApp`
-
+or open `iosApp/module.xcodeproj` in Xcode.
-## Run desktop via Gradle
+## Run web app
-`./gradlew desktopApp:run`
+`./kotlin run -m webApp`
-### Building native desktop distribution
-```
-./gradlew :desktop:packageDistributionForCurrentOS
-# outputs are written to desktop/build/compose/binaries
-```
+and open the printed URL in a browser that supports [Wasm GC](https://kotl.in/wasm-help).
-
\ No newline at end of file
+
diff --git a/examples/codeviewer/androidApp/src/main/assets/data/EditorView.kt b/examples/codeviewer/androidApp/assets/data/EditorView.kt
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/assets/data/EditorView.kt
rename to examples/codeviewer/androidApp/assets/data/EditorView.kt
diff --git a/examples/codeviewer/androidApp/build.gradle.kts b/examples/codeviewer/androidApp/build.gradle.kts
deleted file mode 100644
index c02e2e322d4..00000000000
--- a/examples/codeviewer/androidApp/build.gradle.kts
+++ /dev/null
@@ -1,35 +0,0 @@
-import org.jetbrains.kotlin.gradle.dsl.JvmTarget
-
-plugins {
- alias(libs.plugins.androidApplication)
- alias(libs.plugins.composeCompiler)
- alias(libs.plugins.composeMultiplatform)
-}
-
-kotlin {
- compilerOptions {
- jvmTarget = JvmTarget.JVM_17
- }
-}
-dependencies {
- implementation(project(":shared"))
- implementation(libs.androidx.activity.compose)
-}
-
-android {
- compileSdk {
- version = release(37) { minorApiLevel = 1 }
- }
- namespace = "org.jetbrains.codeviewer"
- defaultConfig {
- applicationId = "org.jetbrains.Codeviewer"
- minSdk = 26
- targetSdk = 37
- versionCode = 1
- versionName = "1.0"
- }
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-}
diff --git a/examples/codeviewer/androidApp/module.yaml b/examples/codeviewer/androidApp/module.yaml
new file mode 100644
index 00000000000..621d4e0e660
--- /dev/null
+++ b/examples/codeviewer/androidApp/module.yaml
@@ -0,0 +1,17 @@
+product: android/app
+
+dependencies:
+ - //shared
+ - $libs.androidx.activity.compose
+
+settings:
+ compose: enabled
+ android:
+ namespace: org.jetbrains.codeviewer
+ applicationId: org.jetbrains.Codeviewer
+ minSdk: 26
+ compileSdk:
+ apiLevel: 37
+ minorApiLevel: 1
+ versionCode: 1
+ versionName: "1.0"
diff --git a/examples/codeviewer/androidApp/src/main/res/drawable/ic_launcher_foreground.xml b/examples/codeviewer/androidApp/res/drawable/ic_launcher_foreground.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/drawable/ic_launcher_foreground.xml
rename to examples/codeviewer/androidApp/res/drawable/ic_launcher_foreground.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
rename to examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher_round.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
rename to examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher_round.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/values-night/styles.xml b/examples/codeviewer/androidApp/res/values-night/styles.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/values-night/styles.xml
rename to examples/codeviewer/androidApp/res/values-night/styles.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/values/ic_launcher_background.xml b/examples/codeviewer/androidApp/res/values/ic_launcher_background.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/values/ic_launcher_background.xml
rename to examples/codeviewer/androidApp/res/values/ic_launcher_background.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/values/strings.xml b/examples/codeviewer/androidApp/res/values/strings.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/values/strings.xml
rename to examples/codeviewer/androidApp/res/values/strings.xml
diff --git a/examples/codeviewer/androidApp/src/main/res/values/styles.xml b/examples/codeviewer/androidApp/res/values/styles.xml
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/res/values/styles.xml
rename to examples/codeviewer/androidApp/res/values/styles.xml
diff --git a/examples/codeviewer/androidApp/src/main/AndroidManifest.xml b/examples/codeviewer/androidApp/src/AndroidManifest.xml
similarity index 92%
rename from examples/codeviewer/androidApp/src/main/AndroidManifest.xml
rename to examples/codeviewer/androidApp/src/AndroidManifest.xml
index f91ba3788ad..42016792c17 100644
--- a/examples/codeviewer/androidApp/src/main/AndroidManifest.xml
+++ b/examples/codeviewer/androidApp/src/AndroidManifest.xml
@@ -10,7 +10,7 @@
android:theme="@style/Theme.Application">
diff --git a/examples/codeviewer/androidApp/src/main/kotlin/org/jetbrains/codeviewer/MainActivity.kt b/examples/codeviewer/androidApp/src/org/jetbrains/codeviewer/MainActivity.kt
similarity index 100%
rename from examples/codeviewer/androidApp/src/main/kotlin/org/jetbrains/codeviewer/MainActivity.kt
rename to examples/codeviewer/androidApp/src/org/jetbrains/codeviewer/MainActivity.kt
diff --git a/examples/codeviewer/build.gradle.kts b/examples/codeviewer/build.gradle.kts
deleted file mode 100644
index 50aea4ca8b4..00000000000
--- a/examples/codeviewer/build.gradle.kts
+++ /dev/null
@@ -1,10 +0,0 @@
-plugins {
- // this is necessary to avoid the plugins to be loaded multiple times
- // in each subproject's classloader
- alias(libs.plugins.androidApplication) apply false
- alias(libs.plugins.androidMultiplatformLibrary) apply false
- alias(libs.plugins.composeMultiplatform) apply false
- alias(libs.plugins.composeCompiler) apply false
- alias(libs.plugins.kotlinJvm) apply false
- alias(libs.plugins.kotlinMultiplatform) apply false
-}
diff --git a/examples/codeviewer/desktopApp/build.gradle.kts b/examples/codeviewer/desktopApp/build.gradle.kts
deleted file mode 100644
index ccef649b265..00000000000
--- a/examples/codeviewer/desktopApp/build.gradle.kts
+++ /dev/null
@@ -1,41 +0,0 @@
-import org.jetbrains.compose.desktop.application.dsl.TargetFormat
-
-plugins {
- alias(libs.plugins.kotlinMultiplatform)
- alias(libs.plugins.composeCompiler)
- alias(libs.plugins.composeMultiplatform)
-}
-
-kotlin {
- jvm {}
-
- sourceSets {
- jvmMain.dependencies {
- implementation(compose.desktop.currentOs)
- implementation(project(":shared"))
- }
- }
-}
-
-compose.desktop {
- application {
- mainClass = "org.jetbrains.codeviewer.MainKt"
-
- nativeDistributions {
- targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
- packageName = "ComposeCodeViewer"
- packageVersion = "1.0.0"
-
- windows {
- menu = true
- // see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html
- upgradeUuid = "AF792DA6-2EA3-495A-95E5-C3C6CBCB9948"
- }
-
- macOS {
- // Use -Pcompose.desktop.mac.sign=true to sign and notarize.
- bundleID = "com.jetbrains.compose.codeviewer"
- }
- }
- }
-}
diff --git a/examples/codeviewer/desktopApp/module.yaml b/examples/codeviewer/desktopApp/module.yaml
new file mode 100644
index 00000000000..11ab5ac5b56
--- /dev/null
+++ b/examples/codeviewer/desktopApp/module.yaml
@@ -0,0 +1,11 @@
+product: jvm/app
+
+dependencies:
+ - //shared
+ - $libs.compose.runtime
+ - $libs.compose.ui
+
+settings:
+ compose: enabled
+ jvm:
+ mainClass: org.jetbrains.codeviewer.MainKt
diff --git a/examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png b/examples/codeviewer/desktopApp/resources/ic_launcher.png
similarity index 100%
rename from examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png
rename to examples/codeviewer/desktopApp/resources/ic_launcher.png
diff --git a/examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt b/examples/codeviewer/desktopApp/src/org/jetbrains/codeviewer/main.kt
similarity index 100%
rename from examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt
rename to examples/codeviewer/desktopApp/src/org/jetbrains/codeviewer/main.kt
diff --git a/examples/codeviewer/gradle.properties b/examples/codeviewer/gradle.properties
deleted file mode 100644
index a5a909b489e..00000000000
--- a/examples/codeviewer/gradle.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-kotlin.code.style=official
-xcodeproj=./iosApp
-android.useAndroidX=true
-org.gradle.jvmargs=-Xmx8g
-org.gradle.configuration-cache=true
-org.gradle.caching=true
-org.jetbrains.compose.experimental.macos.enabled=true
-kotlin.version=2.4.20
-agp.version=9.2.1
-compose.version=1.12.0
diff --git a/examples/codeviewer/gradle/libs.versions.toml b/examples/codeviewer/gradle/libs.versions.toml
deleted file mode 100644
index c3f71366f22..00000000000
--- a/examples/codeviewer/gradle/libs.versions.toml
+++ /dev/null
@@ -1,27 +0,0 @@
-[versions]
-kotlin = "2.3.20" # overriden via gradle.properties
-compose = "1.10.1" # overriden via gradle.properties
-agp = "9.2.1" # overriden via gradle.properties
-androidx-activity = "1.13.0"
-androidx-appcompat = "1.7.1"
-androidx-core = "1.18.0"
-
-[libraries]
-androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
-androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
-androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
-compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose" }
-compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "compose" }
-material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended", version = "1.7.3" }
-compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" }
-compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose" }
-compose-material = { module = "org.jetbrains.compose.material:material", version.ref = "compose" }
-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose"}
-
-[plugins]
-androidApplication = { id = "com.android.application", version.ref = "agp" }
-androidMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
-composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose" }
-composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
-kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
-kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
diff --git a/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar b/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 249e5832f09..00000000000
Binary files a/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties b/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 2b7a686b445..00000000000
--- a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionSha256Sum=553c78f50dafcd54d65b9a444649057857469edf836431389695608536d6b746
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
diff --git a/examples/codeviewer/gradlew b/examples/codeviewer/gradlew
deleted file mode 100755
index a69d9cb6c20..00000000000
--- a/examples/codeviewer/gradlew
+++ /dev/null
@@ -1,240 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 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.
-# 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.
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
-APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# 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" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
diff --git a/examples/codeviewer/gradlew.bat b/examples/codeviewer/gradlew.bat
deleted file mode 100644
index f127cfd49d4..00000000000
--- a/examples/codeviewer/gradlew.bat
+++ /dev/null
@@ -1,91 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%"=="" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%"=="" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if %ERRORLEVEL% equ 0 goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-: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 %*
-
-: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
diff --git a/examples/codeviewer/iosApp/Configuration/Config.xcconfig b/examples/codeviewer/iosApp/Configuration/Config.xcconfig
deleted file mode 100644
index 1393dc4f0b7..00000000000
--- a/examples/codeviewer/iosApp/Configuration/Config.xcconfig
+++ /dev/null
@@ -1,3 +0,0 @@
-TEAM_ID=
-BUNDLE_ID=org.jetbrains.Codeviewer
-APP_NAME=Codeviewer
diff --git a/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj b/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj
deleted file mode 100644
index b2916a6c394..00000000000
--- a/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,382 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 50;
- objects = {
-
-/* Begin PBXBuildFile section */
- 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };
- 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };
- 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };
- 3251B1382AA8CF70001521C0 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3251B1372AA8CF70001521C0 /* ContentView.swift */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
- 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; };
- 3251B1372AA8CF70001521C0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
- 7555FF7B242A565900829871 /* Codeviewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Codeviewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- F85CB1118929364A9C6EFABC /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 058557D7273AAEEB004C7B11 /* Preview Content */ = {
- isa = PBXGroup;
- children = (
- 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */,
- );
- path = "Preview Content";
- sourceTree = "";
- };
- 7555FF72242A565900829871 = {
- isa = PBXGroup;
- children = (
- AB1DB47929225F7C00F7AF9C /* Configuration */,
- 7555FF7D242A565900829871 /* iosApp */,
- 7555FF7C242A565900829871 /* Products */,
- );
- sourceTree = "";
- };
- 7555FF7C242A565900829871 /* Products */ = {
- isa = PBXGroup;
- children = (
- 7555FF7B242A565900829871 /* Codeviewer.app */,
- );
- name = Products;
- sourceTree = "";
- };
- 7555FF7D242A565900829871 /* iosApp */ = {
- isa = PBXGroup;
- children = (
- 058557BA273AAA24004C7B11 /* Assets.xcassets */,
- 7555FF8C242A565B00829871 /* Info.plist */,
- 2152FB032600AC8F00CF470E /* iOSApp.swift */,
- 058557D7273AAEEB004C7B11 /* Preview Content */,
- 3251B1372AA8CF70001521C0 /* ContentView.swift */,
- );
- path = iosApp;
- sourceTree = "";
- };
- AB1DB47929225F7C00F7AF9C /* Configuration */ = {
- isa = PBXGroup;
- children = (
- AB3632DC29227652001CCB65 /* Config.xcconfig */,
- );
- path = Configuration;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 7555FF7A242A565900829871 /* iosApp */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */;
- buildPhases = (
- 05E104072A8AA90A00D11C3D /* Compile Kotlin */,
- 7555FF77242A565900829871 /* Sources */,
- 7555FF79242A565900829871 /* Resources */,
- F85CB1118929364A9C6EFABC /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = iosApp;
- productName = iosApp;
- productReference = 7555FF7B242A565900829871 /* Codeviewer.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 7555FF73242A565900829871 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 1130;
- LastUpgradeCheck = 1130;
- ORGANIZATIONNAME = orgName;
- TargetAttributes = {
- 7555FF7A242A565900829871 = {
- CreatedOnToolsVersion = 11.3.1;
- };
- };
- };
- buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */;
- compatibilityVersion = "Xcode 9.3";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 7555FF72242A565900829871;
- productRefGroup = 7555FF7C242A565900829871 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 7555FF7A242A565900829871 /* iosApp */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 7555FF79242A565900829871 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */,
- 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 05E104072A8AA90A00D11C3D /* Compile Kotlin */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- );
- name = "Compile Kotlin";
- outputFileListPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "cd \"$SRCROOT/..\"\n./gradlew :shared:embedAndSignAppleFrameworkForXcode\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 7555FF77242A565900829871 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 3251B1382AA8CF70001521C0 /* ContentView.swift in Sources */,
- 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 7555FFA3242A565B00829871 /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 14.1;
- MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
- MTL_FAST_MATH = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- };
- name = Debug;
- };
- 7555FFA4242A565B00829871 /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 14.1;
- MTL_ENABLE_DEBUG_INFO = NO;
- MTL_FAST_MATH = YES;
- SDKROOT = iphoneos;
- SWIFT_COMPILATION_MODE = wholemodule;
- SWIFT_OPTIMIZATION_LEVEL = "-O";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 7555FFA6242A565B00829871 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
- DEVELOPMENT_TEAM = "${TEAM_ID}";
- ENABLE_PREVIEWS = YES;
- FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n";
- INFOPLIST_FILE = iosApp/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 14.1;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- OTHER_LDFLAGS = (
- "$(inherited)",
- "-framework",
- "shared\n",
- );
- PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
- PRODUCT_NAME = "${APP_NAME}";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 7555FFA7242A565B00829871 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
- DEVELOPMENT_TEAM = "${TEAM_ID}";
- ENABLE_PREVIEWS = YES;
- FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n";
- INFOPLIST_FILE = iosApp/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 14.1;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- OTHER_LDFLAGS = (
- "$(inherited)",
- "-framework",
- "shared\n",
- );
- PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
- PRODUCT_NAME = "${APP_NAME}";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7555FFA3242A565B00829871 /* Debug */,
- 7555FFA4242A565B00829871 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7555FFA6242A565B00829871 /* Debug */,
- 7555FFA7242A565B00829871 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 7555FF73242A565900829871 /* Project object */;
-}
diff --git a/examples/codeviewer/iosApp/iosApp/Info.plist b/examples/codeviewer/iosApp/iosApp/Info.plist
deleted file mode 100644
index 412e3781280..00000000000
--- a/examples/codeviewer/iosApp/iosApp/Info.plist
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- $(PRODUCT_BUNDLE_PACKAGE_TYPE)
- CFBundleShortVersionString
- 1.0
- CFBundleVersion
- 1
- LSRequiresIPhoneOS
-
- CADisableMinimumFrameDurationOnPhone
-
- UIApplicationSceneManifest
-
- UIApplicationSupportsMultipleScenes
-
-
- UILaunchScreen
-
- UIRequiredDeviceCapabilities
-
- armv7
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
-
-
diff --git a/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
deleted file mode 100644
index 4aa7c5350bf..00000000000
--- a/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
\ No newline at end of file
diff --git a/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj b/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..1bbc11aa054
--- /dev/null
+++ b/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj
@@ -0,0 +1,221 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXFileReference section */
+ 61953054E79C679999285760 /* Codeviewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Codeviewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 61953F84EDE8841FF4EB58FD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; name = Info.plist; path = src/Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ 619536EC3227DE902FA82C88 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ Info.plist,
+ );
+ target = 61953448E778222CB0131C83 /* app */;
+ };
+/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ 6195343827A0FB09880F5E89 /* src */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ exceptions = (
+ 619536EC3227DE902FA82C88 /* PBXFileSystemSynchronizedBuildFileExceptionSet */,
+ );
+ path = src;
+ sourceTree = SOURCE_ROOT;
+ };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 61953852C94087CBE26CE7E2 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 61953869EC51EBC6C13E7A72 = {
+ isa = PBXGroup;
+ children = (
+ 61953F4FE2725B94BB5DE016 /* Products */,
+ 61953F84EDE8841FF4EB58FD /* Info.plist */,
+ 6195343827A0FB09880F5E89 /* src */,
+ );
+ sourceTree = "";
+ };
+ 61953F4FE2725B94BB5DE016 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61953054E79C679999285760 /* Codeviewer.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 61953448E778222CB0131C83 /* app */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 619537AD847CA000C1640B8B /* Build configuration list for PBXNativeTarget "app" */;
+ buildPhases = (
+ 61953AB277B46DCD95A720D6 /* Build Kotlin */,
+ 61953E99CB2418540738CD58 /* Sources */,
+ 61953852C94087CBE26CE7E2 /* Frameworks */,
+ 61953807DDCA3237E8120E0C /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ 6195343827A0FB09880F5E89 /* src */,
+ );
+ name = app;
+ productName = app;
+ productReference = 61953054E79C679999285760 /* Codeviewer.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 61953894F26186C70B8C203C /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 61953A94F0B4D42348B90F07 /* Build configuration list for PBXProject "module" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 61953869EC51EBC6C13E7A72;
+ productRefGroup = 61953F4FE2725B94BB5DE016 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 61953448E778222CB0131C83 /* app */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 61953807DDCA3237E8120E0C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 61953AB277B46DCD95A720D6 /* Build Kotlin */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ inputPaths = (
+ );
+ name = "Build Kotlin";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# !KOTLIN INTEGRATION STEP!\n# This script is managed by the Kotlin Toolchain, do not edit manually!\n\"${KOTLIN_CLI_WRAPPER_PATH}\" tool xcode-integration\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 61953E99CB2418540738CD58 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 619532473E3B85FD35EA73E8 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = src/Info.plist;
+ KOTLIN_CLI_WRAPPER_PATH = ../kotlin;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.Codeviewer;
+ PRODUCT_MODULE_NAME = app;
+ PRODUCT_NAME = Codeviewer;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = (
+ 1,
+ 2,
+ );
+ };
+ name = Debug;
+ };
+ 619534C7499BFCC9FFF5D8EC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 619536FEC92F1AEADBE2167D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ INFOPLIST_FILE = src/Info.plist;
+ KOTLIN_CLI_WRAPPER_PATH = ../kotlin;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.Codeviewer;
+ PRODUCT_MODULE_NAME = app;
+ PRODUCT_NAME = Codeviewer;
+ SDKROOT = iphoneos;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = (
+ 1,
+ 2,
+ );
+ };
+ name = Release;
+ };
+ 61953F9B26C121FF0F32B955 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 619537AD847CA000C1640B8B /* Build configuration list for PBXNativeTarget "app" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 619532473E3B85FD35EA73E8 /* Debug */,
+ 619536FEC92F1AEADBE2167D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+ 61953A94F0B4D42348B90F07 /* Build configuration list for PBXProject "module" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 619534C7499BFCC9FFF5D8EC /* Debug */,
+ 61953F9B26C121FF0F32B955 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 61953894F26186C70B8C203C /* Project object */;
+}
diff --git a/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme b/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme
new file mode 100644
index 00000000000..4910983be59
--- /dev/null
+++ b/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/codeviewer/iosApp/module.yaml b/examples/codeviewer/iosApp/module.yaml
new file mode 100644
index 00000000000..392eaa5f782
--- /dev/null
+++ b/examples/codeviewer/iosApp/module.yaml
@@ -0,0 +1,8 @@
+product: ios/app
+
+dependencies:
+ - //shared
+ - $libs.compose.ui
+
+settings:
+ compose: enabled
diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/AccentColor.colorset/Contents.json
similarity index 100%
rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
rename to examples/codeviewer/iosApp/src/Assets.xcassets/AccentColor.colorset/Contents.json
diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to examples/codeviewer/iosApp/src/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/Contents.json
similarity index 100%
rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json
rename to examples/codeviewer/iosApp/src/Assets.xcassets/Contents.json
diff --git a/examples/codeviewer/iosApp/iosApp/ContentView.swift b/examples/codeviewer/iosApp/src/ContentView.swift
similarity index 95%
rename from examples/codeviewer/iosApp/iosApp/ContentView.swift
rename to examples/codeviewer/iosApp/src/ContentView.swift
index ddb2dd9b6eb..f5de0ba0a83 100644
--- a/examples/codeviewer/iosApp/iosApp/ContentView.swift
+++ b/examples/codeviewer/iosApp/src/ContentView.swift
@@ -1,6 +1,6 @@
import UIKit
import SwiftUI
-import shared
+import KotlinModules
struct ContentView: View {
var body: some View {
diff --git a/examples/codeviewer/iosApp/src/Info.plist b/examples/codeviewer/iosApp/src/Info.plist
new file mode 100644
index 00000000000..80d2cac7d55
--- /dev/null
+++ b/examples/codeviewer/iosApp/src/Info.plist
@@ -0,0 +1,41 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(MARKETING_VERSION)
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ UILaunchScreen
+
+ UIApplicationSupportsIndirectInputEvents
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ CADisableMinimumFrameDurationOnPhone
+
+
+
diff --git a/examples/codeviewer/iosApp/iosApp/iOSApp.swift b/examples/codeviewer/iosApp/src/iOSApp.swift
similarity index 100%
rename from examples/codeviewer/iosApp/iosApp/iOSApp.swift
rename to examples/codeviewer/iosApp/src/iOSApp.swift
diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/main.ios.kt b/examples/codeviewer/iosApp/src/main.ios.kt
similarity index 100%
rename from examples/codeviewer/shared/src/iosMain/kotlin/main.ios.kt
rename to examples/codeviewer/iosApp/src/main.ios.kt
diff --git a/examples/codeviewer/kotlin b/examples/codeviewer/kotlin
new file mode 100755
index 00000000000..5ef1dee4f32
--- /dev/null
+++ b/examples/codeviewer/kotlin
@@ -0,0 +1,292 @@
+#!/bin/sh
+
+#
+# Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+#
+
+# Possible environment variables:
+# KOTLIN_CLI_DOWNLOAD_ROOT Maven repository to download the Kotlin CLI dist from.
+# default: https://packages.jetbrains.team/maven/p/amper/amper
+# KOTLIN_CLI_JRE_DOWNLOAD_ROOT Url prefix to download the JRE to run the Kotlin CLI
+# default: https:/
+# KOTLIN_CLI_BOOTSTRAP_CACHE_DIR Cache directory to store the extracted JRE and Kotlin CLI distribution
+# KOTLIN_CLI_JAVA_HOME JRE to run the Kotlin CLI itself (optional, does not affect compilation)
+# KOTLIN_CLI_JAVA_OPTIONS JVM options to pass to the JVM running the Kotlin CLI (does not affect the user's application)
+# KOTLIN_CLI_NO_WELCOME_BANNER Disables the first-run welcome message if set to a non-empty value
+
+set -e -u
+
+# The version of the Kotlin Toolchain (and CLI) distribution to provision and use
+kotlin_cli_version=0.13.0
+# Establish chain of trust from here by specifying exact checksum of Kotlin Toolchain (and CLI) distribution to be run
+kotlin_cli_sha256=fa82b9872dcfa04d26c8f800f33d597c99fbffd747a0e9bbce3a9e4424b3a588
+
+KOTLIN_CLI_DOWNLOAD_ROOT="${KOTLIN_CLI_DOWNLOAD_ROOT:-https://packages.jetbrains.team/maven/p/amper/amper}"
+
+die() {
+ echo >&2
+ echo "$@" >&2
+ echo >&2
+ exit 1
+}
+
+# usage: check_sha SOURCE_MONIKER FILE SHA_CHECKSUM SHA_SIZE
+# $1 SOURCE_MONIKER (e.g. url)
+# $2 FILE
+# $3 SHA hex string
+# $4 SHA size in bits (256, 512, ...)
+check_sha() {
+ sha_size=$4
+ if command -v shasum >/dev/null 2>&1; then
+ echo "$3 *$2" | shasum -a "$sha_size" --status -c || {
+ die "ERROR: Checksum mismatch for $2 (downloaded from $1): expected checksum $3 but got $(shasum --binary -a "$sha_size" "$2" | awk '{print $1}')"
+ }
+ return 0
+ fi
+
+ shaNsumCommand="sha${sha_size}sum"
+ if command -v "$shaNsumCommand" >/dev/null 2>&1; then
+ # discard the output as sha*sum may print redundant warnings in some versions
+ echo "$3 *$2" | $shaNsumCommand -w -c >/dev/null 2>&1 || {
+ die "ERROR: Checksum mismatch for $2 (downloaded from $1): expected checksum $3 but got $($shaNsumCommand "$2" | awk '{print $1}')"
+ }
+ return 0
+ fi
+
+ echo "Both 'shasum' and 'sha${sha_size}sum' utilities are missing. Please install one of them"
+ return 1
+}
+
+
+download_and_extract() {
+ moniker="$1"
+ file_url="$2"
+ file_sha="$3"
+ sha_size="$4"
+ cache_dir="$5"
+ extract_dir="$6"
+ show_banner_on_cache_miss="$7"
+
+ if [ -e "$extract_dir/.flag" ] && [ "$(cat "$extract_dir/.flag")" = "${file_sha}" ]; then
+ # Everything is up-to-date in $extract_dir, do nothing
+ return 0;
+ fi
+
+ mkdir -p "$cache_dir"
+
+ # Take a lock for the download of this file
+ short_sha=$(echo "$file_sha" | cut -c1-32) # cannot use the ${short_sha:0:32} syntax in regular /bin/sh
+ download_lock_file="$cache_dir/download-${short_sha}.lock"
+ process_lock_file="$cache_dir/download-${short_sha}.$$.lock"
+ temp_file="$cache_dir/download-${short_sha}.$$.bin"
+ echo $$ >"$process_lock_file"
+ while ! ln "$process_lock_file" "$download_lock_file" 2>/dev/null; do
+ lock_owner=$(cat "$download_lock_file" 2>/dev/null || true)
+ # We use `kill -0` instead of `ps -p` as the first one is more portable
+ if [ -n "$lock_owner" ] && kill -0 "$lock_owner" >/dev/null; then
+ echo "Another Kotlin CLI instance (pid $lock_owner) is downloading $moniker. Awaiting the result..."
+ sleep 1
+ elif [ -n "$lock_owner" ] && [ "$(cat "$download_lock_file" 2>/dev/null)" = "$lock_owner" ]; then
+ rm -f "$download_lock_file"
+ # We don't want to simply loop again here, because multiple concurrent processes may face this at the same time,
+ # which means the 'rm' command above from another script could delete our new valid lock file. Instead, we just
+ # ask the user to try again. This doesn't 100% eliminate the race, but the probability of issues is drastically
+ # reduced because it would involve 4 processes with perfect timing. We can revisit this later.
+ die "Another Kotlin CLI instance (pid $lock_owner) locked the download of $moniker, but is no longer running. The lock file is now removed, please try again."
+ fi
+ done
+
+
+ # An extraction left half-done must never keep the .flag file, which marks $extract_dir as complete: subsequent runs
+ # would skip the extraction and use the broken directory.
+ cleanup_incomplete_provisioning() {
+ rm -f "$download_lock_file" "$temp_file"
+ rm -rf "$extract_dir"
+ }
+ trap cleanup_incomplete_provisioning EXIT
+ rm -f "$process_lock_file"
+
+ unlock_and_cleanup() {
+ rm -f "$download_lock_file"
+ trap - EXIT
+ return 0
+ }
+
+ if [ -e "$extract_dir/.flag" ] && [ "$(cat "$extract_dir/.flag")" = "${file_sha}" ]; then
+ # Everything is up-to-date in $extract_dir, just release the lock
+ unlock_and_cleanup
+ return 0;
+ fi
+
+ if [ "$show_banner_on_cache_miss" = "true" ] && [ -z "${KOTLIN_CLI_NO_WELCOME_BANNER:-}" ]; then
+ echo
+ cat </dev/null 2>&1; then
+ if [ -t 1 ]; then CURL_PROGRESS="--progress-bar"; else CURL_PROGRESS="--silent --show-error"; fi
+ # shellcheck disable=SC2086
+ curl $CURL_PROGRESS -L --fail --retry 5 --connect-timeout 30 --output "${temp_file}" "$file_url"
+ elif command -v wget >/dev/null 2>&1; then
+ if [ -t 1 ]; then WGET_PROGRESS=""; else WGET_PROGRESS="-nv"; fi
+ wget $WGET_PROGRESS --tries=5 --connect-timeout=30 --read-timeout=120 -O "${temp_file}" "$file_url"
+ else
+ die "ERROR: Please install 'wget' or 'curl', as one of them is required to download $moniker"
+ fi
+
+ check_sha "$file_url" "$temp_file" "$file_sha" "$sha_size"
+
+ rm -rf "$extract_dir"
+ mkdir -p "$extract_dir"
+
+ case "$file_url" in
+ *".zip")
+ if command -v unzip >/dev/null 2>&1; then
+ unzip -q "$temp_file" -d "$extract_dir"
+ else
+ die "ERROR: Please install 'unzip', which is required to extract $moniker"
+ fi ;;
+ *)
+ if command -v tar >/dev/null 2>&1; then
+ tar -x -f "$temp_file" -C "$extract_dir"
+ else
+ die "ERROR: Please install 'tar', which is required to extract $moniker"
+ fi ;;
+ esac
+
+ rm -f "$temp_file"
+
+ echo "$file_sha" >"$extract_dir/.flag"
+
+ # Unlock and cleanup the lock file
+ unlock_and_cleanup
+
+ echo "Download complete."
+ echo
+}
+
+
+# ********** Project-local version detection **********
+
+# 1. Search upwards for an executable `amper` file and/or `project.yaml`
+# Sets wrapper_script to the found wrapper path, or empty string if not found.
+find_project_context() {
+ wrapper_script=""
+ this_script="$(realpath "$0")"
+ project_dir=$(pwd)
+ while [ "$project_dir" != "/" ] && [ -n "$project_dir" ]; do
+ wrapper_candidate="$project_dir/kotlin"
+ if [ "$this_script" = "$wrapper_candidate" ]; then
+ # Found itself (local wrapper case), no need to update any version or search further.
+ return 1
+ fi
+
+ if [ -f "$wrapper_candidate" ] && [ -x "$wrapper_candidate" ]; then
+ # Found the wrapper — check that a project context exists alongside it
+ if [ -f "$project_dir/project.yaml" ] || [ -f "$project_dir/module.yaml" ]; then
+ wrapper_script="$wrapper_candidate"
+ return 0
+ else
+ echo "WARNING: Found wrapper script '$wrapper_candidate', but no project.yaml or module.yaml near it. Skipping." >&2
+ # Continue the search
+ fi
+ elif [ -f "$project_dir/project.yaml" ]; then
+ # Found project.yaml but no executable wrapper alongside it
+ echo "WARNING: Found a project.yaml in '$project_dir', but the wrapper script is missing; using Kotlin Toolchain v$kotlin_cli_version." >&2
+ return 1
+ fi
+
+ project_dir=$(dirname "$project_dir")
+ done
+ # Do not check root '/' - it's an unlikely candidate for a project
+
+ return 1
+}
+
+parse_project_context() {
+ # Parse kotlin_cli_version and kotlin_cli_sha256 from "$wrapper_script" without executing it.
+ parsed_kotlin_cli_version=$(
+ sed -n 's/^kotlin_cli_version=\([A-Za-z0-9._+-]\{1,\}\)[[:space:]]*$/\1/p' "$wrapper_script" \
+ | head -n 1
+ )
+ parsed_kotlin_cli_sha256=$(
+ sed -n 's/^kotlin_cli_sha256=\([0-9a-fA-F]\{64\}\)[[:space:]]*$/\1/p' "$wrapper_script" \
+ | head -n 1
+ )
+
+ if [ -z "$parsed_kotlin_cli_version" ]; then
+ echo "ERROR: Suspicious local wrapper script: failed to detect the distribution version in '$wrapper_script'" >&2
+ return 1
+ fi
+ if [ -z "$parsed_kotlin_cli_sha256" ]; then
+ echo "ERROR: Suspicious local wrapper script: failed to detect the distribution checksum in '$wrapper_script'" >&2
+ return 1
+ fi
+
+ # overwrite builtin values and proceed
+ kotlin_cli_version=$parsed_kotlin_cli_version
+ kotlin_cli_sha256=$parsed_kotlin_cli_sha256
+ return 0
+}
+
+if [ -z "${KOTLIN_CLI_WRAPPER_ALWAYS_USE_INTRINSIC_VERSION:-}" ]; then
+ find_project_context && parse_project_context
+fi
+
+# ********** System detection **********
+
+kernelName=$(uname -s)
+case "$kernelName" in
+ Darwin* )
+ default_kotlin_cli_cache_dir="$HOME/Library/Caches/JetBrains/Kotlin/cli"
+ ;;
+ Linux* )
+ default_kotlin_cli_cache_dir="$HOME/.cache/JetBrains/Kotlin/cli"
+ ;;
+ CYGWIN* | MSYS* | MINGW* )
+ if command -v cygpath >/dev/null 2>&1; then
+ default_kotlin_cli_cache_dir=$(cygpath -u "$LOCALAPPDATA\JetBrains\Kotlin\cli")
+ else
+ die "The 'cypath' command is not available, but the Kotlin CLI needs it. Use kotlin.bat instead, or try a Cygwin or MSYS environment."
+ fi
+ ;;
+ *)
+ die "Unsupported platform $kernelName"
+ ;;
+esac
+
+kotlin_cli_cache_dir="${KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:-$default_kotlin_cli_cache_dir}"
+
+# ********** Provision the Kotlin Toolchain distribution **********
+
+kotlin_cli_url="$KOTLIN_CLI_DOWNLOAD_ROOT/org/jetbrains/kotlin/kotlin-cli/$kotlin_cli_version/kotlin-cli-$kotlin_cli_version-dist.tgz"
+kotlin_cli_target_dir="$kotlin_cli_cache_dir/kotlin-cli-$kotlin_cli_version"
+download_and_extract "Kotlin Toolchain distribution v$kotlin_cli_version" "$kotlin_cli_url" "$kotlin_cli_sha256" 256 "$kotlin_cli_cache_dir" "$kotlin_cli_target_dir" "true"
+
+# ********** Launch the Kotlin CLI **********
+
+launcher_script="$kotlin_cli_target_dir/bin/launcher.sh"
+
+KOTLIN_CLI_WRAPPER_PATH="$(realpath "$0")" \
+exec /bin/sh "$launcher_script" "$@"
diff --git a/examples/codeviewer/kotlin.bat b/examples/codeviewer/kotlin.bat
new file mode 100755
index 00000000000..f295d64bf00
--- /dev/null
+++ b/examples/codeviewer/kotlin.bat
@@ -0,0 +1,280 @@
+@echo off
+
+@rem
+@rem Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+@rem
+
+@rem Possible environment variables:
+@rem KOTLIN_CLI_DOWNLOAD_ROOT Maven repository to download the Kotlin CLI dist from
+@rem default: https://packages.jetbrains.team/maven/p/amper/amper
+@rem KOTLIN_CLI_JRE_DOWNLOAD_ROOT Url prefix to download the Kotlin CLI JRE from.
+@rem default: https:/
+@rem KOTLIN_CLI_BOOTSTRAP_CACHE_DIR Cache directory to store the extracted JRE and Kotlin CLI distribution
+@rem KOTLIN_CLI_JAVA_HOME JRE to run the Kotlin CLI itself (optional, does not affect compilation)
+@rem KOTLIN_CLI_JAVA_OPTIONS JVM options to pass to the JVM running the Kotlin CLI (does not affect the user's application)
+@rem KOTLIN_CLI_NO_WELCOME_BANNER Disables the first-run welcome message if set to a non-empty value
+
+setlocal
+
+@rem The version of the Kotlin Toolchain distribution to provision and use
+set kotlin_cli_version=0.13.0
+@rem Establish chain of trust from here by specifying the exact checksum of the Kotlin Toolchain distribution to be run
+set kotlin_cli_sha256=fa82b9872dcfa04d26c8f800f33d597c99fbffd747a0e9bbce3a9e4424b3a588
+
+if not defined KOTLIN_CLI_DOWNLOAD_ROOT set KOTLIN_CLI_DOWNLOAD_ROOT=https://packages.jetbrains.team/maven/p/amper/amper
+if not defined KOTLIN_CLI_BOOTSTRAP_CACHE_DIR set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%LOCALAPPDATA%\JetBrains\Kotlin\cli
+@rem remove trailing \ if present
+if [%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~-1%] EQU [\] set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~0,-1%
+
+goto :after_function_declarations
+
+REM ********** Download and extract any zip or .tar.gz archive **********
+
+:download_and_extract
+setlocal
+
+set moniker=%~1
+set url=%~2
+set target_dir=%~3
+set sha=%~4
+set sha_size=%~5
+set show_banner_on_cache_miss=%~6
+
+setlocal enableDelayedExpansion
+
+set flag_file=%target_dir%\.flag
+if exist "%flag_file%" (
+ set /p current_flag=<"%flag_file%"
+ if "!current_flag!" == "%sha%" exit /b
+)
+
+set NL=^
+
+
+@rem two empty lines required above for the NL character
+
+@rem We have to build the welcome banner here as an env var because we
+@rem can't pass a multiline string through the single line powershell
+set welcome_banner=!NL! ^
+Welcome to !NL! ^
+ !NL! ^
+@@@ @@@@ @@@ @@@ !NL! ^
+@@@ @@@@ @@@ @@@ @@@ !NL! ^
+@@@ #@@@^" ,@@@ @@@ !NL! ^
+@@@ ,@@@%% ,@@@@@@@, @@@@@@@@@@ @@@ @@@ @@@ ,@@@@@, !NL! ^
+@@@ @@@@ @@@@@%%^"%%@@@@@ @@@@@@@@@@ @@@ @@@ @@@@@@%%%%@@@@@ !NL! ^
+@@@@@@%% @@@%% %%@@@ @@@ @@@ @@@ @@@@ %%@@%% !NL! ^
+@@@ @@@@= #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^
+@@@ @@@@ #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^
+@@@ *@@@%% @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ !NL! ^
+@@@ %%@@@= %%@@@@*,*@@@@%% @@@@### @@@ @@@ @@@ @@@ !NL! ^
+@@@ @@@@ ^"@@@@@@@^" %%@@@@@ @@@ @@@ @@@ @@@ !NL!
+
+@rem This multiline string is actually passed as a single line to powershell, meaning #-comments are not possible.
+@rem So here are a few comments about the code below:
+@rem - we need to support both .zip and .tar.gz archives (for the Kotlin Toolchain distribution and the JRE)
+@rem - tar should be present in all Windows machines since 2018 (and usable from both cmd and powershell)
+@rem - tar requires the destination dir to exist
+@rem - native commands like tar don't raise PowerShell errors on failure, so we have to check $LASTEXITCODE.
+@rem The extraction must never be left half-done with the .flag file in place, because the .flag file marks the
+@rem target dir as complete, and subsequent runs would then skip the extraction and use the broken directory.
+@rem - We use (New-Object Net.WebClient).DownloadFile instead of Invoke-WebRequest for performance. See the issue
+@rem https://github.com/PowerShell/PowerShell/issues/16914, which is still not fixed in Windows PowerShell 5.1
+@rem - DownloadFile requires the directories in the destination file's path to exist
+set download_and_extract_ps1= ^
+Set-StrictMode -Version 3.0; ^
+$ErrorActionPreference = 'Stop'; ^
+ ^
+$temp_file = $null; ^
+$createdNew = $false; ^
+$lock = New-Object System.Threading.Mutex($true, ('Global\kotlin-cli-bootstrap.' + '%target_dir%'.GetHashCode().ToString()), [ref]$createdNew); ^
+if (-not $createdNew) { ^
+ Write-Host 'Another Kotlin CLI instance is bootstrapping. Waiting for our turn...'; ^
+ [void]$lock.WaitOne(); ^
+} ^
+ ^
+try { ^
+ if ((Get-Content '%flag_file%' -ErrorAction Ignore) -ne '%sha%') { ^
+ if (('%show_banner_on_cache_miss%' -eq 'true') -and [string]::IsNullOrEmpty('%KOTLIN_CLI_NO_WELCOME_BANNER%')) { ^
+ Write-Host \"$env:welcome_banner\"; ^
+ Write-Host ''; ^
+ Write-Host 'This is the first run of the Kotlin CLI v%kotlin_cli_version%, so we need to download the Kotlin Toolchain.'; ^
+ Write-Host 'Please give us a few seconds now, subsequent runs will be faster.'; ^
+ Write-Host ''; ^
+ } ^
+ $temp_file = '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\' + [System.IO.Path]::GetRandomFileName(); ^
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ^
+ Write-Host 'Downloading %moniker%...'; ^
+ [void](New-Item '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%' -ItemType Directory -Force); ^
+ if (Get-Command curl.exe -errorAction SilentlyContinue) { ^
+ curl.exe -L --silent --show-error --fail --output $temp_file '%url%'; ^
+ } else { ^
+ (New-Object Net.WebClient).DownloadFile('%url%', $temp_file); ^
+ } ^
+ ^
+ $actualSha = (Get-FileHash -Algorithm SHA%sha_size% -Path $temp_file).Hash.ToString(); ^
+ if ($actualSha -ne '%sha%') { ^
+ $writeErr = if ($Host.Name -eq 'ConsoleHost') { [Console]::Error.WriteLine } else { $host.ui.WriteErrorLine } ^
+ $writeErr.Invoke(\"ERROR: Checksum mismatch for $temp_file (downloaded from %url%): expected checksum %sha% but got $actualSha\"); ^
+ exit 1; ^
+ } ^
+ ^
+ if (Test-Path '%target_dir%') { ^
+ Remove-Item '%target_dir%' -Recurse; ^
+ } ^
+ try { ^
+ if ($temp_file -like '*.zip') { ^
+ Add-Type -A 'System.IO.Compression.FileSystem'; ^
+ [IO.Compression.ZipFile]::ExtractToDirectory($temp_file, '%target_dir%'); ^
+ } else { ^
+ [void](New-Item '%target_dir%' -ItemType Directory -Force); ^
+ tar -xzf $temp_file -C '%target_dir%'; ^
+ if ($LASTEXITCODE -ne 0) { ^
+ throw \"tar failed to extract %moniker% (exit code $LASTEXITCODE)\"; ^
+ } ^
+ } ^
+ } catch { ^
+ Remove-Item '%flag_file%' -Force -ErrorAction Ignore; ^
+ Remove-Item '%target_dir%' -Recurse -Force -ErrorAction Ignore; ^
+ throw; ^
+ } ^
+ ^
+ Set-Content '%flag_file%' -Value '%sha%'; ^
+ Write-Host 'Download complete.'; ^
+ Write-Host ''; ^
+ } ^
+} ^
+finally { ^
+ if ($temp_file) { ^
+ Remove-Item $temp_file -Force -ErrorAction Ignore; ^
+ } ^
+ $lock.ReleaseMutex(); ^
+}
+
+rem We reset the PSModulePath in case this batch script was called from PowerShell Core
+rem See https://github.com/PowerShell/PowerShell/issues/18108#issuecomment-2269703022
+set PSModulePath=
+set powershell=%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
+"%powershell%" -NonInteractive -NoProfile -NoLogo -Command %download_and_extract_ps1%
+if errorlevel 1 exit /b 1
+exit /b 0
+
+:find_project_context
+@rem Search upwards for a kotlin.bat wrapper file and/or project.yaml
+@rem Sets wrapper_script to the found wrapper path, or empty string if not found.
+@rem Returns errorlevel 0 if a valid wrapper (that is not this script itself) was found, 1 otherwise.
+set wrapper_script=
+set this_script=%~f0
+set project_dir=%CD%
+
+:find_loop
+set wrapper_candidate=%project_dir%\kotlin.bat
+if "%this_script%"=="%wrapper_candidate%" (
+ @rem Found itself (local wrapper case), no need to update any version or search further.
+ exit /b 1
+)
+
+if exist "%wrapper_candidate%" (
+ @rem Found a wrapper — check that a project context exists alongside it
+ if exist "%project_dir%\project.yaml" (
+ set wrapper_script=%wrapper_candidate%
+ exit /b 0
+ )
+ if exist "%project_dir%\module.yaml" (
+ set wrapper_script=%wrapper_candidate%
+ exit /b 0
+ )
+ echo WARNING: Found wrapper script '%wrapper_candidate%', but no project.yaml or module.yaml near it. Skipping. >&2
+ @rem Continue the search
+ goto :find_next_parent
+)
+
+if exist "%project_dir%\project.yaml" (
+ @rem Found project.yaml but no wrapper alongside it
+ echo WARNING: Found a project.yaml in '%project_dir%', but the wrapper script is missing; using Kotlin Toolchain v%kotlin_cli_version%. >&2
+ exit /b 1
+)
+
+:find_next_parent
+@rem Move to parent directory
+for %%P in ("%project_dir%\..") do set parent_dir=%%~fP
+if "%parent_dir%"=="%project_dir%" (
+ @rem Reached the root, stop searching
+ exit /b 1
+)
+set project_dir=%parent_dir%
+goto :find_loop
+
+:parse_project_context
+@rem Parse kotlin_cli_version and kotlin_cli_sha256 from the found wrapper_script without executing it.
+set parsed_kotlin_cli_version=
+set parsed_kotlin_cli_sha256=
+
+for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_version=[A-Za-z0-9._+-]*$" "%wrapper_script%"') do (
+ if not defined parsed_kotlin_cli_version set parsed_kotlin_cli_version=%%A
+)
+for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_sha256=[0-9a-fA-F]*$" "%wrapper_script%"') do (
+ if not defined parsed_kotlin_cli_sha256 set parsed_kotlin_cli_sha256=%%A
+)
+
+if not defined parsed_kotlin_cli_version (
+ echo ERROR: Suspicious local wrapper script: failed to detect the distribution version in '%wrapper_script%' >&2
+ exit /b 1
+)
+if not defined parsed_kotlin_cli_sha256 (
+ echo ERROR: Suspicious local wrapper script: failed to detect the distribution checksum in '%wrapper_script%' >&2
+ exit /b 1
+)
+
+@rem Overwrite builtin values and proceed
+set kotlin_cli_version=%parsed_kotlin_cli_version%
+set kotlin_cli_sha256=%parsed_kotlin_cli_sha256%
+exit /b 0
+
+:fail
+echo ERROR: Kotlin CLI bootstrap failed, see errors above
+exit /b 1
+
+:after_function_declarations
+
+REM ********** Project-local version detection **********
+
+if defined KOTLIN_CLI_WRAPPER_ALWAYS_USE_INTRINSIC_VERSION goto :after_local_version_detection
+
+call :find_project_context
+if errorlevel 1 goto :after_local_version_detection
+call :parse_project_context
+if errorlevel 1 goto fail
+:after_local_version_detection
+
+REM ********** Provision the Kotlin Toolchain distribution **********
+
+set kotlin_cli_url=%KOTLIN_CLI_DOWNLOAD_ROOT%/org/jetbrains/kotlin/kotlin-cli/%kotlin_cli_version%/kotlin-cli-%kotlin_cli_version%-dist.tgz
+set kotlin_cli_target_dir=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\kotlin-cli-%kotlin_cli_version%
+call :download_and_extract "Kotlin Toolchain distribution v%kotlin_cli_version%" "%kotlin_cli_url%" "%kotlin_cli_target_dir%" "%kotlin_cli_sha256%" "256" "true"
+if errorlevel 1 goto fail
+
+REM ********** Launch the Kotlin CLI **********
+
+rem Determine the correct busybox binary based on architecture
+if "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
+ set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64a.exe
+) else if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
+ set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64u.exe
+) else (
+ echo Unsupported architecture %PROCESSOR_ARCHITECTURE% >&2
+ goto fail
+)
+
+rem We use busybox here because it doesn't reinterpret the user-passed command-line arguments (that we pass via %*).
+rem Also this way we can use the unified launcher script (.sh)
+set KOTLIN_CLI_WRAPPER_PATH=%~f0
+
+rem The '& call' after the app run is to avoid the "Terminate batch job (Y/N)?" prompt
+"%busybox_exe%" sh "%kotlin_cli_target_dir%\bin\launcher.sh" %* & call :exitWithErrorLevel
+
+:exitWithErrorLevel
+@rem We use "%COMSPEC%" /d /c exit so that and/or operators work properly when calling kotlin.bat directly from a script
+@rem without the `call` command. With a plain `exit /B %ERRORLEVEL%`, using `kotlin.bat && echo success` would print
+@rem 'success' even in case of failure. Consumers would have to use `call kotlin.bat && echo success` for it to work.`
+"%COMSPEC%" /d /c exit %ERRORLEVEL%
diff --git a/examples/codeviewer/libs.versions.toml b/examples/codeviewer/libs.versions.toml
new file mode 100644
index 00000000000..331ceb6ec8e
--- /dev/null
+++ b/examples/codeviewer/libs.versions.toml
@@ -0,0 +1,17 @@
+[versions]
+androidx-activity = "1.13.0"
+androidx-appcompat = "1.7.1"
+androidx-core = "1.18.0"
+compose-multiplatform = "1.12.1"
+material-icons-extended = "1.7.3"
+
+[libraries]
+androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
+androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
+androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
+compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose-multiplatform" }
+compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-multiplatform" }
+compose-material = { module = "org.jetbrains.compose.material:material", version.ref = "compose-multiplatform" }
+compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-multiplatform" }
+compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-multiplatform" }
+material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended", version.ref = "material-icons-extended" }
diff --git a/examples/codeviewer/project.yaml b/examples/codeviewer/project.yaml
new file mode 100644
index 00000000000..e056ef58ed4
--- /dev/null
+++ b/examples/codeviewer/project.yaml
@@ -0,0 +1,6 @@
+modules:
+ - androidApp
+ - desktopApp
+ - iosApp
+ - shared
+ - webApp
diff --git a/examples/codeviewer/run-configurations.png b/examples/codeviewer/run-configurations.png
deleted file mode 100644
index d859ff0870f..00000000000
Binary files a/examples/codeviewer/run-configurations.png and /dev/null differ
diff --git a/examples/codeviewer/settings.gradle.kts b/examples/codeviewer/settings.gradle.kts
deleted file mode 100644
index ca43bf2d371..00000000000
--- a/examples/codeviewer/settings.gradle.kts
+++ /dev/null
@@ -1,33 +0,0 @@
-pluginManagement {
- repositories {
- gradlePluginPortal()
- maven("https://packages.jetbrains.team/maven/p/cmp/dev")
- google()
- }
-}
-
-dependencyResolutionManagement {
- repositories {
- google()
- mavenCentral()
- maven("https://packages.jetbrains.team/maven/p/cmp/dev")
- }
-
- versionCatalogs {
- create("libs") {
- version("kotlin", extra["kotlin.version"].toString())
- version("compose", extra["compose.version"].toString())
- version("agp", extra["agp.version"].toString())
- }
- }
-}
-
-plugins {
- id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0")
-}
-
-rootProject.name = "codeviewer"
-
-include(":androidApp")
-include(":shared")
-include(":desktopApp")
diff --git a/examples/codeviewer/shared/build.gradle.kts b/examples/codeviewer/shared/build.gradle.kts
deleted file mode 100644
index a509d3b44ce..00000000000
--- a/examples/codeviewer/shared/build.gradle.kts
+++ /dev/null
@@ -1,63 +0,0 @@
-@file:Suppress("OPT_IN_IS_NOT_ENABLED")
-
-import org.jetbrains.kotlin.gradle.dsl.JvmTarget
-
-plugins {
- alias(libs.plugins.kotlinMultiplatform)
- alias(libs.plugins.composeCompiler)
- alias(libs.plugins.androidMultiplatformLibrary)
- alias(libs.plugins.composeMultiplatform)
-}
-
-version = "1.0-SNAPSHOT"
-
-kotlin {
- jvm("desktop")
-
- listOf(
- iosArm64(),
- iosSimulatorArm64()
- ).forEach { iosTarget ->
- iosTarget.binaries.framework {
- baseName = "shared"
- isStatic = true
- }
- }
-
- android {
- compileSdk {
- version = release(37) { minorApiLevel = 1 }
- }
- namespace = "org.jetbrains.codeviewer.common"
- minSdk = 26
-
- compilerOptions {
- jvmTarget = JvmTarget.JVM_17
- }
- }
-
- sourceSets {
- commonMain.dependencies {
- implementation(libs.compose.runtime)
- implementation(libs.compose.foundation)
- implementation(libs.compose.material)
- implementation(libs.material.icons.extended)
- implementation(libs.components.resources)
- }
- androidMain {
- kotlin {
- srcDirs("src/jvmMain/kotlin")
- }
- dependencies {
- api(libs.androidx.activity.compose)
- api(libs.androidx.appcompat)
- api(libs.androidx.core.ktx)
- }
- }
- val desktopMain by getting {
- kotlin {
- srcDirs("src/jvmMain/kotlin")
- }
- }
- }
-}
diff --git a/examples/codeviewer/shared/composeResources/files/EditorView.kt b/examples/codeviewer/shared/composeResources/files/EditorView.kt
new file mode 100644
index 00000000000..8917e4c6035
--- /dev/null
+++ b/examples/codeviewer/shared/composeResources/files/EditorView.kt
@@ -0,0 +1,183 @@
+/**
+ * This file is an example (we can open it in iOS application)
+ */
+
+package org.jetbrains.codeviewer.ui.editor
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.text.selection.DisableSelection
+import androidx.compose.material.AmbientContentColor
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.text.*
+import androidx.compose.ui.unit.dp
+import org.jetbrains.codeviewer.platform.SelectionContainer
+import org.jetbrains.codeviewer.ui.common.AppTheme
+import org.jetbrains.codeviewer.ui.common.Fonts
+import org.jetbrains.codeviewer.ui.common.Settings
+import org.jetbrains.codeviewer.util.loadableScoped
+import org.jetbrains.codeviewer.util.withoutWidthConstraints
+import kotlin.text.Regex.Companion.fromLiteral
+
+@Composable
+fun EditorView(model: Editor, settings: Settings) = key(model) {
+ with (LocalDensity.current) {
+ SelectionContainer {
+ Surface(
+ Modifier.fillMaxSize(),
+ color = AppTheme.colors.backgroundDark,
+ ) {
+ val lines by loadableScoped(model.lines)
+
+ if (lines != null) {
+ Box {
+ Lines(lines!!, settings)
+ Box(
+ Modifier
+ .offset(
+ x = settings.fontSize.toDp() * 0.5f * settings.maxLineSymbols
+ )
+ .width(1.dp)
+ .fillMaxHeight()
+ .background(AppTheme.colors.codeGuide)
+ )
+ }
+ } else {
+ CircularProgressIndicator(
+ modifier = Modifier
+ .size(36.dp)
+ .padding(4.dp)
+ )
+ }
+ }
+ }
+ }
+}
+
+@Composable
+private fun Lines(lines: Editor.Lines, settings: Settings) = with(DensityAmbient.current) {
+ val maxNumber = remember(lines.lineNumberDigitCount) {
+ (1..lines.lineNumberDigitCount).joinToString(separator = "") { "9" }
+ }
+
+ Box(Modifier.fillMaxSize()) {
+ val scrollState = rememberLazyListState()
+ val lineHeight = settings.fontSize.toDp() * 1.6f
+
+ LazyColumnFor(
+ lines.size,
+ modifier = Modifier.fillMaxSize(),
+ state = scrollState,
+ itemContent = { index ->
+ val line: Editor.Line? by loadable { lines.get(index) }
+ Box(Modifier.height(lineHeight)) {
+ if (line != null) {
+ Line(Modifier.align(Alignment.CenterStart), maxNumber, line!!, settings)
+ }
+ }
+ }
+ )
+
+ VerticalScrollbar(
+ Modifier.align(Alignment.CenterEnd),
+ scrollState,
+ lines.size,
+ lineHeight
+ )
+ }
+}
+
+// Поддержка русского языка
+// دعم اللغة العربية
+// 中文支持
+@Composable
+private fun Line(modifier: Modifier, maxNumber: String, line: Editor.Line, settings: Settings) {
+ Row(modifier = modifier) {
+ DisableSelection {
+ Box {
+ LineNumber(maxNumber, Modifier.alpha(0f), settings)
+ LineNumber(line.number.toString(), Modifier.align(Alignment.CenterEnd), settings)
+ }
+ }
+ LineContent(
+ line.content,
+ modifier = Modifier
+ .weight(1f)
+ .withoutWidthConstraints()
+ .padding(start = 28.dp, end = 12.dp),
+ settings = settings
+ )
+ }
+}
+
+@Composable
+private fun LineNumber(number: String, modifier: Modifier, settings: Settings) = Text(
+ text = number,
+ fontSize = settings.fontSize,
+ fontFamily = Fonts.jetbrainsMono(),
+ color = AmbientContentColor.current.copy(alpha = 0.30f),
+ modifier = modifier.padding(start = 12.dp)
+)
+
+@Composable
+private fun LineContent(content: Editor.Content, modifier: Modifier, settings: Settings) = Text(
+ text = if (content.isCode) {
+ codeString(content.value.value)
+ } else {
+ AnnotatedString(content.value.value)
+ },
+ fontSize = settings.fontSize,
+ fontFamily = Fonts.jetbrainsMono(),
+ modifier = modifier,
+ softWrap = false
+)
+
+private fun codeString(str: String) = buildAnnotatedString {
+ withStyle(AppTheme.code.simple) {
+ append(str.replace("\t", " "))
+ addStyle(AppTheme.code.punctuation, ":")
+ addStyle(AppTheme.code.punctuation, "=")
+ addStyle(AppTheme.code.punctuation, "\"")
+ addStyle(AppTheme.code.punctuation, "[")
+ addStyle(AppTheme.code.punctuation, "]")
+ addStyle(AppTheme.code.punctuation, "{")
+ addStyle(AppTheme.code.punctuation, "}")
+ addStyle(AppTheme.code.punctuation, "(")
+ addStyle(AppTheme.code.punctuation, ")")
+ addStyle(AppTheme.code.punctuation, ",")
+ addStyle(AppTheme.code.keyword, "fun ")
+ addStyle(AppTheme.code.keyword, "val ")
+ addStyle(AppTheme.code.keyword, "var ")
+ addStyle(AppTheme.code.keyword, "private ")
+ addStyle(AppTheme.code.keyword, "internal ")
+ addStyle(AppTheme.code.keyword, "for ")
+ addStyle(AppTheme.code.keyword, "expect ")
+ addStyle(AppTheme.code.keyword, "actual ")
+ addStyle(AppTheme.code.keyword, "import ")
+ addStyle(AppTheme.code.keyword, "package ")
+ addStyle(AppTheme.code.value, "true")
+ addStyle(AppTheme.code.value, "false")
+ addStyle(AppTheme.code.value, Regex("[0-9]*"))
+ addStyle(AppTheme.code.annotation, Regex("^@[a-zA-Z_]*"))
+ addStyle(AppTheme.code.comment, Regex("^\\s*//.*"))
+ }
+}
+
+private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: String) {
+ addStyle(style, fromLiteral(regexp))
+}
+
+private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: Regex) {
+ for (result in regexp.findAll(toString())) {
+ addStyle(style, result.range.first, result.range.last + 1)
+ }
+}
\ No newline at end of file
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold_italic.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold_italic.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold_italic.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold_italic.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold_italic.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold_italic.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_italic.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_italic.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_italic.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium_italic.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium_italic.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium_italic.ttf
diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_regular.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_regular.ttf
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_regular.ttf
rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_regular.ttf
diff --git a/examples/codeviewer/shared/module.yaml b/examples/codeviewer/shared/module.yaml
new file mode 100644
index 00000000000..f5701d43cc3
--- /dev/null
+++ b/examples/codeviewer/shared/module.yaml
@@ -0,0 +1,28 @@
+product:
+ type: kmp/lib
+ platforms: [android, iosArm64, iosSimulatorArm64, jvm, wasmJs]
+
+aliases:
+ - jvmAndAndroid: [jvm, android]
+
+dependencies:
+ - $libs.compose.runtime
+ - $libs.compose.foundation
+ - $libs.compose.material
+ - $libs.compose.components.resources
+ - $libs.material.icons.extended
+
+dependencies@android:
+ - $libs.androidx.activity.compose: exported
+ - $libs.androidx.appcompat: exported
+ - $libs.androidx.core.ktx: exported
+
+settings:
+ compose:
+ enabled: true
+ resources:
+ packageName: codeviewer.shared.generated.resources
+ android:
+ namespace: org.jetbrains.codeviewer.common
+ minSdk: 26
+
diff --git a/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml b/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 568741e54f2..00000000000
--- a/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/File.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/File.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/File.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Mouse.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Mouse.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Scrollbar.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Scrollbar.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewer.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewer.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewer.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewer.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewerView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewerView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/MainView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/MainView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Fonts.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Fonts.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Settings.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Settings.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Settings.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Settings.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Theme.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Theme.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Theme.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Theme.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editor.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editor.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editor.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editor.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editors.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editors.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editors.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editors.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTree.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTree.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTree.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTree.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/LayoutModifiers.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/LayoutModifiers.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/LayoutModifiers.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/LayoutModifiers.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/Loadable.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/Loadable.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/SingleSelection.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/SingleSelection.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/SingleSelection.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/SingleSelection.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/TextLines.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/TextLines.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/TextLines.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/TextLines.kt
diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/VerticalSplittable.kt
similarity index 100%
rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt
rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/VerticalSplittable.kt
diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/main.android.kt b/examples/codeviewer/shared/src@android/main.android.kt
similarity index 100%
rename from examples/codeviewer/shared/src/androidMain/kotlin/main.android.kt
rename to examples/codeviewer/shared/src@android/main.android.kt
diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/File.kt
similarity index 100%
rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/File.kt
rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/File.kt
diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Mouse.kt
similarity index 100%
rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt
rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Mouse.kt
diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Scrollbar.kt
similarity index 100%
rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt
rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Scrollbar.kt
diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt
similarity index 95%
rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt
rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt
index 2a1dee9218d..a45227e3145 100644
--- a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt
+++ b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt
@@ -34,7 +34,7 @@ actual val HomeFolder: File get() = VirtualFile("files",
VirtualFile("EditorView.kt",
isDirectory = false,
textLines = runBlocking {
- Res.readBytes("EditorView.kt")
+ Res.readBytes("files/EditorView.kt")
}.toTextLines()
)
)
diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Mouse.kt
similarity index 100%
rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt
rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Mouse.kt
diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Scrollbar.kt
similarity index 100%
rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt
rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Scrollbar.kt
diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/main.desktop.kt b/examples/codeviewer/shared/src@jvm/main.desktop.kt
similarity index 100%
rename from examples/codeviewer/shared/src/desktopMain/kotlin/main.desktop.kt
rename to examples/codeviewer/shared/src@jvm/main.desktop.kt
diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/File.kt
similarity index 100%
rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/File.kt
rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/File.kt
diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Mouse.kt
similarity index 100%
rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt
rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Mouse.kt
diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Scrollbar.kt
similarity index 100%
rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt
rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Scrollbar.kt
diff --git a/examples/codeviewer/shared/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt b/examples/codeviewer/shared/src@jvmAndAndroid/org/jetbrains/codeviewer/platform/JvmFile.kt
similarity index 100%
rename from examples/codeviewer/shared/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt
rename to examples/codeviewer/shared/src@jvmAndAndroid/org/jetbrains/codeviewer/platform/JvmFile.kt
diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt
new file mode 100644
index 00000000000..595b847a9a8
--- /dev/null
+++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt
@@ -0,0 +1,52 @@
+package org.jetbrains.codeviewer.platform
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import codeviewer.shared.generated.resources.Res
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import org.jetbrains.codeviewer.util.EmptyTextLines
+import org.jetbrains.codeviewer.util.TextLines
+
+class VirtualFolder(override val name: String, override val children: List) : File {
+ override val isDirectory: Boolean
+ get() = true
+
+ override val hasChildren: Boolean
+ get() = children.isNotEmpty()
+
+ override fun readLines(scope: CoroutineScope): TextLines = EmptyTextLines
+}
+
+class ResourceFile(override val name: String, private val path: String) : File {
+ override val isDirectory: Boolean
+ get() = false
+
+ override val children: List
+ get() = emptyList()
+
+ override val hasChildren: Boolean
+ get() = false
+
+ // Resources are fetched over the network on the web, so lines are loaded in background
+ override fun readLines(scope: CoroutineScope): TextLines {
+ var lines by mutableStateOf(emptyList())
+
+ scope.launch {
+ lines = Res.readBytes(path).decodeToString().split("\n")
+ }
+
+ return object : TextLines {
+ override val size get() = lines.size
+
+ override fun get(index: Int): String = lines[index]
+ }
+ }
+}
+
+actual val HomeFolder: File get() = VirtualFolder("files",
+ children = listOf(
+ ResourceFile("EditorView.kt", "files/EditorView.kt")
+ )
+)
diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt
new file mode 100644
index 00000000000..3a8174f63cf
--- /dev/null
+++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt
@@ -0,0 +1,5 @@
+package org.jetbrains.codeviewer.platform
+
+import androidx.compose.ui.Modifier
+
+actual fun Modifier.cursorForHorizontalResize(): Modifier = this
diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt
new file mode 100644
index 00000000000..c8af7f095c3
--- /dev/null
+++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt
@@ -0,0 +1,25 @@
+package org.jetbrains.codeviewer.platform
+
+import androidx.compose.foundation.ScrollState
+import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.rememberScrollbarAdapter
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+actual fun VerticalScrollbar(
+ modifier: Modifier,
+ scrollState: ScrollState
+) = androidx.compose.foundation.VerticalScrollbar(
+ rememberScrollbarAdapter(scrollState),
+ modifier
+)
+
+@Composable
+actual fun VerticalScrollbar(
+ modifier: Modifier,
+ scrollState: LazyListState
+) = androidx.compose.foundation.VerticalScrollbar(
+ rememberScrollbarAdapter(scrollState),
+ modifier
+)
\ No newline at end of file
diff --git a/examples/codeviewer/webApp/module.yaml b/examples/codeviewer/webApp/module.yaml
new file mode 100644
index 00000000000..f6bb0a65c3f
--- /dev/null
+++ b/examples/codeviewer/webApp/module.yaml
@@ -0,0 +1,8 @@
+product: wasm-js/app
+
+dependencies:
+ - //shared
+ - $libs.compose.ui
+
+settings:
+ compose: enabled
diff --git a/examples/codeviewer/webApp/resources/index.html b/examples/codeviewer/webApp/resources/index.html
new file mode 100644
index 00000000000..de4f11d9af2
--- /dev/null
+++ b/examples/codeviewer/webApp/resources/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Code Viewer
+
+
+
+{{kotlin.scripts}}
+
+
diff --git a/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt b/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt
new file mode 100644
index 00000000000..587b61b408b
--- /dev/null
+++ b/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt
@@ -0,0 +1,10 @@
+package org.jetbrains.codeviewer
+
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.window.ComposeViewport
+import org.jetbrains.codeviewer.ui.MainView
+
+@OptIn(ExperimentalComposeUiApi::class)
+fun main() = ComposeViewport {
+ MainView()
+}
diff --git a/examples/html/compose-in-js/build.gradle.kts b/examples/html/compose-in-js/build.gradle.kts
index a49d05e325a..4baf71022ca 100644
--- a/examples/html/compose-in-js/build.gradle.kts
+++ b/examples/html/compose-in-js/build.gradle.kts
@@ -30,7 +30,7 @@ kotlin {
sourceSets {
val jsMain by getting {
dependencies {
- implementation(compose.web.core)
+ implementation(compose.html.core)
implementation(compose.runtime)
}
}
diff --git a/examples/validateExamples.sh b/examples/validateExamples.sh
index e398a58cb88..09fe752335c 100755
--- a/examples/validateExamples.sh
+++ b/examples/validateExamples.sh
@@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then
version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2")
fi
+compose_version="${1:-}"
+kotlin_version="${2:-}"
runGradle() {
local example="$1"
@@ -32,8 +34,14 @@ runGradle() {
popd
}
+runKotlin() {
+ local example="$1"
+ local platform="$2"
+ ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version"
+}
+
runGradle chat packageDistributionForCurrentOS
-runGradle codeviewer packageDistributionForCurrentOS
+runKotlin codeviewer jvm
runGradle imageviewer packageDistributionForCurrentOS
runGradle issues packageDistributionForCurrentOS
runGradle graphics-2d packageDistributionForCurrentOS
diff --git a/examples/validateExamplesAndroid.sh b/examples/validateExamplesAndroid.sh
index aeab9104b7d..46f6c5732e1 100755
--- a/examples/validateExamplesAndroid.sh
+++ b/examples/validateExamplesAndroid.sh
@@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then
version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2")
fi
+compose_version="${1:-}"
+kotlin_version="${2:-}"
runGradle() {
local example="$1"
@@ -32,8 +34,14 @@ runGradle() {
popd
}
+runKotlin() {
+ local example="$1"
+ local platform="$2"
+ ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version"
+}
+
runGradle chat assembleDebug
-runGradle codeviewer assembleDebug
+runKotlin codeviewer android
runGradle imageviewer assembleDebug
runGradle issues assembleDebug
runGradle graphics-2d assembleDebug
diff --git a/examples/validateExamplesIos.sh b/examples/validateExamplesIos.sh
index 5fd23b337d6..7d19d54720b 100755
--- a/examples/validateExamplesIos.sh
+++ b/examples/validateExamplesIos.sh
@@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then
version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2")
fi
+compose_version="${1:-}"
+kotlin_version="${2:-}"
runGradle() {
local example="$1"
@@ -32,7 +34,13 @@ runGradle() {
popd
}
+runKotlin() {
+ local example="$1"
+ local platform="$2"
+ ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version"
+}
+
runGradle chat
-runGradle codeviewer
+runKotlin codeviewer iosSimulatorArm64
runGradle imageviewer
runGradle graphics-2d
diff --git a/examples/validateExamplesWithJs.sh b/examples/validateExamplesWithJs.sh
index 5636a251556..af9e12910f9 100755
--- a/examples/validateExamplesWithJs.sh
+++ b/examples/validateExamplesWithJs.sh
@@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then
version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2")
fi
+compose_version="${1:-}"
+kotlin_version="${2:-}"
runGradle() {
local example="$1"
@@ -32,7 +34,18 @@ runGradle() {
popd
}
+runKotlin() {
+ local example="$1"
+ local platform="$2"
+ ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version"
+}
+
runGradle html/compose-bird build
+runGradle html/compose-in-js build
runGradle html/landing build
runGradle html/with-react build
+runGradle chat :jsApp:jsBrowserDistribution
+runGradle graphics-2d :jsApp:jsBrowserDistribution
runGradle imageviewer :webApp:wasmJsBrowserDistribution
+runGradle nav_cupcake :webApp:wasmJsBrowserDistribution
+runKotlin codeviewer wasmJs