@effekt-lang/effekt 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/effekt CHANGED
Binary file
@@ -70,7 +70,7 @@
70
70
  (cond
71
71
  ; Same object reference (fast path)
72
72
  [(eq? obj1 obj2) #t]
73
-
73
+
74
74
  ; If both are records, compare them structurally
75
75
  [(and (record? obj1) (record? obj2))
76
76
  (let* ([rtd1 (record-rtd obj1)]
@@ -87,7 +87,7 @@
87
87
  (if (not (equal_impl field1 field2))
88
88
  (set! result #f)))))
89
89
  #f))]
90
-
90
+
91
91
  ; For lists, compare elements recursively
92
92
  [(and (list? obj1) (list? obj2))
93
93
  (and (= (length obj1) (length obj2))
@@ -95,7 +95,7 @@
95
95
  (or (null? l1)
96
96
  (and (equal_impl (car l1) (car l2))
97
97
  (loop (cdr l1) (cdr l2))))))]
98
-
98
+
99
99
  ; For all other types, use Scheme's built-in equal?
100
100
  [else (equal? obj1 obj2)]))
101
101
 
@@ -134,4 +134,10 @@
134
134
  (raise
135
135
  (condition
136
136
  (make-error)
137
- (make-message-condition (string-append pos " not implemented yet" )))))
137
+ (make-message-condition (string-append pos " not implemented yet" )))))
138
+
139
+ (define (unreachable)
140
+ (raise
141
+ (condition
142
+ (make-error)
143
+ (make-message-condition ("should not be reachable!")))))
@@ -0,0 +1,133 @@
1
+ module dictionary
2
+
3
+ import array
4
+ import bytearray
5
+ import stream
6
+
7
+
8
+ /// A trie-based dictionary for efficient key-value storage with bytearray keys.
9
+ /// Supports String and ByteArray keys with fast lookup and insertion.
10
+ type Dictionary[A] {
11
+ Empty()
12
+ Leaf(value: A)
13
+ Branch(children: Array[Dictionary[A]])
14
+ Node(value: A, children: Array[Dictionary[A]])
15
+ }
16
+
17
+ /// Insert a value with a String key.
18
+ def insert[A](trie: Dictionary[A], key: String, value: A): Dictionary[A] =
19
+ insert(trie, key.fromString, value)
20
+
21
+ /// Insert a key-value pair into the dictionary with a ByteArray key.
22
+ def insert[A](trie: Dictionary[A], key: ByteArray, value: A): Dictionary[A] = {
23
+ def go(trie: Dictionary[A], i: Int): Dictionary[A] =
24
+ if (i < key.size) {
25
+ trie match {
26
+ case Empty() =>
27
+ val child = go(Empty(), i + 1)
28
+ val children = array(256, Empty())
29
+ children.unsafeSet(key.unsafeGet(i).toInt, child)
30
+ Branch(children)
31
+ case Leaf(existing) =>
32
+ val child = go(Empty(), i + 1)
33
+ val children = array(256, Empty())
34
+ children.unsafeSet(key.unsafeGet(i).toInt, child)
35
+ Node(existing, children)
36
+ case Branch(children) =>
37
+ val child = go(children.unsafeGet(key.unsafeGet(i).toInt), i + 1)
38
+ children.unsafeSet(key.unsafeGet(i).toInt, child)
39
+ Branch(children)
40
+ case Node(existing, children) =>
41
+ val child = go(children.unsafeGet(key.unsafeGet(i).toInt), i + 1)
42
+ children.unsafeSet(key.unsafeGet(i).toInt, child)
43
+ Node(existing, children)
44
+ }
45
+ } else {
46
+ trie match {
47
+ case Empty() => Leaf(value)
48
+ case Leaf(_) => Leaf(value)
49
+ case Node(_, children) => Node(value, children)
50
+ case Branch(children) => Node(value, children)
51
+ }
52
+ }
53
+ go(trie, 0)
54
+ }
55
+
56
+ /// Look up a value in the dictionary by string key.
57
+ def lookup[A](trie: Dictionary[A], key: String): Option[A] =
58
+ lookup(trie, key.fromString)
59
+
60
+ /// Look up a value in the dictionary by bytearray key.
61
+ def lookup[A](trie: Dictionary[A], key: ByteArray): Option[A] = {
62
+ def go(trie: Dictionary[A], i: Int): Option[A] =
63
+ if (i < key.size) {
64
+ trie match {
65
+ case Empty() => None()
66
+ case Leaf(_) => None()
67
+ case Branch(children) => go(children.unsafeGet(key.unsafeGet(i).toInt), i + 1)
68
+ case Node(_, children) => go(children.unsafeGet(key.unsafeGet(i).toInt), i + 1)
69
+ }
70
+ } else {
71
+ trie match {
72
+ case Empty() => None()
73
+ case Leaf(value) => Some(value)
74
+ case Branch(_) => None()
75
+ case Node(value, _) => Some(value)
76
+ }
77
+ }
78
+ go(trie, 0)
79
+ }
80
+
81
+ /// A record pairing a key with a value for use in streams.
82
+ record Tagged[A](key: ByteArray, value: A)
83
+
84
+ /// Collect key-value pairs from a stream of Tagged elements into a Dictionary.
85
+ def collect[A] { stream: () => Unit / emit[Tagged[A]] }: Dictionary[A] = {
86
+ var trie = Empty()
87
+ for[Tagged[A]] { stream() } { case Tagged(bytes, value) =>
88
+ trie = trie.insert(bytes, value)
89
+ }
90
+ return trie
91
+ }
92
+
93
+ /// Emit all values stored in the dictionary as a push stream.
94
+ def each[A](trie: Dictionary[A]): Unit / emit[A] =
95
+ trie match {
96
+ case Empty() => ()
97
+ case Leaf(value) => do emit(value)
98
+ case Branch(children) =>
99
+ each(0, children.size) { i =>
100
+ each(children.unsafeGet(i))
101
+ }
102
+ case Node(value, children) =>
103
+ do emit(value)
104
+ each(0, children.size) { i =>
105
+ each(children.unsafeGet(i))
106
+ }
107
+ }
108
+
109
+ /// Emit all key-value pairs stored in the dictionary as a push stream of Tagged elements.
110
+ def eachTagged[A](trie: Dictionary[A]): Unit / emit[Tagged[A]] = {
111
+ def fromBytesReverse(bytes: List[Byte], n: Int): ByteArray = {
112
+ val key = bytearray::allocate(n)
113
+ foreachIndex(bytes) { (i, b) => key.unsafeSet(n - 1 - i, b) }
114
+ key
115
+ }
116
+ def go(trie: Dictionary[A], key: List[Byte], n: Int): Unit =
117
+ trie match {
118
+ case Empty() => ()
119
+ case Leaf(value) => do emit(Tagged(fromBytesReverse(key, n), value))
120
+ case Branch(children) =>
121
+ each(0, children.size) { i =>
122
+ go(children.unsafeGet(i), Cons(i.toByte, key), n + 1)
123
+ }
124
+ case Node(value, children) =>
125
+ do emit(Tagged(fromBytesReverse(key, n), value))
126
+ each(0, children.size) { i =>
127
+ go(children.unsafeGet(i), Cons(i.toByte, key), n + 1)
128
+ }
129
+ }
130
+ go(trie, Nil(), 0)
131
+ }
132
+
133
+
@@ -25,12 +25,12 @@ def handleJsonBuilder[R]{b: JsonBuilder}{ body: => R / JsonBuilder }: R = try bo
25
25
  def bool(v) = resume(b.bool(v))
26
26
  def number(n) = resume(b.number(n))
27
27
  def string(s) = resume(b.string(s))
28
- def list() = resume { {c} => b.list{c} }
29
- def dict() = resume { {c} => b.dict{c} }
28
+ def list[T]() = resume { {c} => b.list{c} }
29
+ def dict[T]() = resume { {c} => b.dict{c} }
30
30
  }
31
31
  /// Make explicitly bound JsonObjectBuilder instance implicit
32
32
  def handleJsonObjectBuilder[R]{b: JsonObjectBuilder}{ body: => R / JsonObjectBuilder }: R = try body() with JsonObjectBuilder {
33
- def field(k) = resume { {c} => b.field(k){c} }
33
+ def field[T](k) = resume { {c} => b.field(k){c} }
34
34
  }
35
35
 
36
36
  // --------------------------------------------------------------------------------
@@ -49,8 +49,8 @@ def encodeJsonList[R]{ body: => R / JsonBuilder }: R / emit[String] = {
49
49
  def bool(v) = { c(); resume(do bool(v)) }
50
50
  def number(n) = { c(); resume(do number(n)) }
51
51
  def string(s) = { c(); resume(do string(s)) }
52
- def list() = resume { { b } => c(); do list{b} }
53
- def dict() = resume { { b } => c(); do dict{b} }
52
+ def list[T]() = resume { { b } => c(); do list{b} }
53
+ def dict[T]() = resume { { b } => c(); do dict{b} }
54
54
  }
55
55
  }
56
56
  do emit("]")
@@ -66,7 +66,7 @@ def encodeJsonObject[R]{ body: => R / JsonObjectBuilder }: R / emit[String] = {
66
66
  }
67
67
  val r = encodeJson {
68
68
  try body() with JsonObjectBuilder {
69
- def field(k) = resume { {b} => c(k); b() }
69
+ def field[T](k) = resume { {b} => c(k); b() }
70
70
  }
71
71
  }
72
72
  do emit("}")
@@ -80,8 +80,8 @@ def encodeJson[R]{ body: => R / JsonBuilder }: R / emit[String] = {
80
80
  def bool(v) = { resume(do emit( if(v){ "true" } else { "false" } )) }
81
81
  def number(n) = { resume(do emit(show(n))) }
82
82
  def string(s) = { resume(do emit(escape(s))) }
83
- def list() = resume { {b} => encodeJsonList { b() } }
84
- def dict() = resume { {b} => encodeJsonObject { b() } }
83
+ def list[T]() = resume { {b} => encodeJsonList { b() } }
84
+ def dict[T]() = resume { {b} => encodeJsonObject { b() } }
85
85
  }
86
86
  }
87
87
 
@@ -209,7 +209,7 @@ def decodeJsonList(): Unit / {Scan[Char], JsonBuilder, Exception[WrongFormat]} =
209
209
  // --------------------------------------------------------------------------------
210
210
  /// Ignore the generated calls to JsonObjectBuilder
211
211
  def ignoreDict[R](){ body: => R / JsonObjectBuilder }: R = try body() with JsonObjectBuilder {
212
- def field(k) = resume { {v} => ignore{v} }
212
+ def field[T](k) = resume { {v} => ignore{v} }
213
213
  }
214
214
 
215
215
  /// Ignore the generated calls to JsonBuilder
@@ -218,8 +218,8 @@ def ignore[R](){ body: => R / JsonBuilder }: R = try body() with JsonBuilder {
218
218
  def bool(b) = resume(())
219
219
  def null() = resume(())
220
220
  def string(s) = resume(())
221
- def list() = resume { {e} => ignore{e} }
222
- def dict() = resume { {e} => ignoreDict{e} }
221
+ def list[T]() = resume { {e} => ignore{e} }
222
+ def dict[T]() = resume { {e} => ignoreDict{e} }
223
223
  }
224
224
 
225
225
  // --------------------------------------------------------------------------------
@@ -264,12 +264,12 @@ def build[R](){ body: => R / JsonBuilder }: (R, JsonValue) = {
264
264
  def bool(b) = { r = Bool(b); resume(()) }
265
265
  def null() = { r = Null(); resume(()) }
266
266
  def string(s) = { r = String(s); resume(()) }
267
- def list() = resume { {els} =>
267
+ def list[T]() = resume { {els} =>
268
268
  val x = buildList {els}
269
269
  r = List(x.second)
270
270
  x.first
271
271
  }
272
- def dict() = resume { {fs} =>
272
+ def dict[T]() = resume { {fs} =>
273
273
  val x = buildDict {fs}
274
274
  r = Dict(x.second)
275
275
  x.first
@@ -283,12 +283,12 @@ def buildList[R](){ body: => R / JsonBuilder }: (R, List[JsonValue]) = list::ret
283
283
  def bool(b) = { do emit(Bool(b)); resume(()) }
284
284
  def null() = { do emit(Null()); resume(()) }
285
285
  def string(s) = { do emit(String(s)); resume(()) }
286
- def list() = resume { {els} =>
286
+ def list[T]() = resume { {els} =>
287
287
  val x = buildList {els}
288
288
  do emit(List(x.second))
289
289
  x.first
290
290
  }
291
- def dict() = resume { {fs} =>
291
+ def dict[T]() = resume { {fs} =>
292
292
  val x = buildDict {fs}
293
293
  do emit(Dict(x.second))
294
294
  x.first
@@ -297,7 +297,7 @@ def buildList[R](){ body: => R / JsonBuilder }: (R, List[JsonValue]) = list::ret
297
297
  }
298
298
  def buildDict[R](){ body: => R / JsonObjectBuilder }: (R, List[(String, JsonValue)]) = list::returning::collect[(String, JsonValue), R] {
299
299
  try body() with JsonObjectBuilder {
300
- def field(k) = resume { {v} =>
300
+ def field[T](k) = resume { {v} =>
301
301
  val x = build{v}
302
302
  do emit((k, x.second))
303
303
  x.first
@@ -325,7 +325,7 @@ namespace test {
325
325
  with scanner[Char]
326
326
 
327
327
  def k = new JsonObjectBuilder {
328
- def field(k){v} = { println(k); ignore{v} }
328
+ def field[T](k){v} = { println(k); ignore{v} }
329
329
  }
330
330
  def jsonBuilder[R] {e: => R / JsonBuilder}: R = {
331
331
  def d = new JsonBuilder {
@@ -333,8 +333,8 @@ namespace test {
333
333
  def bool(b) = ()
334
334
  def null() = println("NULL")
335
335
  def string(s) = ()
336
- def list(){e} = jsonBuilder{e}
337
- def dict(){e} = handleJsonObjectBuilder{k}{e}
336
+ def list[T](){e} = jsonBuilder{e}
337
+ def dict[T](){e} = handleJsonObjectBuilder{k}{e}
338
338
  }
339
339
  handleJsonBuilder{d}{e}
340
340
  }
@@ -37,7 +37,7 @@ def foreach[A](self: Option[A]) { f: A => Unit }: Unit = self match {
37
37
  }
38
38
 
39
39
  def value[A](self: Option[A]): A / Exception[MissingValue] = self match {
40
- case None() => do raise(MissingValue(), "Trying to get the value of an empty option")
40
+ case None() => do raise(MissingValue(), "Trying to get the value of an empty option") match {}
41
41
  case Some(v) => v
42
42
  }
43
43
 
@@ -170,7 +170,7 @@ def main() = {
170
170
  val b = randomInt(0, 9)
171
171
  val c = randomInt(0, 9)
172
172
  println(a.show ++ " " ++ b.show ++ " " ++ c.show)
173
- println(a*100 + b*10 + c)
173
+ println(a * 100 + b * 10 + c)
174
174
  }
175
175
  }
176
176
 
@@ -15,9 +15,9 @@ namespace internal {
15
15
  def parent(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
16
16
  with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ s.show) }
17
17
  val c = u.rawElements.get(s)
18
- if (c < 0) {
19
- do raise(MissingValue(), "Root node " ++ s.show ++ " has no parent.")
20
- } else {
18
+ if (c < 0) {
19
+ do raise(MissingValue(), "Root node " ++ s.show ++ " has no parent.")
20
+ } else {
21
21
  c
22
22
  }
23
23
  }
@@ -31,11 +31,11 @@ namespace internal {
31
31
  }
32
32
  }
33
33
  def setParent(u: UnionFind, child: Int, parent: Int) = {
34
- with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ child.show) }
34
+ with default[OutOfBounds, Unit] { do raise(MissingValue(), "No node " ++ child.show) }
35
35
  u.rawElements.set(child, parent)
36
36
  }
37
37
  def setRank(u: UnionFind, root: Int, rank: Int) = {
38
- with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ root.show) }
38
+ with default[OutOfBounds, Unit] { do raise(MissingValue(), "No node " ++ root.show) }
39
39
  u.rawElements.set(root, -1 * rank - 1)
40
40
  }
41
41
  }
@@ -66,7 +66,7 @@ def find(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
66
66
  }
67
67
  val root = goFind(s)
68
68
 
69
- def goCompress(s: Int): Unit = {
69
+ def goCompress(s: Int): Unit = {
70
70
  if (not(u.internal::isRoot(s))) {
71
71
  val p = u.internal::parent(s)
72
72
  u.internal::setParent(s, root)
@@ -82,7 +82,7 @@ def find(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
82
82
  ///
83
83
  /// O(1)
84
84
  def unionRoots(u: UnionFind, x: Int, y: Int): Int / Exception[MissingValue] = {
85
- if(not(u.internal::isRoot(x) && u.internal::isRoot(y))) {
85
+ if(not(u.internal::isRoot(x) && u.internal::isRoot(y))) {
86
86
  panic("unionRoots should only be called on representatives")
87
87
  }
88
88
 
@@ -56,6 +56,6 @@ $effekt.println = function println$impl(str) {
56
56
 
57
57
  $effekt.unit = { __unit: true }
58
58
 
59
- $effekt.emptyMatch = function() { throw "empty match" }
59
+ $effekt.unreachable = function() { throw "should not be reachable!" }
60
60
 
61
61
  $effekt.hole = function(pos) { throw pos + " not implemented yet" }
@@ -7,8 +7,8 @@ declare void @c_io_println(%Pos)
7
7
  declare %Pos @c_io_readln()
8
8
  declare %Double @c_io_random()
9
9
 
10
- declare void @hole(i8*)
11
- declare void @duplicated_prompt()
10
+ declare void @hole(i8*) cold
11
+ declare void @duplicated_prompt() cold
12
12
 
13
13
  declare %Pos @c_ref_fresh(%Pos)
14
14
  declare %Pos @c_ref_get(%Pos)
@@ -143,8 +143,8 @@ void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position,
143
143
  if (result < 0) {
144
144
  uv_fs_req_cleanup(request);
145
145
  free(request);
146
+ free(read_closure);
146
147
  resume_Int(stack, result);
147
- free(read_closure);
148
148
  }
149
149
  }
150
150
 
@@ -166,8 +166,8 @@ void c_fs_write(Int file, struct Pos buffer, Int offset, Int size, Int position,
166
166
  if (result < 0) {
167
167
  uv_fs_req_cleanup(request);
168
168
  free(request);
169
+ free(write_closure);
169
170
  resume_Int(stack, result);
170
- free(write_closure);
171
171
  }
172
172
  }
173
173
 
@@ -7,11 +7,13 @@
7
7
  // this should _morally_ be using `stderr`, but we don't tee it in tests
8
8
  // see PR #823 & issue #815 for context
9
9
 
10
+ __attribute__((cold))
10
11
  void hole(const char* message) {
11
12
  printf("PANIC: %s not implemented yet\n", message);
12
13
  exit(1);
13
14
  }
14
15
 
16
+ __attribute__((cold))
15
17
  void duplicated_prompt() {
16
18
  printf("PANIC: Continuation invoked itself\n");
17
19
  exit(1);
@@ -407,7 +407,7 @@ define private void @invalidate(%Stack %stack, %Stack %end) {
407
407
 
408
408
  error:
409
409
  call void @duplicated_prompt()
410
- ret void
410
+ unreachable
411
411
 
412
412
  check:
413
413
  %isEnd = icmp eq %Stack %next, %end
@@ -690,15 +690,13 @@ define private %Stack @withEmptyStack() {
690
690
  ret %Stack %stack
691
691
  }
692
692
 
693
- define void @resume_Int(%Stack %stack, %Int %argument) {
694
- %stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
695
- %returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
696
- %returnAddress = load %ReturnAddress, ptr %returnAddressPointer, !alias.scope !12, !noalias !22
697
- tail call tailcc void %returnAddress(%Int %argument, %Stack %stack)
693
+ define ccc void @resume_Int(%Stack %stack, %Int %integer) {
694
+ %argument = call ccc %Pos @coerceIntPos(%Int %integer)
695
+ call ccc void @resume_Pos(%Stack %stack, %Pos %argument)
698
696
  ret void
699
697
  }
700
698
 
701
- define void @resume_Pos(%Stack %stack, %Pos %argument) {
699
+ define ccc void @resume_Pos(%Stack %stack, %Pos %argument) {
702
700
  %stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
703
701
  %returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
704
702
  %returnAddress = load %ReturnAddress, ptr %returnAddressPointer, !alias.scope !12, !noalias !22
@@ -706,56 +704,36 @@ define void @resume_Pos(%Stack %stack, %Pos %argument) {
706
704
  ret void
707
705
  }
708
706
 
709
- define void @run(%Pos %boxed) {
710
- ; unbox
711
- %f = call %Neg @coercePosNeg(%Pos %boxed)
707
+ define ccc void @run(%Pos %boxed) {
712
708
 
713
- ; fresh stack
709
+ %function = call %Neg @coercePosNeg(%Pos %boxed)
714
710
  %stack = call %Stack @withEmptyStack()
715
711
 
716
- ; prepare call
717
- %arrayPointer = extractvalue %Neg %f, 0
718
- %object = extractvalue %Neg %f, 1
712
+ %arrayPointer = extractvalue %Neg %function, 0
713
+ %object = extractvalue %Neg %function, 1
719
714
  %functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
720
715
  %functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
721
716
 
722
- ; call
723
717
  tail call tailcc %Pos %functionPointer(%Object %object, %Stack %stack)
724
718
  ret void
725
719
  }
726
720
 
727
- define void @run_Int(%Pos %boxed, i64 %argument) {
728
- ; unbox
729
- %f = call %Neg @coercePosNeg(%Pos %boxed)
730
-
731
- ; fresh stack
732
- %stack = call %Stack @withEmptyStack()
733
-
734
- ; prepare call
735
- %arrayPointer = extractvalue %Neg %f, 0
736
- %object = extractvalue %Neg %f, 1
737
- %functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
738
- %functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
739
-
740
- ; call
741
- tail call tailcc %Pos %functionPointer(%Object %object, i64 %argument, %Stack %stack)
721
+ define ccc void @run_Int(%Pos %boxed, %Int %integer) {
722
+ %argument = call ccc %Pos @coerceIntPos(%Int %integer)
723
+ call ccc %Pos @run_Pos(%Pos %boxed, %Pos %argument)
742
724
  ret void
743
725
  }
744
726
 
745
- define void @run_Pos(%Pos %boxed, %Pos %argument) {
746
- ; unbox
747
- %f = call %Neg @coercePosNeg(%Pos %boxed)
727
+ define ccc void @run_Pos(%Pos %boxed, %Pos %argument) {
748
728
 
749
- ; fresh stack
729
+ %function = call ccc %Neg @coercePosNeg(%Pos %boxed)
750
730
  %stack = call %Stack @withEmptyStack()
751
731
 
752
- ; prepare call
753
- %arrayPointer = extractvalue %Neg %f, 0
754
- %object = extractvalue %Neg %f, 1
732
+ %arrayPointer = extractvalue %Neg %function, 0
733
+ %object = extractvalue %Neg %function, 1
755
734
  %functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
756
735
  %functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
757
736
 
758
- ; call
759
737
  tail call tailcc %Pos %functionPointer(%Object %object, %Pos %argument, %Stack %stack)
760
738
  ret void
761
739
  }
@@ -1,5 +1,5 @@
1
1
  <!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title>
2
- <meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/og-image.jpg"><meta name=twitter:image content="https://www.eclipse.org/images/og-image.jpg"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.144.2"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1765134958"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a href=#main class=skip-link>Skip to content</a><div class=eclipsefdn-featured-story-banner data-publish-target=eclipse_org></div><header class="header-wrapper header-wrapper" id=header><div class="navigation-bar dark"><div class=container><div class=navigation-bar-inner><div class=navigation-bar-left><a class="focus-highlight focus-inverse" href=/><img class=navigation-bar-brand src=https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-foundation-white-orange.svg alt="Eclipse Foundation"></a></div><nav class="navigation-bar-nav hidden-xs hidden-sm"><ul><li><a href=# data-target=join-us-menu>Join us</a></li><li><a href=# data-target=what-we-do-menu>What we do</a></li><li><a href=# data-target=resources-menu>Resources</a></li><li><a href=# data-target=about-us-menu>About us</a></li></ul></nav><div class=navigation-bar-right><div class="navigation-bar-controls hidden-xs hidden-sm"><ul><li class=dropdown><a class="dropdown-toggle link-unstyled focus-highlight" tabindex=0 id=search-dropdown-toggle data-toggle=dropdown href=# aria-label=Search><i class="fa-solid fa-magnifying-glass" aria-hidden=true></i></a><form class="search-bar dropdown-menu dropdown-menu-right" aria-labelledby=search-dropdown-toggle action=https://www.eclipse.org/home/search/ method=get><input class=search-bar-input name=q placeholder=Search>
2
+ <meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/og-image.jpg"><meta name=twitter:image content="https://www.eclipse.org/images/og-image.jpg"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.144.2"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1766497060"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a href=#main class=skip-link>Skip to content</a><div class=eclipsefdn-featured-story-banner data-publish-target=eclipse_org></div><header class="header-wrapper header-wrapper" id=header><div class="navigation-bar dark"><div class=container><div class=navigation-bar-inner><div class=navigation-bar-left><a class="focus-highlight focus-inverse" href=/><img class=navigation-bar-brand src=https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-foundation-white-orange.svg alt="Eclipse Foundation"></a></div><nav class="navigation-bar-nav hidden-xs hidden-sm"><ul><li><button type=button class="btn btn-link" data-target=join-us-menu>Join us</button></li><li><button type=button class="btn btn-link" data-target=what-we-do-menu>What we do</button></li><li><button type=button class="btn btn-link" data-target=resources-menu>Resources</button></li><li><button type=button class="btn btn-link" data-target=about-us-menu>About us</button></li></ul></nav><div class=navigation-bar-right><div class="navigation-bar-controls hidden-xs hidden-sm"><ul><li class=dropdown><a class="dropdown-toggle link-unstyled focus-highlight" tabindex=0 id=search-dropdown-toggle data-toggle=dropdown href=# aria-label=Search><i class="fa-solid fa-magnifying-glass" aria-hidden=true></i></a><form class="search-bar dropdown-menu dropdown-menu-right" aria-labelledby=search-dropdown-toggle action=https://www.eclipse.org/home/search/ method=get><input class=search-bar-input name=q placeholder=Search>
3
3
  <button class="btn btn-link" type=submit>
4
4
  <i class="fa-solid fa-arrow-right"></i></button></form></li><li class=dropdown><a class="dropdown-toggle focus-highlight" id=user-menu href=# data-toggle=dropdown aria-haspopup=true aria-expanded=false tabindex=0><i class="fa-regular fa-user" aria-hidden=true></i></a><ul class="dropdown-menu dropdown-menu-right" aria-labelledby=user-menu><li><a href=https://accounts.eclipse.org/user><i class="fa-solid fa-user margin-right-10" aria-hidden=true></i>
5
5
  View my account</a></li><li><a href=https://accounts.eclipse.org/user/edit><i class="fa-solid fa-edit margin-right-10" aria-hidden=true></i>
@@ -30,7 +30,7 @@ Manage cookies</a></li></ul></li></ul></div><div class="navigation-bar-ctas hidd
30
30
  <i class="external-icon fa-solid fa-arrow-up-right-from-square" aria-hidden=true></i></li><li><a href=https://www.eclipse.org/topics/automotive-and-mobility/>Automotive & mobility</a></li><li><a href=https://orcwg.org/ target=_blank>Policy & compliance</a>
31
31
  <i class="external-icon fa-solid fa-arrow-up-right-from-square" aria-hidden=true></i></li></ul></div><div class=submenu style=grid-column:-3;margin-top:-20rem><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-flag" aria-hidden=true></i></span><h2 class=menu-heading>Strategic services</h2></div><ul><li><a href=https://www.eclipse.org/research/>Transform research into open source</a></li><li><a href=https://www.eclipse.org/os4biz/services/>Engage professional services</a></li><li><a href=https://www.eclipse.org/os4biz/ospo/>Build your OSPO</a></li></ul></div></nav></div></div><div class="menu hidden" id=resources-menu><div class=container><nav><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-bullhorn" aria-hidden=true></i></span><h2 class=menu-heading>What's happening</h2></div><ul><li><a href=https://blogs.eclipse.org/>Read our blog</a></li><li><a href=https://accounts.eclipse.org/mailing-list>Join mailing lists</a></li><li><a href=https://newsroom.eclipse.org/>Get news updates</a></li><li><a href=https://www.eclipse.org/community/eclipse_newsletter>Subscribe to newsletter</a></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-calendar-days" aria-hidden=true></i></span><h2 class=menu-heading>Events</h2></div><ul><li><a href=https://events.eclipse.org/>Explore events</a></li><li><a href=https://www.eclipse.org/events/open-community-meetups/>Join a community meetup</a></li><li><a href=https://www.eclipse.org/events/open-community-webinars/>Attend a webinar</a></li><li><a href=https://www.ocxconf.org/ target=_blank>Join OCX</a>
32
32
  <i class="external-icon fa-solid fa-arrow-up-right-from-square" aria-hidden=true></i></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-code" aria-hidden=true></i></span><h2 class=menu-heading>Developer resources</h2></div><ul><li><a href=https://www.eclipse.org/projects/>Explore projects hub</a></li><li><a href=https://www.eclipse.org/projects/calendar/#office-hours>Attend office hours</a></li><li><a href=https://www.eclipse.org/security/>Report a vulnerability</a></li><li><a href=https://www.eclipse.org/security/known/>View known vulnerabilities</a></li><li><a href=https://github.com/eclipse-csi/security-handbook/blob/main/docs/vulnerabilities/advisories.md target=_blank>Use the security handbook</a></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-gear" aria-hidden=true></i></span><h2 class=menu-heading>Industry insights</h2></div><ul><li><a href=https://www.eclipse.org/org/value/#success_stories>View case studies</a></li><li><a href=https://www.eclipse.org/org/value/#whitepapers>View whitepapers</a></li><li><a href=https://www.eclipse.org/org/value/#surveyReports>View surveys & reports</a></li></ul></div><div class=submenu style=grid-column:-2;margin-top:-6rem><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-store" aria-hidden=true></i></span><h2 class=menu-heading>Marketplaces</h2></div><ul><li><a href=https://adoptium.net/>Adoptium</a></li><li><a href=https://marketplace.eclipse.org/>Eclipse IDE</a></li><li><a href=https://open-vsx.org/>Open VSX</a></li></ul></div></nav></div></div><div class="menu hidden" id=about-us-menu><div class=container><nav><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-regular fa-moon rotate-90" aria-hidden=true></i></span><h2 class=menu-heading>The Foundation</h2></div><ul><li><a href=https://www.eclipse.org/about/>About</a></li><li><a href=https://www.eclipse.org/org/foundation/staff/>Meet the team</a></li><li><a href=https://www.eclipse.org/org/governance/>Board & governance</a></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-user-group" aria-hidden=true></i></span><h2 class=menu-heading>Our members</h2></div><ul><li><a href=https://www.eclipse.org/membership/>Become a member</a></li><li><a href=https://www.eclipse.org/membership/explore-membership/>View member directory</a></li><li><a href=https://membership.eclipse.org/portal target=_blank>Access member portal</a></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-regular fa-bookmark" aria-hidden=true></i></span><h2 class=menu-heading>Sponsorship</h2></div><ul><li><a href=https://www.eclipse.org/sponsor/>Become a sponsor</a></li><li><a href=https://www.eclipse.org/org/our-sponsors/>Sponsor directory</a></li></ul></div><div class=submenu><div class=menu-heading-group><span class=menu-pre><i class="fa-solid fa-cube" aria-hidden=true></i></span><h2 class=menu-heading>More</h2></div><ul><li><a href=https://www.eclipse.org/careers/>Join our team</a></li><li><a href=https://www.eclipse.org/org/artwork/>Explore our brand</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact us</a></li></ul></div></nav></div></div></div></header><main id=main><nav aria-label=Breadcrumb><div class=container><ol class=breadcrumb><li><a href=https://www.eclipse.org/>Home</a></li><li><a href=https://www.eclipse.org/legal/>Eclipse Foundation Legal …</a></li><li class=active>Eclipse Public License 2.0 (EPL)</li></ol></div></nav><div class="container padding-bottom-30"><div class=row><div class=col-md-6><aside class=sidebar><a class="sidebar-toggle sidebar-toggle-open" type=button href=#sidebar-open><i class="fa-solid fa-bars" aria-hidden=true></i>
33
- </a><a class="sidebar-toggle sidebar-toggle-close" type=button href=#sidebar-close><i class="fa-solid fa-close" aria-hidden=true></i></a><nav><ul class=sidebar-menu><li class=menu-group><a href=#legal data-toggle=collapse aria-expanded=true class=dropdown-toggle>Legal</a><ul class="collapse in" id=legal><li class=menu-subgroup><a href=#legal-eca data-toggle=collapse aria-expanded=false class=dropdown-toggle>ECA</a><ul class=collapse id=legal-eca><li><a href=/legal/eca>About</a></li><li><a href=https://accounts.eclipse.org/user/eca>Sign</a></li><li><a href=https://accounts.eclipse.org/user/eca>Validation Tool</a></li></ul></li><li class=menu-subgroup><a href=#legal-epl-20 data-toggle=collapse aria-expanded=false class=dropdown-toggle>EPL-2.0</a><ul class=collapse id=legal-epl-20><li><a href=/legal/epl-2.0/>About</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.html>Plain HTML</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.txt>Plain Text</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.pdf>PDF</a></li><li><a href=/legal/epl-2.0/faq/>FAQ</a></li></ul></li><li class=menu-subgroup><a href=#legal-epl-10 data-toggle=collapse aria-expanded=false class=dropdown-toggle>EPL-1.0</a><ul class=collapse id=legal-epl-10><li><a href=/org/documents/epl-v10.php>About</a></li><li><a href=/org/documents/epl-v10.html>Plain HTML</a></li><li><a href=/org/documents/epl-1.0/EPL-1.0.txt>Plain Text</a></li><li><a href=/legal/epl/faq>FAQ</a></li></ul></li><li class=menu-subgroup><a href=#legal-licenses data-toggle=collapse aria-expanded=false class=dropdown-toggle>Licenses</a><ul class=collapse id=legal-licenses><li><a href=/legal/licenses#approved>Approved 3rd Party</a></li><li><a href=/legal/licenses#nonapproved>Non Approved</a></li><li><a href=/projects/handbook/#ip-copyright-headers>File Headers</a></li><li><a href=/legal/non-code-licenses>Docs & Examples</a></li></ul></li><li class=menu-subgroup><a href=#legal-specs data-toggle=collapse aria-expanded=false class=dropdown-toggle>Specifications</a><ul class=collapse id=legal-specs><li><a href=/projects/efsp/>Specifications Process</a></li><li><a href=/projects/efsp/operations.php>Specifications Operations</a></li><li><a href=/legal/efsl>Specification License</a></li><li><a href=/legal/tck>TCK License</a></li></ul></li></ul></li></ul></nav></aside></div><div class=col-md-18><div id=content></div><script async src=/public/js/generate-body-content.js type=text/javascript></script></div></main><aside class=featured-footer id=featured-footer data-publish-target=eclipse_org><div class="eclipsefdn-featured-footer container-fluid"><div class=row><div class="col-sm-24 featured-container"></div></div></div></aside><footer class=footer><div class=container><div class=footer-inner><section class=links-section><ul><li>Eclipse Foundation</li><li><ul><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></li></ul><ul><li>Legal</li><li><ul><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a href=#>Manage Cookies</a></li></ul></li></ul><ul><li>More</li><li><ul><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></li></ul></section><section class=social-media-section><p class="subheading text-tertiary">See what we're up to</p><ul class=social-media-list><li><a href=https://x.com/EclipseFdn aria-label=X><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
33
+ </a><a class="sidebar-toggle sidebar-toggle-close" type=button href=#sidebar-close><i class="fa-solid fa-close" aria-hidden=true></i></a><nav><ul class=sidebar-menu><li class=menu-group><a href=#legal data-toggle=collapse aria-expanded=true class=dropdown-toggle>Legal</a><ul class="collapse in" id=legal><li class=menu-subgroup><a href=#legal-eca data-toggle=collapse aria-expanded=false class=dropdown-toggle>ECA</a><ul class=collapse id=legal-eca><li><a href=/legal/eca>About</a></li><li><a href=https://accounts.eclipse.org/user/eca>Sign</a></li><li><a href=https://accounts.eclipse.org/user/eca>Validation Tool</a></li></ul></li><li class=menu-subgroup><a href=#legal-epl-20 data-toggle=collapse aria-expanded=false class=dropdown-toggle>EPL-2.0</a><ul class=collapse id=legal-epl-20><li><a href=/legal/epl-2.0/>About</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.html>Plain HTML</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.txt>Plain Text</a></li><li><a href=/org/documents/epl-2.0/EPL-2.0.pdf>PDF</a></li><li><a href=/legal/epl-2.0/faq/>FAQ</a></li></ul></li><li class=menu-subgroup><a href=#legal-epl-10 data-toggle=collapse aria-expanded=false class=dropdown-toggle>EPL-1.0</a><ul class=collapse id=legal-epl-10><li><a href=/org/documents/epl-v10.php>About</a></li><li><a href=/org/documents/epl-v10.html>Plain HTML</a></li><li><a href=/org/documents/epl-1.0/EPL-1.0.txt>Plain Text</a></li><li><a href=/legal/epl/faq>FAQ</a></li></ul></li><li class=menu-subgroup><a href=#legal-licenses data-toggle=collapse aria-expanded=false class=dropdown-toggle>Licenses</a><ul class=collapse id=legal-licenses><li><a href=/legal/licenses#approved>Approved 3rd Party</a></li><li><a href=/legal/licenses#nonapproved>Non Approved</a></li><li><a href=/projects/handbook/#ip-copyright-headers>File Headers</a></li><li><a href=/legal/non-code-licenses>Docs & Examples</a></li></ul></li><li class=menu-subgroup><a href=#legal-specs data-toggle=collapse aria-expanded=false class=dropdown-toggle>Specifications</a><ul class=collapse id=legal-specs><li><a href=/projects/efsp/>Specifications Process</a></li><li><a href=/projects/efsp/operations.php>Specifications Operations</a></li><li><a href=/legal/efsl>Specification License</a></li><li><a href=/legal/tck>TCK License</a></li></ul></li></ul></li></ul></nav></aside></div><div class=col-md-18><div id=content></div><script async src=/public/js/generate-body-content.js type=text/javascript></script></div></main><aside class=featured-footer id=featured-footer><div class="eclipsefdn-featured-footer container-fluid" data-publish-target=eclipse_org><div class=row><div class="col-sm-24 featured-container"></div></div></div></aside><footer class=footer><div class=container><div class=footer-inner><section class=links-section><ul><li>Eclipse Foundation</li><li><ul><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></li></ul><ul><li>Legal</li><li><ul><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><button type=button class="btn btn-link toolbar-manage-cookies">Manage Cookies</button></li></ul></li></ul><ul><li>More</li><li><ul><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></li></ul></section><section class=social-media-section><p class="subheading text-tertiary">See what we're up to</p><ul class=social-media-list><li><a href=https://x.com/EclipseFdn aria-label=X><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
34
34
  <i class="fa-brands fa-x-twitter fa-stack-1x fa-inverse" aria-hidden=true></i></span></a></li><li><a href=https://bsky.app/profile/eclipse.org aria-label=Bluesky><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
35
35
  <i class="fa-brands fa-bluesky fa-stack-1x fa-inverse" aria-hidden=true></i></span></a></li><li><a href=https://mastodon.social/@EclipseFdn aria-label=Mastodon><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
36
36
  <i class="fa-brands fa-mastodon fa-stack-1x fa-inverse" aria-hidden=true></i></span></a></li><li><a href=https://www.facebook.com/eclipse.org aria-label=Facebook><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
@@ -39,4 +39,4 @@ Manage cookies</a></li></ul></li></ul></div><div class="navigation-bar-ctas hidd
39
39
  <i class="fa-brands fa-youtube fa-stack-1x fa-inverse" aria-hidden=true></i></span></a></li><li><a href=https://www.linkedin.com/company/eclipse-foundation aria-label=LinkedIn><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
40
40
  <i class="fa-brands fa-linkedin-in fa-stack-1x fa-inverse" aria-hidden=true></i></span></a></li></ul></section><section class=newsletter-section><p class="subheading text-tertiary">Stay up to date</p><h2>Subscribe to our newsletter</h2><form class="newsletter-form margin-top-40" id=mc-embedded-subscribe-form action="https://eclipse.us6.list-manage.com/subscribe/post?u=eaf9e1f06f194eadc66788a85&amp;id=e7538485cd&amp;f_id=00f9c2e1f0" method=post novalidate target=_blank><div class=text-field-outlined><input name=EMAIL type=email placeholder="Your email">
41
41
  <button class=newsletter-form-submit type=submit name=subscribe id=mc-embedded-subscribe aria-label=Submit>
42
- <i class="fa-solid fa-arrow-right" aria-hidden=true></i></button></div></form></section><section class=footer-bottom-section><img class="img-responsive logo" src=https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-foundation-white.svg alt="Eclipse Foundation"><div class=legal-information><p>Copyright &copy; Eclipse Foundation AISBL. All rights reserved.</p><ul class=legal-links><li><a href=https://www.eclipse.org/legal/privacy/>Privacy policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/legal/>Legal</a></li></ul></div></section></div></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1765134958"></script><script>(function(){})(jQuery,document)</script></div></body></html>
42
+ <i class="fa-solid fa-arrow-right" aria-hidden=true></i></button></div></form></section><section class=footer-bottom-section><img class="img-responsive logo" src=https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-foundation-white.svg alt="Eclipse Foundation"><div class=legal-information><p>Copyright &copy; Eclipse Foundation AISBL. All rights reserved.</p><ul class=legal-links><li><a href=https://www.eclipse.org/legal/privacy/>Privacy policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/legal/>Legal</a></li></ul></div></section></div></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1766497060"></script><script>(function(){})(jQuery,document)</script></div></body></html>