diff --git a/fatamorgana/test/build_testfiles.py b/fatamorgana/test/build_testfiles.py index e776c61..5bb7525 100644 --- a/fatamorgana/test/build_testfiles.py +++ b/fatamorgana/test/build_testfiles.py @@ -1,10 +1,8 @@ ''' Build files equivalent to the test cases used by KLayout. ''' -# type: ignore -from typing import Callable -from io import BufferedIOBase +from typing import Callable, IO from . import ( @@ -16,7 +14,7 @@ from . import ( ) -def build_file(num: str, func: Callable[[BufferedIOBase], BufferedIOBase]) -> None: +def build_file(num: str, func: Callable[[IO[bytes]], IO[bytes]]) -> None: with open('t' + num + '.oas', 'wb') as f: func(f) diff --git a/fatamorgana/test/test_files_cblocks.py b/fatamorgana/test/test_files_cblocks.py index cf3f2ec..3f02e93 100644 --- a/fatamorgana/test/test_files_cblocks.py +++ b/fatamorgana/test/test_files_cblocks.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from numpy.testing import assert_equal @@ -26,7 +26,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.cells[0].properties -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_cells.py b/fatamorgana/test/test_files_cells.py index 9fae7b8..59bc6d4 100644 --- a/fatamorgana/test/test_files_cells.py +++ b/fatamorgana/test/test_files_cells.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO import pytest @@ -23,7 +23,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' Single cell with explicit name 'XYZ' ''' @@ -48,7 +48,7 @@ def test_file_1() -> None: assert not layout.cellnames -def write_file_2(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_2(buf: IO[bytes]) -> IO[bytes]: ''' Two cellnames ('XYZ', 'ABC') and two cells with name references. ''' @@ -85,7 +85,7 @@ def test_file_2() -> None: assert layout.cells[1].name == 1 -def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_3(buf: IO[bytes]) -> IO[bytes]: ''' Invalid file, contains a mix of explicit and implicit cellnames ''' @@ -116,7 +116,7 @@ def test_file_3() -> None: layout = OasisLayout.read(buf) -def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_4(buf: IO[bytes]) -> IO[bytes]: ''' Two cells referencing two names with explicit ids (unsorted) ''' @@ -155,7 +155,7 @@ def test_file_4() -> None: assert layout.cells[1].name == 1 -def write_file_5(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_5(buf: IO[bytes]) -> IO[bytes]: ''' Reference to non-existent cell name. ''' @@ -196,7 +196,7 @@ def test_file_5() -> None: #TODO add optional error checking for this case -def write_file_6(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_6(buf: IO[bytes]) -> IO[bytes]: ''' Cellname with invalid n-string. ''' @@ -237,7 +237,7 @@ def test_file_6() -> None: #assert layout.cells[1].name == 1 -def write_file_7(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_7(buf: IO[bytes]) -> IO[bytes]: ''' Unused cellname. ''' diff --git a/fatamorgana/test/test_files_circles.py b/fatamorgana/test/test_files_circles.py index 794c18f..f29b18f 100644 --- a/fatamorgana/test/test_files_circles.py +++ b/fatamorgana/test/test_files_circles.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte @@ -24,7 +24,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.cells[0].properties -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_ctrapezoids.py b/fatamorgana/test/test_files_ctrapezoids.py index fdcc6cf..095909f 100644 --- a/fatamorgana/test/test_files_ctrapezoids.py +++ b/fatamorgana/test/test_files_ctrapezoids.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte @@ -20,7 +20,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -153,7 +153,7 @@ def test_file_1() -> None: assert geometry[55].repetition.b_vector == [0, 300] -def write_file_2(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_2(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_empty.py b/fatamorgana/test/test_files_empty.py index acf651d..8554c28 100644 --- a/fatamorgana/test/test_files_empty.py +++ b/fatamorgana/test/test_files_empty.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO import struct from .utils import MAGIC_BYTES, FOOTER @@ -22,7 +22,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' File contains one PAD record. 1000 units/micron @@ -55,7 +55,7 @@ def test_file_1() -> None: assert layout.unit == 1000 -def write_file_2(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_2(buf: IO[bytes]) -> IO[bytes]: ''' File contains no records. 1/2 unit/micron @@ -86,7 +86,7 @@ def test_file_2() -> None: assert layout.unit == 0.5 -def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_3(buf: IO[bytes]) -> IO[bytes]: ''' File contains no records. 10/4 unit/micron @@ -118,7 +118,7 @@ def test_file_3() -> None: assert layout.unit == 10 / 4 -def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_4(buf: IO[bytes]) -> IO[bytes]: ''' File contains no records. 12.5 unit/micron (float32) @@ -149,7 +149,7 @@ def test_file_4() -> None: assert layout.unit == 12.5 -def write_file_5(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_5(buf: IO[bytes]) -> IO[bytes]: ''' File contains no records. 12.5 unit/micron (float64) diff --git a/fatamorgana/test/test_files_layernames.py b/fatamorgana/test/test_files_layernames.py index 94a2cc8..d430aaf 100644 --- a/fatamorgana/test/test_files_layernames.py +++ b/fatamorgana/test/test_files_layernames.py @@ -1,18 +1,19 @@ # type: ignore -from typing import Sequence +from typing import Sequence, IO -from io import BytesIO, BufferedIOBase +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte from ..main import OasisLayout -LAYERS = [(1, 2), (1, 5), (1, 6), (1, 8), - (5, 2), (5, 5), (5, 6), (5, 8), - (6, 2), (6, 5), (6, 6), (6, 8), - (7, 2), (7, 5), (7, 6), (7, 8), - ] +LAYERS = [ + (1, 2), (1, 5), (1, 6), (1, 8), + (5, 2), (5, 5), (5, 6), (5, 8), + (6, 2), (6, 5), (6, 6), (6, 8), + (7, 2), (7, 5), (7, 6), (7, 8), + ] def base_tests(layout: OasisLayout) -> None: assert layout.version.string == '1.0' @@ -30,7 +31,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.cells[0].properties -def write_names_geom(buf: BufferedIOBase, short: bool = False) -> BufferedIOBase: +def write_names_geom(buf: IO[bytes], short: bool = False) -> IO[bytes]: write_uint(buf, 11) # LAYERNAME record (geometry) write_bstring(buf, b'AA') # name write_uint(buf, 0) # all layers @@ -96,7 +97,7 @@ def write_names_geom(buf: BufferedIOBase, short: bool = False) -> BufferedIOBase return buf -def write_names_text(buf: BufferedIOBase, prefix: bytes = b'') -> BufferedIOBase: +def write_names_text(buf: IO[bytes], prefix: bytes = b'') -> IO[bytes]: write_uint(buf, 12) # LAYERNAME record (geometry) write_bstring(buf, prefix + b'AA') # name write_uint(buf, 0) # all layers @@ -128,7 +129,7 @@ def write_names_text(buf: BufferedIOBase, prefix: bytes = b'') -> BufferedIOBase write_uint(buf, 0) # all datatypes return buf -def write_geom(buf: BufferedIOBase) -> BufferedIOBase: +def write_geom(buf: IO[bytes]) -> IO[bytes]: for ll, dt in LAYERS: write_uint(buf, 27) # CIRCLE record write_byte(buf, 0b0011_1011) # 00rX_YRDL @@ -140,7 +141,7 @@ def write_geom(buf: BufferedIOBase) -> BufferedIOBase: return buf -def write_text(buf: BufferedIOBase) -> BufferedIOBase: +def write_text(buf: IO[bytes]) -> IO[bytes]: for ll, dt in LAYERS: write_uint(buf, 19) # TEXT record write_byte(buf, 0b0101_1011) # 0CNX_YRTL @@ -205,7 +206,7 @@ def elem_test_text(geometry: Sequence) -> None: assert not gg.properties, msg -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -235,7 +236,7 @@ def test_file_1() -> None: name_test(layout.layers, is_textlayer=False) -def write_file_2(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_2(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -265,7 +266,7 @@ def test_file_2() -> None: name_test(layout.layers, is_textlayer=True) -def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_3(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -281,7 +282,7 @@ def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: return buf -def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_4(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_modals.py b/fatamorgana/test/test_files_modals.py index d2417f2..9eac770 100644 --- a/fatamorgana/test/test_files_modals.py +++ b/fatamorgana/test/test_files_modals.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte @@ -20,7 +20,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_paths.py b/fatamorgana/test/test_files_paths.py index 8fb2cc0..3243a79 100644 --- a/fatamorgana/test/test_files_paths.py +++ b/fatamorgana/test/test_files_paths.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from numpy.testing import assert_equal @@ -26,7 +26,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.cells[0].properties -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_placements.py b/fatamorgana/test/test_files_placements.py index 390876e..290ffee 100644 --- a/fatamorgana/test/test_files_placements.py +++ b/fatamorgana/test/test_files_placements.py @@ -1,11 +1,12 @@ # type: ignore -from typing import Tuple -from io import BytesIO, BufferedIOBase +from typing import Tuple, IO, cast, List +from io import BytesIO from numpy.testing import assert_equal from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte, write_float32, write_float64 +from ..records import Rectangle from ..main import OasisLayout @@ -21,7 +22,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_rectangle(buf: BufferedIOBase, pos: Tuple[int, int] = (300, -400)) -> None: +def write_rectangle(buf: IO[bytes], pos: Tuple[int, int] = (300, -400)) -> None: write_uint(buf, 20) # RECTANGLE record write_byte(buf, 0b0111_1011) # SWHX_YRDL write_uint(buf, 1) # layer @@ -32,7 +33,7 @@ def write_rectangle(buf: BufferedIOBase, pos: Tuple[int, int] = (300, -400)) -> write_sint(buf, pos[1]) # geometry-y (absolute) -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -173,7 +174,7 @@ def test_file_1() -> None: assert not layout.cells[1].properties assert not layout.cells[1].geometry - geometry = layout.cells[0].geometry + geometry = cast(List[Rectangle], layout.cells[0].geometry) assert len(geometry) == 1 assert geometry[0].layer == 1 assert geometry[0].datatype == 2 @@ -248,7 +249,7 @@ def test_file_1() -> None: assert placements[12].repetition.b_vector == [-330, 330] -def write_file_common(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_common(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' assert variant in (2, 3, 5, 7), 'Error in test definition!' @@ -514,7 +515,7 @@ def common_tests(layout: OasisLayout, variant: int) -> None: assert placements[6].y == 2400 -def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_4(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -593,7 +594,7 @@ def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: return buf -def write_file_6(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_6(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -746,7 +747,7 @@ def test_file_6() -> None: assert pp.y == [0, 1000][ii], msg -def write_file_8(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_8(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -842,7 +843,7 @@ def test_file_8() -> None: assert not layout.cells[2].properties assert not layout.cells[2].placements - geometry = layout.cells[2].geometry + geometry = cast(List[Rectangle], layout.cells[2].geometry) assert len(geometry) == 1 assert geometry[0].layer == 1 assert geometry[0].datatype == 2 diff --git a/fatamorgana/test/test_files_polygons.py b/fatamorgana/test/test_files_polygons.py index 2deb808..f89a019 100644 --- a/fatamorgana/test/test_files_polygons.py +++ b/fatamorgana/test/test_files_polygons.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO import numpy from numpy.testing import assert_equal @@ -106,7 +106,7 @@ def common_tests(layout: OasisLayout) -> None: assert_equal(geometry[ii].point_list, [[0, 150], [50, 0], [0, -50], [50, 0], [0, -100], [-100, 0]], err_msg=msg) -def write_file_common(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_common(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' assert variant in (1, 3), 'Error in test!!' @@ -375,7 +375,7 @@ def test_file_1() -> None: assert not gg.properties, f'Fail on polygon {ii}' -def write_file_2(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_2(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_properties.py b/fatamorgana/test/test_files_properties.py index 107b64a..99bdc37 100644 --- a/fatamorgana/test/test_files_properties.py +++ b/fatamorgana/test/test_files_properties.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO import pytest from numpy.testing import assert_equal @@ -23,7 +23,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.layers -def write_file_common(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_common(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' include_repetitions = variant in (2, 5) @@ -354,7 +354,7 @@ def test_file_5() -> None: assert gg.repetition.b_vector == [0, 320], msg -def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_3(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -579,7 +579,7 @@ def test_file_3() -> None: assert geometry[ii].properties[0].values[1].string == 'PROP_VALUE2', msg -def write_file_4_6(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_4_6(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' buf.write(HEADER) @@ -927,7 +927,7 @@ def test_file_6() -> None: assert placements[ii].properties[0].values[1].string == 'PROP_VALUE2', msg -def write_file_7_8_9(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_7_8_9(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' buf.write(HEADER) diff --git a/fatamorgana/test/test_files_rectangles.py b/fatamorgana/test/test_files_rectangles.py index e9f0b99..a7ffdc7 100644 --- a/fatamorgana/test/test_files_rectangles.py +++ b/fatamorgana/test/test_files_rectangles.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte @@ -74,7 +74,7 @@ def base_tests(layout: OasisLayout) -> None: assert geometry[10].repetition.x_displacements == [200, 300] -def write_file_common(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_common(buf: IO[bytes], variant: int) -> IO[bytes]: ''' ''' assert variant in (1, 2), 'Error in test!!' diff --git a/fatamorgana/test/test_files_texts.py b/fatamorgana/test/test_files_texts.py index 0ee22a0..0d10744 100644 --- a/fatamorgana/test/test_files_texts.py +++ b/fatamorgana/test/test_files_texts.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO import pytest @@ -99,7 +99,7 @@ def common_tests(layout: OasisLayout) -> None: assert geometry[19].repetition.y_displacements == [12, -9] -def write_file_common(buf: BufferedIOBase, variant: int) -> BufferedIOBase: +def write_file_common(buf: IO[bytes], variant: int) -> IO[bytes]: ''' Single cell with explicit name 'XYZ' ''' @@ -460,7 +460,7 @@ def test_file_12() -> None: assert layout.textstrings[2].string == 'B' -def write_file_3(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_3(buf: IO[bytes]) -> IO[bytes]: ''' File with one textstring with explicit id, and one with an implicit id. Should fail. @@ -497,7 +497,7 @@ def test_file_3() -> None: layout = OasisLayout.read(buf) -def write_file_4(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_4(buf: IO[bytes]) -> IO[bytes]: ''' File with a TEXT record that references a non-existent TEXTSTRING @@ -537,7 +537,7 @@ def test_file_4() -> None: base_tests(layout) -def write_file_6(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_6(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses an un-filled modal for the repetition ''' @@ -570,7 +570,7 @@ def test_file_6() -> None: layout = OasisLayout.read(buf) -def write_file_7(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_7(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses an un-filled modal for the layer ''' @@ -601,7 +601,7 @@ def test_file_7() -> None: layout = OasisLayout.read(buf) -def write_file_8(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_8(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses an un-filled modal for the datatype ''' @@ -632,7 +632,7 @@ def test_file_8() -> None: layout = OasisLayout.read(buf) -def write_file_9(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_9(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses a default modal for the x coordinate ''' @@ -668,7 +668,7 @@ def test_file_9() -> None: assert text.y == -200 -def write_file_10(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_10(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses a default modal for the y coordinate ''' @@ -704,7 +704,7 @@ def test_file_10() -> None: assert text.x == 100 -def write_file_11(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_11(buf: IO[bytes]) -> IO[bytes]: ''' File with TEXT record that uses an un-filled modal for the text string ''' diff --git a/fatamorgana/test/test_files_trapezoids.py b/fatamorgana/test/test_files_trapezoids.py index 574054d..cea3123 100644 --- a/fatamorgana/test/test_files_trapezoids.py +++ b/fatamorgana/test/test_files_trapezoids.py @@ -1,6 +1,6 @@ # type: ignore - -from io import BytesIO, BufferedIOBase +from typing import IO +from io import BytesIO from .utils import HEADER, FOOTER from ..basic import write_uint, write_sint, write_bstring, write_byte @@ -24,7 +24,7 @@ def base_tests(layout: OasisLayout) -> None: assert not layout.cells[0].properties -def write_file_1(buf: BufferedIOBase) -> BufferedIOBase: +def write_file_1(buf: IO[bytes]) -> IO[bytes]: ''' ''' buf.write(HEADER)