diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/course.md
new file mode 100644
index 0000000..76e4d7c
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/course.md
@@ -0,0 +1,316 @@
+# Chapter 29 : Interoperability with Michelson
+
+
+
+
+LIGO can work together with other smart contract languages on Tezos. However data structures might have different representations in Michelson and not correctly match the standard LIGO types.
+
+## Annotations
+
+### Michelson types and annotations
+
+Michelson types consist of *or*'s and *pair*'s, combined with field annotations. Field annotations add contraints on a Michelson type, for example a _pair_ of *(pair (int %foo) (string %bar))* will only work with the exact equivalence or the same type without the field annotations.
+
+For example, the following _pair_
+```
+(pair (int %foo) (string %bar))
+```
+
+will accept these definitions and fail with the ones that does not respect the typing or the order of pair fields:
+```
+(pair (int %foo) (string %bar)) // OK
+(pair int string) // OK
+(pair (int %bar) (string %foo)) // KO
+(pair (string %bar) (int %foo)) // KO
+```
+
+
+### Entrypoints and annotations
+
+As seen in chapter Polymorphism, a contract can be called by another contract. Using the predefined function *Tezos.get_entrypoint_opt* allows to a calling contract ot point to a specific entry point of the called contract.
+
+Here is an exemple. Let's consider the following contract :
+```
+type storage is int
+
+type parameter is
+ | Left of int
+ | Right of int
+
+function main (const p: parameter; const x: storage): (list(operation) * storage) is
+ ((nil: list(operation)), case p of
+ | Left(i) -> x - i
+ | Right(i) -> x + i
+ end)
+```
+
+The following contract sends a transaction to the previous contract.
+
+```
+type storage is int
+
+type parameter is int
+
+type x is Left of int
+
+function main (const p: parameter; const s: storage): (list(operation) * storage) is block {
+ const contract: contract(x) =
+ case (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx":address)): option(contract(x))) of
+ | Some (c) -> c
+ | None -> (failwith("not a correct contract") : contract(x))
+ end;
+
+ const result: (list(operation) * storage) = ((list [Tezos.transaction(Left(2), 2mutez, contract)]: list(operation)), s)
+} with result
+```
+
+⚠️ Notice how we directly use the *%left* entrypoint without mentioning the %right entrypoint. This is done with the help of annotations. Without annotations it wouldn't be clear what our int would be referring to.
+
+These annotations works for _or_'s or _variant_ types in LIGO.
+
+## Interop with Michelson
+
+To interop with existing Michelson code or for compatibility with certain development tooling, LIGO has two special interop types: *michelson_or* and *michelson_pair*. These types give the flexibility to model the exact Michelson output, including field annotations.
+
+Take for example the following Michelson type that we want to interop with:
+```
+(or
+ (unit %z)
+ (or %other
+ (unit %y)
+ (pair %other
+ (string %x)
+ (pair %other
+ (int %w)
+ (nat %v)))))
+```
+
+To reproduce this type we can use the following LIGO code:
+
+```
+type w_and_v is michelson_pair(int, "w", nat, "v")
+type x_and is michelson_pair(string, "x", w_and_v, "other")
+type y_or is michelson_or(unit, "y", x_and, "other")
+type z_or is michelson_or(unit, "z", y_or, "other")
+```
+
+If you don't want to have an annotation, you need to provide an empty string.
+
+To use variables of type michelson_or you have to use *M_left* and *M_right*. *M_left* picks the left _or_ case while *M_right* picks the right _or_ case. For *michelson_pair* you need to use tuples.
+
+```
+const z: z_or = (M_left (unit) : z_or);
+
+const y_1: y_or = (M_left (unit): y_or);
+const y: z_or = (M_right (y_1) : z_or);
+
+const x_pair: x_and = ("foo", (2, 3n));
+const x_1: y_or = (M_right (x_pair): y_or);
+const x: z_or = (M_right (y_1) : z_or);
+```
+
+## Helper functions
+
+Conversions from Ligo types to michelson types requires a precise knowledge of data structures representation.
+
+So it becomes even more relevant with nested pairs that there are many possible decomposition of a record in pairs of pairs.
+
+The following record
+```
+type l_record is record [
+ s: string;
+ w: int;
+ v: nat
+]
+```
+
+can be transformed in a left combed data structure
+```
+ (pair %other
+ (pair %other
+ (string %s)
+ (int %w)
+ )
+ (nat %v)
+ )
+```
+ or a right combed data structure
+ ```
+ (pair %other
+ (string %s)
+ (pair %other
+ (int %w)
+ (nat %v)
+ )
+ )
+ ```
+
+Converting between different LIGO types and data structures can happen in two ways. The first way is to use the provided layout conversion functions, and the second way is to handle the layout conversion manually.
+
+### Converting left combed Michelson data structures
+
+#### Pair
+
+Conversion between the Michelson type and record type is handled with the functions *Layout.convert_from_left_comb* and *Layout.convert_to_left_comb*.
+
+Here's an example of a left combed Michelson data structure using pairs:
+
+```
+ (pair %other
+ (pair %other
+ (string %s)
+ (int %w)
+ )
+ (nat %v)
+ )
+```
+
+Which could respond with the following record type:
+```
+type l_record is record [
+ s: string;
+ w: int;
+ v: nat
+]
+```
+
+This snippet of code shows
+* how to use *Layout.convert_from_left_comb* to transform a michelson type into a record type.
+* how to use *Layout.convert_to_left_comb* to transform a record type into a michelson type.
+```
+type michelson is michelson_pair_left_comb(l_record)
+
+function of_michelson (const f: michelson) : l_record is
+ block {
+ const p: l_record = Layout.convert_from_left_comb(f)
+ }
+ with p
+
+function to_michelson (const f: l_record) : michelson is
+ block {
+ const p: michelson = Layout.convert_to_left_comb ((f: l_record))
+ }
+ with p
+```
+
+#### Variant
+In the case of a left combed Michelson or data structure, that you want to translate to a variant, you can use the *michelson_or_left_comb* type.
+
+```
+type vari is
+| Foo of int
+| Bar of nat
+| Other of bool
+
+type r is michelson_or_left_comb(vari)
+```
+
+And then use these types in *Layout.convert_from_left_comb* or *Layout.convert_to_left_comb*, similar to the pairs example above
+
+```
+function of_michelson_or (const f: r) : vari is
+ block {
+ const p: vari = Layout.convert_from_left_comb(f)
+ }
+ with p
+
+function to_michelson_or (const f: vari) : r is
+ block {
+ const p: r = Layout.convert_to_left_comb((f: vari))
+ }
+ with p
+```
+
+### Converting left combed Michelson data structures
+
+you can almost use the same code as that for the left combed data structures, but with *michelson_or_right_comb*, *michelson_pair_right_comb*, *Layout.convert_from_right_comb*, and *Layout.convert_to_left_comb* respectively.
+
+### Manual data structure conversion
+
+If you want to get your hands dirty, it's also possible to do manual data structure conversion.
+
+The following code can be used as inspiration:
+```
+type z_to_v is
+| Z
+| Y
+| X
+| W
+| V
+
+type w_or_v is michelson_or(unit, "w", unit, "v")
+type x_or is michelson_or(unit, "x", w_or_v, "other")
+type y_or is michelson_or(unit, "y", x_or, "other")
+type z_or is michelson_or(unit, "z", y_or, "other")
+
+type test is record [
+ z: string;
+ y: int;
+ x: string;
+ w: bool;
+ v: int;
+]
+
+function make_concrete_sum (const r: z_to_v) : z_or is block {
+ const z: z_or = (M_left (unit) : z_or);
+
+ const y_1: y_or = (M_left (unit): y_or);
+ const y: z_or = (M_right (y_1) : z_or);
+
+ const x_2: x_or = (M_left (unit): x_or);
+ const x_1: y_or = (M_right (x_2): y_or);
+ const x: z_or = (M_right (x_1) : z_or);
+
+ const w_3: w_or_v = (M_left (unit): w_or_v);
+ const w_2: x_or = (M_right (w_3): x_or);
+ const w_1: y_or = (M_right (w_2): y_or);
+ const w: z_or = (M_right (w_1) : z_or);
+
+ const v_3: w_or_v = (M_right (unit): w_or_v);
+ const v_2: x_or = (M_right (v_3): x_or);
+ const v_1: y_or = (M_right (v_2): y_or);
+ const v: z_or = (M_right (v_1) : z_or);
+}
+ with (case r of
+ | Z -> z
+ | Y -> y
+ | X -> x
+ | W -> w
+ | V -> v
+ end)
+
+
+function make_concrete_record (const r: test) : (string * int * string * bool * int) is
+ (r.z, r.y, r.x, r.w, r.v)
+
+function make_abstract_sum (const z_or: z_or) : z_to_v is
+ (case z_or of
+ | M_left (n) -> Z
+ | M_right (y_or) ->
+ (case y_or of
+ | M_left (n) -> Y
+ | M_right (x_or) ->
+ (case x_or of
+ | M_left (n) -> X
+ | M_right (w_or) ->
+ (case (w_or) of
+ | M_left (n) -> W
+ | M_right (n) -> V
+ end)
+ end)
+ end)
+ end)
+
+function make_abstract_record (const z: string; const y: int; const x: string; const w: bool; const v: int) : test is
+ record [ z = z; y = y; x = x; w = w; v = v ]
+```
+
+
+
+## Your mission
+
+We want you to modify our "inventory" contract. As you can see the storage is mainly composed of an item inventory where each item is a right combed nested pairs. The contract possess a single entry point AddInventory. This *AddInventory* function adds each element in the inventory (don't worry about duplicates it has already been taken care of).
+
+1- Complete the implementation of the *update_inventory* lambda function. This function takes a list of item as parameter and must transform each item in a combed pair structure and add this transformed structure in the storage inventory. (When naming your temporary variables, use *acc* for the accumulator name and *i* for the current item)
+
+
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/exercise.mligo b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/exercise.mligo
new file mode 100644
index 0000000..7510bf8
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/exercise.mligo
@@ -0,0 +1,30 @@
+type item is record [
+ item_id : nat;
+ cost : nat;
+ name : string
+]
+
+type item_michelson is michelson_pair_right_comb(item)
+
+type storage is record [
+ inventory : list(item_michelson)
+]
+
+type return is (list(operation) * storage)
+
+type entry_points is
+ | AddInventory of list(item)
+
+// This function takes a list of item as parameter and transform each item in a right combed pair structure and add this transformed item in inventory
+function addInventory (const params : list(item); const s : storage) : return is
+block {
+ const item_list : list(item) = params;
+ // Type your solution below
+
+ s.inventory := List.fold(update_inventory, item_list, s.inventory);
+} with ((nil : list(operation)), s)
+
+function main (const p : entry_points; const s : storage) : return is
+ case (p) of
+ | AddInventory(p) -> addInventory(p,s)
+ end
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/index.ts b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/index.ts
new file mode 100644
index 0000000..5ba0a9f
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/index.ts
@@ -0,0 +1,11 @@
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import course from "!raw-loader!./course.md";
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import exercise from "!raw-loader!./exercise.ligo";
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import solution from "!raw-loader!./solution.ligo";
+
+export const data = { course, exercise, solution };
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/solution.mligo b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/solution.mligo
new file mode 100644
index 0000000..ea71e6c
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterInterop/solution.mligo
@@ -0,0 +1,30 @@
+type item is record [
+ item_id : nat;
+ cost : nat;
+ name : string
+]
+
+type item_michelson is michelson_pair_right_comb(item)
+
+type storage is record [
+ inventory : list(item_michelson)
+]
+
+type return is (list(operation) * storage)
+
+type entry_points is
+ | AddInventory of list(item)
+
+// This function takes a list of item as parameter and transform each item in a right combed pair structure and add this transformed item in inventory
+function addInventory (const params : list(item); const s : storage) : return is
+block {
+ const item_list : list(item) = params;
+ // Type your solution below
+ function update_inventory (const acc : list(item_michelson); const i : item) : list(item_michelson) is Layout.convert_to_right_comb(i) # acc;
+ s.inventory := List.fold(update_inventory, item_list, s.inventory);
+} with ((nil : list(operation)), s)
+
+function main (const p : entry_points; const s : storage) : return is
+ case (p) of
+ | AddInventory(p) -> addInventory(p,s)
+ end
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/course.md
new file mode 100644
index 0000000..b197c7f
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/course.md
@@ -0,0 +1,296 @@
+# Chapter 29 : Interoperability with Michelson
+
+
+
+
+LIGO can work together with other smart contract languages on Tezos. However data structures might have different representations in Michelson and not correctly match the standard LIGO types.
+
+## Annotations
+
+### Michelson types and annotations
+
+Michelson types consist of *or*'s and *pair*'s, combined with field annotations. Field annotations add contraints on a Michelson type, for example a _pair_ of *(pair (int %foo) (string %bar))* will only work with the exact equivalence or the same type without the field annotations.
+
+For example, the following _pair_
+```
+(pair (int %foo) (string %bar))
+```
+
+will accept these definitions and fail with the ones that does not respect the typing or the order of pair fields:
+```
+(pair (int %foo) (string %bar)) // OK
+(pair int string) // OK
+(pair (int %bar) (string %foo)) // KO
+(pair (string %bar) (int %foo)) // KO
+```
+
+
+### Entrypoints and annotations
+
+As seen in chapter Polymorphism, a contract can be called by another contract. Using the predefined function *Tezos.get_entrypoint_opt* allows to a calling contract ot point to a specific entry point of the called contract.
+
+Here is an exemple. Let's consider the following "Counter" contract :
+```
+type storage = int
+
+type parameter =
+ | Left(int)
+ | Right(int)
+
+let main = ((p, x): (parameter, storage)): (list(operation), storage) => {
+ ([]: list(operation), (switch(p) {
+ | Left(i) => x - i
+ | Right(i) => x + i
+ }))
+};
+```
+
+Thre following contract sends a transaction to the "Counter" contract.
+
+```
+type storage = int;
+
+type parameter = int;
+
+type x = Left(int);
+
+let main = ((p, s): (parameter, storage)): (list(operation), storage) => {
+ let contract: contract(x) =
+ switch (Tezos.get_entrypoint_opt("%left", ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)): option(contract(x))) {
+ | Some c => c
+ | None => (failwith ("contract does not match"): contract(x))
+ };
+ ([
+ Tezos.transaction(Left(2), 2mutez, contract)
+ ]: list(operation), s);
+};
+```
+
+⚠️ Notice how we directly use the *%left* entrypoint without mentioning the %right entrypoint. This is done with the help of annotations. Without annotations it wouldn't be clear what our int would be referring to.
+
+These annotations works for _or_'s or _variant_ types in LIGO.
+
+## Interop with Michelson
+
+To interop with existing Michelson code or for compatibility with certain development tooling, LIGO has two special interop types: *michelson_or* and *michelson_pair*. These types give the flexibility to model the exact Michelson output, including field annotations.
+
+Take for example the following Michelson type that we want to interop with:
+```
+(or
+ (unit %z)
+ (or %other
+ (unit %y)
+ (pair %other
+ (string %x)
+ (pair %other
+ (int %w)
+ (nat %v)))))
+```
+
+To reproduce this type we can use the following LIGO code:
+
+```
+type w_and_v = michelson_pair(int, "w", nat, "v")
+type x_and = michelson_pair(string, "x", w_and_v, "other")
+type y_or = michelson_or(unit, "y", x_and, "other")
+type z_or = michelson_or(unit, "z", y_or, "other")
+```
+
+If you don't want to have an annotation, you need to provide an empty string.
+
+To use variables of type michelson_or you have to use *M_left* and *M_right*. *M_left* picks the left _or_ case while *M_right* picks the right _or_ case. For *michelson_pair* you need to use tuples.
+
+```
+let z: z_or = (M_left (unit) : z_or)
+
+let y_1: y_or = (M_left (unit): y_or)
+let y: z_or = (M_right (y_1) : z_or)
+
+let x_pair: x_and = ("foo", (2, 3n))
+let x_1: y_or = (M_right (x_pair): y_or)
+let x: z_or = (M_right (y_1) : z_or)
+```
+
+## Helper functions
+
+Conversions from Ligo types to michelson types requires a precise knowledge of data structures representation.
+
+So it becomes even more relevant with nested pairs that there are many possible decomposition of a record in pairs of pairs.
+
+The following record
+```
+type l_record = {
+ s: string,
+ w: int,
+ v: nat
+}
+```
+
+can be transformed in a left combed data structure
+```
+ (pair %other
+ (pair %other
+ (string %s)
+ (int %w)
+ )
+ (nat %v)
+ )
+```
+ or a right combed data structure
+ ```
+ (pair %other
+ (string %s)
+ (pair %other
+ (int %w)
+ (nat %v)
+ )
+ )
+ ```
+
+Converting between different LIGO types and data structures can happen in two ways. The first way is to use the provided layout conversion functions, and the second way is to handle the layout conversion manually.
+
+### Converting left combed Michelson data structures
+
+#### Pair
+
+Conversion between the Michelson type and record type is handled with the functions *Layout.convert_from_left_comb* and *Layout.convert_to_left_comb*.
+
+Here's an example of a left combed Michelson data structure using pairs:
+
+```
+ (pair %other
+ (pair %other
+ (string %s)
+ (int %w)
+ )
+ (nat %v)
+ )
+```
+
+Which could respond with the following record type:
+```
+type l_record = {
+ s: string,
+ w: int,
+ v: nat
+}
+```
+
+This snippet of code shows
+* how to use *Layout.convert_from_left_comb* to transform a michelson type into a record type.
+* how to use *Layout.convert_to_left_comb* to transform a record type into a michelson type.
+```
+type michelson = michelson_pair_left_comb(l_record);
+
+let of_michelson = (f: michelson) : l_record => {
+ let p: l_record = Layout.convert_from_left_comb(f);
+ p
+};
+
+let to_michelson = (f: l_record) : michelson => {
+ let p = Layout.convert_to_left_comb(f: l_record);
+ p
+}
+```
+
+#### Variant
+In the case of a left combed Michelson or data structure, that you want to translate to a variant, you can use the *michelson_or_left_comb* type.
+
+```
+type vari =
+| Foo(int)
+| Bar(nat)
+| Other(bool)
+
+type r = michelson_or_left_comb(vari)
+```
+
+And then use these types in *Layout.convert_from_left_comb* or *Layout.convert_to_left_comb*, similar to the pairs example above
+
+```
+let of_michelson_or = (f: r) : vari => {
+ let p: vari = Layout.convert_from_left_comb(f);
+ p
+};
+
+let to_michelson_or = (f: vari) : r => {
+ let p = Layout.convert_to_left_comb(f: vari);
+ p
+}
+```
+
+### Converting left combed Michelson data structures
+
+you can almost use the same code as that for the left combed data structures, but with *michelson_or_right_comb*, *michelson_pair_right_comb*, *Layout.convert_from_right_comb*, and *Layout.convert_to_left_comb* respectively.
+
+### Manual data structure conversion
+
+If you want to get your hands dirty, it's also possible to do manual data structure conversion.
+
+The following code can be used as inspiration:
+```
+type z_to_v =
+| Z
+| Y
+| X
+| W
+| V
+
+type w_or_v = michelson_or(unit, "w", unit, "v")
+type x_or = michelson_or(unit, "x", w_or_v, "other")
+type y_or = michelson_or(unit, "y", x_or, "other")
+type z_or = michelson_or(unit, "z", y_or, "other")
+
+type test = {
+ z: string,
+ y: int,
+ x: string,
+ w: bool,
+ v: int
+}
+
+let make_concrete_sum = (r: z_to_v) : z_or =>
+ switch(r){
+ | Z => (M_left (unit) : z_or)
+ | Y => (M_right (M_left (unit): y_or) : z_or )
+ | X => (M_right (M_right (M_left (unit): x_or): y_or) : z_or )
+ | W => (M_right (M_right (M_right (M_left (unit): w_or_v): x_or): y_or) : z_or )
+ | V => (M_right (M_right (M_right (M_right (unit): w_or_v): x_or): y_or) : z_or )
+ }
+
+let make_concrete_record = (r: test) : (string, int, string, bool, int) =>
+ (r.z, r.y, r.x, r.w, r.v)
+
+let make_abstract_sum = (z_or: z_or) : z_to_v =>
+ switch (z_or) {
+ | M_left n => Z
+ | M_right y_or => (
+ switch (y_or) {
+ | M_left n => Y
+ | M_right x_or => (
+ switch (x_or) {
+ | M_left n => X
+ | M_right w_or => (
+ switch (w_or) {
+ | M_left n => W
+ | M_right n => V
+ })
+ })
+ })
+ }
+
+
+let make_abstract_record = (z: string, y: int, x: string, w: bool, v: int) : test =>
+ { z : z, y, x, w, v }
+
+```
+
+
+
+## Your mission
+
+We want you to modify our "inventory" contract. As you can see the storage is mainly composed of an item inventory where each item is a right combed nested pairs. The contract possess a single entry point AddInventory. This *AddInventory* function adds each element in the inventory (don't worry about duplicates it has already been taken care of).
+
+1- Complete the implementation of the *update_inventory* lambda function. This function takes a list of item as parameter and must transform each item in a combed pair structure and add this transformed structure in the storage inventory. (When naming your temporary variables, use *acc* for the accumulator name and *i* for the current item)
+
+
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/exercise.mligo b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/exercise.mligo
new file mode 100644
index 0000000..e9d8e31
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/exercise.mligo
@@ -0,0 +1,31 @@
+type item = {
+ item_id : nat,
+ cost : nat,
+ name : string
+}
+
+type item_michelson = michelson_pair_right_comb(item)
+
+type storage = {
+ inventory : list(item_michelson)
+}
+
+type return = (list(operation), storage)
+
+type entry_points =
+ | AddInventory (list(item))
+
+// This function takes a list of item as parameter and transform each item in a right combed pair structure and add this transformed item in inventory
+let addInventory = ((params,s) : (list(item), storage)) : return =>
+{
+ let item_list : list(item) = params;
+ // Type your solution below
+
+ let new_inventory : list(item_michelson) = List.fold(update_inventory, item_list, s.inventory);
+ (([] : list(operation)), {...s, inventory:new_inventory})
+};
+
+let main = ((p,s) : (entry_points, storage)) : return =>
+ switch (p) {
+ | AddInventory(p) => addInventory((p,s))
+ }
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/index.ts b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/index.ts
new file mode 100644
index 0000000..03e8990
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/index.ts
@@ -0,0 +1,11 @@
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import course from "!raw-loader!./course.md";
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import exercise from "!raw-loader!./exercise.religo";
+/* eslint import/no-webpack-loader-syntax: off */
+// @ts-ignore
+import solution from "!raw-loader!./solution.religo";
+
+export const data = { course, exercise, solution };
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.mligo b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.mligo
new file mode 100644
index 0000000..3d85cd3
--- /dev/null
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.mligo
@@ -0,0 +1,31 @@
+type item = {
+ item_id : nat,
+ cost : nat,
+ name : string
+}
+
+type item_michelson = michelson_pair_right_comb(item)
+
+type storage = {
+ inventory : list(item_michelson)
+}
+
+type return = (list(operation), storage)
+
+type entry_points =
+ | AddInventory (list(item))
+
+// This function takes a list of item as parameter and transform each item in a right combed pair structure and add this transformed item in inventory
+let addInventory = ((params,s) : (list(item), storage)) : return =>
+{
+ let item_list : list(item) = params;
+ // Type your solution below
+ let update_inventory = ((acc,i) : (list(item_michelson), item)) : list(item_michelson) => [Layout.convert_to_right_comb(i), ...acc];
+ let new_inventory : list(item_michelson) = List.fold(update_inventory, item_list, s.inventory);
+ (([] : list(operation)), {...s, inventory:new_inventory})
+};
+
+let main = ((p,s) : (entry_points, storage)) : return =>
+ switch (p) {
+ | AddInventory(p) => addInventory((p,s))
+ }
\ No newline at end of file