mirror of
https://github.com/gotson/komga.git
synced 2026-05-08 12:35:30 +02:00
test: add tests for EpubMetadataProvider.kt
This commit is contained in:
parent
d3b57753f0
commit
bb70bcd91d
4 changed files with 331 additions and 0 deletions
|
|
@ -8,4 +8,20 @@ class Author(
|
|||
val role = role.trim().toLowerCase()
|
||||
|
||||
override fun toString(): String = "Author($name, $role)"
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Author) return false
|
||||
|
||||
if (name != other.name) return false
|
||||
if (role != other.role) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = name.hashCode()
|
||||
result = 31 * result + role.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
package org.gotson.komga.infrastructure.metadata.epub
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.apache.commons.validator.routines.ISBNValidator
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.model.BookWithMedia
|
||||
import org.gotson.komga.domain.model.Media
|
||||
import org.gotson.komga.domain.model.SeriesMetadata
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.infrastructure.mediacontainer.EpubExtractor
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.core.io.ClassPathResource
|
||||
import java.time.LocalDate
|
||||
|
||||
class EpubMetadataProviderTest {
|
||||
|
||||
private val mockExtractor = mockk<EpubExtractor>()
|
||||
private val isbnValidator = ISBNValidator(true)
|
||||
private val epubMetadataProvider = EpubMetadataProvider(mockExtractor, isbnValidator)
|
||||
|
||||
private val book = makeBook("book")
|
||||
private val media = Media(
|
||||
status = Media.Status.READY,
|
||||
mediaType = "application/epub+zip",
|
||||
)
|
||||
|
||||
@Nested
|
||||
inner class Book {
|
||||
|
||||
@Test
|
||||
fun `given epub 3 opf when getting book metadata then metadata patch is valid`() {
|
||||
val opf = ClassPathResource("epub/Panik im Paradies.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getBookMetadataFromBook(BookWithMedia(book, media))
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isEqualTo("Panik im Paradies")
|
||||
assertThat(summary).isEqualTo("Bereits im ersten Band \"Panik im Paradies\" machen die drei berühmten Detektive ihrem Namen alle Ehre. Eigentlich haben sie ja gerade Ferien. Doch dann treffen sie auf diesen schrulligen Kapitän Larsson, der sich einen kleinen Privatzoo mit exotischen Tieren hält. Als plötzlich alle Tiere an rätselhaften Infektionen erkranken und die Besucher ausbleiben, werden Justus, Peter und Bob neugierig. Schon bald merken sie, daß da jemand ein düsteres Geheimnis hütet...")
|
||||
assertThat(releaseDate).isEqualTo(LocalDate.of(1999, 7, 31))
|
||||
assertThat(authors).containsExactlyInAnyOrder(
|
||||
Author("Blanck, Ulf", "writer"),
|
||||
Author("Editor, The", "editor"),
|
||||
)
|
||||
assertThat(isbn).isEqualTo("9783440077894")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given epub 2 opf when getting book metadata then metadata patch is valid`() {
|
||||
val opf = ClassPathResource("epub/1979.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getBookMetadataFromBook(BookWithMedia(book, media))
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isEqualTo("1979")
|
||||
assertThat(summary).isEqualTo("Auf dem Weg nach Teheran sah ich aus dem Autofenster, mir wurde etwas übel und ich hielt mich an Christophers Knie fest. Sein Hosenbein war von den aufgeplatzten Blasen ganz naß. Wir fuhren an endlosen Reihen von Birken vorbei. Ich schlief.Später hielten wir an, um uns zu erfrischen. Ich trank ein Glas Tee, Christopher eine Limonade. Es wurde sehr rasch Nacht.Es gab einige Militärkontrollen, denn seit September herrschte Kriegsrecht, was ja eigentlich nichts zu bedeuten hatte in diesen Ländern, sagte Christopher. Wir wurden weitergewunken, einmal sah ich einen Arm, eine weiße Bandage darum und eine Taschenlampe, die uns ins Gesicht schien, dann ging es weiter.Die Luft war staubig, ab und zu roch es im Wagen nach Mais. Wir hatten nur zwei Kassetten dabei; wir hörten erst Blondie, dann Devo, dann wieder Blondie. Es waren Christophers Kassetten.CHRISTIAN KRACHT, 1966 geboren, ist Schweizer. Das Foto zeigt den Autor auf der Landstraße nach Tashigang, Tibet, Volksrepublik China.GESTALTUNG: PAUL BARNES UND PETER SAVILLEFOTO: ECKHART NICKEL")
|
||||
assertThat(releaseDate).isEqualTo(LocalDate.of(101, 1, 1))
|
||||
assertThat(authors).containsExactlyInAnyOrder(
|
||||
Author("Kracht, Christian", "writer"),
|
||||
Author("Editor, The", "editor"),
|
||||
)
|
||||
assertThat(isbn).isNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Series {
|
||||
|
||||
@Test
|
||||
fun `given epub 3 opf when getting series metadata then metadata patch is valid`() {
|
||||
val opf = ClassPathResource("epub/Panik im Paradies.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isEqualTo("Die drei ??? Kids")
|
||||
assertThat(titleSort).isEqualTo("Die drei ??? Kids")
|
||||
assertThat(readingDirection).isEqualTo(SeriesMetadata.ReadingDirection.RIGHT_TO_LEFT)
|
||||
assertThat(publisher).isEqualTo("Kosmos")
|
||||
assertThat(language).isEqualTo("de")
|
||||
assertThat(genres).containsExactlyInAnyOrder("Kinder- und Jugendbücher")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given epub 2 opf when getting series metadata then metadata patch is valid`() {
|
||||
val opf = ClassPathResource("epub/1979.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isNull()
|
||||
assertThat(titleSort).isNull()
|
||||
assertThat(readingDirection).isNull()
|
||||
assertThat(publisher).isNull()
|
||||
assertThat(language).isEqualTo("de")
|
||||
assertThat(genres).isNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
komga/src/test/resources/epub/1979.opf
Executable file
78
komga/src/test/resources/epub/1979.opf
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="uuid_id" version="2.0">
|
||||
<metadata xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata" xmlns:opf="http://www.idpf.org/2007/opf"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
>
|
||||
<dc:language>de</dc:language>
|
||||
<meta name="cover" content="cover"/>
|
||||
<meta name="calibre:timestamp" content="2014-12-05T19:43:29.849000+00:00"/>
|
||||
<dc:contributor opf:role="bkp">calibre (2.10.0) [http://calibre-ebook.com]</dc:contributor>
|
||||
<dc:description><div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">Auf dem Weg nach Teheran sah ich aus dem Autofenster, mir wurde etwas übel und ich hielt mich an Christophers Knie fest. Sein Hosenbein war von den aufgeplatzten Blasen ganz naß. Wir fuhren an endlosen Reihen von Birken vorbei. Ich schlief.</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">Später hielten wir an, um uns zu erfrischen. Ich trank ein Glas Tee, Christopher eine Limonade. Es wurde sehr rasch Nacht.</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">Es gab einige Militärkontrollen, denn seit September herrschte Kriegsrecht, was ja eigentlich nichts zu bedeuten hatte in diesen Ländern, sagte Christopher. Wir wurden weitergewunken, einmal sah ich einen Arm, eine weiße Bandage darum und eine Taschenlampe, die uns ins Gesicht schien, dann ging es weiter.</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">Die Luft war staubig, ab und zu roch es im Wagen nach Mais. Wir hatten nur zwei Kassetten dabei; wir hörten erst Blondie, dann Devo, dann wieder Blondie. Es waren Christophers Kassetten.</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">CHRISTIAN KRACHT, 1966 geboren, ist Schweizer. Das Foto zeigt den Autor auf der Landstraße nach Tashigang, Tibet, Volksrepublik China.</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;"><br></span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">GESTALTUNG: PAUL BARNES UND PETER SAVILLE</span></font></div><div><font face="MS Shell Dlg 2, sans-serif"><span style="font-size: 14px;">FOTO: ECKHART NICKEL</span></font></div><div style="font-family: 'MS Shell Dlg 2', sans-serif; font-size: 14px;"><br></div></div></dc:description>
|
||||
<dc:creator opf:file-as="Kracht, Christian" opf:role="aut">Kracht, Christian</dc:creator>
|
||||
<dc:creator opf:file-as="Editor, The" opf:role="edt">The Editor</dc:creator>
|
||||
<meta name="calibre:title_sort" content="1979"/>
|
||||
<dc:identifier id="uuid_id" opf:scheme="uuid">84b3a7d8-eb3f-4fd8-ad65-4e3f75d019f9</dc:identifier>
|
||||
<dc:identifier opf:scheme="calibre">84b3a7d8-eb3f-4fd8-ad65-4e3f75d019f9</dc:identifier>
|
||||
<dc:date>0101-01-01T00:00:00+00:00</dc:date>
|
||||
<dc:title>1979</dc:title>
|
||||
</metadata>
|
||||
<manifest>
|
||||
<item href="cover.jpeg" id="cover" media-type="image/jpeg"/>
|
||||
<item href="1979_split_000.htm" id="html22" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_001.htm" id="html21" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_002.htm" id="html20" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_003.htm" id="html19" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_004.htm" id="html18" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_005.htm" id="html17" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_006.htm" id="html16" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_007.htm" id="html15" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_008.htm" id="html14" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_009.htm" id="html13" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_010.htm" id="html12" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_011.htm" id="html11" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_012.htm" id="html10" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_013.htm" id="html9" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_014.htm" id="html8" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_015.htm" id="html7" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_016.htm" id="html6" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_017.htm" id="html5" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_018.htm" id="html4" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_019.htm" id="html3" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_020.htm" id="html2" media-type="application/xhtml+xml"/>
|
||||
<item href="1979_split_021.htm" id="html1" media-type="application/xhtml+xml"/>
|
||||
<item href="aa026-145.png" id="added" media-type="image/png"/>
|
||||
<item href="aa026-146.png" id="added1" media-type="image/png"/>
|
||||
<item href="page_styles.css" id="page_css" media-type="text/css"/>
|
||||
<item href="stylesheet.css" id="css" media-type="text/css"/>
|
||||
<item href="titlepage.xhtml" id="titlepage" media-type="application/xhtml+xml"/>
|
||||
<item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml"/>
|
||||
</manifest>
|
||||
<spine toc="ncx">
|
||||
<itemref idref="titlepage"/>
|
||||
<itemref idref="html22"/>
|
||||
<itemref idref="html21"/>
|
||||
<itemref idref="html20"/>
|
||||
<itemref idref="html19"/>
|
||||
<itemref idref="html18"/>
|
||||
<itemref idref="html17"/>
|
||||
<itemref idref="html16"/>
|
||||
<itemref idref="html15"/>
|
||||
<itemref idref="html14"/>
|
||||
<itemref idref="html13"/>
|
||||
<itemref idref="html12"/>
|
||||
<itemref idref="html11"/>
|
||||
<itemref idref="html10"/>
|
||||
<itemref idref="html9"/>
|
||||
<itemref idref="html8"/>
|
||||
<itemref idref="html7"/>
|
||||
<itemref idref="html6"/>
|
||||
<itemref idref="html5"/>
|
||||
<itemref idref="html4"/>
|
||||
<itemref idref="html3"/>
|
||||
<itemref idref="html2"/>
|
||||
<itemref idref="html1"/>
|
||||
</spine>
|
||||
<guide>
|
||||
<reference href="titlepage.xhtml" title="Cover" type="cover"/>
|
||||
</guide>
|
||||
</package>
|
||||
128
komga/src/test/resources/epub/Panik im Paradies.opf
Normal file
128
komga/src/test/resources/epub/Panik im Paradies.opf
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="uuid_id" prefix="calibre: https://calibre-ebook.com">
|
||||
<metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/"
|
||||
xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata">
|
||||
<dc:title id="id">Panik im Paradies</dc:title>
|
||||
<dc:creator id="id-1">Ulf Blanck</dc:creator>
|
||||
<dc:creator id="id-3">The Editor</dc:creator>
|
||||
<dc:identifier>goodreads:222735</dc:identifier>
|
||||
<dc:identifier>isbn:9783440077894</dc:identifier>
|
||||
<dc:identifier>calibre:255</dc:identifier>
|
||||
<dc:identifier>uuid:499def46-39dc-4e79-b474-d0ec12ea5dc5</dc:identifier>
|
||||
<dc:identifier id="uuid_id">uuid:499def46-39dc-4e79-b474-d0ec12ea5dc5</dc:identifier>
|
||||
<dc:language>de</dc:language>
|
||||
<dc:date>1999-07-31T16:00:00+00:00</dc:date>
|
||||
<dc:description><div>
|
||||
<p>Bereits im ersten Band "Panik im Paradies" machen die drei berühmten Detektive ihrem Namen alle Ehre. Eigentlich haben sie ja gerade Ferien. Doch dann treffen sie auf diesen schrulligen Kapitän Larsson, der sich einen kleinen Privatzoo mit exotischen Tieren hält. Als plötzlich alle Tiere an rätselhaften Infektionen erkranken und die Besucher ausbleiben, werden Justus, Peter und Bob neugierig. Schon bald merken sie, daß da jemand ein düsteres Geheimnis hütet...</p></div></dc:description>
|
||||
<dc:publisher>Kosmos</dc:publisher>
|
||||
<dc:subject>Kinder- und Jugendbücher</dc:subject>
|
||||
<opf:meta refines="#id" property="title-type">main</opf:meta>
|
||||
<opf:meta refines="#id" property="file-as">Panik im Paradies</opf:meta>
|
||||
<meta name="cover" content="cover"/>
|
||||
<meta property="calibre:timestamp" scheme="dcterms:W3CDTF">2020-08-09T08:40:58Z</meta>
|
||||
<meta property="dcterms:modified" scheme="dcterms:W3CDTF">2021-06-19T08:20:33Z</meta>
|
||||
<opf:meta refines="#id-1" property="role" scheme="marc:relators">aut</opf:meta>
|
||||
<opf:meta refines="#id-1" property="file-as">Blanck, Ulf</opf:meta>
|
||||
<opf:meta refines="#id-3" property="role" scheme="marc:relators">edt</opf:meta>
|
||||
<opf:meta refines="#id-3" property="file-as">Editor, The</opf:meta>
|
||||
<opf:meta property="calibre:rating">6</opf:meta>
|
||||
<opf:meta property="belongs-to-collection" id="id-2">Die drei ??? Kids</opf:meta>
|
||||
<opf:meta refines="#id-2" property="collection-type">series</opf:meta>
|
||||
<opf:meta refines="#id-2" property="group-position">1</opf:meta>
|
||||
<opf:meta property="calibre:author_link_map">{"Ulf Blanck": ""}</opf:meta>
|
||||
</metadata>
|
||||
<manifest>
|
||||
<item id="titlepage" href="titlepage.xhtml" media-type="application/xhtml+xml" properties="svg calibre:title-page"/>
|
||||
<item id="TableOfContents_html" href="OPS/TableOfContents.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0001_html" href="OPS/section-0001.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0002_html" href="OPS/section-0002.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0003_html" href="OPS/section-0003.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0004_html" href="OPS/section-0004.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0005_html" href="OPS/section-0005.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0006_html" href="OPS/section-0006.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0007_html" href="OPS/section-0007.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0008_html" href="OPS/section-0008.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0009_html" href="OPS/section-0009.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0010_html" href="OPS/section-0010.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0011_html" href="OPS/section-0011.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0012_html" href="OPS/section-0012.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0013_html" href="OPS/section-0013.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0014_html" href="OPS/section-0014.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0015_html" href="OPS/section-0015.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0016_html" href="OPS/section-0016.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0017_html" href="OPS/section-0017.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0018_html" href="OPS/section-0018.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0019_html" href="OPS/section-0019.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0020_html" href="OPS/section-0020.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0021_html" href="OPS/section-0021.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0022_html" href="OPS/section-0022.html" media-type="application/xhtml+xml"/>
|
||||
<item id="section-0023_html" href="OPS/section-0023.html" media-type="application/xhtml+xml"/>
|
||||
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
|
||||
<item id="page_css" href="page_styles.css" media-type="text/css"/>
|
||||
<item id="css" href="stylesheet.css" media-type="text/css"/>
|
||||
<item id="cover" href="cover.jpeg" media-type="image/jpeg" properties="cover-image"/>
|
||||
<item id="image0_jpg" href="OPS/image0.jpg" media-type="image/jpeg"/>
|
||||
<item id="image1_jpg" href="OPS/image1.jpg" media-type="image/jpeg"/>
|
||||
<item id="image10_jpg" href="OPS/image10.jpg" media-type="image/jpeg"/>
|
||||
<item id="image11_jpg" href="OPS/image11.jpg" media-type="image/jpeg"/>
|
||||
<item id="image12_jpg" href="OPS/image12.jpg" media-type="image/jpeg"/>
|
||||
<item id="image13_jpg" href="OPS/image13.jpg" media-type="image/jpeg"/>
|
||||
<item id="image14_jpg" href="OPS/image14.jpg" media-type="image/jpeg"/>
|
||||
<item id="image15_jpg" href="OPS/image15.jpg" media-type="image/jpeg"/>
|
||||
<item id="image16_jpg" href="OPS/image16.jpg" media-type="image/jpeg"/>
|
||||
<item id="image17_jpg" href="OPS/image17.jpg" media-type="image/jpeg"/>
|
||||
<item id="image18_jpg" href="OPS/image18.jpg" media-type="image/jpeg"/>
|
||||
<item id="image19_jpg" href="OPS/image19.jpg" media-type="image/jpeg"/>
|
||||
<item id="image2_jpg" href="OPS/image2.jpg" media-type="image/jpeg"/>
|
||||
<item id="image20_jpg" href="OPS/image20.jpg" media-type="image/jpeg"/>
|
||||
<item id="image21_jpg" href="OPS/image21.jpg" media-type="image/jpeg"/>
|
||||
<item id="image22_jpg" href="OPS/image22.jpg" media-type="image/jpeg"/>
|
||||
<item id="image23_jpg" href="OPS/image23.jpg" media-type="image/jpeg"/>
|
||||
<item id="image24_jpg" href="OPS/image24.jpg" media-type="image/jpeg"/>
|
||||
<item id="image25_jpg" href="OPS/image25.jpg" media-type="image/jpeg"/>
|
||||
<item id="image26_jpg" href="OPS/image26.jpg" media-type="image/jpeg"/>
|
||||
<item id="image27_jpg" href="OPS/image27.jpg" media-type="image/jpeg"/>
|
||||
<item id="image28_jpg" href="OPS/image28.jpg" media-type="image/jpeg"/>
|
||||
<item id="image29_jpg" href="OPS/image29.jpg" media-type="image/jpeg"/>
|
||||
<item id="image3_jpg" href="OPS/image3.jpg" media-type="image/jpeg"/>
|
||||
<item id="image30_jpg" href="OPS/image30.jpg" media-type="image/jpeg"/>
|
||||
<item id="image31_jpg" href="OPS/image31.jpg" media-type="image/jpeg"/>
|
||||
<item id="image32_jpg" href="OPS/image32.jpg" media-type="image/jpeg"/>
|
||||
<item id="image33_jpg" href="OPS/image33.jpg" media-type="image/jpeg"/>
|
||||
<item id="image34_jpg" href="OPS/image34.jpg" media-type="image/jpeg"/>
|
||||
<item id="image35_jpg" href="OPS/image35.jpg" media-type="image/jpeg"/>
|
||||
<item id="image4_jpg" href="OPS/image4.jpg" media-type="image/jpeg"/>
|
||||
<item id="image5_jpg" href="OPS/image5.jpg" media-type="image/jpeg"/>
|
||||
<item id="image6_jpg" href="OPS/image6.jpg" media-type="image/jpeg"/>
|
||||
<item id="image7_jpg" href="OPS/image7.jpg" media-type="image/jpeg"/>
|
||||
<item id="image8_jpg" href="OPS/image8.jpg" media-type="image/jpeg"/>
|
||||
<item id="image9_jpg" href="OPS/image9.jpg" media-type="image/jpeg"/>
|
||||
</manifest>
|
||||
<spine page-progression-direction="rtl">
|
||||
<itemref idref="titlepage"/>
|
||||
<itemref idref="TableOfContents_html"/>
|
||||
<itemref idref="section-0001_html"/>
|
||||
<itemref idref="section-0002_html"/>
|
||||
<itemref idref="section-0003_html"/>
|
||||
<itemref idref="section-0004_html"/>
|
||||
<itemref idref="section-0005_html"/>
|
||||
<itemref idref="section-0006_html"/>
|
||||
<itemref idref="section-0007_html"/>
|
||||
<itemref idref="section-0008_html"/>
|
||||
<itemref idref="section-0009_html"/>
|
||||
<itemref idref="section-0010_html"/>
|
||||
<itemref idref="section-0011_html"/>
|
||||
<itemref idref="section-0012_html"/>
|
||||
<itemref idref="section-0013_html"/>
|
||||
<itemref idref="section-0014_html"/>
|
||||
<itemref idref="section-0015_html"/>
|
||||
<itemref idref="section-0016_html"/>
|
||||
<itemref idref="section-0017_html"/>
|
||||
<itemref idref="section-0018_html"/>
|
||||
<itemref idref="section-0019_html"/>
|
||||
<itemref idref="section-0020_html"/>
|
||||
<itemref idref="section-0021_html"/>
|
||||
<itemref idref="section-0022_html"/>
|
||||
<itemref idref="section-0023_html"/>
|
||||
</spine>
|
||||
</package>
|
||||
Loading…
Reference in a new issue