Compare commits

...

31 Commits

Author SHA1 Message Date
Roman Acevedo
9575cc1c87 fake commit to run flaky tests 2025-12-05 18:07:27 +01:00
Florian Hussonnois
3cbad1ce0d fix(tests): fix StatefulTriggerInterfaceTest 2025-12-05 17:56:32 +01:00
Debjyoti Shit
760050e9fc fix(ui): improve responsive layout and styling of flow editor and sidebar (#13371)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-12-05 17:35:25 +01:00
Nancy Sangani
43f47ec337 fix: error dialogue not appearing after first use of checks #13357 (#13364)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-05 16:24:53 +01:00
Avirup Banik
ad5521199a Fix(ui): button glow timing and banner placement (#13417) 2025-12-05 18:44:22 +05:30
brian-mulier-p
fe7849d7fe fix(metadata): add system namespace to migrated namespaces (#13419)
closes https://github.com/kestra-io/kestra-ee/issues/6019
2025-12-05 14:01:02 +01:00
Loïc Mathieu
feeaeff0b2 chore(tests): remove running tests in parallel 2025-12-05 13:23:29 +01:00
Nirnay
ed6bc50163 fix(ui): Overflow of Flow labels in flow editor page (#13374) 2025-12-05 12:30:53 +01:00
Pratik Dey
069845f579 chore(core): properly handle conditional visibility of elements on dependency view (#13387)
Closes https://github.com/kestra-io/kestra/issues/13291.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-05 11:33:48 +01:00
Aditya Kumar Puri
f613eb0433 refactor(core): remove usage of unnecessary i18n composable (#13389)
Closes https://github.com/kestra-io/kestra/issues/13201.

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-12-05 09:55:18 +01:00
Florian Hussonnois
e440c402b4 fix(flows): add flow variables to runContext for checks
Related-to: kestra-io/kestra-ee#5759
2025-12-04 16:13:32 +01:00
Miloš Paunović
700527b5dc chore(executions): properly cast values for the disabled property to boolean (#13384) 2025-12-04 15:50:32 +01:00
Miloš Paunović
5245014a32 chore(executions): avoid uppercase letters and monospace fonts for property labels (#13383)
Closes https://github.com/kestra-io/kestra/issues/13363.
2025-12-04 13:56:50 +01:00
Kollakota Siva Sai
5db0f44fb6 refactor(core): remove usage of unnecessary i18n composable (#13382)
Closes https://github.com/kestra-io/kestra/issues/13353.

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-12-04 13:37:05 +01:00
brian-mulier-p
a8635108b7 fix(core): safeguard for null flow when trying to reset trigger in JdbcExecutor (#13381) 2025-12-04 12:46:53 +01:00
Miloš Paunović
cd4470044e feat(executions): make prev/next buttons loop through the executions of that flow (#13296)
Closes https://github.com/kestra-io/kestra/issues/9873.
2025-12-04 12:28:24 +01:00
yuri1969
4ec7f23a7b Amend inconsistency 2025-12-04 12:20:16 +01:00
yuri1969
107ba16ce3 feat(core): modernize Pebble cache
* Modernized the LRU cache from Guava to Caffeine.
* Registered metrics.
2025-12-04 12:20:16 +01:00
Miloš Paunović
042d548598 refactor(core): remove all traces of the old e2e setup (#13356) 2025-12-04 12:12:59 +01:00
Kunal
94bd6f0a1e chore(executions): amend alignment of the timeline element on the overview page (#13370)
Closes https://github.com/kestra-io/kestra/issues/13282.

Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-04 11:57:56 +01:00
Avirup Banik
f43f11e125 refactor(core): remove usage of unnecessary i18n composable (#13379)
Closes https://github.com/kestra-io/kestra/issues/13354.

Signed-off-by: Avirup Banik <avirup.banik2017@gmail.com>
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-04 11:23:59 +01:00
brian-mulier-p
3dfa5f97c4 fix(core): deprecate Await util (#13369)
This reverts commit 9fa94deba9.
2025-12-04 09:57:12 +01:00
Roman Acevedo
8898ba736b test(executions): fix ES duration tests 2025-12-03 18:37:49 +01:00
Loïc Mathieu
f5665bf719 Update core/src/test/java/io/kestra/core/serializers/YamlParserTest.java 2025-12-03 17:34:52 +01:00
Loïc Mathieu
b6db688003 Update core/src/test/resources/flows/valids/labels-deserialization.yaml 2025-12-03 17:34:52 +01:00
lizi3
93f5e366ed fix: add unit test 2025-12-03 17:34:52 +01:00
lizi3
0465ffa5df fix: unify label deserialization for numeric values in array form
The START_ARRAY branch did not apply type conversion for label values,
causing Integer/Boolean values to fail during execution state update.
Applying the same allowed-type conversion logic as the START_OBJECT branch
fixes the inconsistency and prevents cast errors.
2025-12-03 17:34:52 +01:00
brian.mulier
e869c54883 fix(ns-files): prevent ns files revision history failure & working restore
closes https://github.com/kestra-io/kestra-ee/issues/6022
2025-12-03 16:04:39 +01:00
YannC
32da15b2ea fix: missing tenant id for flow creation in AbstractSchedulerTest (#13311) 2025-12-03 15:58:52 +01:00
François Delbrayelle
a72ecfc2eb chore(icons): remove white backgrounds (#13362) 2025-12-03 15:27:24 +01:00
sarika
7cb494b244 refactor(core): remove usage of unnecessary i18n composable (#13366)
Closes https://github.com/kestra-io/kestra/issues/13224.

Co-authored-by: MilosPaunovic <paun992@hotmail.com>
2025-12-03 15:19:10 +01:00
128 changed files with 692 additions and 507 deletions

View File

@@ -223,13 +223,13 @@ subprojects {subProj ->
t.environment 'ENV_TEST2', "Pass by env"
if (subProj.name == 'core' || subProj.name == 'jdbc-h2' || subProj.name == 'jdbc-mysql' || subProj.name == 'jdbc-postgres') {
// JUnit 5 parallel settings
t.systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
t.systemProperty 'junit.jupiter.execution.parallel.mode.default', 'concurrent'
t.systemProperty 'junit.jupiter.execution.parallel.mode.classes.default', 'same_thread'
t.systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'dynamic'
}
// if (subProj.name == 'core' || subProj.name == 'jdbc-h2' || subProj.name == 'jdbc-mysql' || subProj.name == 'jdbc-postgres') {
// // JUnit 5 parallel settings
// t.systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
// t.systemProperty 'junit.jupiter.execution.parallel.mode.default', 'concurrent'
// t.systemProperty 'junit.jupiter.execution.parallel.mode.classes.default', 'same_thread'
// t.systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'dynamic'
// }
}
tasks.register('flakyTest', Test) { Test t ->

View File

@@ -24,6 +24,7 @@ import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static io.kestra.core.utils.Rethrow.throwConsumer;
import static io.kestra.core.utils.Rethrow.throwFunction;
@@ -36,11 +37,15 @@ public class MetadataMigrationService {
protected KvMetadataRepositoryInterface kvMetadataRepository;
protected NamespaceFileMetadataRepositoryInterface namespaceFileMetadataRepository;
protected StorageInterface storageInterface;
protected NamespaceUtils namespaceUtils;
@VisibleForTesting
public Map<String, List<String>> namespacesPerTenant() {
String tenantId = tenantService.resolveTenant();
return Map.of(tenantId, flowRepository.findDistinctNamespace(tenantId).stream().map(NamespaceUtils::asTree).flatMap(Collection::stream).distinct().toList());
return Map.of(tenantId, Stream.concat(
Stream.of(namespaceUtils.getSystemFlowNamespace()),
flowRepository.findDistinctNamespace(tenantId).stream()
).map(NamespaceUtils::asTree).flatMap(Collection::stream).distinct().toList());
}
public void kvMigration() throws IOException {

View File

@@ -57,7 +57,7 @@ public class StateStoreMigrateCommand extends AbstractCommand {
String taskRunValue = statesUriPart.length > 2 ? statesUriPart[1] : null;
String stateSubName = statesUriPart[statesUriPart.length - 1];
boolean flowScoped = flowQualifierWithStateQualifiers[0].endsWith("/" + flow.getId());
StateStore stateStore = new StateStore(runContext(runContextFactory, flow), false);
StateStore stateStore = new StateStore(runContextFactory.of(flow, Map.of()), false);
try (InputStream is = storageInterface.get(flow.getTenantId(), flow.getNamespace(), stateStoreFileUri)) {
stateStore.putState(flowScoped, stateName, stateSubName, taskRunValue, is.readAllBytes());
@@ -70,12 +70,4 @@ public class StateStoreMigrateCommand extends AbstractCommand {
stdOut("Successfully ran the state-store migration.");
return 0;
}
private RunContext runContext(RunContextFactory runContextFactory, Flow flow) {
Map<String, String> flowVariables = new HashMap<>();
flowVariables.put("tenantId", flow.getTenantId());
flowVariables.put("id", flow.getId());
flowVariables.put("namespace", flow.getNamespace());
return runContextFactory.of(flow, Map.of("flow", flowVariables));
}
}

View File

@@ -10,12 +10,15 @@ import org.mockito.Mockito;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
public class MetadataMigrationServiceTest<T extends MetadataMigrationService> {
private static final String TENANT_ID = TestsUtils.randomTenant();
protected static final String SYSTEM_NAMESPACE = "my.system.namespace";
@Test
void namespacesPerTenant() {
Map<String, List<String>> expected = getNamespacesPerTenant();
@@ -24,8 +27,13 @@ public class MetadataMigrationServiceTest<T extends MetadataMigrationService> {
).namespacesPerTenant();
assertThat(result).hasSize(expected.size());
expected.forEach((tenantId, namespaces) -> {;
assertThat(result.get(tenantId)).containsExactlyInAnyOrderElementsOf(namespaces.stream().map(NamespaceUtils::asTree).flatMap(Collection::stream).distinct().toList());
expected.forEach((tenantId, namespaces) -> {
assertThat(result.get(tenantId)).containsExactlyInAnyOrderElementsOf(
Stream.concat(
Stream.of(SYSTEM_NAMESPACE),
namespaces.stream()
).map(NamespaceUtils::asTree).flatMap(Collection::stream).distinct().toList()
);
});
}
@@ -36,12 +44,14 @@ public class MetadataMigrationServiceTest<T extends MetadataMigrationService> {
protected T metadataMigrationService(Map<String, List<String>> namespacesPerTenant) {
FlowRepositoryInterface mockedFlowRepository = Mockito.mock(FlowRepositoryInterface.class);
Mockito.doAnswer((params) -> namespacesPerTenant.get(params.getArgument(0).toString())).when(mockedFlowRepository).findDistinctNamespace(Mockito.anyString());
NamespaceUtils namespaceUtils = Mockito.mock(NamespaceUtils.class);
Mockito.when(namespaceUtils.getSystemFlowNamespace()).thenReturn(SYSTEM_NAMESPACE);
//noinspection unchecked
return ((T) new MetadataMigrationService(mockedFlowRepository, new TenantService() {
@Override
public String resolveTenant() {
return TENANT_ID;
}
}, null, null, null));
}, null, null, null, namespaceUtils));
}
}

View File

@@ -55,11 +55,7 @@ class StateStoreMigrateCommandTest {
);
assertThat(storage.exists(tenantId, flow.getNamespace(), oldStateStoreUri)).isTrue();
RunContext runContext = ctx.getBean(RunContextFactory.class).of(flow, Map.of("flow", Map.of(
"tenantId", tenantId,
"id", flow.getId(),
"namespace", flow.getNamespace()
)));
RunContext runContext = ctx.getBean(RunContextFactory.class).of(flow, Map.of());
StateStore stateStore = new StateStore(runContext, true);
Assertions.assertThrows(MigrationRequiredException.class, () -> stateStore.getState(true, "my-state", "sub-name", "my-taskrun-value"));

View File

@@ -171,14 +171,16 @@ public class RunContextFactory {
.build();
}
@VisibleForTesting
public RunContext of(final FlowInterface flow, final Map<String, Object> variables) {
RunContextLogger runContextLogger = new RunContextLogger();
return newBuilder()
.withLogger(runContextLogger)
.withStorage(new InternalStorage(runContextLogger.logger(), StorageContext.forFlow(flow), storageInterface, namespaceService, namespaceFactory))
.withVariables(variables)
.withVariables(newRunVariablesBuilder()
.withFlow(flow)
.withVariables(variables)
.build(runContextLogger, PropertyContext.create(this.variableRenderer))
)
.withSecretInputs(secretInputsFromFlow(flow))
.build();
}

View File

@@ -160,7 +160,7 @@ public class RunnerUtils {
executionEmitter.run();
if (duration == null) {
Await.untilWithSleepInterval(() -> receive.get() != null, Duration.ofMillis(10));
Await.until(() -> receive.get() != null, Duration.ofMillis(10));
} else {
Await.until(() -> receive.get() != null, Duration.ofMillis(10), duration);
}

View File

@@ -2,6 +2,7 @@ package io.kestra.core.runners.pebble;
import io.kestra.core.runners.VariableRenderer;
import io.kestra.core.runners.pebble.functions.RenderingFunctionInterface;
import io.micrometer.core.instrument.MeterRegistry;
import io.micronaut.context.ApplicationContext;
import io.micronaut.core.annotation.Nullable;
import io.pebbletemplates.pebble.PebbleEngine;
@@ -18,35 +19,37 @@ import java.util.stream.Collectors;
@Singleton
public class PebbleEngineFactory {
private final ApplicationContext applicationContext;
private final VariableRenderer.VariableConfiguration variableConfiguration;
private final MeterRegistry meterRegistry;
@Inject
public PebbleEngineFactory(ApplicationContext applicationContext, @Nullable VariableRenderer.VariableConfiguration variableConfiguration) {
public PebbleEngineFactory(ApplicationContext applicationContext, @Nullable VariableRenderer.VariableConfiguration variableConfiguration, MeterRegistry meterRegistry) {
this.applicationContext = applicationContext;
this.variableConfiguration = variableConfiguration;
this.meterRegistry = meterRegistry;
}
public PebbleEngine create() {
PebbleEngine.Builder builder = newPebbleEngineBuilder();
this.applicationContext.getBeansOfType(Extension.class).forEach(builder::extension);
return builder.build();
}
public PebbleEngine createWithMaskedFunctions(VariableRenderer renderer, final List<String> functionsToMask) {
PebbleEngine.Builder builder = newPebbleEngineBuilder();
this.applicationContext.getBeansOfType(Extension.class).stream()
.map(e -> functionsToMask.stream().anyMatch(fun -> e.getFunctions().containsKey(fun))
? extensionWithMaskedFunctions(renderer, e, functionsToMask)
: e)
.forEach(builder::extension);
return builder.build();
}
private PebbleEngine.Builder newPebbleEngineBuilder() {
PebbleEngine.Builder builder = new PebbleEngine.Builder()
.registerExtensionCustomizer(ExtensionCustomizer::new)
@@ -54,13 +57,15 @@ public class PebbleEngineFactory {
.cacheActive(this.variableConfiguration.getCacheEnabled())
.newLineTrimming(false)
.autoEscaping(false);
if (this.variableConfiguration.getCacheEnabled()) {
builder = builder.templateCache(new PebbleLruCache(this.variableConfiguration.getCacheSize()));
PebbleLruCache cache = new PebbleLruCache(this.variableConfiguration.getCacheSize());
cache.register(meterRegistry);
builder = builder.templateCache(cache);
}
return builder;
}
private Extension extensionWithMaskedFunctions(VariableRenderer renderer, Extension initialExtension, List<String> maskedFunctions) {
return (Extension) Proxy.newProxyInstance(
initialExtension.getClass().getClassLoader(),
@@ -74,16 +79,16 @@ public class PebbleEngineFactory {
} else if (RenderingFunctionInterface.class.isAssignableFrom(entry.getValue().getClass())) {
return Map.entry(entry.getKey(), this.variableRendererProxy(renderer, entry.getValue()));
}
return entry;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
return method.invoke(initialExtension, methodArgs);
}
);
}
private Function variableRendererProxy(VariableRenderer renderer, Function initialFunction) {
return (Function) Proxy.newProxyInstance(
initialFunction.getClass().getClassLoader(),
@@ -96,7 +101,7 @@ public class PebbleEngineFactory {
}
);
}
private Function maskedFunctionProxy(Function initialFunction) {
return (Function) Proxy.newProxyInstance(
initialFunction.getClass().getClassLoader(),

View File

@@ -1,29 +1,29 @@
package io.kestra.core.runners.pebble;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics;
import io.pebbletemplates.pebble.cache.PebbleCache;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
@Slf4j
public class PebbleLruCache implements PebbleCache<Object, PebbleTemplate> {
Cache<Object, PebbleTemplate> cache;
private final Cache<Object, PebbleTemplate> cache;
public PebbleLruCache(int maximumSize) {
cache = CacheBuilder.newBuilder()
cache = Caffeine.newBuilder()
.initialCapacity(250)
.maximumSize(maximumSize)
.recordStats()
.build();
}
@Override
public PebbleTemplate computeIfAbsent(Object key, Function<? super Object, ? extends PebbleTemplate> mappingFunction) {
try {
return cache.get(key, () -> mappingFunction.apply(key));
return cache.get(key, mappingFunction);
} catch (Exception e) {
// we retry the mapping function in order to let the exception be thrown instead of being capture by cache
return mappingFunction.apply(key);
@@ -34,4 +34,8 @@ public class PebbleLruCache implements PebbleCache<Object, PebbleTemplate> {
public void invalidateAll() {
cache.invalidateAll();
}
public void register(MeterRegistry meterRegistry) {
CaffeineCacheMetrics.monitor(meterRegistry, cache, "pebble-template");
}
}

View File

@@ -26,7 +26,14 @@ public class ListOrMapOfLabelDeserializer extends JsonDeserializer<List<Label>>
else if (p.hasToken(JsonToken.START_ARRAY)) {
// deserialize as list
List<Map<String, String>> ret = ctxt.readValue(p, List.class);
return ret.stream().map(map -> new Label(map.get("key"), map.get("value"))).toList();
return ret.stream().map(map -> {
Object value = map.get("value");
if (isAllowedType(value)) {
return new Label(map.get("key"), String.valueOf(value));
} else {
throw new IllegalArgumentException("Unsupported type for key: " + map.get("key") + ", value: " + value);
}
}).toList();
}
else if (p.hasToken(JsonToken.START_OBJECT)) {
// deserialize as map

View File

@@ -6,18 +6,18 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
/**
* @deprecated use {@link org.awaitility.Awaitility} instead
*/
@Deprecated
public class Await {
private static final Duration defaultSleep = Duration.ofMillis(100);
public static void until(BooleanSupplier condition) {
Await.untilWithSleepInterval(condition, null);
Await.until(condition, null);
}
public static void untilWithTimeout(BooleanSupplier condition, Duration timeout) throws TimeoutException {
until(condition, null, timeout);
}
public static void untilWithSleepInterval(BooleanSupplier condition, Duration sleep) {
public static void until(BooleanSupplier condition, Duration sleep) {
if (sleep == null) {
sleep = defaultSleep;
}
@@ -78,10 +78,10 @@ public class Await {
return result.get();
}
public static <T> T untilWithSleepInterval(Supplier<T> supplier, Duration sleep) {
public static <T> T until(Supplier<T> supplier, Duration sleep) {
AtomicReference<T> result = new AtomicReference<>();
Await.untilWithSleepInterval(untilSupplier(supplier, result), sleep);
Await.until(untilSupplier(supplier, result), sleep);
return result.get();
}

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-288 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-288 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-624 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-736 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-848 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-400 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-512 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-624 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-736 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-848 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-960 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1072 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1184 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-400 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-512 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1520 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1632 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1744 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1296 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1408 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1520 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1632 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1744 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-176 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1408 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1296 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1520 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1408 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1632 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1744 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-288 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-176 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-400 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-624 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1184 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-512 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-736 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-848 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-960 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1072 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -466)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-176 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-288 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1408 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1520 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1632 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1744 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-960 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1072 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1184 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1296 -606)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-400 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-736 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-848 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-960 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1072 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-624 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-512 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1296 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1184 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1408 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1520 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1632 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1744 -746)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-176 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-288 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-512 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-624 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-400 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-736 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-848 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-960 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1072 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1184 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-1296 -886)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,7 +1,7 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" fill="#F2F2F2"/>
<g filter="url(#filter0_ii_0_1)">
<rect width="1936" height="1336" transform="translate(-64 -326)" fill="white"/>
<g filter="url(#filter1_i_0_1)">
<path d="M0 20C0 8.95431 8.95431 0 20 0H60C71.0457 0 80 8.95431 80 20V60C80 71.0457 71.0457 80 60 80H20C8.95431 80 0 71.0457 0 60V20Z" fill="url(#paint0_linear_0_1)"/>
</g>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -1,6 +1,7 @@
package io.kestra.core.models.triggers;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.runners.RunContextFactory;
import jakarta.inject.Inject;
@@ -22,21 +23,15 @@ class StatefulTriggerInterfaceTest {
RunContextFactory runContextFactory;
@Test
void shouldPersistAndReadState() throws Exception {
void shouldPersistAndReadState() {
var flow = Flow.builder()
.tenantId("main")
.namespace("io.kestra.unittest")
.id("test-flow")
.revision(1)
.build();
var runContext = runContextFactory.of(flow, Map.of(
"flow", Map.of(
"tenantId", "main",
"namespace", "io.kestra.unittest",
"id", "test-flow",
"revision", 1
)
));
var runContext = runContextFactory.of(flow, Map.of());
var key = defaultKey("ns", "test-flow", "trigger-persist");
var ttl = Optional.of(Duration.ofMinutes(5));
@@ -59,21 +54,15 @@ class StatefulTriggerInterfaceTest {
}
@Test
void shouldExpireOldEntriesAfterTTL() throws Exception {
void shouldExpireOldEntriesAfterTTL() {
var flow = Flow.builder()
.tenantId("main")
.namespace("io.kestra.unittest")
.id("test-flow")
.revision(1)
.build();
var runContext = runContextFactory.of(flow, Map.of(
"flow", Map.of(
"tenantId", "main",
"namespace", "io.kestra.unittest",
"id", "test-flow",
"revision", 1
)
));
var runContext = runContextFactory.of(flow, Map.of());
var key = defaultKey("ns", "test-flow", "trigger-ttl");
var ttl = Optional.of(Duration.ofMinutes(5));

View File

@@ -32,6 +32,8 @@ import io.kestra.plugin.core.dashboard.data.Executions;
import io.kestra.plugin.core.debug.Return;
import io.micronaut.data.model.Pageable;
import io.micronaut.data.model.Sort;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -46,6 +48,7 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -648,7 +651,8 @@ public abstract class AbstractExecutionRepositoryTest {
);
assertThat(data.getTotal()).isEqualTo(1L);
assertThat(data).first().hasFieldOrPropertyWithValue("count", 1);
assertThat(data).first().hasFieldOrProperty("count");
assertThat(data).first().extracting("count").hasToString("1");
assertThat(data).first().hasFieldOrPropertyWithValue("id", execution.getId());
}
@@ -831,12 +835,7 @@ inject(tenant);
)
)
).build();
try {
var res= JacksonMapper.ofJson().writeValueAsString(successExecution);
System.out.println(res);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
assertThat(successExecution.getState().getDuration().get()).isCloseTo(Duration.ofSeconds(20), Duration.ofMillis(3));
executionRepository.save(successExecution);
@@ -888,7 +887,7 @@ inject(tenant);
// when
List<QueryFilter> emptyFilters = null;
var sort = Sort.of(Sort.Order.asc("state_duration"));
var sort = createSortLikeInControllers(List.of("state.duration:asc"), executionRepository.sortMapping());
var sortedByShortestDuration = executionRepository.find(Pageable.from(sort), tenant, emptyFilters);
// then
@@ -916,7 +915,7 @@ inject(tenant);
// when
List<QueryFilter> emptyFilters = null;
var sort = Sort.of(Sort.Order.desc("state_duration"));
var sort = createSortLikeInControllers(List.of("state.duration:desc"), executionRepository.sortMapping());
var sortedByLongestDuration = executionRepository.find(Pageable.from(sort), tenant, emptyFilters);
// then
@@ -945,7 +944,7 @@ inject(tenant);
// when
List<QueryFilter> emptyFilters = null;
var sort = Sort.of(Sort.Order.asc("start_date"));
var sort = createSortLikeInControllers(List.of("state.startDate:asc"), executionRepository.sortMapping());
var page = Pageable.from(1, 1, sort);
var findByMoreRecentStartDate = executionRepository.find(
page,
@@ -968,7 +967,7 @@ inject(tenant);
// when
List<QueryFilter> emptyFilters = null;
var sort = Sort.of(Sort.Order.desc("start_date"));
var sort = createSortLikeInControllers(List.of("state.startDate:desc"), executionRepository.sortMapping());
var page = Pageable.from(1, 1, sort);
var findByMoreRecentStartDate = executionRepository.find(
page,
@@ -983,6 +982,28 @@ inject(tenant);
.containsExactly(testData.failedExecution().getId());
}
// duplicated from PageableUtils, because mapping is different between PG and ES
private Sort createSortLikeInControllers(List<String> sort, Function<String, String> sortMapper) {
return sort == null ? null :
Sort.of(sort
.stream()
.map(s -> {
String[] split = s.split(":");
if (split.length != 2) {
throw new HttpStatusException(HttpStatus.UNPROCESSABLE_ENTITY, "Invalid sort parameter");
}
String col = split[0];
if (sortMapper != null) {
col = sortMapper.apply(col);
}
return split[1].equals("asc") ? Sort.Order.asc(col) : Sort.Order.desc(col);
})
.toList()
);
}
@Test
protected void shouldReturnLastExecutionsWhenInputsAreNull() {
var tenant = TestsUtils.randomTenant(this.getClass().getSimpleName());

View File

@@ -21,6 +21,7 @@ import io.kestra.core.storages.kv.KVStore;
import io.kestra.core.storages.kv.KVValue;
import io.kestra.core.tenant.TenantService;
import io.kestra.core.utils.IdUtils;
import io.micrometer.core.instrument.MeterRegistry;
import io.micronaut.context.ApplicationContext;
import io.micronaut.test.annotation.MockBean;
import jakarta.inject.Inject;
@@ -37,16 +38,16 @@ import static org.assertj.core.api.Assertions.assertThat;
@KestraTest
class RunVariablesTest {
@Inject
VariableRenderer renderer;
@Inject
StorageInterface storageInterface;
@Inject
KvMetadataRepositoryInterface kvMetadataRepository;
@MockBean(KVStoreService.class)
KVStoreService testKVStoreService() {
return new KVStoreService() {
@@ -61,7 +62,7 @@ class RunVariablesTest {
}
};
}
@Test
@SuppressWarnings("unchecked")
void shouldGetEmptyVariables() {
@@ -163,6 +164,7 @@ class RunVariablesTest {
void nonResolvableDynamicInputsShouldBeSkipped() {
VariableRenderer.VariableConfiguration mkVariableConfiguration = Mockito.mock(VariableRenderer.VariableConfiguration.class);
ApplicationContext mkApplicationContext = Mockito.mock(ApplicationContext.class);
MeterRegistry mkMeterRegistry = Mockito.mock(MeterRegistry.class);
Map<String, Object> variables = new RunVariables.DefaultBuilder()
.withFlow(Flow
.builder()
@@ -175,13 +177,13 @@ class RunVariablesTest {
.build()
)
.withExecution(Execution.builder().id(IdUtils.create()).build())
.build(new RunContextLogger(), PropertyContext.create(new VariableRenderer(new PebbleEngineFactory(mkApplicationContext, mkVariableConfiguration), mkVariableConfiguration)));
.build(new RunContextLogger(), PropertyContext.create(new VariableRenderer(new PebbleEngineFactory(mkApplicationContext, mkVariableConfiguration, mkMeterRegistry), mkVariableConfiguration)));
Assertions.assertEquals(Map.of(
"a", true
), variables.get("inputs"));
}
@Test
void shouldBuildVariablesGivenFlowWithInputHavingDefaultPebbleExpression() {
FlowInterface flow = GenericFlow.fromYaml(TenantService.MAIN_TENANT, """
@@ -192,12 +194,12 @@ class RunVariablesTest {
type: STRING
defaults: "{{ kv('???') }}"
""");
Map<String, Object> variables = new RunVariables.DefaultBuilder()
.withFlow(flow)
.withExecution(Execution.builder().id(IdUtils.create()).build())
.build(new RunContextLogger(), PropertyContext.create(renderer));
assertThat(variables.get("inputs")).isEqualTo(Map.of("input", "value"));
}
}

View File

@@ -3,6 +3,7 @@ package io.kestra.core.serializers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.models.flows.Input;
import io.kestra.core.models.flows.Type;
import io.kestra.core.models.flows.input.StringInput;
@@ -32,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
@KestraTest
class YamlParserTest {
private static final ObjectMapper MAPPER = JacksonMapper.ofJson();
private static final ObjectMapper OBJECT_MAPPER = JacksonMapper.ofYaml().copy();
@Inject
private ModelValidator modelValidator;
@@ -235,6 +237,29 @@ class YamlParserTest {
assertThat(new ArrayList<>(exception.getConstraintViolations()).getFirst().getMessage()).contains("Duplicate field 'variables.tf'");
}
@Test
void vaildLabelsParser() throws IOException {
Flow flow = parse("flows/valids/labels-deserialization.yaml");
// like change execution state api,Serialize flow to YAML/JSON string
String s = OBJECT_MAPPER.writeValueAsString(flow);
assertThat(s).isEqualTo("id: labels-deserialization\n" +
"namespace: io.kestra.tests\n" +
"disabled: false\n" +
"deleted: false\n" +
"labels:\n" +
"- key: key1\n" +
" value: 123\n" +
"tasks:\n" +
"- id: t1\n" +
" type: io.kestra.plugin.core.log.Log\n" +
" message: \"{{ task.id }}\"\n");
Map<String, Object> mapFlow = OBJECT_MAPPER.readValue(s, JacksonMapper.MAP_TYPE_REFERENCE);
// Parse into FlowWithSource (simulates state update scenario)
FlowWithSource parse = YamlParser.parse(mapFlow, FlowWithSource.class, false);
assertThat(parse.getLabels().size()).isEqualTo(1);;
}
private Flow parse(String path) {
URL resource = TestsUtils.class.getClassLoader().getResource(path);
assert resource != null;

View File

@@ -1,7 +1,6 @@
package io.kestra.core.services;
import io.kestra.core.exceptions.FlowProcessingException;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.FlowInterface;
@@ -25,7 +24,6 @@ import java.util.Optional;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -519,4 +517,21 @@ class FlowServiceTest {
c.getBehavior() == Check.Behavior.BLOCK_EXECUTION &&
c.getStyle() == Check.Style.ERROR);
}
@Test
void shouldAcceptExpressionWithFlowWhenRenderingChecks() {
// Given
Check passCheck = Check.builder().condition("{{ flow.id == 'test' }}").message("pass").build();
Flow flow = mock(Flow.class);
when(flow.getChecks()).thenReturn(List.of(passCheck));
when(flow.getNamespace()).thenReturn("io.kestra.unittest");
when(flow.getId()).thenReturn("test");
// When
List<Check> result = flowService.getFailedChecks(flow, Map.of());
// Then
assertThat(result).isEmpty();
}
}

View File

@@ -0,0 +1,17 @@
id: labels-deserialization
namespace: io.kestra.tests
labels:
key1: 123
#triggers:
#- type: schedule
# expression: 42 4 1 * *
# backfill:
# start: 2018-01-01
# depend-on-past: false
#
tasks:
- id: t1
type: io.kestra.plugin.core.log.Log
message: "{{ task.id }}"

View File

@@ -1,28 +0,0 @@
configurations {
implementation.extendsFrom(micronaut)
}
dependencies {
testImplementation project(':tests')
testImplementation("com.microsoft.playwright:playwright")
}
/**********************************************************************************************************************\
* ./gradlew playwright
**********************************************************************************************************************/
tasks.register('playwright', JavaExec) {
classpath sourceSets.test.runtimeClasspath
mainClass = 'com.microsoft.playwright.CLI'
}
/**********************************************************************************************************************\
* Test
**********************************************************************************************************************/
test {
useJUnitPlatform {
if (project.hasProperty('tags')) {
includeTags project.getProperty('tags').split(',')
}
// Setting the number of parallel forks
maxParallelForks = Runtime.runtime.availableProcessors()
}
}

View File

@@ -1135,11 +1135,18 @@ public class JdbcExecutor implements ExecutorInterface {
// We need to detect that and reset them as they will never reach the reset code later on this method.
if (execution.getTrigger() != null && execution.getState().isFailed() && ListUtils.isEmpty(execution.getTaskRunList())) {
FlowWithSource flow = executor.getFlow();
triggerRepository
.findByExecution(execution)
.ifPresent(trigger -> {
this.triggerState.update(executionService.resetExecution(flow, execution, trigger));
});
if (flow == null) {
log.error("Couldn't reset trigger for execution {} as flow {} is missing. Trigger {} might stay stuck.",
execution.getId(),
execution.getTenantId() + "/" + execution.getNamespace() + "/" + execution.getFlowId(),
execution.getTrigger().getId()
);
} else {
triggerRepository
.findByExecution(execution)
.ifPresent(trigger -> this.triggerState.update(executionService.resetExecution(flow, execution, trigger)));
}
}
return;

View File

@@ -36,6 +36,8 @@ import java.util.Optional;
@KestraTest(rebuildContext = true)
abstract public class AbstractSchedulerTest {
public final static String TENANT_ID = "main";
@Inject
protected ApplicationContext applicationContext;
@@ -74,7 +76,7 @@ abstract public class AbstractSchedulerTest {
*/
@Deprecated
protected static FlowWithSource createFlow(List<AbstractTrigger> triggers) {
return createFlow(null, triggers);
return createFlow(TENANT_ID, triggers);
}
protected static FlowWithSource createFlow(String tenantId, List<AbstractTrigger> triggers) {

Some files were not shown because too many files have changed in this diff Show More