diff --git a/components/IscnRegisterForm.vue b/components/IscnRegisterForm.vue
index 9a7c19ba..c2230a32 100644
--- a/components/IscnRegisterForm.vue
+++ b/components/IscnRegisterForm.vue
@@ -355,6 +355,15 @@
:placeholder="$t('IscnRegisterForm.placeholder.url')"
/>
+
+
+
@@ -740,6 +750,7 @@ export enum AuthorDialogType {
export default class IscnRegisterForm extends Vue {
@Prop({ default: [] }) readonly fileRecords!: any[]
@Prop({ default: [] }) readonly uploadArweaveList!: string[]
+ @Prop() readonly epubMetadata!: any | null
@Prop(String) readonly ipfsHash!: string
@Prop(String) readonly arweaveId!: string
@@ -759,7 +770,7 @@ export default class IscnRegisterForm extends Vue {
fileTypeOptions = [
'epub',
'pdf',
- 'mp3',
+ 'audio',
'jpg',
'png',
]
@@ -784,8 +795,10 @@ export default class IscnRegisterForm extends Vue {
tags: string[] = []
sameAs: string[] = []
url: string = ''
+ isbn: string = ''
license: string = this.licenseOptions[0]
customLicense: string = ''
+ thumbnailUrl: string = ''
authorName: string = ''
authorUrl: string[] = []
authorWalletAddress: string[] = []
@@ -834,6 +847,7 @@ export default class IscnRegisterForm extends Vue {
currentAuthorDialogType: AuthorDialogType = AuthorDialogType.stakeholder
sameAsList: any = []
+ language: string = ''
get ipfsHashList() {
const list = []
@@ -987,6 +1001,7 @@ export default class IscnRegisterForm extends Vue {
tagsString: this.tagsString,
sameAs: this.formattedSameAsList,
url: this.url,
+ isbn: this.isbn,
exifInfo: this.exif.filter(file => file),
license: this.formattedLicense,
ipfsHash: this.ipfsHashList,
@@ -1001,6 +1016,8 @@ export default class IscnRegisterForm extends Vue {
likerIdsAddresses: this.likerIdsAddresses,
authorDescriptions: this.authorDescriptions,
contentFingerprints: this.customContentFingerprints,
+ inLanguage: this.language,
+ thumbnailUrl: this.thumbnailUrl,
}
}
@@ -1084,6 +1101,16 @@ export default class IscnRegisterForm extends Vue {
}
async mounted() {
+ if (this.epubMetadata) {
+ this.name = this.epubMetadata.title;
+ this.description = this.extractText(this.epubMetadata.description);
+ this.author.name = this.epubMetadata.author;
+ this.language = this.epubMetadata.language
+ this.tags = this.epubMetadata.tags
+ this.thumbnailUrl = this.formatArweave(this.epubMetadata.thumbnailUrl) as string
+ if (this.author.name) { this.authors.push(this.author) }
+ }
+
this.uploadStatus = 'loading'
// ISCN Fee needs Arweave fee to calculate
await this.calculateISCNFee()
@@ -1433,5 +1460,14 @@ export default class IscnRegisterForm extends Vue {
this.displayImageSrc = this.fileRecords[index].fileData
this.displayExifInfo = this.fileRecords[index].exifInfo
}
+
+ // eslint-disable-next-line class-methods-use-this
+ extractText(htmlString: string) {
+ if (!htmlString) return ''
+ const div = document.createElement('div');
+ div.innerHTML = htmlString;
+ div.innerHTML = div.innerHTML.replace(/
/gi, "\n");
+ return div.textContent || div.innerText;
+ }
}
diff --git a/components/IscnUploadForm.vue b/components/IscnUploadForm.vue
index 7ef8fea9..2f7a831f 100644
--- a/components/IscnUploadForm.vue
+++ b/components/IscnUploadForm.vue
@@ -227,6 +227,7 @@ import { namespace } from 'vuex-class'
import exifr from 'exifr'
import Hash from 'ipfs-only-hash'
import BigNumber from 'bignumber.js'
+import ePub from 'epubjs';
import { OfflineSigner } from '@cosmjs/proto-signing'
@@ -282,8 +283,6 @@ export default class UploadForm extends Vue {
string, { transactionHash?: string, arweaveId?: string }
>()
-
-
likerId: string = ''
error: string = ''
shouldShowAlert = false
@@ -292,6 +291,8 @@ export default class UploadForm extends Vue {
signDialogError = ''
balance = new BigNumber(0)
+ epubMetadataList: any[] = []
+
get formClasses() {
return [
'flex',
@@ -356,7 +357,7 @@ export default class UploadForm extends Vue {
case 'MISSING_SIGNER':
return this.$t('IscnRegisterForm.error.missingSigner')
default:
- return ''
+ return this.error
}
}
@@ -442,6 +443,10 @@ export default class UploadForm extends Vue {
console.error(err)
}
}
+ if (file.type === 'application/epub+zip') {
+ // eslint-disable-next-line no-await-in-loop
+ await this.processEPub({ buffer: fileBytes, file })
+ }
}
} else {
this.isSizeExceeded = true
@@ -451,6 +456,109 @@ export default class UploadForm extends Vue {
}
}
+ async processEPub({ buffer, file }: { buffer: ArrayBuffer; file: File }) {
+ try {
+ const book = ePub(buffer)
+ await book.ready
+ const epubMetadata: any = {}
+
+ // Get metadata
+ const { metadata } = book.packaging
+ if (metadata) {
+ epubMetadata.epubFileName = file.name
+ epubMetadata.title = metadata.title
+ epubMetadata.author = metadata.creator
+ epubMetadata.language = this.formatLanguage(metadata.language)
+ epubMetadata.description = metadata.description
+ }
+
+ // Get tags
+ const opfFilePath = await (book.path as any).path
+ const opfContent = await book.archive.getText(opfFilePath)
+ const parser = new DOMParser()
+ const opfDocument = parser.parseFromString(opfContent, 'application/xml')
+ const dcSubjectElements = opfDocument.querySelectorAll(
+ 'dc\\:subject, subject',
+ )
+ const subjects: string[] = []
+ dcSubjectElements.forEach((element) => {
+ const subject = element.textContent
+ if (subject) {
+ subjects.push(subject)
+ }
+ })
+ epubMetadata.tags = subjects
+
+ // Get cover file
+ const coverUrl = await book.coverUrl()
+ if (coverUrl) {
+ const response = await fetch(coverUrl)
+ const blobData = await response.blob()
+ if (blobData) {
+ const coverFile = new File(
+ [blobData],
+ `${metadata.title}_cover.jpeg`,
+ {
+ type: 'image/jpeg',
+ },
+ )
+ const fileBytes = (await fileToArrayBuffer(
+ coverFile,
+ )) as unknown as ArrayBuffer
+ if (fileBytes) {
+ const [
+ fileSHA256,
+ imageType,
+ ipfsHash,
+ // eslint-disable-next-line no-await-in-loop
+ ] = await Promise.all([
+ digestFileSHA256(fileBytes),
+ readImageType(fileBytes),
+ Hash.of(Buffer.from(fileBytes)),
+ ])
+
+ epubMetadata.ipfsHash = ipfsHash
+
+ const fileRecord: any = {
+ fileName: coverFile.name,
+ fileSize: coverFile.size,
+ fileType: coverFile.type,
+ fileBlob: coverFile,
+ ipfsHash,
+ fileSHA256,
+ isFileImage: !!imageType,
+ }
+ const reader = new FileReader()
+ reader.onload = (e) => {
+ if (!e.target) return
+ fileRecord.fileData = e.target.result as string
+ this.fileRecords.push(fileRecord)
+ }
+ reader.readAsDataURL(coverFile)
+ }
+ }
+ }
+ this.epubMetadataList.push(epubMetadata)
+ } catch (err) {
+ console.error(err)
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ formatLanguage(language: string) {
+ let formattedLanguage = '';
+ if (language) {
+ if (language.toLowerCase().startsWith('en')) {
+ formattedLanguage = 'en'
+ } else if (language.toLowerCase().startsWith('zh')) {
+ formattedLanguage = 'zh'
+ } else {
+ formattedLanguage = language
+ }
+ }
+ return formattedLanguage
+ }
+
onEnterURL() {
if (
!(
@@ -472,7 +580,13 @@ export default class UploadForm extends Vue {
}
handleDeleteFile(index: number) {
- this.fileRecords.splice(index, 1)
+ const deletedFile = this.fileRecords[index];
+ this.fileRecords.splice(index, 1);
+
+ const indexToDelete = this.epubMetadataList.findIndex(item => item.ipfsHash === deletedFile.ipfsHashList);
+ if (indexToDelete !== -1) {
+ this.epubMetadataList.splice(indexToDelete, 1);
+ }
}
handleClickExifInfo(index: number) {
@@ -514,6 +628,10 @@ export default class UploadForm extends Vue {
}
if (arweaveId) {
this.sentArweaveTransactionInfo.set(ipfsHash, { transactionHash: '', arweaveId });
+ const metadata = this.epubMetadataList.find((data: any) => data.ipfsHash === ipfsHash)
+ if (metadata) {
+ metadata.thumbnailUrl = arweaveId;
+ }
}
if (!this.arweaveFeeTargetAddress) {
this.arweaveFeeTargetAddress = address;
@@ -589,19 +707,21 @@ export default class UploadForm extends Vue {
if (arweaveId) {
const uploadedData = this.sentArweaveTransactionInfo.get(records.ipfsHash) || {};
this.sentArweaveTransactionInfo.set(records.ipfsHash, { ...uploadedData, arweaveId });
+ if (tempRecord.fileName.includes('cover.jpeg')) {
+ const metadata = this.epubMetadataList.find((file: any) => file.ipfsHash === records.ipfsHash)
+ metadata.thumbnailUrl = arweaveId
+ }
this.$emit('arweaveUploaded', { arweaveId })
this.isOpenSignDialog = false
} else {
- this.shouldShowAlert = true
- this.errorMessage = this.$t('IscnRegisterForm.error.arweave') as string
- this.$emit('handleContinue')
+ this.isOpenWarningSnackbar = true
+ this.error = this.$t('IscnRegisterForm.error.arweave') as string
+ throw new Error(this.error)
}
} catch (err) {
// TODO: Handle error
// eslint-disable-next-line no-console
- console.error(err)
- this.shouldShowAlert = true
- this.errorMessage = (err as Error).toString()
+ throw new Error(err as string)
}
}
@@ -637,12 +757,26 @@ export default class UploadForm extends Vue {
} catch (error) {
// eslint-disable-next-line no-console
console.error(error)
+ this.isOpenWarningSnackbar = true
+ this.error = (error as Error).toString()
+ this.uploadStatus = '';
+ return
} finally {
this.uploadStatus = '';
}
const uploadArweaveIdList = Array.from(this.sentArweaveTransactionInfo.values()).map(entry => entry.arweaveId);
- this.$emit('submit', { fileRecords: this.fileRecords, arweaveIds: uploadArweaveIdList })
+ this.fileRecords.forEach((record: any, index:number) => {
+ if (this.sentArweaveTransactionInfo.has(record.ipfsHash)) {
+ const arweaveId = this.sentArweaveTransactionInfo.get(
+ record.ipfsHash,
+ )?.arweaveId
+ if (arweaveId) {
+ this.fileRecords[index].arweaveId = arweaveId
+ }
+ }
+ })
+ this.$emit('submit', { fileRecords: this.fileRecords, arweaveIds: uploadArweaveIdList, epubMetadata: this.epubMetadataList[0] })
}
handleSignDialogClose() {
diff --git a/components/SameAsFieldList.vue b/components/SameAsFieldList.vue
index ce882d65..73a56370 100644
--- a/components/SameAsFieldList.vue
+++ b/components/SameAsFieldList.vue
@@ -16,13 +16,13 @@
-
+
-
+
handleSelectValue({ value, index: i })"
/>
+
@Prop({ default: () => [] }) readonly currentList!: Array
+ @Prop({ default: () => [] }) readonly fileRecords!: Array
@Prop(String) readonly name!: string | undefined
sameAsList: any = [{
@@ -86,6 +94,11 @@ export default class WalletFieldList extends Vue {
filetype: SAME_AS_FILE_TYPES[0],
}]
+ fileTypeToFind = [
+ 'epub',
+ 'pdf',
+ ]
+
// eslint-disable-next-line class-methods-use-this
get sameAsFiletypeOptions() {
return SAME_AS_FILE_TYPES
@@ -101,7 +114,7 @@ export default class WalletFieldList extends Vue {
return this.name.replace(/[.,!?;:'"(){}[\]<>]/g, '').replace(/\s+/g, '_').toUpperCase();
}
- get formatUrlOptions() {
+ get filteredUrlOptions() {
return this.urlOptions.filter(url => url.startsWith('ar://'))
}
@@ -112,20 +125,30 @@ export default class WalletFieldList extends Vue {
id: `${list.url}-${list.filename}`,
filename: list.filename,
filetype: list.filetype || SAME_AS_FILE_TYPES[0],
+ originFileName: list.originFileName,
}))
- } else if (this.formatUrlOptions.length) {
- this.sameAsList = this.formatUrlOptions.map((url, index) => ({
- url,
- id: `${url}-${index}`,
- filename: this.formatName,
- filetype: SAME_AS_FILE_TYPES[0],
- }))
+ } else if (this.filteredUrlOptions.length) {
+ this.sameAsList = this.fileRecords
+ .filter((file) => this.fileTypeToFind.includes(this.formatFileType(file.fileType)) && file.arweaveId)
+ .map((file, index) => {
+ const url = this.filteredUrlOptions.find((ar) => ar.includes(file.arweaveId));
+ const formattedFileType = this.formatFileType(file.fileType);
+
+ return {
+ url,
+ id: `${url}-${index}`,
+ filename: this.formatName,
+ filetype: formattedFileType || SAME_AS_FILE_TYPES[0],
+ originFileName: file.fileName || '',
+ };
+ });
} else {
this.sameAsList = [{
url: '',
id: 1,
filename: this.formatName,
filetype: SAME_AS_FILE_TYPES[0],
+ originFileName:'',
}]
}
}
@@ -159,5 +182,35 @@ export default class WalletFieldList extends Vue {
this.deleteEmptyField()
this.$emit('onConfirm', this.sameAsList)
}
+
+ // eslint-disable-next-line class-methods-use-this
+ formatFileType(fileType: string) {
+ let formattedFileType = ''
+ if (fileType) {
+ switch (true) {
+ case fileType.includes('jpg'):
+ case fileType.includes('jpeg'):
+ formattedFileType = 'jpg'
+ break
+ case fileType.includes('png'):
+ formattedFileType = 'png'
+ break
+ case fileType.includes('audio'):
+ // audio/ogg
+ formattedFileType = 'audio'
+ break
+ case fileType.includes('pdf'):
+ formattedFileType = 'pdf'
+ break
+ case fileType.includes('epub'):
+ formattedFileType = 'epub'
+ break
+ default:
+ formattedFileType = ''
+ break
+ }
+ }
+ return formattedFileType
+ }
}
diff --git a/constant/index.ts b/constant/index.ts
index a09ffea7..c62f91c9 100644
--- a/constant/index.ts
+++ b/constant/index.ts
@@ -62,7 +62,7 @@ export const WALLET_TYPES = [
export const SAME_AS_FILE_TYPES = [
'epub',
'pdf',
- 'mp3',
+ 'audio',
'jpg',
'png',
]
diff --git a/locales/en.json b/locales/en.json
index 39698d51..db70e273 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -214,12 +214,14 @@
"IscnRegisterForm.label.emptyFile": "No Content",
"IscnRegisterForm.label.fingerprints": "Content Fingerprints",
"IscnRegisterForm.label.iscn": "ISCN Title",
+ "IscnRegisterForm.label.isbn": "ISBN",
"IscnRegisterForm.label.license": "License",
"IscnRegisterForm.label.likerID": "LikerID",
"IscnRegisterForm.label.sameAs" : "Same As URLs",
"IscnRegisterForm.label.name": "Name",
"IscnRegisterForm.label.fileName": "File name",
"IscnRegisterForm.label.fileType": "File type",
+ "IscnRegisterForm.label.originFile": "origin file: {name}",
"IscnRegisterForm.label.numbersProtocol": "Numbers Protocol",
"IscnRegisterForm.label.numbersProtocol.details": "Register your image asset in {link}",
"IscnRegisterForm.label.numbersProtocol.details.link": "Numbers Protocol",
@@ -238,6 +240,7 @@
"IscnRegisterForm.placeholder.fileName": "File Name (en)",
"IscnRegisterForm.placeholder.fileType": "File Type",
"IscnRegisterForm.placeholder.url": "URL",
+ "IscnRegisterForm.placeholder.isbn": "ISBN 10/ ISBN 13",
"IscnRegisterForm.placeholder.wallet": "Wallet Address",
"IscnRegisterForm.quitAlertDialog.confirm": "Cancel Registration",
"IscnRegisterForm.quitAlertDialog.content": "Your registration will be cancelled if you leave this page, and the paid fee cannot be refunded.",
diff --git a/package.json b/package.json
index 6fc46c55..0229f7a3 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"core-js": "^3.15.1",
"cosmjs-types": "^0.8.0",
"easyqrcodejs": "^4.4.6",
+ "epubjs": "^0.3.93",
"exifr": "^7.1.2",
"express": "^4.17.1",
"fast-json-stable-stringify": "^2.1.0",
diff --git a/pages/new/index.vue b/pages/new/index.vue
index 7abe7099..a71427e7 100644
--- a/pages/new/index.vue
+++ b/pages/new/index.vue
@@ -41,6 +41,7 @@
:ipfs-hash="urlIpfsHash"
:arweave-id="urlArweaveId"
:upload-arweave-list=uploadArweaveList
+ :epub-metadata="epubMetadata"
:step="step"
@txBroadcasted="onISCNTxInfo"
@@ -134,6 +135,7 @@ export default class NewIndexPage extends Vue {
uploadFileRecords: any[] = []
urlFileRecords: any[] = []
+ epubMetadata: any | null = null
get shouldSkipToMintNFT(): boolean {
return this.$route.query.mint === '1'
@@ -189,9 +191,11 @@ export default class NewIndexPage extends Vue {
onSubmitUpload({
fileRecords,
arweaveIds,
+ epubMetadata,
}: {
fileRecords: any[]
arweaveIds: string[]
+ epubMetadata: any
}) {
if (fileRecords && fileRecords.length) {
this.uploadFileRecords = [...fileRecords]
@@ -199,6 +203,9 @@ export default class NewIndexPage extends Vue {
if (arweaveIds && arweaveIds.length) {
this.uploadArweaveList = [...arweaveIds]
}
+ if (epubMetadata) {
+ this.epubMetadata = {...epubMetadata}
+ }
this.state = 'iscn'
logTrackerEvent(this, 'ISCNCreate', 'ISCNConfirmFile', '', 1)
}
diff --git a/utils/cosmos/iscn/iscn.type.ts b/utils/cosmos/iscn/iscn.type.ts
index d450ead7..7862b9ac 100644
--- a/utils/cosmos/iscn/iscn.type.ts
+++ b/utils/cosmos/iscn/iscn.type.ts
@@ -24,6 +24,9 @@ export interface ISCNRegisterPayload {
stakeholders?: any[];
recordNotes?: string;
memo?: string;
+ inLanguage?: string;
+ thumbnailUrl?: string;
+ isbn?: string;
}
export interface ISCNRecordWithID extends ISCNRecord {
id: string;
diff --git a/yarn.lock b/yarn.lock
index d592e15a..59ec1d7e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4970,6 +4970,13 @@
resolved "https://registry.yarnpkg.com/@types/less/-/less-3.0.2.tgz#2761d477678c8374cb9897666871662eb1d1115e"
integrity sha512-62vfe65cMSzYaWmpmhqCMMNl0khen89w57mByPi1OseGfcV/LV03fO8YVrNj7rFQsRWNJo650WWyh6m7p8vZmA==
+"@types/localforage@0.0.34":
+ version "0.0.34"
+ resolved "https://registry.yarnpkg.com/@types/localforage/-/localforage-0.0.34.tgz#5e31c32dd8791ec4b9ff3ef47c9cb55b2d0d9438"
+ integrity sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==
+ dependencies:
+ localforage "*"
+
"@types/lodash.chunk@^4.2.6":
version "4.2.6"
resolved "https://registry.yarnpkg.com/@types/lodash.chunk/-/lodash.chunk-4.2.6.tgz#9d35f05360b0298715d7f3d9efb34dd4f77e5d2a"
@@ -6226,6 +6233,11 @@
"@webassemblyjs/wast-parser" "1.9.0"
"@xtuc/long" "4.2.2"
+"@xmldom/xmldom@^0.7.5":
+ version "0.7.13"
+ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.13.tgz#ff34942667a4e19a9f4a0996a76814daac364cf3"
+ integrity sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==
+
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
@@ -8623,6 +8635,11 @@ core-js@^3.15.1:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.1.tgz#6c08ab88abdf56545045ccf5fd81f47f407e7f1a"
integrity sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==
+core-js@^3.18.3:
+ version "3.33.2"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb"
+ integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==
+
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -9179,6 +9196,14 @@ cyclist@^1.0.1:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
+d@1, d@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
+ integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
+ dependencies:
+ es5-ext "^0.10.50"
+ type "^1.0.1"
+
data-urls@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
@@ -9885,6 +9910,21 @@ entities@^4.2.0, entities@^4.3.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.0.tgz#62915f08d67353bb4eb67e3d62641a4059aec656"
integrity sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==
+epubjs@^0.3.93:
+ version "0.3.93"
+ resolved "https://registry.yarnpkg.com/epubjs/-/epubjs-0.3.93.tgz#100c4597db152fc07d5246be38acca928b6b0b22"
+ integrity sha512-c06pNSdBxcXv3dZSbXAVLE1/pmleRhOT6mXNZo6INKmvuKpYB65MwU/lO7830czCtjIiK9i+KR+3S+p0wtljrw==
+ dependencies:
+ "@types/localforage" "0.0.34"
+ "@xmldom/xmldom" "^0.7.5"
+ core-js "^3.18.3"
+ event-emitter "^0.3.5"
+ jszip "^3.7.1"
+ localforage "^1.10.0"
+ lodash "^4.17.21"
+ marks-pane "^1.0.9"
+ path-webpack "0.0.3"
+
err-code@^3.0.0, err-code@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920"
@@ -9984,11 +10024,29 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
+es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14:
+ version "0.10.62"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
+ integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
+ dependencies:
+ es6-iterator "^2.0.3"
+ es6-symbol "^3.1.3"
+ next-tick "^1.1.0"
+
es5-shim@^4.5.13:
version "4.5.15"
resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.15.tgz#6a26869b261854a3b045273f5583c52d390217fe"
integrity sha512-FYpuxEjMeDvU4rulKqFdukQyZSTpzhg4ScQHrAosrlVpR6GFyaw14f74yn2+4BugniIS0Frpg7TvwZocU4ZMTw==
+es6-iterator@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
+ integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
+ dependencies:
+ d "1"
+ es5-ext "^0.10.35"
+ es6-symbol "^3.1.1"
+
es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@@ -10006,6 +10064,14 @@ es6-shim@^0.35.5:
resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.6.tgz#d10578301a83af2de58b9eadb7c2c9945f7388a0"
integrity sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==
+es6-symbol@^3.1.1, es6-symbol@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
+ integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
+ dependencies:
+ d "^1.0.1"
+ ext "^1.1.2"
+
escalade@^3.0.2, escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -10344,6 +10410,14 @@ etag@^1.8.1, etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+event-emitter@^0.3.5:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
+ integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
+ dependencies:
+ d "1"
+ es5-ext "~0.10.14"
+
eventemitter3@^4.0.0, eventemitter3@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
@@ -10488,6 +10562,13 @@ express@^4.17.1:
utils-merge "1.0.1"
vary "~1.1.2"
+ext@^1.1.2:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
+ integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
+ dependencies:
+ type "^2.7.2"
+
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@@ -13693,6 +13774,16 @@ jstransformer@1.0.0:
is-promise "^2.0.0"
promise "^7.0.1"
+jszip@^3.7.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
+ integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
+ dependencies:
+ lie "~3.3.0"
+ pako "~1.0.2"
+ readable-stream "~2.3.6"
+ setimmediate "^1.0.5"
+
junk@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
@@ -13941,6 +14032,13 @@ lie@3.1.1:
dependencies:
immediate "~3.0.5"
+lie@~3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
+ integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
+ dependencies:
+ immediate "~3.0.5"
+
lilconfig@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd"
@@ -14014,7 +14112,7 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4
emojis-list "^3.0.0"
json5 "^1.0.1"
-localforage@^1.8.1:
+localforage@*, localforage@^1.10.0, localforage@^1.8.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4"
integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==
@@ -14321,6 +14419,11 @@ markdown-to-jsx@^7.1.3:
resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.3.tgz#f00bae66c0abe7dd2d274123f84cb6bd2a2c7c6a"
integrity sha512-jtQ6VyT7rMT5tPV0g2EJakEnXLiPksnvlYtwQsVVZ611JsWGN8bQ1tVSDX4s6JllfEH6wmsYxNjTUAMrPmNA8w==
+marks-pane@^1.0.9:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/marks-pane/-/marks-pane-1.0.9.tgz#c0b5ab813384d8cd81faaeb3bbf3397dc809c1b3"
+ integrity sha512-Ahs4oeG90tbdPWwAJkAAoHg2lRR8lAs9mZXETNPO9hYg3AkjUJBKi1NQ4aaIQZVGrig7c/3NUV1jANl8rFTeMg==
+
mathml-tag-names@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
@@ -14986,6 +15089,11 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
+next-tick@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
+ integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
+
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
@@ -15638,7 +15746,7 @@ p5@^1.4.0:
resolved "https://registry.yarnpkg.com/p5/-/p5-1.4.0.tgz#d4d0f001c297525831861af5e017cdb5ef517a75"
integrity sha512-U888W2ChcIzPhRhnv4FkNhaa4f5BDIWZfLhzvx9ZrQ5KtkZr/+o1UPIicV3yWTRy0HEG23NviHyDR3kgjaJ9wA==
-pako@1.0.11, pako@~1.0.5:
+pako@1.0.11, pako@~1.0.2, pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -15850,6 +15958,11 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+path-webpack@0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/path-webpack/-/path-webpack-0.0.3.tgz#ff6dec749eec5a94605c04d5f63fc55607a03a16"
+ integrity sha512-AmeDxedoo5svf7aB3FYqSAKqMxys014lVKBzy1o/5vv9CtU7U4wgGWL1dA2o6MOzcD53ScN4Jmiq6VbtLz1vIQ==
+
pbkdf2@^3.0.16, pbkdf2@^3.0.3, pbkdf2@^3.0.9, pbkdf2@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
@@ -18601,7 +18714,7 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -20086,6 +20199,16 @@ type-tagger@^1.0.0:
resolved "https://registry.yarnpkg.com/type-tagger/-/type-tagger-1.0.0.tgz#dc6297e52e17097c1b92b42c16816a18f631e7f4"
integrity sha512-FIPqqpmDgdaulCnRoKv1/d3U4xVBUrYn42QXWNP3XYmgfPUDuBUsgFOb9ntT0aIe0UsUP+lknpQ5d9Kn36RssA==
+type@^1.0.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
+ integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
+
+type@^2.7.2:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
+ integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
+
typedarray-to-buffer@3.1.5, typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"